pmdk-1.11.1/0000775000000000000000000000000014123365127011232 5ustar rootrootpmdk-1.11.1/.codecov.yml0000664000000000000000000000053314123364546013462 0ustar rootrootignore: - src/windows/ - src/test/ - src/common/valgrind/ - src/benchmarks/ comment: layout: "diff" behavior: default require_changes: yes coverage: status: project: default: threshold: 1% parsers: gcov: branch_detection: conditional: false loop: false method: false macro: false pmdk-1.11.1/.github/0000775000000000000000000000000014123364546012576 5ustar rootrootpmdk-1.11.1/.github/workflows/0000775000000000000000000000000014123364546014633 5ustar rootrootpmdk-1.11.1/.github/workflows/coverity.yml0000664000000000000000000000174714123364546017233 0ustar rootroot name: Coverity on: schedule: # run this job at 00:00 UTC every day - cron: '0 0 * * *' env: GITHUB_REPO: pmem/pmdk DOCKER_REPO: ghcr.io/pmem/pmdk COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} HOST_WORKDIR: /home/runner/work/pmdk/pmdk WORKDIR: utils/docker PMDK_CC: gcc PMDK_CXX: g++ MAKE_PKG: 0 REMOTE_TESTS: 1 VALGRIND: 1 jobs: linux: name: Linux runs-on: ubuntu-latest strategy: matrix: CONFIG: ["COVERITY=1 OS=ubuntu OS_VER=20.04"] steps: - name: Print out the current date and time run: date - name: Clone the git repo uses: actions/checkout@v2 - name: Pull or rebuild the image run: cd $WORKDIR && ${{ matrix.CONFIG }} ./pull-or-rebuild-image.sh - name: Run the build run: cd $WORKDIR && ${{ matrix.CONFIG }} ./build-CI.sh pmdk-1.11.1/.github/workflows/gha.yml0000664000000000000000000001451214123364546016120 0ustar rootroot name: PMDK on: [push, pull_request] env: GITHUB_REPO: pmem/pmdk DOCKER_REPO: ghcr.io/pmem/pmdk jobs: linux: name: Linux runs-on: ubuntu-latest env: # use org's Private Access Token to log in to GitHub Container Registry GH_CR_USER: ${{ secrets.GH_CR_USER }} GH_CR_PAT: ${{ secrets.GH_CR_PAT }} DOC_UPDATE_GITHUB_TOKEN: ${{ secrets.DOC_UPDATE_GITHUB_TOKEN }} HOST_WORKDIR: /home/runner/work/pmdk/pmdk WORKDIR: utils/docker PMDK_CC: gcc PMDK_CXX: g++ MAKE_PKG: 0 REMOTE_TESTS: 1 VALGRIND: 1 SRC_CHECKERS: 0 strategy: matrix: CONFIG: ["N=1 OS=ubuntu OS_VER=20.04 FAULT_INJECTION=1 TEST_BUILD=debug", "N=2 OS=ubuntu OS_VER=20.04 FAULT_INJECTION=1 TEST_BUILD=nondebug UBSAN=1", "N=3 OS=ubuntu OS_VER=20.04 PMDK_CC=clang PMDK_CXX=clang++ TEST_BUILD=debug SRC_CHECKERS=1", "N=4 OS=ubuntu OS_VER=20.04 PMDK_CC=clang PMDK_CXX=clang++ TEST_BUILD=nondebug", "N=5 OS=fedora OS_VER=31 PMDK_CC=clang PMDK_CXX=clang++ TEST_BUILD=debug", "N=6 OS=fedora OS_VER=31 PMDK_CC=clang PMDK_CXX=clang++ TEST_BUILD=nondebug AUTO_DOC_UPDATE=1", "N=7 OS=fedora OS_VER=31 MAKE_PKG=1 EXPERIMENTAL=y REMOTE_TESTS=0 VALGRIND=0 PMEMSET_INSTALL=y PUSH_IMAGE=1", "N=8 OS=ubuntu OS_VER=20.04 MAKE_PKG=1 EXPERIMENTAL=y REMOTE_TESTS=0 VALGRIND=0 NDCTL_ENABLE=n PMEMSET_INSTALL=y PUSH_IMAGE=1", "N=9 OS=ubuntu OS_VER=20.04 MAKE_PKG=1 EXPERIMENTAL=y REMOTE_TESTS=0 VALGRIND=0 NDCTL_ENABLE=n PMDK_CC=clang PMDK_CXX=clang++", "N=10 OS=ubuntu OS_VER=20.04 COVERAGE=1 FAULT_INJECTION=1 TEST_BUILD=debug"] steps: - name: Clone the git repo uses: actions/checkout@v2 with: fetch-depth: 50 - name: Pull or rebuild the image run: cd $WORKDIR && ${{ matrix.CONFIG }} ./pull-or-rebuild-image.sh - name: Run the build run: cd $WORKDIR && ${{ matrix.CONFIG }} ./build-CI.sh - name: Push the image run: cd $WORKDIR && source ./set-vars.sh && ${{ matrix.CONFIG }} /bin/bash -c "if [[ -f ${CI_FILE_PUSH_IMAGE_TO_REPO} ]]; then images/push-image.sh; fi" windows: name: Windows runs-on: windows-latest env: platform: x64 solutionname: PMDK.sln ex_solutionname: Examples.sln msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin" # Platform Toolset for Visual Studio 2019 platform_toolset: "v142" perl: "C:\\Strawberry\\perl\\bin" strategy: matrix: CONFIG: [Debug, Release] steps: - name: Update Path run: | echo "${env:msbuild}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "${env:perl}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Clone the git repo uses: actions/checkout@v2 - name: Unshallow it run: git fetch --prune --unshallow - name: Various debug checks (cstyle, whitespace etc.) run: | if ("${{ matrix.CONFIG }}" -eq "Release") { Install-Module PsScriptAnalyzer -Force utils/CSTYLE.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } utils/CHECK_WHITESPACE.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } utils/ps_analyze.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } perl utils/sort_solution check if ($LASTEXITCODE -ne 0) { exit 1 } ./utils/check_sdk_version.py -d . if ($LASTEXITCODE -ne 0) { exit 1 } } - name: Build run: | msbuild src\$Env:solutionname -property:Configuration=${{ matrix.CONFIG }},PlatformToolset=$Env:platform_toolset -m -v:m msbuild src\examples\$Env:ex_solutionname -property:Configuration=${{ matrix.CONFIG }},PlatformToolset=$Env:platform_toolset -m -v:m - name: Create ZIP archive run: utils/CREATE-ZIP.ps1 -b ${{ matrix.CONFIG }} - name: Run tests shell: powershell run: | if ($true) { cd src\test echo "`$Env:NON_PMEM_FS_DIR = `"C:\temp`"" >> testconfig.ps1 echo "`$Env:PMEM_FS_DIR = `"C:\temp`"" >> testconfig.ps1 echo "`$Env:PMEM_FS_DIR_FORCE_PMEM = `"1`"" >> testconfig.ps1 echo "`$Env:PMDK_NO_ABORT_MSG = `"1`"" >> testconfig.ps1 echo "`$Env:TM = `"1`"" >> testconfig.ps1 write-output "config = { 'unittest_log_level': 1, 'cacheline_fs_dir': 'C:\\temp', 'force_cacheline': True, 'page_fs_dir': 'C:\\temp', 'force_page': False, 'byte_fs_dir': 'C:\\temp', 'force_byte': True, 'tm': True, 'test_type': 'check', 'granularity': 'all', 'fs_dir_force_pmem': 1, 'keep_going': False, 'timeout': '4m', 'build': 'debug', 'force_enable': None, 'fail_on_skip': False, 'enable_admin_tests': False, }" | out-file "testconfig.py" -encoding utf8 if ("${{ matrix.CONFIG }}" -eq "Debug") { ./RUNTESTS.ps1 -b debug -o 4m if ($?) { python ./RUNTESTS.py -b debug } } if ("${{ matrix.CONFIG }}" -eq "Release") { ./RUNTESTS.ps1 -b nondebug -o 4m if ($?) { python ./RUNTESTS.py -b release } } } pmdk-1.11.1/.github/ISSUE_TEMPLATE/0000775000000000000000000000000014123364546014761 5ustar rootrootpmdk-1.11.1/.github/ISSUE_TEMPLATE/question.md0000664000000000000000000000060214123364546017150 0ustar rootroot--- name: Question about: Do you have question regarding PMDK? Don't hesitate to ask. labels: "Type: Question" --- # QUESTION: ## Details pmdk-1.11.1/.github/ISSUE_TEMPLATE/feature.md0000664000000000000000000000051314123364546016735 0ustar rootroot--- name: Feature about: Feature your request labels: "Type: Feature" --- # FEAT: ## Rationale ## Description ## API Changes ## Implementation details ## Meta pmdk-1.11.1/.github/ISSUE_TEMPLATE/bug_report.md0000664000000000000000000000317214123364546017456 0ustar rootroot--- name: Bug report about: Did you find a bug in PMDK? Please let us know. labels: "Type: Bug" --- # ISSUE: ## Environment Information - PMDK package version(s): - OS(es) version(s): - ndctl version(s): - kernel version(s): - compiler, libraries, packaging and other related tools version(s): ## Please provide a reproduction of the bug: ## How often bug is revealed: (always, often, rare): ## Actual behavior: ## Expected behavior: ## Details ## Additional information about Priority and Help Requested: Are you willing to submit a pull request with a proposed change? (Yes, No) Requested priority: (Showstopper, High, Medium, Low) pmdk-1.11.1/.github/ISSUE_TEMPLATE.md0000664000000000000000000000175414123364546015312 0ustar rootroot# GENERAL ISSUE: ## Bug Report - PMDK package version(s): - OS(es) version(s): - ndctl version(s): - kernel version(s): - compiler, libraries, packaging and other related tools version(s): ## Describe the issue: ## Actual behavior: ## Expected behavior: ## Additional information about Priority and Help Requested: Are you willing to submit a pull request with a proposed change? (Yes, No) Requested priority: (Showstopper, High, Medium, Low) pmdk-1.11.1/.cirrus.yml0000664000000000000000000000043714123364546013352 0ustar rootrootfreebsd_instance: image: freebsd-12-2-release-amd64 task: install_script: ASSUME_ALWAYS_YES=yes pkg bootstrap -f; pkg install -y autoconf bash binutils coreutils e2fsprogs-libuuid git gmake libunwind ncurses pkgconf hs-pandoc script: CFLAGS="-Wno-unused-value" gmake pmdk-1.11.1/CONTRIBUTING.md0000664000000000000000000001451714123364546013477 0ustar rootroot# Contributing to the Persistent Memory Development Kit Down below you'll find instructions on how to contribute to the Persistent Memory Development Kit. Your contributions are most welcome! You'll find it is best to begin with a conversation about your changes, rather than just writing a bunch of code and contributing it out of the blue. There are several good ways to suggest new features, offer to add a feature, or just begin a dialog about the Persistent Memory Development Kit: * Open an issue in our [GitHub Issues Database](https://github.com/pmem/pmdk/issues) * Suggest a feature, ask a question, start a discussion, etc. in our [pmem Google group](https://groups.google.com/group/pmem) * Chat with members of the PMDK team real-time on the **#pmem** IRC channel on [OFTC](https://www.oftc.net) **NOTE: If you do decide to implement code changes and contribute them, please make sure you agree your contribution can be made available under the [BSD-style License used for the Persistent Memory Development Kit](https://github.com/pmem/pmdk/blob/master/LICENSE).** **NOTE: Submitting your changes also means that you certify the following:** ``` Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` In case of any doubt, the gatekeeper may ask you to certify the above in writing, i.e. via email or by including a `Signed-off-by:` line at the bottom of your commit comments. To improve tracking of who is the author of the contribution, we kindly ask you to use your real name (not an alias) when committing your changes to the Persistent Memory Development Kit: ``` Author: Random J Developer ``` ### Code Contributions Please feel free to use the forums mentioned above to ask for comments & questions on your code before submitting a pull request. The Persistent Memory Development Kit project uses the common *fork and merge* workflow used by most GitHub-hosted projects. The [Git Workflow blog article](https://pmem.io/2014/09/09/git-workflow.html) describes our workflow in more detail. #### Linux/FreeBSD Before contributing please remember to run: ``` $ make cstyle ``` This will check all C/C++ files in the tree for style issues. To check C++ files you have to have clang-format version 6.0, otherwise they will be skipped. If you want to run this target automatically at build time, you can pass CSTYLEON=1 to make. If you want cstyle to be run, but not fail the build, pass CSTYLEON=2 to make. There is also a target for automatic C++ code formatting, to do this run: ``` $ make format ``` There are cases, when you might have several clang-format-X.Y binaries and either no clang-format or it pointing to an older version. In such case run: ``` $ make CLANG_FORMAT=/path/to/clang-format cstyle|format ``` #### Windows On Windows to check the code for style issues, please run: ``` $ pmdk\utils\CSTYLE.ps1 ``` To check or format C++ files, you may use a standalone Visual Studio plugin for clang-format. The plugin installer can be downloaded from [LLVM Builds](https://llvm.org/builds) page. If you are actively working on an PMDK feature, please let other developers know by [creating an issue](https://github.com/pmem/pmdk/issues). Use the template `Feature` and assign it to yourself (due to the way GitHub permissions work, you may have to ask a team member to assign it to you). ### Bug Reports Bugs for the PMDK project are tracked in our [GitHub Issues Database](https://github.com/pmem/pmdk/issues). When reporting a new bug, please use `New issue` button, pick proper template and fill in all fields. Provide as much information as possible, including the product version: #### PMDK version Put the release name of the version of PMDK running when the bug was discovered in a bug comment. If you saw this bug in multiple PMDK versions, please put at least the most recent version and list the others if necessary. - Stable release names are in the form `#.#` (where `#` represents an integer); for example `0.3`. - Release names from working versions look like `#.#+b#` (adding a build #) or `#.#-rc#` (adding a release candidate number) If PMDK was built from source, the version number can be retrieved from git using this command: `git describe` For binary PMDK releases, use the entire package name. For RPMs, use `rpm -q pmdk` to display the name. For Deb packages, run `dpkg-query -W pmdk` and use the second (version) string. #### Priority Requested priority describes the urgency to resolve a defect and establishes the time frame for providing a verified resolution. Priorities are defined as: * **P1**: Showstopper bug, requiring a resolution before the next release of the library. * **P2**: High-priority bug, requiring a resolution although it may be decided that the bug does not prevent the next release of the library. * **P3**: Medium-priority bug. The expectation is that the bug will be evaluated and a plan will be made for when the bug will be resolved. * **P4**: Low-priority bug, the least urgent. Fixed when the resources are available. ### Other issues On our issues page we also gather feature requests and questions. Templates to use are `Feature` and `Question`, respectively. They should help deliver a meaningful description of a feature or ask a question to us (remember though we have different means of communication, as described at the top of the page). pmdk-1.11.1/CODING_STYLE.md0000664000000000000000000001625414123364546013513 0ustar rootroot# C Style and Coding Standards for Persistent Memory Development Kit This document defines the coding standards and conventions for writing PMDK code. To ensure readability and consistency within the code, the contributed code must adhere to the rules below. ### Introduction The Persistent Memory Development Kit coding style is quite similar to the style used for the SunOS product. A full description of that standard can be found [here.](https://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf) This document does not cover the entire set of recommendations and formatting rules used in writing PMDK code, but rather focuses on some PMDK-specific conventions, not described in the document mentioned above, as well as the ones the violation of which is most frequently observed during the code review. Also, keep in mind that more important than the particular style is **consistency** of coding style. So, when modifying the existing code, the changes should be coded in the same style as the file being modified. ### Code formatting Most of the common stylistic errors can be detected by the [style checker program](https://github.com/pmem/pmdk/blob/master/utils/cstyle) included in the repo. Simply run `make cstyle` or `CSTYLE.ps1` to verify if your code is well-formatted. Here is the list of the most important rules: - The limit of line length is 80 characters. - Indent the code with TABs, not spaces. Tab width is 8 characters. - Do not break user-visible strings (even when they are longer than 80 characters) - Put each variable declaration in a separate line. - Do not use C++ comments (`//`). - Spaces around operators are mandatory. - No whitespace is allowed at the end of line. - For multi-line macros, do not put whitespace before `\` character. - Precede definition of each function with a brief, non-trivial description. (Usually a single line is enough.) - Use `XXX` tag to indicate a hack, problematic code, or something to be done. - For pointer variables, place the `*` close to the variable name not pointer type. - Avoid unnecessary variable initialization. - Never type `unsigned int` - just use `unsigned` in such case. Same with `long int` and `long`, etc. - Sized types like `uint32_t`, `int64_t` should be used when there is an on-media format. Otherwise, just use `unsigned`, `long`, etc. - Functions with local scope must be declared as `static`. ### License & copyright - Make sure you have the right to submit your contribution under the BSD license, especially if it is based upon previous work. See [CONTRIBUTING.md](https://github.com/pmem/pmdk/blob/master/CONTRIBUTING.md) for details. - A copy of the [BSD-style License](https://github.com/pmem/pmdk/blob/master/LICENSE) must be placed at the beginning of each source file, script or man page (Obviously, it does not apply to README's, Visual Studio projects and \*.match files.) - When adding a new file to the repo, or when making a contribution to an existing file, feel free to put your copyright string on top of it. ### Naming convention - Keep identifier names short, but meaningful. One-letter variables are discouraged. - Use proper prefix for function name, depending on the module it belongs to. - Use *under_score* pattern for function/variable names. Please, do not use CamelCase or Hungarian notation. - UPPERCASE constant/macro/enum names. - Capitalize first letter for variables with global or module-level scope. - Avoid using `l` as a variable name, because it is hard to distinguish `l` from `1` on some displays. ### Multi-OS support (Linux/FreeBSD/Windows) - Do not add `#ifdef ` sections lightly. They should be treated as technical debt and avoided when possible. - Use `_WIN32` macro for conditional directives when including code using Windows-specific API. - Use `__FreeBSD__` macro for conditional directives for FreeBSD-specific code. - Use `_MSC_VER` macro for conditional directives when including code using VC++ or gcc specific extensions. - In case of large portions of code (i.e. a whole function) that have different implementation for each OS, consider moving them to separate files. (i.e. *xxx_linux.c*, *xxx_freebsd.c* and *xxx_windows.c*) - Keep in mind that `long int` is always 32-bit in VC++, even when building for 64-bit platforms. Remember to use `long long` types whenever it applies, as well as proper formatting strings and type suffixes (i.. `%llu`, `ULL`). - Standard compliant solutions should be used in preference of compiler-specific ones. (i.e. static inline functions versus statement expressions) - Do not use formatting strings that are not supported by Windows implementations of printf()/scanf() family. (like `%m`) - It is recommended to use `PRI*` and `SCN*` macros in printf()/scanf() functions for width-based integral types (`uint32_t`, `int64_t`, etc.). ### Debug traces and assertions - Put `LOG(3, ...)` at the beginning of each function. Consider using higher log level for most frequently called routines. - Make use of `COMPILE_ERROR_ON` and `ASSERT*` macros. - Use `ERR()` macro to log error messages. ### Unit tests - There **must** be unit tests provided for each new function/module added. - Test scripts **must** start with `#!/usr/bin/env ` for portability between Linux and FreeBSD. - Please, see [this](https://github.com/pmem/pmdk/blob/master/src/test/README) and [that](https://github.com/pmem/pmdk/blob/master/src/test/unittest/README) document to get familiar with our test framework and the guidelines on how to write and run unit tests. ### Commit messages All commit lines (entered when you run `git commit`) must follow the common conventions for git commit messages: - The first line is a short summary, no longer than **50 characters,** starting with an area name and then a colon. There should be no period after the short summary. - Valid area names are: **pmem, pmem2, obj, blk, log, set, test, doc, daxio, pmreorder, pool** (for *libpmempool* and *pmempool*), **rpmem** (for *librpmem* and *rpmemd*), **benchmark, examples, core** and **common** (for everything else). - It is acceptable for the short summary to be the only thing in the commit message if it is a trivial change. Otherwise, the second line must be a blank line. - Starting at the third line, additional information is given in complete English sentences and, optionally, bulleted points. This content must not extend beyond **column 72.** - The English sentences should be written in the imperative, so you say "Fix bug X" instead of "Fixed bug X" or "Fixes bug X". - Bullet points should use hanging indents when they take up more than one line (see example below). - There can be any number of paragraphs, separated by a blank line, as many as it takes to describe the change. - Any references to GitHub issues are at the end of the commit message. For example, here is a properly-formatted commit message: ``` doc: fix code formatting in man pages This section contains paragraph style text with complete English sentences. There can be as many paragraphs as necessary. - Bullet points are typically sentence fragments - The first word of the bullet point is usually capitalized and if the point is long, it is continued with a hanging indent - The sentence fragments don't typically end with a period Ref: pmem/issues#1 ``` pmdk-1.11.1/.mailmap0000664000000000000000000000235214123364546012661 0ustar rootrootDaria Lewandowska Gábor Buella Grzegorz Brzeziński Hu Wan Igor Chorążewicz Jacob Chang Jan M Michalski Kamil Diedrich Kamil Diedrich Krzysztof Czuryło Lukasz Dorau Lukasz Dorau Łukasz Godlewski Łukasz Godlewski Łukasz Plewa Łukasz Stolarczuk Łukasz Stolarczuk Maciej Ramotowski Michał Biesek Oksana Sałyk Oksana Sałyk Paul Luse Paweł Lebioda Piotr Balcer Sławomir Pawłowski Tomasz Kapela Weronika Lewandowska Weronika Lewandowska Wojciech Uss pmdk-1.11.1/Makefile0000664000000000000000000000675214123364546012710 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2021, Intel Corporation # # Makefile -- top-level Makefile for PMDK # # Use "make" to build the library. # # Use "make doc" to build documentation. # # Use "make test" to build unit tests. Add "SKIP_SYNC_REMOTES=y" to skip # or "FORCE_SYNC_REMOTES=y" to force syncing remote nodes if any is defined. # # Use "make check" to run unit tests. # # Use "make check-remote" to run only remote unit tests. # # Use "make clean" to delete all intermediate files (*.o, etc). # # Use "make clobber" to delete everything re-buildable (binaries, etc.). # # Use "make gitclean" for a complete tree clean, save for test configs. # # Use "make cstyle" to run cstyle on all C source files # # Use "make check-license" to check copyright and license in all source files # # Use "make rpm" to build rpm packages # # Use "make dpkg" to build dpkg packages # # Use "make source DESTDIR=path_to_dir" to copy source files # from HEAD to 'path_to_dir/pmdk' directory. # # As root, use "make install" to install the library in the usual # locations (/usr/local/lib, /usr/local/include, and /usr/local/share/man). # You can provide custom directory prefix for installation using # DESTDIR variable e.g.: "make install DESTDIR=/opt" # You can override the prefix within DESTDIR using prefix variable # e.g.: "make install prefix=/usr" include src/common.inc RPM_BUILDDIR=rpmbuild DPKG_BUILDDIR=dpkgbuild EXPERIMENTAL ?= n BUILD_PACKAGE_CHECK ?= y BUILD_RPMEM ?= y TEST_CONFIG_FILE ?= "$(CURDIR)"/src/test/testconfig.sh PMEMSET_INSTALL ?= n DOC ?= y rpm : override DESTDIR="$(CURDIR)/$(RPM_BUILDDIR)" dpkg: override DESTDIR="$(CURDIR)/$(DPKG_BUILDDIR)" rpm dpkg: override prefix=/usr all: doc $(MAKE) -C src $@ doc: ifeq ($(DOC),y) test -f .skip-doc || $(MAKE) -C doc all endif clean: $(MAKE) -C src $@ ifeq ($(DOC),y) test -f .skip-doc || $(MAKE) -C doc $@ endif $(RM) -r $(RPM_BUILDDIR) $(DPKG_BUILDDIR) $(RM) -f $(GIT_VERSION) clobber: $(MAKE) -C src $@ ifeq ($(DOC),y) test -f .skip-doc || $(MAKE) -C doc $@ endif $(RM) -r $(RPM_BUILDDIR) $(DPKG_BUILDDIR) rpm dpkg $(RM) -f $(GIT_VERSION) require-rpmem: ifneq ($(BUILD_RPMEM),y) $(error ERROR: cannot run remote tests because $(BUILD_RPMEM_INFO)) endif check-remote: require-rpmem all $(MAKE) -C src $@ test check pcheck pycheck: all $(MAKE) -C src $@ check pcheck pycheck: check-doc cstyle: test -d .git && utils/check-commits.sh $(MAKE) -C src $@ $(MAKE) -C utils $@ @echo Checking files for whitespace issues... @utils/check_whitespace -g @echo Done. format: $(MAKE) -C src $@ @echo Done. check-license: @utils/check_license/check-headers.sh $(TOP) BSD-3-Clause @echo Done. check-doc: doc BUILD_RPMEM="$(BUILD_RPMEM)" utils/check-manpages sparse: $(MAKE) -C src sparse gitclean: git clean -dfx -etestconfig.sh -etestconfig.py source: clobber $(if "$(DESTDIR)", , $(error Please provide DESTDIR variable)) +utils/copy-source.sh "$(DESTDIR)" $(SRCVERSION) pkg-clean: $(RM) -r "$(DESTDIR)" rpm dpkg: pkg-clean $(MAKE) source DESTDIR="$(DESTDIR)" +utils/build-$@.sh -t $(SRCVERSION) -s "$(DESTDIR)"/pmdk -w "$(DESTDIR)" -o $(CURDIR)/$@\ -e $(EXPERIMENTAL) -c $(BUILD_PACKAGE_CHECK) -r $(BUILD_RPMEM)\ -f $(TEST_CONFIG_FILE) -n $(NDCTL_ENABLE) -l $(PMEMSET_INSTALL) install: all install uninstall: $(MAKE) -C src $@ ifeq ($(DOC),y) $(MAKE) -C doc $@ endif .PHONY: all clean clobber test check cstyle check-license install uninstall\ source rpm dpkg pkg-clean pcheck check-remote format doc require-rpmem\ $(SUBDIRS) pmdk-1.11.1/LICENSE0000664000000000000000000000357314123364546012253 0ustar rootrootSPDX-License-Identifier: BSD-3-Clause Copyright 2014-2020, Intel Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Everything in this source tree is covered by the previous license with the following exceptions: * src/core/valgrind/valgrind.h, src/core/valgrind/memcheck.h, src/core/valgrind/helgrind.h, src/core/valgrind/drd.h are covered by another similar BSD license variant, contained in those files. * utils/cstyle (used only during development) licensed under CDDL. pmdk-1.11.1/appveyor.yml0000664000000000000000000000451614123364546013634 0ustar rootrootversion: 1.4.{build} os: Visual Studio 2019 platform: x64 install: - ps: Install-PackageProvider -Name NuGet -Force - ps: Install-Module PsScriptAnalyzer -Force configuration: - Debug - Release environment: solutionname: PMDK.sln ex_solutionname: Examples.sln matrix: fast_finish: true before_build: - ps: >- if ($Env:CONFIGURATION -eq "Release") { utils/CSTYLE.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } utils/CHECK_WHITESPACE.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } utils/ps_analyze.ps1 if ($LASTEXITCODE -ne 0) { exit 1 } ./utils/check_sdk_version.py -d . if ($LASTEXITCODE -ne 0) { exit 1 } } build_script: - ps: msbuild src\$Env:solutionname /property:Configuration=$Env:CONFIGURATION /m /v:m - ps: msbuild src\examples\$Env:ex_solutionname /property:Configuration=$Env:CONFIGURATION /m /v:m after_build: - ps: utils/CREATE-ZIP.ps1 -b $Env:CONFIGURATION test_script: - ps: >- if ($true) { cd src\test md C:\temp echo "`$Env:NON_PMEM_FS_DIR = `"C:\temp`"" >> testconfig.ps1 echo "`$Env:PMEM_FS_DIR = `"C:\temp`"" >> testconfig.ps1 echo "`$Env:PMEM_FS_DIR_FORCE_PMEM = `"1`"" >> testconfig.ps1 echo "`$Env:PMDK_NO_ABORT_MSG = `"1`"" >> testconfig.ps1 echo "`$Env:TM = `"1`"" >> testconfig.ps1 write-output "config = { 'unittest_log_level': 1, 'cacheline_fs_dir': 'C:\\temp', 'force_cacheline': True, 'page_fs_dir': 'C:\\temp', 'force_page': False, 'byte_fs_dir': 'C:\\temp', 'force_byte': True, 'tm': True, 'test_type': 'check', 'granularity': 'all', 'fs_dir_force_pmem': 1, 'keep_going': False, 'timeout': '4m', 'build': 'debug', 'force_enable': None, 'fail_on_skip': False, 'enable_admin_tests': False, }" | out-file "testconfig.py" -encoding utf8 if ($Env:CONFIGURATION -eq "Debug") { ./RUNTESTS.ps1 -b debug -o 4m if ($?) { ./RUNTESTS.py -b debug } } if ($Env:CONFIGURATION -eq "Release") { ./RUNTESTS.ps1 -b nondebug -o 4m if ($?) { ./RUNTESTS.py -b release } } } artifacts: - path: 'src\x64\*.zip' name: PMDK pmdk-1.11.1/doc/0000775000000000000000000000000014123364546012003 5ustar rootrootpmdk-1.11.1/doc/libpmempool/0000775000000000000000000000000014123364734014321 5ustar rootrootpmdk-1.11.1/doc/libpmempool/pmempool_sync.30000664000000000000000000001354314123364734017277 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL_SYNC" "3" "2021-09-24" "PMDK - pmempool API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmempool_sync\f[](), \f[B]pmempool_transform\f[]() \- pool set synchronization and transformation .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmempool_sync(const\ char\ *poolset_file,\ \ \ \ \ unsigned\ flags);\ (EXPERIMENTAL) int\ pmempool_transform(const\ char\ *poolset_file_src, \ \ \ \ const\ char\ *poolset_file_dst,\ unsigned\ flags);\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool_sync\f[]() function synchronizes data between replicas within a pool set. .PP \f[B]pmempool_sync\f[]() accepts two arguments: .IP \[bu] 2 \f[I]poolset_file\f[] \- a path to a pool set file, .IP \[bu] 2 \f[I]flags\f[] \- a combination of flags (ORed) which modify how synchronization is performed. .RS .PP NOTE: Only the pool set file used to create the pool should be used for syncing the pool. .RE .RS .PP NOTE: The \f[B]pmempool_sync\f[]() cannot do anything useful if there are no replicas in the pool set. In such case, it fails with an error. .RE .RS .PP NOTE: At the moment, replication is only supported for \f[B]libpmemobj\f[](7) pools, so \f[B]pmempool_sync\f[]() cannot be used with other pool types (\f[B]libpmemlog\f[](7), \f[B]libpmemblk\f[](7)). .RE .PP The following flags are available: .IP \[bu] 2 \f[B]PMEMPOOL_SYNC_DRY_RUN\f[] \- do not apply changes, only check for viability of synchronization. .PP \f[B]pmempool_sync\f[]() checks that the metadata of all replicas in a pool set is consistent, i.e.\ all parts are healthy, and if any of them is not, the corrupted or missing parts are recreated and filled with data from one of the healthy replicas. .PP If a pool set has the option \f[I]SINGLEHDR\f[] (see \f[B]poolset\f[](5)), the internal metadata of each replica is limited to the beginning of the first part in the replica. If the option \f[I]NOHDRS\f[] is used, replicas contain no internal metadata. In both cases, only the missing parts or the ones which cannot be opened are recreated with the \f[B]pmempool_sync\f[]() function. .PP \f[B]pmempool_transform\f[]() modifies the internal structure of a pool set. It supports the following operations: .IP \[bu] 2 adding one or more replicas, .IP \[bu] 2 removing one or more replicas , .IP \[bu] 2 adding or removing pool set options. .PP Only one of the above operations can be performed at a time. .PP \f[B]pmempool_transform\f[]() accepts three arguments: .IP \[bu] 2 \f[I]poolset_file_src\f[] \- pathname of the pool \f[I]set\f[] file for the source pool set to be changed, .IP \[bu] 2 \f[I]poolset_file_dst\f[] \- pathname of the pool \f[I]set\f[] file that defines the new structure of the pool set, .IP \[bu] 2 \f[I]flags\f[] \- a combination of flags (ORed) which modify how synchronization is performed. .PP The following flags are available: .IP \[bu] 2 \f[B]PMEMPOOL_TRANSFORM_DRY_RUN\f[] \- do not apply changes, only check for viability of transformation. .PP When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. When adding or removing pool set options (see \f[B]poolset\f[](5)), the rest of both pool set files have to be of the same structure. The operation of adding/removing a pool set option can be performed on a pool set with local replicas only. To add/remove a pool set option to/from a pool set with remote replicas, one has to remove the remote replicas first, then add/remove the option, and finally recreate the remote replicas having added/removed the pool set option to/from the remote replicas' poolset files. To add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. If none of the pool set options is used, the effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files. If the option \f[I]SINGLEHDR\f[] is used, the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. In this case only the first part contains internal metadata. If the option \f[I]NOHDRS\f[] is used, the effective size of a replica is the sum of sizes of all its part files. In this case none of the parts contains internal metadata. .RS .PP NOTE: At the moment, \f[I]transform\f[] operation is only supported for \f[B]libpmemobj\f[](7) pools, so \f[B]pmempool_transform\f[]() cannot be used with other pool types (\f[B]libpmemlog\f[](7), \f[B]libpmemblk\f[](7)). .RE .SH RETURN VALUE .PP \f[B]pmempool_sync\f[]() and \f[B]pmempool_transform\f[]() return 0 on success. Otherwise, they return \-1 and set \f[I]errno\f[] appropriately. .SH ERRORS .PP \f[B]EINVAL\f[] Invalid format of the input/output pool set file. .PP \f[B]EINVAL\f[] Unsupported \f[I]flags\f[] value. .PP \f[B]EINVAL\f[] There is only master replica defined in the input pool set passed to \f[B]pmempool_sync\f[](). .PP \f[B]EINVAL\f[] The source pool set passed to \f[B]pmempool_transform\f[]() is not a \f[B]libpmemobj\f[] pool. .PP \f[B]EINVAL\f[] The input and output pool sets passed to \f[B]pmempool_transform\f[]() are identical. .PP \f[B]EINVAL\f[] Attempt to perform more than one transform operation at a time. .PP \f[B]ENOTSUP\f[] The pool set contains a remote replica, but remote replication is not supported (\f[B]librpmem\f[](7) is not available). .SH NOTES .PP The \f[B]pmempool_sync\f[]() API is experimental and it may change in future versions of the library. .PP The \f[B]pmempool_transform\f[]() API is experimental and it may change in future versions of the library. .SH SEE ALSO .PP \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmempool/pmempool_check_init.30000664000000000000000000001753114123364734020424 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL_CHECK_INIT" "3" "2021-09-24" "PMDK - pmempool API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmempool_check_init\f[](), \f[B]pmempool_check\f[](), \f[B]pmempool_check_end\f[]() \- checks pmempool health .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMpoolcheck\ *pmempool_check_init(struct\ pmempool_check_args\ *args,\ \ \ \ \ size_t\ args_size); struct\ pmempool_check_status\ *pmempool_check(PMEMpoolcheck\ *ppc); enum\ pmempool_check_result\ pmempool_check_end(PMEMpoolcheck\ *ppc); \f[] .fi .SH DESCRIPTION .PP To perform the checks provided by \f[B]libpmempool\f[], a \f[I]check context\f[] must first be initialized using the \f[B]pmempool_check_init\f[]() function described in this section. Once initialized, the \f[I]check context\f[] is represented by an opaque handle of type \f[I]PMEMpoolcheck*\f[], which is passed to all of the other functions available in \f[B]libpmempool\f[] .PP To execute checks, \f[B]pmempool_check\f[]() must be called iteratively. Each call generates a new check status, represented by a \f[I]struct pmempool_check_status\f[] structure. Status messages are described later below. .PP When the checks are completed, \f[B]pmempool_check\f[]() returns NULL. The check must be finalized using \f[B]pmempool_check_end\f[](), which returns an \f[I]enum pmempool_check_result\f[] describing the results of the entire check. .PP \f[B]pmempool_check_init\f[]() initializes the check context. \f[I]args\f[] describes parameters of the check context. \f[I]args_size\f[] should be equal to the size of the \f[I]struct pmempool_check_args\f[]. \f[I]struct pmempool_check_args\f[] is defined as follows: .IP .nf \f[C] struct\ pmempool_check_args { \ \ \ \ /*\ path\ to\ the\ pool\ to\ check\ */ \ \ \ \ const\ char\ *path; \ \ \ \ /*\ optional\ backup\ path\ */ \ \ \ \ const\ char\ *backup_path; \ \ \ \ /*\ type\ of\ the\ pool\ */ \ \ \ \ enum\ pmempool_pool_type\ pool_type; \ \ \ \ /*\ parameters\ */ \ \ \ \ int\ flags; }; \f[] .fi .PP The \f[I]flags\f[] argument accepts any combination of the following values (ORed): .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_REPAIR\f[] \- perform repairs .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_DRY_RUN\f[] \- emulate repairs, not supported on Device DAX .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_ADVANCED\f[] \- perform hazardous repairs .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_ALWAYS_YES\f[] \- do not ask before repairs .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_VERBOSE\f[] \- generate info statuses .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_FORMAT_STR\f[] \- generate string format statuses .PP \f[I]pool_type\f[] must match the type of the \f[I]pool\f[] being processed. Pool type detection may be enabled by setting \f[I]pool_type\f[] to \f[B]PMEMPOOL_POOL_TYPE_DETECT\f[]. A pool type detection failure ends the check. .PP \f[I]backup_path\f[] may be: .IP \[bu] 2 NULL. No backup will be performed. .IP \[bu] 2 a non\-existent file: \f[I]backup_path\f[] will be created and backup will be performed. \f[I]path\f[] must be a single file \f[I]pool\f[]. .IP \[bu] 2 an existing \f[I]pool set\f[] file: Backup will be performed as defined by the \f[I]backup_path\f[] pool set. \f[I]path\f[] must be a pool set, and \f[I]backup_path\f[] must have the same structure (the same number of parts with exactly the same size) as the \f[I]path\f[] pool set. .PP Backup is supported only if the source \f[I]pool set\f[] has no defined replicas. .PP Neither \f[I]path\f[] nor \f[I]backup_path\f[] may specify a pool set with remote replicas. .PP The \f[B]pmempool_check\f[]() function starts or resumes the check indicated by \f[I]ppc\f[]. When the next status is generated, the check is paused and \f[B]pmempool_check\f[]() returns a pointer to the \f[I]struct pmempool_check_status\f[] structure: .IP .nf \f[C] struct\ pmempool_check_status { \ \ \ \ enum\ pmempool_check_msg_type\ type;\ /*\ type\ of\ the\ status\ */ \ \ \ \ struct \ \ \ \ { \ \ \ \ \ \ \ \ const\ char\ *msg;\ /*\ status\ message\ string\ */ \ \ \ \ \ \ \ \ const\ char\ *answer;\ /*\ answer\ to\ message\ if\ applicable\ */ \ \ \ \ }\ str; }; \f[] .fi .PP This structure can describe three types of statuses: .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_MSG_TYPE_INFO\f[] \- detailed information about the check. Generated only if a \f[B]PMEMPOOL_CHECK_VERBOSE\f[] flag was set. .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_MSG_TYPE_ERROR\f[] \- An error was encountered. .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_MSG_TYPE_QUESTION\f[] \- question. Generated only if an \f[B]PMEMPOOL_CHECK_ALWAYS_YES\f[] flag was not set. It requires \f[I]answer\f[] to be set to \[lq]yes\[rq] or \[lq]no\[rq] before continuing. .PP After calling \f[B]pmempool_check\f[]() again, the previously provided \f[I]struct pmempool_check_status\f[] pointer must be considered invalid. .PP The \f[B]pmempool_check_end\f[]() function finalizes the check and releases all related resources. \f[I]ppc\f[] is invalid after calling \f[B]pmempool_check_end\f[](). .SH RETURN VALUE .PP \f[B]pmempool_check_init\f[]() returns an opaque handle of type \f[I]PMEMpoolcheck*\f[]. If the provided parameters are invalid or the initialization process fails, \f[B]pmempool_check_init\f[]() returns NULL and sets \f[I]errno\f[] appropriately. .PP Each call to \f[B]pmempool_check\f[]() returns a pointer to a \f[I]struct pmempool_check_status\f[] structure when a status is generated. When the check completes, \f[B]pmempool_check\f[]() returns NULL. .PP The \f[B]pmempool_check_end\f[]() function returns an \f[I]enum pmempool_check_result\f[] summarizing the results of the finalized check. \f[B]pmempool_check_end\f[]() can return one of the following values: .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_CONSISTENT\f[] \- the \f[I]pool\f[] is consistent .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_NOT_CONSISTENT\f[] \- the \f[I]pool\f[] is not consistent .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_REPAIRED\f[] \- the \f[I]pool\f[] has issues but all repair steps completed successfully .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_CANNOT_REPAIR\f[] \- the \f[I]pool\f[] has issues which can not be repaired .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_ERROR\f[] \- the \f[I]pool\f[] has errors or the check encountered an issue .IP \[bu] 2 \f[B]PMEMPOOL_CHECK_RESULT_SYNC_REQ\f[] \- the \f[I]pool\f[] has single healthy replica. To fix remaining issues use \f[B]pmempool_sync\f[](3). .SH EXAMPLE .PP This is an example of a \f[I]check context\f[] initialization: .IP .nf \f[C] struct\ pmempool_check_args\ args\ = { \ \ \ \ .path\ =\ "/path/to/blk.pool", \ \ \ \ .backup_path\ =\ NULL, \ \ \ \ .pool_type\ =\ PMEMPOOL_POOL_TYPE_BLK, \ \ \ \ .flags\ =\ PMEMPOOL_CHECK_REPAIR\ |\ PMEMPOOL_CHECK_DRY_RUN\ | \ \ \ \ \ \ \ \ PMEMPOOL_CHECK_VERBOSE\ |\ PMEMPOOL_CHECK_FORMAT_STR }; \f[] .fi .IP .nf \f[C] PMEMpoolcheck\ *ppc\ =\ pmempool_check_init(&args,\ sizeof(args)); \f[] .fi .PP The check will process a \f[I]pool\f[] of type \f[B]PMEMPOOL_POOL_TYPE_BLK\f[] located in the path \f[I]/path/to/blk.pool\f[]. Before the check it will not create a backup of the \f[I]pool\f[] (\f[I]backup_path == NULL\f[]). If the check finds any issues it will try to perform repair steps (\f[B]PMEMPOOL_CHECK_REPAIR\f[]), but it will not make any changes to the \f[I]pool\f[] (\f[B]PMEMPOOL_CHECK_DRY_RUN\f[]) and it will not perform any dangerous repair steps (no \f[B]PMEMPOOL_CHECK_ADVANCED\f[]). The check will ask before performing any repair steps (no \f[B]PMEMPOOL_CHECK_ALWAYS_YES\f[]). It will also generate detailed information about the check (\f[B]PMEMPOOL_CHECK_VERBOSE\f[]). The \f[B]PMEMPOOL_CHECK_FORMAT_STR\f[] flag indicates string format statuses (\f[I]struct pmempool_check_status\f[]). Currently this is the only supported status format so this flag is required. .SH NOTES .PP Currently, checking the consistency of a \f[I]pmemobj\f[] pool is \f[B]not\f[] supported. .SH SEE ALSO .PP \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmempool/pmempool_errormsg.30000664000000000000000000000002714123364546020155 0ustar rootroot.so man7/libpmempool.7 pmdk-1.11.1/doc/libpmempool/pmempool_check.30000664000000000000000000000003214123364546017366 0ustar rootroot.so pmempool_check_init.3 pmdk-1.11.1/doc/libpmempool/libpmempool.7.md0000664000000000000000000002144714123364546017340 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEMPOOL, 7) collection: libpmempool header: PMDK date: pmempool API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (libpmempool.7 -- man page for libpmempool) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also)
# NAME # **libpmempool** - persistent memory pool management library # SYNOPSIS # ```c #include cc _WINUX(,-std=gnu99) ... -lpmempool -lpmem ``` _UNICODE() ##### Library API versioning: ##### ```c _UWFUNC(pmempool_check_version, =q= unsigned major_required, unsigned minor_required=e=) ``` ##### Error handling: ##### ```c _UWFUNC(pmempool_errormsg, void) ``` ##### Other library functions: ##### A description of other **libpmempool** functions can be found on the following manual pages: + health check functions: **pmempool_check_init**(3) + pool set synchronization and transformation: **pmempool_sync**(3) + pool set management functions: **pmempool_rm**(3) + toggle or query pool set features: **pmempool_feature_query**(3) # DESCRIPTION # **libpmempool** provides a set of utilities for off-line analysis and manipulation of a *pool*. A *pool* in this manpage means a pmemobj pool, pmemblk pool, pmemlog pool or BTT layout, independent of the underlying storage. Some **libpmempool** functions are required to work without any impact on the *pool* but some may create a new or modify an existing *pool*. **libpmempool** is for applications that need high reliability or built-in troubleshooting. It may be useful for testing and debugging purposes also. **libpmempool** introduces functionality of pool set health check, synchronization, transformation and removal. # CAVEATS # **libpmempool** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. _WINUX(,=q=**libpmempool** requires the **-std=gnu99** compilation flag to build properly.=e=) # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The _UW(pmempool_check_version) function is used to see if the installed **libpmempool** supports the version of the library API required by an application. The easiest way to do this for the application is to supply the compile-time version information, supplied by defines in **\**, like this: ```c reason = _U(pmempool_check_version)(PMEMPOOL_MAJOR_VERSION, PMEMPOOL_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. When the version check performed by _UW(pmempool_check_version) is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by _UW(pmempool_check_version) must not be modified or freed. # DEBUGGING AND ERROR HANDLING # If an error is detected during the call to a **libpmempool** function, the application may retrieve an error message describing the reason for the failure from _UW(pmempool_errormsg). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmempool** function indicated an error, or if *errno* was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. Two versions of **libpmempool** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmempool** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **libpmempool**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEMPOOL_LOG_LEVEL** The value of **PMEMPOOL_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEMPOOL_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged (in addition to returning the *errno*-based errors as usual). The same information may be retrieved using _UW(pmempool_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmempool** developers. Unless **PMEMPOOL_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMPOOL_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEMPOOL_LOG_FILE** is not set, output is written to *stderr*. # EXAMPLE # The following example illustrates how the **libpmempool** API is used. The program detects the type and checks consistency of given pool. If there are any issues detected, the pool is automatically repaired. ```c #include _WINUX(,=q= #include =e=) #include #include #include #define PATH "./pmem-fs/myfile" #define CHECK_FLAGS (PMEMPOOL_CHECK_FORMAT_STR|PMEMPOOL_CHECK_REPAIR|\ PMEMPOOL_CHECK_VERBOSE) int main(int argc, char *argv[]) { PMEMpoolcheck *ppc; struct _U(pmempool_check_status) *status; enum pmempool_check_result ret; /* arguments for check */ struct _U(pmempool_check_args) args = { .path = PATH, .backup_path = NULL, .pool_type = PMEMPOOL_POOL_TYPE_DETECT, .flags = CHECK_FLAGS }; /* initialize check context */ if ((ppc = _U(pmempool_check_init)(&args, sizeof(args))) == NULL) { perror("_U(pmempool_check_init)"); exit(EXIT_FAILURE); } /* perform check and repair, answer 'yes' for each question */ while ((status = _U(pmempool_check)(ppc)) != NULL) { switch (status->type) { case PMEMPOOL_CHECK_MSG_TYPE_ERROR: printf("%s\n", status->str.msg); break; case PMEMPOOL_CHECK_MSG_TYPE_INFO: printf("%s\n", status->str.msg); break; case PMEMPOOL_CHECK_MSG_TYPE_QUESTION: printf("%s\n", status->str.msg); status->str.answer = "yes"; break; default: pmempool_check_end(ppc); exit(EXIT_FAILURE); } } /* finalize the check and get the result */ ret = pmempool_check_end(ppc); switch (ret) { case PMEMPOOL_CHECK_RESULT_CONSISTENT: case PMEMPOOL_CHECK_RESULT_REPAIRED: return 0; default: return 1; } } ``` See for more examples using the **libpmempool** API. # ACKNOWLEDGEMENTS # **libpmempool** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **dlclose**(3), **pmempool_check_init**(3), **pmempool_feature_query**(3), **pmempool_rm**(3), **pmempool_sync**(3), **strerror**(3), **libpmem**(7), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7)** and **** pmdk-1.11.1/doc/libpmempool/pmempool_check_version.30000664000000000000000000000002714123364546021137 0ustar rootroot.so man7/libpmempool.7 pmdk-1.11.1/doc/libpmempool/pmempool_check_end.30000664000000000000000000000003214123364546020214 0ustar rootroot.so pmempool_check_init.3 pmdk-1.11.1/doc/libpmempool/pmempool_feature_disable.30000664000000000000000000000003514123364546021432 0ustar rootroot.so pmempool_feature_query.3 pmdk-1.11.1/doc/libpmempool/pmempool_sync.3.md0000664000000000000000000001451514123364546017677 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL_SYNC, 3) collection: libpmempool header: PMDK date: pmempool API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmempool_sync.3 -- man page for pmempool sync and transform) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[NOTES](#notes)
[SEE ALSO](#see-also)
# NAME # _UW(pmempool_sync), _UW(pmempool_transform) - pool set synchronization and transformation # SYNOPSIS # ```c #include _UWFUNCR1(int, pmempool_sync, *poolset_file,=q= unsigned flags=e=, =q= (EXPERIMENTAL)=e=) _UWFUNCR12(int, pmempool_transform, *poolset_file_src, *poolset_file_dst, unsigned flags, =q= (EXPERIMENTAL)=e=) ``` _UNICODE() # DESCRIPTION # The _UW(pmempool_sync) function synchronizes data between replicas within a pool set. _UW(pmempool_sync) accepts two arguments: * *poolset_file* - a path to a pool set file, * *flags* - a combination of flags (ORed) which modify how synchronization is performed. >NOTE: Only the pool set file used to create the pool should be used for syncing the pool. >NOTE: The _UW(pmempool_sync) cannot do anything useful if there are no replicas in the pool set. In such case, it fails with an error. >NOTE: At the moment, replication is only supported for **libpmemobj**(7) pools, so _UW(pmempool_sync) cannot be used with other pool types (**libpmemlog**(7), **libpmemblk**(7)). The following flags are available: * **PMEMPOOL_SYNC_DRY_RUN** - do not apply changes, only check for viability of synchronization. _UW(pmempool_sync) checks that the metadata of all replicas in a pool set is consistent, i.e. all parts are healthy, and if any of them is not, the corrupted or missing parts are recreated and filled with data from one of the healthy replicas. _WINUX(,=q=If a pool set has the option *SINGLEHDR* (see **poolset**(5)), the internal metadata of each replica is limited to the beginning of the first part in the replica. If the option *NOHDRS* is used, replicas contain no internal metadata. In both cases, only the missing parts or the ones which cannot be opened are recreated with the _UW(pmempool_sync) function.=e=) _UW(pmempool_transform) modifies the internal structure of a pool set. It supports the following operations: * adding one or more replicas, * removing one or more replicas _WINUX(.,=q=, * adding or removing pool set options.=e=) Only one of the above operations can be performed at a time. _UW(pmempool_transform) accepts three arguments: * *poolset_file_src* - pathname of the pool *set* file for the source pool set to be changed, * *poolset_file_dst* - pathname of the pool *set* file that defines the new structure of the pool set, * *flags* - a combination of flags (ORed) which modify how synchronization is performed. The following flags are available: * **PMEMPOOL_TRANSFORM_DRY_RUN** - do not apply changes, only check for viability of transformation. _WINUX(=q=When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. One cannot add and remove replicas in the same step. Only one of these operations can be performed at a time. Reordering replicas is not supported. Also, to add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. The effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files.=e=) _WINUX(,=q=When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. When adding or removing pool set options (see **poolset**(5)), the rest of both pool set files have to be of the same structure. The operation of adding/removing a pool set option can be performed on a pool set with local replicas only. To add/remove a pool set option to/from a pool set with remote replicas, one has to remove the remote replicas first, then add/remove the option, and finally recreate the remote replicas having added/removed the pool set option to/from the remote replicas' poolset files. To add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. If none of the pool set options is used, the effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files. If the option *SINGLEHDR* is used, the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. In this case only the first part contains internal metadata. If the option *NOHDRS* is used, the effective size of a replica is the sum of sizes of all its part files. In this case none of the parts contains internal metadata.=e=) >NOTE: At the moment, *transform* operation is only supported for **libpmemobj**(7) pools, so _UW(pmempool_transform) cannot be used with other pool types (**libpmemlog**(7), **libpmemblk**(7)). # RETURN VALUE # _UW(pmempool_sync) and _UW(pmempool_transform) return 0 on success. Otherwise, they return -1 and set *errno* appropriately. # ERRORS # **EINVAL** Invalid format of the input/output pool set file. **EINVAL** Unsupported *flags* value. **EINVAL** There is only master replica defined in the input pool set passed to _UW(pmempool_sync). **EINVAL** The source pool set passed to _UW(pmempool_transform) is not a **libpmemobj** pool. **EINVAL** The input and output pool sets passed to _UW(pmempool_transform) are identical. **EINVAL** Attempt to perform more than one transform operation at a time. **ENOTSUP** The pool set contains a remote replica, but remote replication is not supported (**librpmem**(7) is not available). # NOTES # The _UW(pmempool_sync) API is experimental and it may change in future versions of the library. The _UW(pmempool_transform) API is experimental and it may change in future versions of the library. # SEE ALSO # **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmempool/pmempool_check_init.3.md0000664000000000000000000002001214123364546021010 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL_CHECK_INIT, 3) collection: libpmempool header: PMDK date: pmempool API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmempool_check_init.3 -- man page for pmempool health check functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[EXAMPLE](#example)
[NOTES](#notes)
[SEE ALSO](#see-also)
# NAME # _UW(pmempool_check_init), _UW(pmempool_check), **pmempool_check_end**() - checks pmempool health # SYNOPSIS # ```c #include _UWFUNCR1UW(PMEMpoolcheck, *pmempool_check_init, struct pmempool_check_args, *args,=q= size_t args_size=e=) _UWFUNCRUW(struct pmempool_check_status, *pmempool_check, PMEMpoolcheck *ppc) enum pmempool_check_result pmempool_check_end(PMEMpoolcheck *ppc); ``` _UNICODE() # DESCRIPTION # To perform the checks provided by **libpmempool**, a *check context* must first be initialized using the _UW(pmempool_check_init) function described in this section. Once initialized, the *check context* is represented by an opaque handle of type *PMEMpoolcheck\**, which is passed to all of the other functions available in **libpmempool** To execute checks, _UW(pmempool_check) must be called iteratively. Each call generates a new check status, represented by a _UWS(pmempool_check_status) structure. Status messages are described later below. When the checks are completed, _UW(pmempool_check) returns NULL. The check must be finalized using **pmempool_check_end**(), which returns an *enum pmempool_check_result* describing the results of the entire check. _UW(pmempool_check_init) initializes the check context. *args* describes parameters of the check context. *args_size* should be equal to the size of the _UWS(pmempool_check_args). _UWS(pmempool_check_args) is defined as follows: _WINUX(=q= ```c struct pmempool_check_argsU { /* path to the pool to check */ const char *path; /* optional backup path */ const char *backup_path; /* type of the pool */ enum pmempool_pool_type pool_type; /* parameters */ int flags; }; struct pmempool_check_argsW { /* path to the pool to check */ const wchar_t *path; /* optional backup path */ const wchar_t *backup_path; /* type of the pool */ enum pmempool_pool_type pool_type; /* parameters */ int flags; }; ``` =e=,=q= ```c struct pmempool_check_args { /* path to the pool to check */ const char *path; /* optional backup path */ const char *backup_path; /* type of the pool */ enum pmempool_pool_type pool_type; /* parameters */ int flags; }; ``` =e=) The *flags* argument accepts any combination of the following values (ORed): + **PMEMPOOL_CHECK_REPAIR** - perform repairs + **PMEMPOOL_CHECK_DRY_RUN** - emulate repairs, not supported on Device DAX + **PMEMPOOL_CHECK_ADVANCED** - perform hazardous repairs + **PMEMPOOL_CHECK_ALWAYS_YES** - do not ask before repairs + **PMEMPOOL_CHECK_VERBOSE** - generate info statuses + **PMEMPOOL_CHECK_FORMAT_STR** - generate string format statuses *pool_type* must match the type of the *pool* being processed. Pool type detection may be enabled by setting *pool_type* to **PMEMPOOL_POOL_TYPE_DETECT**. A pool type detection failure ends the check. *backup_path* may be: + NULL. No backup will be performed. + a non-existent file: *backup_path* will be created and backup will be performed. *path* must be a single file *pool*. + an existing *pool set* file: Backup will be performed as defined by the *backup_path* pool set. *path* must be a pool set, and *backup_path* must have the same structure (the same number of parts with exactly the same size) as the *path* pool set. Backup is supported only if the source *pool set* has no defined replicas. Neither *path* nor *backup_path* may specify a pool set with remote replicas. The _UW(pmempool_check) function starts or resumes the check indicated by *ppc*. When the next status is generated, the check is paused and _UW(pmempool_check) returns a pointer to the _UWS(pmempool_check_status) structure: _WINUX(=q= { ```c struct pmempool_check_statusU { enum pmempool_check_msg_type type; /* type of the status */ struct { const char *msg; /* status message string */ const char *answer; /* answer to message if applicable */ } str; }; struct pmempool_check_statusW { enum pmempool_check_msg_type type; /* type of the status */ struct { const wchar_t *msg; /* status message string */ const wchar_t *answer; /* answer to message if applicable */ } str; }; ``` =e=,=q= ```c struct pmempool_check_status { enum pmempool_check_msg_type type; /* type of the status */ struct { const char *msg; /* status message string */ const char *answer; /* answer to message if applicable */ } str; }; ``` =e=) This structure can describe three types of statuses: + **PMEMPOOL_CHECK_MSG_TYPE_INFO** - detailed information about the check. Generated only if a **PMEMPOOL_CHECK_VERBOSE** flag was set. + **PMEMPOOL_CHECK_MSG_TYPE_ERROR** - An error was encountered. + **PMEMPOOL_CHECK_MSG_TYPE_QUESTION** - question. Generated only if an **PMEMPOOL_CHECK_ALWAYS_YES** flag was not set. It requires *answer* to be set to "yes" or "no" before continuing. After calling _UW(pmempool_check) again, the previously provided _UWS(pmempool_check_status) pointer must be considered invalid. The **pmempool_check_end**() function finalizes the check and releases all related resources. *ppc* is invalid after calling **pmempool_check_end**(). # RETURN VALUE # _UW(pmempool_check_init) returns an opaque handle of type *PMEMpoolcheck\**. If the provided parameters are invalid or the initialization process fails, _UW(pmempool_check_init) returns NULL and sets *errno* appropriately. Each call to _UW(pmempool_check) returns a pointer to a _UWS(pmempool_check_status) structure when a status is generated. When the check completes, _UW(pmempool_check) returns NULL. The **pmempool_check_end**() function returns an *enum pmempool_check_result* summarizing the results of the finalized check. **pmempool_check_end**() can return one of the following values: + **PMEMPOOL_CHECK_RESULT_CONSISTENT** - the *pool* is consistent + **PMEMPOOL_CHECK_RESULT_NOT_CONSISTENT** - the *pool* is not consistent + **PMEMPOOL_CHECK_RESULT_REPAIRED** - the *pool* has issues but all repair steps completed successfully + **PMEMPOOL_CHECK_RESULT_CANNOT_REPAIR** - the *pool* has issues which can not be repaired + **PMEMPOOL_CHECK_RESULT_ERROR** - the *pool* has errors or the check encountered an issue + **PMEMPOOL_CHECK_RESULT_SYNC_REQ** - the *pool* has single healthy replica. To fix remaining issues use **pmempool_sync**(3). # EXAMPLE # This is an example of a *check context* initialization: ```c struct _U(pmempool_check_args) args = { .path = "/path/to/blk.pool", .backup_path = NULL, .pool_type = PMEMPOOL_POOL_TYPE_BLK, .flags = PMEMPOOL_CHECK_REPAIR | PMEMPOOL_CHECK_DRY_RUN | PMEMPOOL_CHECK_VERBOSE | PMEMPOOL_CHECK_FORMAT_STR }; ``` ```c PMEMpoolcheck *ppc = _U(pmempool_check_init)(&args, sizeof(args)); ``` The check will process a *pool* of type **PMEMPOOL_POOL_TYPE_BLK** located in the path */path/to/blk.pool*. Before the check it will not create a backup of the *pool* (*backup_path == NULL*). If the check finds any issues it will try to perform repair steps (**PMEMPOOL_CHECK_REPAIR**), but it will not make any changes to the *pool* (**PMEMPOOL_CHECK_DRY_RUN**) and it will not perform any dangerous repair steps (no **PMEMPOOL_CHECK_ADVANCED**). The check will ask before performing any repair steps (no **PMEMPOOL_CHECK_ALWAYS_YES**). It will also generate detailed information about the check (**PMEMPOOL_CHECK_VERBOSE**). The **PMEMPOOL_CHECK_FORMAT_STR** flag indicates string format statuses (*struct pmempool_check_status*). Currently this is the only supported status format so this flag is required. # NOTES # Currently, checking the consistency of a *pmemobj* pool is **not** supported. # SEE ALSO # **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmempool/.gitignore0000664000000000000000000000013314123364546016307 0ustar rootrootlibpmempool.7 pmempool_check_init.3 pmempool_feature_query.3 pmempool_rm.3 pmempool_sync.3 pmdk-1.11.1/doc/libpmempool/pmempool_rm.30000664000000000000000000000305714123364734016740 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL_RM" "3" "2021-09-24" "PMDK - pmempool API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmempool_rm\f[]() \- remove persistent memory pool .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmempool_rm(const\ char\ *path,\ int\ flags); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool_rm\f[]() function removes the pool pointed to by \f[I]path\f[]. The \f[I]path\f[] can point to a regular file, device dax or pool set file. If \f[I]path\f[] is a pool set file, \f[B]pmempool_rm\f[]() will remove all part files from local replicas using \f[B]unlink\f[](2), and all remote replicas using \f[B]rpmem_remove\f[](3) (see \f[B]librpmem\f[](7)), before removing the pool set file itself. .PP The \f[I]flags\f[] argument determines the behavior of \f[B]pmempool_rm\f[](). It is either 0 or the bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEMPOOL_RM_FORCE\f[] \- Ignore all errors when removing part files from local or remote replicas. .IP \[bu] 2 \f[B]PMEMPOOL_RM_POOLSET_LOCAL\f[] \- Also remove local pool set file. .IP \[bu] 2 \f[B]PMEMPOOL_RM_POOLSET_REMOTE\f[] \- Also remove remote pool set file. .SH RETURN VALUE .PP On success, \f[B]pmempool_rm\f[]() returns 0. On error, it returns \-1 and sets \f[I]errno\f[] accordingly. .SH SEE ALSO .PP \f[B]rpmem_remove\f[](3), \f[B]unlink\f[](3), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7), \f[B]librpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmempool/pmempool_feature_enable.30000664000000000000000000000003514123364546021255 0ustar rootroot.so pmempool_feature_query.3 pmdk-1.11.1/doc/libpmempool/pmempool_feature_query.3.md0000664000000000000000000000645414123364546021606 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL_FEATURE_QUERY, 3) collection: libpmempool header: PMDK date: pmempool API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018, Intel Corporation) [comment]: <> (pmempool_feature_query.3 -- man page for toggle and query pool set features) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[COMPATIBILITY](#compatibility)
[DISCLAIMER](#disclaimer)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # _UW(pmempool_feature_query), _UW(pmempool_feature_enable), _UW(pmempool_feature_disable) - toggle or query pool set features # SYNOPSIS # ```c #include _UWFUNCR1(int, pmempool_feature_query, *path, =q=enum pmempool_feature feature, unsigned flags=e=) _UWFUNCR1(int, pmempool_feature_enable, *path, =q=enum pmempool_feature feature, unsigned flags=e=) _UWFUNCR1(int, pmempool_feature_disable, *path, =q=enum pmempool_feature feature, unsigned flags=e=) ``` _UNICODE() # DESCRIPTION # The *feature* argument accepts following values: + **PMEMPOOL_FEAT_SINGLEHDR** - only the first part in each replica contains the pool part internal metadata. This value can be used only with **pmempool_feature_query**(). It can not be enabled or disabled. For details see **poolset**(5). + **PMEMPOOL_FEAT_CKSUM_2K** - only the first 2KiB of pool part internal metadata is checksummed. Other features may depend on this one to store additional metadata in otherwise unused second 2KiB part of a header. When **PMEMPOOL_FEAT_CKSUM_2K** is disabled whole 4KiB is checksummed. + **PMEMPOOL_FEAT_SHUTDOWN_STATE** - enables additional check performed during pool open which verifies pool consistency in the presence of dirty shutdown. **PMEMPOOL_FEAT_CKSUM_2K** has to be enabled prior to **PMEMPOOL_FEAT_SHUTDOWN_STATE** otherwise enabling **PMEMPOOL_FEAT_SHUTDOWN_STATE** will fail. + **PMEMPOOL_FEAT_CHECK_BAD_BLOCKS** - enables checking bad blocks performed during opening a pool and fixing bad blocks performed by pmempool-sync during syncing a pool. For details see **pmempool-feature**(1). The _UW(pmempool_feature_query) function checks state of *feature* in the pool set pointed by *path*. The _UW(pmempool_feature_enable) function enables *feature* in the pool set pointed by *path*. The _UW(pmempool_feature_disable) function disables *feature* in the pool set pointed by *path*. # COMPATIBILITY # Poolsets with features not defined in this document (e.g. enabled by the newer software version) are not supported. # DISCLAIMER # _UW(pmempool_feature_query), _UW(pmempool_feature_enable) and _UW(pmempool_feature_disable) are not fail safe. # RETURN VALUE # On success, _UW(pmempool_feature_query) returns 0 if *feature* is disabled or 1 if it is enabled. On error, it returns -1 and sets *errno* accordingly. On success, _UW(pmempool_feature_enable) returns 0. On error, it returns -1 and sets *errno* accordingly. On success, _UW(pmempool_feature_disable) returns 0. On error, it returns -1 and sets *errno* accordingly. If *path* points poolset with remote replica **errno** is set to EINVAL and function returns -1. If non zero *flags* are provided **errno** is set to EINVAL and function returns -1. # SEE ALSO # **poolset**(5) and **** pmdk-1.11.1/doc/libpmempool/pmempool_transform.30000664000000000000000000000002414123364546020325 0ustar rootroot.so pmempool_sync.3 pmdk-1.11.1/doc/libpmempool/libpmempool.70000664000000000000000000002336714123364725016743 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEMPOOL" "7" "2021-09-24" "PMDK - pmempool API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]libpmempool\f[] \- persistent memory pool management library .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ \-std=gnu99\ ...\ \-lpmempool\ \-lpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *pmempool_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Error handling: .IP .nf \f[C] const\ char\ *pmempool_errormsg(void); \f[] .fi .SS Other library functions: .PP A description of other \f[B]libpmempool\f[] functions can be found on the following manual pages: .IP \[bu] 2 health check functions: \f[B]pmempool_check_init\f[](3) .IP \[bu] 2 pool set synchronization and transformation: \f[B]pmempool_sync\f[](3) .IP \[bu] 2 pool set management functions: \f[B]pmempool_rm\f[](3) .IP \[bu] 2 toggle or query pool set features: \f[B]pmempool_feature_query\f[](3) .SH DESCRIPTION .PP \f[B]libpmempool\f[] provides a set of utilities for off\-line analysis and manipulation of a \f[I]pool\f[]. A \f[I]pool\f[] in this manpage means a pmemobj pool, pmemblk pool, pmemlog pool or BTT layout, independent of the underlying storage. Some \f[B]libpmempool\f[] functions are required to work without any impact on the \f[I]pool\f[] but some may create a new or modify an existing \f[I]pool\f[]. .PP \f[B]libpmempool\f[] is for applications that need high reliability or built\-in troubleshooting. It may be useful for testing and debugging purposes also. .PP \f[B]libpmempool\f[] introduces functionality of pool set health check, synchronization, transformation and removal. .SH CAVEATS .PP \f[B]libpmempool\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .PP \f[B]libpmempool\f[] requires the \f[B]\-std=gnu99\f[] compilation flag to build properly. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]pmempool_check_version\f[]() function is used to see if the installed \f[B]libpmempool\f[] supports the version of the library API required by an application. The easiest way to do this for the application is to supply the compile\-time version information, supplied by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ pmempool_check_version(PMEMPOOL_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEMPOOL_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP When the version check performed by \f[B]pmempool_check_version\f[]() is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by \f[B]pmempool_check_version\f[]() must not be modified or freed. .SH DEBUGGING AND ERROR HANDLING .PP If an error is detected during the call to a \f[B]libpmempool\f[] function, the application may retrieve an error message describing the reason for the failure from \f[B]pmempool_errormsg\f[](). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmempool\f[] function indicated an error, or if \f[I]errno\f[] was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. .PP Two versions of \f[B]libpmempool\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmempool\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]libpmempool\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEMPOOL_LOG_LEVEL\f[] .PP The value of \f[B]PMEMPOOL_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEMPOOL_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged (in addition to returning the \f[I]errno\f[]\-based errors as usual). The same information may be retrieved using \f[B]pmempool_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmempool\f[] developers. .PP Unless \f[B]PMEMPOOL_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMPOOL_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEMPOOL_LOG_FILE\f[] is not set, output is written to \f[I]stderr\f[]. .SH EXAMPLE .PP The following example illustrates how the \f[B]libpmempool\f[] API is used. The program detects the type and checks consistency of given pool. If there are any issues detected, the pool is automatically repaired. .IP .nf \f[C] #include\ #include\ #include\ #include\ #include\ #define\ PATH\ "./pmem\-fs/myfile" #define\ CHECK_FLAGS\ (PMEMPOOL_CHECK_FORMAT_STR|PMEMPOOL_CHECK_REPAIR|\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEMPOOL_CHECK_VERBOSE) int main(int\ argc,\ char\ *argv[]) { \ \ \ \ PMEMpoolcheck\ *ppc; \ \ \ \ struct\ pmempool_check_status\ *status; \ \ \ \ enum\ pmempool_check_result\ ret; \ \ \ \ /*\ arguments\ for\ check\ */ \ \ \ \ struct\ pmempool_check_args\ args\ =\ { \ \ \ \ \ \ \ \ .path\ \ \ \ \ \ \ =\ PATH, \ \ \ \ \ \ \ \ .backup_path\ \ \ \ =\ NULL, \ \ \ \ \ \ \ \ .pool_type\ \ =\ PMEMPOOL_POOL_TYPE_DETECT, \ \ \ \ \ \ \ \ .flags\ \ \ \ \ \ =\ CHECK_FLAGS \ \ \ \ }; \ \ \ \ /*\ initialize\ check\ context\ */ \ \ \ \ if\ ((ppc\ =\ pmempool_check_init(&args,\ sizeof(args)))\ ==\ NULL)\ { \ \ \ \ \ \ \ \ perror("pmempool_check_init"); \ \ \ \ \ \ \ \ exit(EXIT_FAILURE); \ \ \ \ } \ \ \ \ /*\ perform\ check\ and\ repair,\ answer\ \[aq]yes\[aq]\ for\ each\ question\ */ \ \ \ \ while\ ((status\ =\ pmempool_check(ppc))\ !=\ NULL)\ { \ \ \ \ \ \ \ \ switch\ (status\->type)\ { \ \ \ \ \ \ \ \ case\ PMEMPOOL_CHECK_MSG_TYPE_ERROR: \ \ \ \ \ \ \ \ \ \ \ \ printf("%s\\n",\ status\->str.msg); \ \ \ \ \ \ \ \ \ \ \ \ break; \ \ \ \ \ \ \ \ case\ PMEMPOOL_CHECK_MSG_TYPE_INFO: \ \ \ \ \ \ \ \ \ \ \ \ printf("%s\\n",\ status\->str.msg); \ \ \ \ \ \ \ \ \ \ \ \ break; \ \ \ \ \ \ \ \ case\ PMEMPOOL_CHECK_MSG_TYPE_QUESTION: \ \ \ \ \ \ \ \ \ \ \ \ printf("%s\\n",\ status\->str.msg); \ \ \ \ \ \ \ \ \ \ \ \ status\->str.answer\ =\ "yes"; \ \ \ \ \ \ \ \ \ \ \ \ break; \ \ \ \ \ \ \ \ default: \ \ \ \ \ \ \ \ \ \ \ \ pmempool_check_end(ppc); \ \ \ \ \ \ \ \ \ \ \ \ exit(EXIT_FAILURE); \ \ \ \ \ \ \ \ } \ \ \ \ } \ \ \ \ /*\ finalize\ the\ check\ and\ get\ the\ result\ */ \ \ \ \ ret\ =\ pmempool_check_end(ppc); \ \ \ \ switch\ (ret)\ { \ \ \ \ \ \ \ \ case\ PMEMPOOL_CHECK_RESULT_CONSISTENT: \ \ \ \ \ \ \ \ case\ PMEMPOOL_CHECK_RESULT_REPAIRED: \ \ \ \ \ \ \ \ \ \ \ \ return\ 0; \ \ \ \ \ \ \ \ default: \ \ \ \ \ \ \ \ \ \ \ \ return\ 1; \ \ \ \ } } \f[] .fi .PP See for more examples using the \f[B]libpmempool\f[] API. .SH ACKNOWLEDGEMENTS .PP \f[B]libpmempool\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]dlclose\f[](3), \f[B]pmempool_check_init\f[](3), \f[B]pmempool_feature_query\f[](3), \f[B]pmempool_rm\f[](3), \f[B]pmempool_sync\f[](3), \f[B]strerror\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7)\f[B] and \f[]** pmdk-1.11.1/doc/libpmempool/pmempool_feature_query.30000664000000000000000000000645014123364734021202 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL_FEATURE_QUERY" "3" "2021-09-24" "PMDK - pmempool API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018, Intel Corporation .SH NAME .PP \f[B]pmempool_feature_query\f[](), \f[B]pmempool_feature_enable\f[](), \f[B]pmempool_feature_disable\f[]() \- toggle or query pool set features .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmempool_feature_query(const\ char\ *path,\ enum\ pmempool_feature\ feature,\ unsigned\ flags); int\ pmempool_feature_enable(const\ char\ *path,\ enum\ pmempool_feature\ feature,\ unsigned\ flags); int\ pmempool_feature_disable(const\ char\ *path,\ enum\ pmempool_feature\ feature,\ unsigned\ flags); \f[] .fi .SH DESCRIPTION .PP The \f[I]feature\f[] argument accepts following values: .IP \[bu] 2 \f[B]PMEMPOOL_FEAT_SINGLEHDR\f[] \- only the first part in each replica contains the pool part internal metadata. This value can be used only with \f[B]pmempool_feature_query\f[](). It can not be enabled or disabled. For details see \f[B]poolset\f[](5). .IP \[bu] 2 \f[B]PMEMPOOL_FEAT_CKSUM_2K\f[] \- only the first 2KiB of pool part internal metadata is checksummed. Other features may depend on this one to store additional metadata in otherwise unused second 2KiB part of a header. When \f[B]PMEMPOOL_FEAT_CKSUM_2K\f[] is disabled whole 4KiB is checksummed. .IP \[bu] 2 \f[B]PMEMPOOL_FEAT_SHUTDOWN_STATE\f[] \- enables additional check performed during pool open which verifies pool consistency in the presence of dirty shutdown. \f[B]PMEMPOOL_FEAT_CKSUM_2K\f[] has to be enabled prior to \f[B]PMEMPOOL_FEAT_SHUTDOWN_STATE\f[] otherwise enabling \f[B]PMEMPOOL_FEAT_SHUTDOWN_STATE\f[] will fail. .IP \[bu] 2 \f[B]PMEMPOOL_FEAT_CHECK_BAD_BLOCKS\f[] \- enables checking bad blocks performed during opening a pool and fixing bad blocks performed by pmempool\-sync during syncing a pool. For details see \f[B]pmempool\-feature\f[](1). .PP The \f[B]pmempool_feature_query\f[]() function checks state of \f[I]feature\f[] in the pool set pointed by \f[I]path\f[]. .PP The \f[B]pmempool_feature_enable\f[]() function enables \f[I]feature\f[] in the pool set pointed by \f[I]path\f[]. .PP The \f[B]pmempool_feature_disable\f[]() function disables \f[I]feature\f[] in the pool set pointed by \f[I]path\f[]. .SH COMPATIBILITY .PP Poolsets with features not defined in this document (e.g.\ enabled by the newer software version) are not supported. .SH DISCLAIMER .PP \f[B]pmempool_feature_query\f[](), \f[B]pmempool_feature_enable\f[]() and \f[B]pmempool_feature_disable\f[]() are not fail safe. .SH RETURN VALUE .PP On success, \f[B]pmempool_feature_query\f[]() returns 0 if \f[I]feature\f[] is disabled or 1 if it is enabled. On error, it returns \-1 and sets \f[I]errno\f[] accordingly. .PP On success, \f[B]pmempool_feature_enable\f[]() returns 0. On error, it returns \-1 and sets \f[I]errno\f[] accordingly. .PP On success, \f[B]pmempool_feature_disable\f[]() returns 0. On error, it returns \-1 and sets \f[I]errno\f[] accordingly. .PP If \f[I]path\f[] points poolset with remote replica \f[B]errno\f[] is set to EINVAL and function returns \-1. .PP If non zero \f[I]flags\f[] are provided \f[B]errno\f[] is set to EINVAL and function returns \-1. .SH SEE ALSO .PP \f[B]poolset\f[](5) and \f[B]\f[] pmdk-1.11.1/doc/libpmempool/pmempool_rm.3.md0000664000000000000000000000323014123364546017331 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL_RM, 3) collection: libpmempool header: PMDK date: pmempool API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmempool_rm.3 -- man page for pool set management functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # _UW(pmempool_rm) - remove persistent memory pool # SYNOPSIS # ```c #include _UWFUNCR1(int, pmempool_rm, *path, int flags) ``` _UNICODE() # DESCRIPTION # The _UW(pmempool_rm) function removes the pool pointed to by *path*. The *path* can point to a regular file, device dax or pool set file. If *path* is a pool set file, _UW(pmempool_rm) will remove all part files from local replicas using **unlink**(2)_WINUX(,=q=, and all remote replicas using **rpmem_remove**(3) (see **librpmem**(7)),=e=) before removing the pool set file itself. The *flags* argument determines the behavior of _UW(pmempool_rm). It is either 0 or the bitwise OR of one or more of the following flags: + **PMEMPOOL_RM_FORCE** - Ignore all errors when removing part files from local _WINUX(,or remote )replicas. + **PMEMPOOL_RM_POOLSET_LOCAL** - Also remove local pool set file. _WINUX(, + **PMEMPOOL_RM_POOLSET_REMOTE** - Also remove remote pool set file.) # RETURN VALUE # On success, _UW(pmempool_rm) returns 0. On error, it returns -1 and sets *errno* accordingly. # SEE ALSO # **rpmem_remove**(3), **unlink**(3), **libpmemlog**(7), **libpmemobj**(7), **librpmem**(7) and **** pmdk-1.11.1/doc/librpmem/0000775000000000000000000000000014123364735013612 5ustar rootrootpmdk-1.11.1/doc/librpmem/rpmem_deep_persist.30000664000000000000000000000002414123364546017560 0ustar rootroot.so rpmem_persist.3 pmdk-1.11.1/doc/librpmem/rpmem_persist.30000664000000000000000000001360614123364735016575 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "RPMEM_PERSIST" "3" "2021-09-24" "PMDK - rpmem API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]rpmem_persist\f[](), \f[B]rpmem_deep_persist\f[](), \f[B]rpmem_flush\f[](), \f[B]rpmem_drain\f[](), \f[B]rpmem_read\f[]() \- functions to copy and read remote pools .SH SYNOPSIS .IP .nf \f[C] #include\ int\ rpmem_persist(RPMEMpool\ *rpp,\ size_t\ offset, \ \ \ \ size_t\ length,\ unsigned\ lane,\ unsigned\ flags); int\ rpmem_deep_persist(RPMEMpool\ *rpp,\ size_t\ offset, \ \ \ \ size_t\ length,\ unsigned\ lane); int\ rpmem_flush(RPMEMpool\ *rpp,\ size_t\ offset, \ \ \ \ size_t\ length,\ unsigned\ lane,\ unsigned\ flags); int\ rpmem_drain(RPMEMpool\ *rpp,\ unsigned\ lane,\ unsigned\ flags); int\ rpmem_read(RPMEMpool\ *rpp,\ void\ *buff,\ size_t\ offset, \ \ \ \ size_t\ length,\ unsigned\ lane); \f[] .fi .SH DESCRIPTION .PP The \f[B]rpmem_persist\f[]() function copies data of given \f[I]length\f[] at given \f[I]offset\f[] from the associated local memory pool and makes sure the data is persistent on the remote node before the function returns. The remote node is identified by the \f[I]rpp\f[] handle which must be returned from either \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3). The \f[I]offset\f[] is relative to the \f[I]pool_addr\f[] specified in the \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3) call. If the remote pool was created using \f[B]rpmem_create\f[]() with non\-NULL \f[I]create_attr\f[] argument, \f[I]offset\f[] has to be greater or equal to 4096. In that case the first 4096 bytes of the pool is used for storing the pool metadata and cannot be overwritten. If the pool was created with NULL \f[I]create_attr\f[] argument, the pool metadata is not stored with the pool and \f[I]offset\f[] can be any nonnegative number. The \f[I]offset\f[] and \f[I]length\f[] combined must not exceed the \f[I]pool_size\f[] passed to \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3). The \f[B]rpmem_persist\f[]() operation is performed using the given \f[I]lane\f[] number. The lane must be less than the value returned by \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3) through the \f[I]nlanes\f[] argument (so it can take a value from 0 to \f[I]nlanes\f[] \- 1). The \f[I]flags\f[] argument can be 0 or RPMEM_PERSIST_RELAXED which means the persist operation will be done without any guarantees regarding atomicity of memory transfer. .PP The \f[B]rpmem_deep_persist\f[]() function works in the same way as \f[B]rpmem_persist\f[](3) function, but additionally it flushes the data to the lowest possible persistency domain available from software. Please see \f[B]pmem_deep_persist\f[](3) for details. .PP The \f[B]rpmem_flush\f[]() and \f[B]rpmem_drain\f[]() functions are two halves of the single \f[B]rpmem_persist\f[](). The \f[B]rpmem_persist\f[]() copies data and makes it persistent in the one shot, where \f[B]rpmem_flush\f[]() and \f[B]rpmem_drain\f[]() split this operation into two stages. The \f[B]rpmem_flush\f[]() copies data of given \f[I]length\f[] at a given \f[I]offset\f[] from the associated local memory pool to the remote node. The \f[B]rpmem_drain\f[]() makes sure the data copied in all preceding \f[B]rpmem_flush\f[]() calls is persistent on the remote node before the function returns. Data copied using \f[B]rpmem_flush\f[]() can not be considered persistent on the remote node before return from following \f[B]rpmem_drain\f[](). Single \f[B]rpmem_drain\f[]() confirms persistence on the remote node of data copied by all \f[B]rpmem_flush\f[]() functions called before it and using the same \f[I]lane\f[]. The last \f[B]rpmem_flush\f[]() + \f[B]rpmem_drain\f[]() can be replaced with \f[B]rpmem_persist\f[]() at no cost. .PP The \f[I]flags\f[] argument for \f[B]rpmem_flush\f[]() can be 0 or RPMEM_FLUSH_RELAXED which means the flush operation will be done without any guarantees regarding atomicity of memory transfer. The \f[I]flags\f[] argument for \f[B]rpmem_drain\f[]() must be 0. .PP The \f[B]rpmem_flush\f[]() function performance is affected by \f[B]RPMEM_WORK_QUEUE_SIZE\f[] environment variable (see \f[B]librpmem\f[](7) for more details). .PP The \f[B]rpmem_read\f[]() function reads \f[I]length\f[] bytes of data from a remote pool at \f[I]offset\f[] and copies it to the buffer \f[I]buff\f[]. The operation is performed on the specified \f[I]lane\f[]. The lane must be less than the value returned by \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3) through the \f[I]nlanes\f[] argument (so it can take a value from 0 to \f[I]nlanes\f[] \- 1). The \f[I]rpp\f[] must point to a remote pool opened or created previously by \f[B]rpmem_open\f[](3) or \f[B]rpmem_create\f[](3). .SH RETURN VALUE .PP The \f[B]rpmem_persist\f[]() function returns 0 if the entire memory area was made persistent on the remote node. Otherwise it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .PP The \f[B]rpmem_flush\f[]() function returns 0 if duplication of the memory area to the remote node was initialized successfully. Otherwise, it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .PP The \f[B]rpmem_drain\f[]() function returns 0 if the memory areas duplicated by all \f[B]rpmem_flush\f[]() calls preceding the \f[B]rpmem_drain\f[]() are made persistent on the remote node. Otherwise, it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .PP The \f[B]rpmem_read\f[]() function returns 0 if the data was read entirely. Otherwise it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .SH CAVEATS .PP Ordering of \f[B]rpmem_flush\f[]() and \f[B]rpmem_persist\f[]() operations which are using different \f[I]lane\f[] values is not guaranteed. .SH SEE ALSO .PP \f[B]rpmem_create\f[](3), \f[B]rpmem_open\f[](3), \f[B]rpmem_persist\f[](3), \f[B]sysconf\f[](3), \f[B]limits.conf\f[](5), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/librpmem/rpmem_persist.3.md0000664000000000000000000001302714123364546017171 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(RPMEM_PERSIST, 3) collection: librpmem header: PMDK date: rpmem API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (rpmem_persist.3 -- man page for rpmem persist, flush, drain and read functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # **rpmem_persist**(), **rpmem_deep_persist**(), **rpmem_flush**(), **rpmem_drain**(), **rpmem_read**() - functions to copy and read remote pools # SYNOPSIS # ```c #include int rpmem_persist(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane, unsigned flags); int rpmem_deep_persist(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane); int rpmem_flush(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane, unsigned flags); int rpmem_drain(RPMEMpool *rpp, unsigned lane, unsigned flags); int rpmem_read(RPMEMpool *rpp, void *buff, size_t offset, size_t length, unsigned lane); ``` # DESCRIPTION # The **rpmem_persist**() function copies data of given *length* at given *offset* from the associated local memory pool and makes sure the data is persistent on the remote node before the function returns. The remote node is identified by the *rpp* handle which must be returned from either **rpmem_open**(3) or **rpmem_create**(3). The *offset* is relative to the *pool_addr* specified in the **rpmem_open**(3) or **rpmem_create**(3) call. If the remote pool was created using **rpmem_create**() with non-NULL *create_attr* argument, *offset* has to be greater or equal to 4096. In that case the first 4096 bytes of the pool is used for storing the pool metadata and cannot be overwritten. If the pool was created with NULL *create_attr* argument, the pool metadata is not stored with the pool and *offset* can be any nonnegative number. The *offset* and *length* combined must not exceed the *pool_size* passed to **rpmem_open**(3) or **rpmem_create**(3). The **rpmem_persist**() operation is performed using the given *lane* number. The lane must be less than the value returned by **rpmem_open**(3) or **rpmem_create**(3) through the *nlanes* argument (so it can take a value from 0 to *nlanes* - 1). The *flags* argument can be 0 or RPMEM_PERSIST_RELAXED which means the persist operation will be done without any guarantees regarding atomicity of memory transfer. The **rpmem_deep_persist**() function works in the same way as **rpmem_persist**(3) function, but additionally it flushes the data to the lowest possible persistency domain available from software. Please see **pmem_deep_persist**(3) for details. The **rpmem_flush**() and **rpmem_drain**() functions are two halves of the single **rpmem_persist**(). The **rpmem_persist**() copies data and makes it persistent in the one shot, where **rpmem_flush**() and **rpmem_drain**() split this operation into two stages. The **rpmem_flush**() copies data of given *length* at a given *offset* from the associated local memory pool to the remote node. The **rpmem_drain**() makes sure the data copied in all preceding **rpmem_flush**() calls is persistent on the remote node before the function returns. Data copied using **rpmem_flush**() can not be considered persistent on the remote node before return from following **rpmem_drain**(). Single **rpmem_drain**() confirms persistence on the remote node of data copied by all **rpmem_flush**() functions called before it and using the same *lane*. The last **rpmem_flush**() + **rpmem_drain**() can be replaced with **rpmem_persist**() at no cost. The *flags* argument for **rpmem_flush**() can be 0 or RPMEM_FLUSH_RELAXED which means the flush operation will be done without any guarantees regarding atomicity of memory transfer. The *flags* argument for **rpmem_drain**() must be 0. The **rpmem_flush**() function performance is affected by **RPMEM_WORK_QUEUE_SIZE** environment variable (see **librpmem**(7) for more details). The **rpmem_read**() function reads *length* bytes of data from a remote pool at *offset* and copies it to the buffer *buff*. The operation is performed on the specified *lane*. The lane must be less than the value returned by **rpmem_open**(3) or **rpmem_create**(3) through the *nlanes* argument (so it can take a value from 0 to *nlanes* - 1). The *rpp* must point to a remote pool opened or created previously by **rpmem_open**(3) or **rpmem_create**(3). # RETURN VALUE # The **rpmem_persist**() function returns 0 if the entire memory area was made persistent on the remote node. Otherwise it returns a non-zero value and sets *errno* appropriately. The **rpmem_flush**() function returns 0 if duplication of the memory area to the remote node was initialized successfully. Otherwise, it returns a non-zero value and sets *errno* appropriately. The **rpmem_drain**() function returns 0 if the memory areas duplicated by all **rpmem_flush**() calls preceding the **rpmem_drain**() are made persistent on the remote node. Otherwise, it returns a non-zero value and sets *errno* appropriately. The **rpmem_read**() function returns 0 if the data was read entirely. Otherwise it returns a non-zero value and sets *errno* appropriately. # CAVEATS # Ordering of **rpmem_flush**() and **rpmem_persist**() operations which are using different *lane* values is not guaranteed. # SEE ALSO # **rpmem_create**(3), **rpmem_open**(3), **rpmem_persist**(3), **sysconf**(3), **limits.conf**(5), **libpmemobj**(7) and **** pmdk-1.11.1/doc/librpmem/rpmem_errormsg.30000664000000000000000000000002414123364546016732 0ustar rootroot.so man7/librpmem.7 pmdk-1.11.1/doc/librpmem/rpmem_set_attr.30000664000000000000000000000002314123364546016716 0ustar rootroot.so rpmem_create.3 pmdk-1.11.1/doc/librpmem/rpmem_read.30000664000000000000000000000002414123364546016005 0ustar rootroot.so rpmem_persist.3 pmdk-1.11.1/doc/librpmem/rpmem_open.30000664000000000000000000000002314123364546016032 0ustar rootroot.so rpmem_create.3 pmdk-1.11.1/doc/librpmem/rpmem_remove.30000664000000000000000000000002114123364546016364 0ustar rootroot.so rpmem_open.3 pmdk-1.11.1/doc/librpmem/rpmem_create.30000664000000000000000000002104514123364735016343 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "RPMEM_CREATE" "3" "2021-09-24" "PMDK - rpmem API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]rpmem_create\f[](), \f[B]rpmem_open\f[](), \f[B]rpmem_set_attr\f[](), \f[B]rpmem_close\f[](), \f[B]rpmem_remove\f[]() \- most commonly used functions for remote access to \f[I]persistent memory\f[] .SH SYNOPSIS .IP .nf \f[C] #include\ RPMEMpool\ *rpmem_create(const\ char\ *target,\ const\ char\ *pool_set_name, \ \ \ \ void\ *pool_addr,\ size_t\ pool_size,\ unsigned\ *nlanes, \ \ \ \ const\ struct\ rpmem_pool_attr\ *create_attr); RPMEMpool\ *rpmem_open(const\ char\ *target,\ const\ char\ *pool_set_name, \ \ \ \ void\ *pool_addr,\ size_t\ pool_size,\ unsigned\ *nlanes, \ \ \ \ struct\ rpmem_pool_attr\ *open_attr); int\ rpmem_set_attr(RPMEMpool\ *rpp,\ const\ struct\ rpmem_pool_attr\ *attr); int\ rpmem_close(RPMEMpool\ *rpp); int\ rpmem_remove(const\ char\ *target,\ const\ char\ *pool_set_name,\ int\ flags); \f[] .fi .SH DESCRIPTION .PP The \f[B]rpmem_create\f[]() function creates a remote pool on a given \f[I]target\f[] node, using pool \f[I]set\f[] file \f[I]pool_set_name\f[] to map the remote pool. \f[I]pool_set_name\f[] is a relative path in the root config directory on the \f[I]target\f[] node. For pool set file format and options see \f[B]poolset\f[](5). \f[I]pool_addr\f[] is a pointer to the associated local memory pool with size \f[I]pool_size\f[]. Both \f[I]pool_addr\f[] and \f[I]pool_size\f[] must be aligned to the system's page size (see \f[B]sysconf\f[](3)). The size of the remote pool must be at least \f[I]pool_size\f[]. See \f[B]REMOTE POOL SIZE\f[], below, for details. \f[I]nlanes\f[] points to the maximum number of lanes which the caller is requesting. Upon successful creation of the remote pool, *\f[I]nlanes\f[] is set to the maximum number of lanes supported by both the local and remote nodes. See \f[B]LANES\f[], below, for details. The \f[I]create_attr\f[] structure contains the attributes used for creating the remote pool. If the \f[I]create_attr\f[] structure is not NULL, a pool with internal metadata is created. The metadata is stored in the first 4096 bytes of the pool and can be read when opening the remote pool with \f[B]rpmem_open\f[](). To prevent user from overwriting the pool metadata, this region is not accessible to the user via \f[B]rpmem_persist\f[](). If \f[I]create_attr\f[] is NULL or zeroed, remote pool set file must contain the \f[I]NOHDRS\f[] option. In that case the remote pool is created without internal metadata in it and the entire pool space is available to the user. See \f[B]rpmem_persist\f[](3) for details. .PP The \f[B]rpmem_open\f[]() function opens the existing remote pool with \f[I]set\f[] file \f[I]pool_set_name\f[] on remote node \f[I]target\f[]. \f[I]pool_set_name\f[] is a relative path in the root config directory on the \f[I]target\f[] node. \f[I]pool_addr\f[] is a pointer to the associated local memory pool of size \f[I]pool_size\f[]. Both \f[I]pool_addr\f[] and \f[I]pool_size\f[] must be aligned to the system's page size (see \f[B]sysconf\f[](3)). The size of the remote pool must be at least \f[I]pool_size\f[]. See \f[B]REMOTE POOL SIZE\f[], below, for details. \f[I]nlanes\f[] points to the maximum number of lanes which the caller is requesting. Upon successful opening of the remote pool, *\f[I]nlanes\f[] is set to the maximum number of lanes supported by both the local and remote nodes. See \f[B]LANES\f[], below, for details. .PP The \f[B]rpmem_set_attr\f[]() function overwrites the pool's attributes. The \f[I]attr\f[] structure contains the attributes used for overwriting the remote pool attributes that were passed to \f[B]rpmem_create\f[]() at pool creation. If \f[I]attr\f[] is NULL, a zeroed structure with attributes will be used. New attributes are stored in the pool's metadata. .PP The \f[B]rpmem_close\f[]() function closes the remote pool \f[I]rpp\f[]. All resources are released on both the local and remote nodes. The remote pool itself persists on the remote node and may be re\-opened at a later time using \f[B]rpmem_open\f[](). .PP The \f[B]rpmem_remove\f[]() function removes the remote pool with \f[I]set\f[] file name \f[I]pool_set_name\f[] from node \f[I]target\f[]. The \f[I]pool_set_name\f[] is a relative path in the root config directory on the \f[I]target\f[] node. By default only the pool part files are removed; the pool \f[I]set\f[] file is left untouched. If the pool is not consistent, the \f[B]rpmem_remove\f[]() function fails. The \f[I]flags\f[] argument determines the behavior of \f[B]rpmem_remove\f[](). \f[I]flags\f[] may be either 0 or the bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]RPMEM_REMOVE_FORCE\f[] \- Ignore errors when opening an inconsistent pool. The pool \f[I]set\f[] file must still be in appropriate format for the pool to be removed. .IP \[bu] 2 \f[B]RPMEM_REMOVE_POOL_SET\f[] \- Remove the pool \f[I]set\f[] file after removing the pool described by this pool set. .SH RETURN VALUE .PP On success, \f[B]rpmem_create\f[]() returns an opaque handle to the remote pool for use in subsequent \f[B]librpmem\f[] calls. If any error prevents the remote pool from being created, \f[B]rpmem_create\f[]() returns NULL and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]rpmem_open\f[]() returns an opaque handle to the remote pool for subsequent \f[B]librpmem\f[] calls. If the \f[I]open_attr\f[] argument is not NULL, the remote pool attributes are returned in the provided structure. If the remote pool was created without internal metadata, zeroes are returned in the \f[I]open_attr\f[] structure on successful call to \f[B]rpmem_open\f[](). If any error prevents the remote pool from being opened, \f[B]rpmem_open\f[]() returns NULL and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]rpmem_set_attr\f[]() returns 0. On error, it returns \-1 and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]rpmem_close\f[]() returns 0. On error, it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]rpmem_remove\f[]() returns 0. On error, it returns a non\-zero value and sets \f[I]errno\f[] appropriately. .SH NOTES .SS REMOTE POOL SIZE .PP The size of a remote pool depends on the configuration in the pool set file on the remote node (see \f[B]poolset\f[](5)). If no pool set options is used in the remote pool set file, the remote pool size is the sum of the sizes of all part files, decreased by 4096 bytes per part file. 4096 bytes of each part file are utilized for storing internal metadata. If the \f[I]SINGLEHDR\f[] option is used in the remote pool set file, the remote pool size is the sum of sizes of all part files, decreased once by 4096 bytes. In this case only the first part contains internal metadata. If a remote pool set file contains the \f[I]NOHDRS\f[] option, the remote pool size is the sum of sizes of all its part files. In this case none of the parts contains internal metadata. For other consequences of using the \f[I]SINGLEHDR\f[] and \f[I]NOHDRS\f[] options see \f[B]rpmem_persist\f[](3). \f[B]RPMEM_MIN_PART\f[] and \f[B]RPMEM_MIN_POOL\f[] in \f[B]\f[] define the minimum size allowed by \f[B]librpmem\f[] for a part file and a remote pool, respectively. .SS LANES .PP The term \f[I]lane\f[] means an isolated path of execution. The underlying hardware utilized by both local and remote nodes may have limited resources that restrict the maximum number of parallel \f[B]rpmem_persist\f[](3) operations. The maximum number of supported lanes is returned by the \f[B]rpmem_open\f[]() and \f[B]rpmem_create\f[]() function calls. The caller passes the maximum number of lanes requested in *\f[I]nlanes\f[]. If the pool is successfully created or opened, *\f[I]nlanes\f[] is updated to reflect the minimum of the number of lanes requested by the caller and the maximum number of lanes supported by underlying hardware. The application is obligated to use at most the returned number of lanes in parallel. .PP \f[B]rpmem_persist\f[](3) does not provide any locking mechanism; thus any serialization of calls must be performed by the application if required. .PP Each lane requires a separate connection, represented by a file descriptor. If the system runs out of free file descriptors during \f[B]rpmem_create\f[]() or \f[B]rpmem_open\f[](), these functions will fail. See \f[B]nofile\f[] in \f[B]limits.conf\f[](5) for more details. .SH SEE ALSO .PP \f[B]rpmem_persist\f[](3), \f[B]sysconf\f[](3), \f[B]limits.conf\f[](5), \f[B]libpmemobj\f[](7), \f[B]librpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/librpmem/librpmem.70000664000000000000000000004176614123364725015526 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBRPMEM" "7" "2021-09-24" "PMDK - rpmem API version 1.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2019, Intel Corporation .SH NAME .PP \f[B]librpmem\f[] \- remote persistent memory support library (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lrpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *rpmem_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Error handling: .IP .nf \f[C] const\ char\ *rpmem_errormsg(void); \f[] .fi .SS Other library functions: .PP A description of other \f[B]librpmem\f[] functions can be found on the following manual pages: .IP \[bu] 2 \f[B]rpmem_create\f[](3), \f[B]rpmem_persist\f[](3) .SH DESCRIPTION .PP \f[B]librpmem\f[] provides low\-level support for remote access to \f[I]persistent memory\f[] (pmem) utilizing RDMA\-capable RNICs. The library can be used to remotely replicate a memory region over the RDMA protocol. It utilizes an appropriate persistency mechanism based on the remote node's platform capabilities. \f[B]librpmem\f[] utilizes the \f[B]ssh\f[](1) client to authenticate a user on the remote node, and for encryption of the connection's out\-of\-band configuration data. See \f[B]SSH\f[], below, for details. .PP The maximum replicated memory region size can not be bigger than the maximum locked\-in\-memory address space limit. See \f[B]memlock\f[] in \f[B]limits.conf\f[](5) for more details. .PP This library is for applications that use remote persistent memory directly, without the help of any library\-supplied transactions or memory allocation. Higher\-level libraries that build on \f[B]libpmem\f[](7) are available and are recommended for most applications, see: .IP \[bu] 2 \f[B]libpmemobj\f[](7), a general use persistent memory API, providing memory allocation and transactional operations on variable\-sized objects. .SH TARGET NODE ADDRESS FORMAT .IP .nf \f[C] [\@][:] \f[] .fi .PP The target node address is described by the \f[I]hostname\f[] which the client connects to, with an optional \f[I]user\f[] name. The user must be authorized to authenticate to the remote machine without querying for password/passphrase. The optional \f[I]port\f[] number is used to establish the SSH connection. The default port number is 22. .SH REMOTE POOL ATTRIBUTES .PP The \f[I]rpmem_pool_attr\f[] structure describes a remote pool and is stored in remote pool's metadata. This structure must be passed to the \f[B]rpmem_create\f[](3) function by caller when creating a pool on remote node. When opening the pool using \f[B]rpmem_open\f[](3) function the appropriate fields are read from pool's metadata and returned back to the caller. .IP .nf \f[C] #define\ RPMEM_POOL_HDR_SIG_LEN\ \ \ \ 8 #define\ RPMEM_POOL_HDR_UUID_LEN\ \ \ 16 #define\ RPMEM_POOL_USER_FLAGS_LEN\ 16 struct\ rpmem_pool_attr\ { \ \ \ \ char\ signature[RPMEM_POOL_HDR_SIG_LEN]; \ \ \ \ uint32_t\ major; \ \ \ \ uint32_t\ compat_features; \ \ \ \ uint32_t\ incompat_features; \ \ \ \ uint32_t\ ro_compat_features; \ \ \ \ unsigned\ char\ poolset_uuid[RPMEM_POOL_HDR_UUID_LEN]; \ \ \ \ unsigned\ char\ uuid[RPMEM_POOL_HDR_UUID_LEN]; \ \ \ \ unsigned\ char\ next_uuid[RPMEM_POOL_HDR_UUID_LEN]; \ \ \ \ unsigned\ char\ prev_uuid[RPMEM_POOL_HDR_UUID_LEN]; \ \ \ \ unsigned\ char\ user_flags[RPMEM_POOL_USER_FLAGS_LEN]; }; \f[] .fi .PP The \f[I]signature\f[] field is an 8\-byte field which describes the pool's on\-media format. .PP The \f[I]major\f[] field is a major version number of the pool's on\-media format. .PP The \f[I]compat_features\f[] field is a mask describing compatibility of pool's on\-media format optional features. .PP The \f[I]incompat_features\f[] field is a mask describing compatibility of pool's on\-media format required features. .PP The \f[I]ro_compat_features\f[] field is a mask describing compatibility of pool's on\-media format features. If these features are not available, the pool shall be opened in read\-only mode. .PP The \f[I]poolset_uuid\f[] field is an UUID of the pool which the remote pool is associated with. .PP The \f[I]uuid\f[] field is an UUID of a first part of the remote pool. This field can be used to connect the remote pool with other pools in a list. .PP The \f[I]next_uuid\f[] and \f[I]prev_uuid\f[] fields are UUIDs of next and previous replicas respectively. These fields can be used to connect the remote pool with other pools in a list. .PP The \f[I]user_flags\f[] field is a 16\-byte user\-defined flags. .SH SSH .PP \f[B]librpmem\f[] utilizes the \f[B]ssh\f[](1) client to login and execute the \f[B]rpmemd\f[](1) process on the remote node. By default, \f[B]ssh\f[](1) is executed with the \f[B]\-4\f[] option, which forces using \f[B]IPv4\f[] addressing. .PP For debugging purposes, both the ssh client and the commands executed on the remote node may be overridden by setting the \f[B]RPMEM_SSH\f[] and \f[B]RPMEM_CMD\f[] environment variables, respectively. See \f[B]ENVIRONMENT\f[] for details. .SH FORK .PP The \f[B]ssh\f[](1) client is executed by \f[B]rpmem_open\f[](3) and \f[B]rpmem_create\f[](3) after forking a child process using \f[B]fork\f[](2). The application must take this into account when using \f[B]wait\f[](2) and \f[B]waitpid\f[](2), which may return the \f[I]PID\f[] of the \f[B]ssh\f[](1) process executed by \f[B]librpmem\f[]. .PP If \f[B]fork\f[](2) support is not enabled in \f[B]libibverbs\f[], \f[B]rpmem_open\f[](3) and \f[B]rpmem_create\f[](3) will fail. By default, \f[B]fabric\f[](7) initializes \f[B]libibverbs\f[] with \f[B]fork\f[](2) support by calling the \f[B]ibv_fork_init\f[](3) function. See \f[B]fi_verbs\f[](7) for more details. .SH CAVEATS .PP \f[B]librpmem\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .PP \f[B]librpmem\f[] registers a pool as a single memory region. A Chelsio T4 and T5 hardware can not handle a memory region greater than or equal to 8GB due to a hardware bug. So \f[I]pool_size\f[] value for \f[B]rpmem_create\f[](3) and \f[B]rpmem_open\f[](3) using this hardware can not be greater than or equal to 8GB. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]rpmem_check_version\f[]() function is used to see if the installed \f[B]librpmem\f[] supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile\-time version information, supplied by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ rpmem_check_version(RPMEM_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ RPMEM_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP When the version check performed by \f[B]rpmem_check_version\f[]() is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by \f[B]rpmem_check_version\f[]() must not be modified or freed. .SH ENVIRONMENT .PP \f[B]librpmem\f[] can change its default behavior based on the following environment variables. These are largely intended for testing and are not normally required. .IP \[bu] 2 \f[B]RPMEM_SSH\f[]=\f[I]ssh_client\f[] .PP Setting this environment variable overrides the default \f[B]ssh\f[](1) client command name. .IP \[bu] 2 \f[B]RPMEM_CMD\f[]=\f[I]cmd\f[] .PP Setting this environment variable overrides the default command executed on the remote node using either \f[B]ssh\f[](1) or the alternative remote shell command specified by \f[B]RPMEM_SSH\f[]. .PP \f[B]RPMEM_CMD\f[] can contain multiple commands separated by a vertical bar (\f[C]|\f[]). Each consecutive command is executed on the remote node in order read from a pool set file. This environment variable is read when the library is initialized, so \f[B]RPMEM_CMD\f[] must be set prior to application launch (or prior to \f[B]dlopen\f[](3) if \f[B]librpmem\f[] is being dynamically loaded). .IP \[bu] 2 \f[B]RPMEM_ENABLE_SOCKETS\f[]=0|1 .PP Setting this variable to 1 enables using \f[B]fi_sockets\f[](7) provider for in\-band RDMA connection. The \f[I]sockets\f[] provider does not support IPv6. It is required to disable IPv6 system wide if \f[B]RPMEM_ENABLE_SOCKETS\f[] == 1 and \f[I]target\f[] == localhost (or any other loopback interface address) and \f[B]SSH_CONNECTION\f[] variable (see \f[B]ssh\f[](1) for more details) contains IPv6 address after ssh to loopback interface. By default the \f[I]sockets\f[] provider is disabled. .IP \[bu] 2 \f[B]RPMEM_ENABLE_VERBS\f[]=0|1 .PP Setting this variable to 0 disables using \f[B]fi_verbs\f[](7) provider for in\-band RDMA connection. The \f[I]verbs\f[] provider is enabled by default. .IP \[bu] 2 \f[B]RPMEM_MAX_NLANES\f[]=\f[I]num\f[] .PP Limit the maximum number of lanes to \f[I]num\f[]. See \f[B]LANES\f[], in \f[B]rpmem_create\f[](3), for details. .IP \[bu] 2 \f[B]RPMEM_WORK_QUEUE_SIZE\f[]=\f[I]size\f[] .PP Suggest the work queue size. The effective work queue size can be greater than suggested if \f[B]librpmem\f[] requires it or it can be smaller if underlying hardware does not support the suggested size. The work queue size affects the performance of communication to the remote node. \f[B]rpmem_flush\f[](3) operations can be added to the work queue up to the size of this queue. When work queue is full any subsequent call has to wait till the work queue will be drained. \f[B]rpmem_drain\f[](3) and \f[B]rpmem_persist\f[](3) among other things also drain the work queue. .SH DEBUGGING AND ERROR HANDLING .PP If an error is detected during the call to a \f[B]librpmem\f[] function, the application may retrieve an error message describing the reason for the failure from \f[B]rpmem_errormsg\f[](). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]librpmem\f[] function indicated an error, or if \f[I]errno\f[] was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. .PP Two versions of \f[B]librpmem\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lrpmem\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]librpmem\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]RPMEM_LOG_LEVEL\f[] .PP The value of \f[B]RPMEM_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]RPMEM_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged (in addition to returning the \f[I]errno\f[]\-based errors as usual). The same information may be retrieved using \f[B]rpmem_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]librpmem\f[] developers. .PP Unless \f[B]RPMEM_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]RPMEM_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]RPMEM_LOG_FILE\f[] is not set, logging output is written to \f[I]stderr\f[]. .SH EXAMPLE .PP The following example uses \f[B]librpmem\f[] to create a remote pool on given target node identified by given pool set name. The associated local memory pool is zeroed and the data is made persistent on remote node. Upon success the remote pool is closed. .IP .nf \f[C] #include\ #include\ #include\ #include\ #include\ #include\ #define\ POOL_SIGNATURE\ \ "MANPAGE" #define\ POOL_SIZE\ \ \ (32\ *\ 1024\ *\ 1024) #define\ NLANES\ \ \ \ \ \ 4 #define\ DATA_OFF\ \ \ \ 4096 #define\ DATA_SIZE\ \ \ (POOL_SIZE\ \-\ DATA_OFF) static\ void parse_args(int\ argc,\ char\ *argv[],\ const\ char\ **target,\ const\ char\ **poolset) { \ \ \ \ if\ (argc\ <\ 3)\ { \ \ \ \ \ \ \ \ fprintf(stderr,\ "usage:\\t%s\ \ \\n",\ argv[0]); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ *target\ =\ argv[1]; \ \ \ \ *poolset\ =\ argv[2]; } static\ void\ * alloc_memory() { \ \ \ \ long\ pagesize\ =\ sysconf(_SC_PAGESIZE); \ \ \ \ if\ (pagesize\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("sysconf"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ allocate\ a\ page\ size\ aligned\ local\ memory\ pool\ */ \ \ \ \ void\ *mem; \ \ \ \ int\ ret\ =\ posix_memalign(&mem,\ pagesize,\ POOL_SIZE); \ \ \ \ if\ (ret)\ { \ \ \ \ \ \ \ \ fprintf(stderr,\ "posix_memalign:\ %s\\n",\ strerror(ret)); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ assert(mem\ !=\ NULL); \ \ \ \ return\ mem; } int main(int\ argc,\ char\ *argv[]) { \ \ \ \ const\ char\ *target,\ *poolset; \ \ \ \ parse_args(argc,\ argv,\ &target,\ &poolset); \ \ \ \ unsigned\ nlanes\ =\ NLANES; \ \ \ \ void\ *pool\ =\ alloc_memory(); \ \ \ \ int\ ret; \ \ \ \ /*\ fill\ pool_attributes\ */ \ \ \ \ struct\ rpmem_pool_attr\ pool_attr; \ \ \ \ memset(&pool_attr,\ 0,\ sizeof(pool_attr)); \ \ \ \ strncpy(pool_attr.signature,\ POOL_SIGNATURE,\ RPMEM_POOL_HDR_SIG_LEN); \ \ \ \ /*\ create\ a\ remote\ pool\ */ \ \ \ \ RPMEMpool\ *rpp\ =\ rpmem_create(target,\ poolset,\ pool,\ POOL_SIZE, \ \ \ \ \ \ \ \ \ \ \ \ &nlanes,\ &pool_attr); \ \ \ \ if\ (!rpp)\ { \ \ \ \ \ \ \ \ fprintf(stderr,\ "rpmem_create:\ %s\\n",\ rpmem_errormsg()); \ \ \ \ \ \ \ \ return\ 1; \ \ \ \ } \ \ \ \ /*\ store\ data\ on\ local\ pool\ */ \ \ \ \ memset(pool,\ 0,\ POOL_SIZE); \ \ \ \ /*\ make\ local\ data\ persistent\ on\ remote\ node\ */ \ \ \ \ ret\ =\ rpmem_persist(rpp,\ DATA_OFF,\ DATA_SIZE,\ 0,\ 0); \ \ \ \ if\ (ret)\ { \ \ \ \ \ \ \ \ fprintf(stderr,\ "rpmem_persist:\ %s\\n",\ rpmem_errormsg()); \ \ \ \ \ \ \ \ return\ 1; \ \ \ \ } \ \ \ \ /*\ close\ the\ remote\ pool\ */ \ \ \ \ ret\ =\ rpmem_close(rpp); \ \ \ \ if\ (ret)\ { \ \ \ \ \ \ \ \ fprintf(stderr,\ "rpmem_close:\ %s\\n",\ rpmem_errormsg()); \ \ \ \ \ \ \ \ return\ 1; \ \ \ \ } \ \ \ \ free(pool); \ \ \ \ return\ 0; } \f[] .fi .SH NOTE .PP The \f[B]librpmem\f[] API is experimental and may be subject to change in the future. However, using the remote replication in \f[B]libpmemobj\f[](7) is safe and backward compatibility will be preserved. .SH ACKNOWLEDGEMENTS .PP \f[B]librpmem\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]rpmemd\f[](1), \f[B]ssh\f[](1), \f[B]fork\f[](2), \f[B]dlclose\f[](3), \f[B]dlopen\f[](3), \f[B]ibv_fork_init\f[](3), \f[B]rpmem_create\f[](3), \f[B]rpmem_drain\f[](3), \f[B]rpmem_flush\f[](3), \f[B]rpmem_open\f[](3), \f[B]rpmem_persist\f[](3), \f[B]strerror\f[](3), \f[B]limits.conf\f[](5), \f[B]fabric\f[](7), \f[B]fi_sockets\f[](7), \f[B]fi_verbs\f[](7), \f[B]libpmem\f[](7), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/librpmem/.gitignore0000664000000000000000000000005214123364546015577 0ustar rootrootlibrpmem.7 rpmem_create.3 rpmem_persist.3 pmdk-1.11.1/doc/librpmem/rpmem_close.30000664000000000000000000000002314123364546016176 0ustar rootroot.so rpmem_create.3 pmdk-1.11.1/doc/librpmem/rpmem_flush.30000664000000000000000000000002414123364546016213 0ustar rootroot.so rpmem_persist.3 pmdk-1.11.1/doc/librpmem/librpmem.7.md0000664000000000000000000003700614123364546016116 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBRPMEM, 7) collection: librpmem header: PMDK date: rpmem API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2019, Intel Corporation) [comment]: <> (librpmem.7 -- man page for librpmem) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[TARGET NODE ADDRESS FORMAT](#target-node-address-format)
[REMOTE POOL ATTRIBUTES](#remote-pool-attributes)
[SSH](#ssh)
[FORK](#fork)
[CAVEATS](#caveats)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[ENVIRONMENT](#environment)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also) # NAME # **librpmem** - remote persistent memory support library (EXPERIMENTAL) # SYNOPSIS # ```c #include cc ... -lrpmem ``` ##### Library API versioning: ##### ```c const char *rpmem_check_version( unsigned major_required, unsigned minor_required); ``` ##### Error handling: ##### ```c const char *rpmem_errormsg(void); ``` ##### Other library functions: ##### A description of other **librpmem** functions can be found on the following manual pages: + **rpmem_create**(3), **rpmem_persist**(3) # DESCRIPTION # **librpmem** provides low-level support for remote access to *persistent memory* (pmem) utilizing RDMA-capable RNICs. The library can be used to remotely replicate a memory region over the RDMA protocol. It utilizes an appropriate persistency mechanism based on the remote node's platform capabilities. **librpmem** utilizes the **ssh**(1) client to authenticate a user on the remote node, and for encryption of the connection's out-of-band configuration data. See **SSH**, below, for details. The maximum replicated memory region size can not be bigger than the maximum locked-in-memory address space limit. See **memlock** in **limits.conf**(5) for more details. This library is for applications that use remote persistent memory directly, without the help of any library-supplied transactions or memory allocation. Higher-level libraries that build on **libpmem**(7) are available and are recommended for most applications, see: + **libpmemobj**(7), a general use persistent memory API, providing memory allocation and transactional operations on variable-sized objects. # TARGET NODE ADDRESS FORMAT # ``` [@][:] ``` The target node address is described by the *hostname* which the client connects to, with an optional *user* name. The user must be authorized to authenticate to the remote machine without querying for password/passphrase. The optional *port* number is used to establish the SSH connection. The default port number is 22. # REMOTE POOL ATTRIBUTES # The *rpmem_pool_attr* structure describes a remote pool and is stored in remote pool's metadata. This structure must be passed to the **rpmem_create**(3) function by caller when creating a pool on remote node. When opening the pool using **rpmem_open**(3) function the appropriate fields are read from pool's metadata and returned back to the caller. ```c #define RPMEM_POOL_HDR_SIG_LEN 8 #define RPMEM_POOL_HDR_UUID_LEN 16 #define RPMEM_POOL_USER_FLAGS_LEN 16 struct rpmem_pool_attr { char signature[RPMEM_POOL_HDR_SIG_LEN]; uint32_t major; uint32_t compat_features; uint32_t incompat_features; uint32_t ro_compat_features; unsigned char poolset_uuid[RPMEM_POOL_HDR_UUID_LEN]; unsigned char uuid[RPMEM_POOL_HDR_UUID_LEN]; unsigned char next_uuid[RPMEM_POOL_HDR_UUID_LEN]; unsigned char prev_uuid[RPMEM_POOL_HDR_UUID_LEN]; unsigned char user_flags[RPMEM_POOL_USER_FLAGS_LEN]; }; ``` The *signature* field is an 8-byte field which describes the pool's on-media format. The *major* field is a major version number of the pool's on-media format. The *compat_features* field is a mask describing compatibility of pool's on-media format optional features. The *incompat_features* field is a mask describing compatibility of pool's on-media format required features. The *ro_compat_features* field is a mask describing compatibility of pool's on-media format features. If these features are not available, the pool shall be opened in read-only mode. The *poolset_uuid* field is an UUID of the pool which the remote pool is associated with. The *uuid* field is an UUID of a first part of the remote pool. This field can be used to connect the remote pool with other pools in a list. The *next_uuid* and *prev_uuid* fields are UUIDs of next and previous replicas respectively. These fields can be used to connect the remote pool with other pools in a list. The *user_flags* field is a 16-byte user-defined flags. # SSH # **librpmem** utilizes the **ssh**(1) client to login and execute the **rpmemd**(1) process on the remote node. By default, **ssh**(1) is executed with the **-4** option, which forces using **IPv4** addressing. For debugging purposes, both the ssh client and the commands executed on the remote node may be overridden by setting the **RPMEM_SSH** and **RPMEM_CMD** environment variables, respectively. See **ENVIRONMENT** for details. # FORK # The **ssh**(1) client is executed by **rpmem_open**(3) and **rpmem_create**(3) after forking a child process using **fork**(2). The application must take this into account when using **wait**(2) and **waitpid**(2), which may return the *PID* of the **ssh**(1) process executed by **librpmem**. If **fork**(2) support is not enabled in **libibverbs**, **rpmem_open**(3) and **rpmem_create**(3) will fail. By default, **fabric**(7) initializes **libibverbs** with **fork**(2) support by calling the **ibv_fork_init**(3) function. See **fi_verbs**(7) for more details. # CAVEATS # **librpmem** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. **librpmem** registers a pool as a single memory region. A Chelsio T4 and T5 hardware can not handle a memory region greater than or equal to 8GB due to a hardware bug. So *pool_size* value for **rpmem_create**(3) and **rpmem_open**(3) using this hardware can not be greater than or equal to 8GB. # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The **rpmem_check_version**() function is used to see if the installed **librpmem** supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile-time version information, supplied by defines in **\**, like this: ```c reason = rpmem_check_version(RPMEM_MAJOR_VERSION, RPMEM_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. When the version check performed by **rpmem_check_version**() is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by **rpmem_check_version**() must not be modified or freed. # ENVIRONMENT # **librpmem** can change its default behavior based on the following environment variables. These are largely intended for testing and are not normally required. + **RPMEM_SSH**=*ssh_client* Setting this environment variable overrides the default **ssh**(1) client command name. + **RPMEM_CMD**=*cmd* Setting this environment variable overrides the default command executed on the remote node using either **ssh**(1) or the alternative remote shell command specified by **RPMEM_SSH**. **RPMEM_CMD** can contain multiple commands separated by a vertical bar (`|`). Each consecutive command is executed on the remote node in order read from a pool set file. This environment variable is read when the library is initialized, so **RPMEM_CMD** must be set prior to application launch (or prior to **dlopen**(3) if **librpmem** is being dynamically loaded). + **RPMEM_ENABLE_SOCKETS**=0\|1 Setting this variable to 1 enables using **fi_sockets**(7) provider for in-band RDMA connection. The *sockets* provider does not support IPv6. It is required to disable IPv6 system wide if **RPMEM_ENABLE_SOCKETS** == 1 and *target* == localhost (or any other loopback interface address) and **SSH_CONNECTION** variable (see **ssh**(1) for more details) contains IPv6 address after ssh to loopback interface. By default the *sockets* provider is disabled. * **RPMEM_ENABLE_VERBS**=0\|1 Setting this variable to 0 disables using **fi_verbs**(7) provider for in-band RDMA connection. The *verbs* provider is enabled by default. * **RPMEM_MAX_NLANES**=*num* Limit the maximum number of lanes to *num*. See **LANES**, in **rpmem_create**(3), for details. * **RPMEM_WORK_QUEUE_SIZE**=*size* Suggest the work queue size. The effective work queue size can be greater than suggested if **librpmem** requires it or it can be smaller if underlying hardware does not support the suggested size. The work queue size affects the performance of communication to the remote node. **rpmem_flush**(3) operations can be added to the work queue up to the size of this queue. When work queue is full any subsequent call has to wait till the work queue will be drained. **rpmem_drain**(3) and **rpmem_persist**(3) among other things also drain the work queue. # DEBUGGING AND ERROR HANDLING # If an error is detected during the call to a **librpmem** function, the application may retrieve an error message describing the reason for the failure from **rpmem_errormsg**(). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **librpmem** function indicated an error, or if *errno* was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. Two versions of **librpmem** are typically available on a development system. The normal version, accessed when a program is linked using the **-lrpmem** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **librpmem**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **RPMEM_LOG_LEVEL** The value of **RPMEM_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **RPMEM_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged (in addition to returning the *errno*-based errors as usual). The same information may be retrieved using **rpmem_errormsg**(). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **librpmem** developers. Unless **RPMEM_LOG_FILE** is set, debugging output is written to *stderr*. + **RPMEM_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **RPMEM_LOG_FILE** is not set, logging output is written to *stderr*. # EXAMPLE # The following example uses **librpmem** to create a remote pool on given target node identified by given pool set name. The associated local memory pool is zeroed and the data is made persistent on remote node. Upon success the remote pool is closed. ```c #include #include #include #include #include #include #define POOL_SIGNATURE "MANPAGE" #define POOL_SIZE (32 * 1024 * 1024) #define NLANES 4 #define DATA_OFF 4096 #define DATA_SIZE (POOL_SIZE - DATA_OFF) static void parse_args(int argc, char *argv[], const char **target, const char **poolset) { if (argc < 3) { fprintf(stderr, "usage:\t%s \n", argv[0]); exit(1); } *target = argv[1]; *poolset = argv[2]; } static void * alloc_memory() { long pagesize = sysconf(_SC_PAGESIZE); if (pagesize < 0) { perror("sysconf"); exit(1); } /* allocate a page size aligned local memory pool */ void *mem; int ret = posix_memalign(&mem, pagesize, POOL_SIZE); if (ret) { fprintf(stderr, "posix_memalign: %s\n", strerror(ret)); exit(1); } assert(mem != NULL); return mem; } int main(int argc, char *argv[]) { const char *target, *poolset; parse_args(argc, argv, &target, &poolset); unsigned nlanes = NLANES; void *pool = alloc_memory(); int ret; /* fill pool_attributes */ struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); strncpy(pool_attr.signature, POOL_SIGNATURE, RPMEM_POOL_HDR_SIG_LEN); /* create a remote pool */ RPMEMpool *rpp = rpmem_create(target, poolset, pool, POOL_SIZE, &nlanes, &pool_attr); if (!rpp) { fprintf(stderr, "rpmem_create: %s\n", rpmem_errormsg()); return 1; } /* store data on local pool */ memset(pool, 0, POOL_SIZE); /* make local data persistent on remote node */ ret = rpmem_persist(rpp, DATA_OFF, DATA_SIZE, 0, 0); if (ret) { fprintf(stderr, "rpmem_persist: %s\n", rpmem_errormsg()); return 1; } /* close the remote pool */ ret = rpmem_close(rpp); if (ret) { fprintf(stderr, "rpmem_close: %s\n", rpmem_errormsg()); return 1; } free(pool); return 0; } ``` # NOTE # The **librpmem** API is experimental and may be subject to change in the future. However, using the remote replication in **libpmemobj**(7) is safe and backward compatibility will be preserved. # ACKNOWLEDGEMENTS # **librpmem** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **rpmemd**(1), **ssh**(1), **fork**(2), **dlclose**(3), **dlopen**(3), **ibv_fork_init**(3), **rpmem_create**(3), **rpmem_drain**(3), **rpmem_flush**(3), **rpmem_open**(3), **rpmem_persist**(3), **strerror**(3), **limits.conf**(5), **fabric**(7), **fi_sockets**(7), **fi_verbs**(7), **libpmem**(7), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/librpmem/rpmem_drain.30000664000000000000000000000002414123364546016167 0ustar rootroot.so rpmem_persist.3 pmdk-1.11.1/doc/librpmem/rpmem_check_version.30000664000000000000000000000002414123364546017714 0ustar rootroot.so man7/librpmem.7 pmdk-1.11.1/doc/librpmem/rpmem_create.3.md0000664000000000000000000002001014123364546016731 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(RPMEM_CREATE, 3) collection: librpmem header: PMDK date: rpmem API version 1.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (rpmem_create.3 -- man page for most commonly used librpmem functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[NOTES](#notes)
[SEE ALSO](#see-also)
# NAME # **rpmem_create**(), **rpmem_open**(), **rpmem_set_attr**(), **rpmem_close**(), **rpmem_remove**() - most commonly used functions for remote access to *persistent memory* # SYNOPSIS # ```c #include RPMEMpool *rpmem_create(const char *target, const char *pool_set_name, void *pool_addr, size_t pool_size, unsigned *nlanes, const struct rpmem_pool_attr *create_attr); RPMEMpool *rpmem_open(const char *target, const char *pool_set_name, void *pool_addr, size_t pool_size, unsigned *nlanes, struct rpmem_pool_attr *open_attr); int rpmem_set_attr(RPMEMpool *rpp, const struct rpmem_pool_attr *attr); int rpmem_close(RPMEMpool *rpp); int rpmem_remove(const char *target, const char *pool_set_name, int flags); ``` # DESCRIPTION # The **rpmem_create**() function creates a remote pool on a given *target* node, using pool *set* file *pool_set_name* to map the remote pool. *pool_set_name* is a relative path in the root config directory on the *target* node. For pool set file format and options see **poolset**(5). *pool_addr* is a pointer to the associated local memory pool with size *pool_size*. Both *pool_addr* and *pool_size* must be aligned to the system's page size (see **sysconf**(3)). The size of the remote pool must be at least *pool_size*. See **REMOTE POOL SIZE**, below, for details. *nlanes* points to the maximum number of lanes which the caller is requesting. Upon successful creation of the remote pool, \**nlanes* is set to the maximum number of lanes supported by both the local and remote nodes. See **LANES**, below, for details. The *create_attr* structure contains the attributes used for creating the remote pool. If the *create_attr* structure is not NULL, a pool with internal metadata is created. The metadata is stored in the first 4096 bytes of the pool and can be read when opening the remote pool with **rpmem_open**(). To prevent user from overwriting the pool metadata, this region is not accessible to the user via **rpmem_persist**(). If *create_attr* is NULL or zeroed, remote pool set file must contain the *NOHDRS* option. In that case the remote pool is created without internal metadata in it and the entire pool space is available to the user. See **rpmem_persist**(3) for details. The **rpmem_open**() function opens the existing remote pool with *set* file *pool_set_name* on remote node *target*. *pool_set_name* is a relative path in the root config directory on the *target* node. *pool_addr* is a pointer to the associated local memory pool of size *pool_size*. Both *pool_addr* and *pool_size* must be aligned to the system's page size (see **sysconf**(3)). The size of the remote pool must be at least *pool_size*. See **REMOTE POOL SIZE**, below, for details. *nlanes* points to the maximum number of lanes which the caller is requesting. Upon successful opening of the remote pool, \**nlanes* is set to the maximum number of lanes supported by both the local and remote nodes. See **LANES**, below, for details. The **rpmem_set_attr**() function overwrites the pool's attributes. The *attr* structure contains the attributes used for overwriting the remote pool attributes that were passed to **rpmem_create**() at pool creation. If *attr* is NULL, a zeroed structure with attributes will be used. New attributes are stored in the pool's metadata. The **rpmem_close**() function closes the remote pool *rpp*. All resources are released on both the local and remote nodes. The remote pool itself persists on the remote node and may be re-opened at a later time using **rpmem_open**(). The **rpmem_remove**() function removes the remote pool with *set* file name *pool_set_name* from node *target*. The *pool_set_name* is a relative path in the root config directory on the *target* node. By default only the pool part files are removed; the pool *set* file is left untouched. If the pool is not consistent, the **rpmem_remove**() function fails. The *flags* argument determines the behavior of **rpmem_remove**(). *flags* may be either 0 or the bitwise OR of one or more of the following flags: + **RPMEM_REMOVE_FORCE** - Ignore errors when opening an inconsistent pool. The pool *set* file must still be in appropriate format for the pool to be removed. + **RPMEM_REMOVE_POOL_SET** - Remove the pool *set* file after removing the pool described by this pool set. # RETURN VALUE # On success, **rpmem_create**() returns an opaque handle to the remote pool for use in subsequent **librpmem** calls. If any error prevents the remote pool from being created, **rpmem_create**() returns NULL and sets *errno* appropriately. On success, **rpmem_open**() returns an opaque handle to the remote pool for subsequent **librpmem** calls. If the *open_attr* argument is not NULL, the remote pool attributes are returned in the provided structure. If the remote pool was created without internal metadata, zeroes are returned in the *open_attr* structure on successful call to **rpmem_open**(). If any error prevents the remote pool from being opened, **rpmem_open**() returns NULL and sets *errno* appropriately. On success, **rpmem_set_attr**() returns 0. On error, it returns -1 and sets *errno* appropriately. On success, **rpmem_close**() returns 0. On error, it returns a non-zero value and sets *errno* appropriately. On success, **rpmem_remove**() returns 0. On error, it returns a non-zero value and sets *errno* appropriately. # NOTES # ## REMOTE POOL SIZE ## The size of a remote pool depends on the configuration in the pool set file on the remote node (see **poolset**(5)). If no pool set options is used in the remote pool set file, the remote pool size is the sum of the sizes of all part files, decreased by 4096 bytes per part file. 4096 bytes of each part file are utilized for storing internal metadata. If the *SINGLEHDR* option is used in the remote pool set file, the remote pool size is the sum of sizes of all part files, decreased once by 4096 bytes. In this case only the first part contains internal metadata. If a remote pool set file contains the *NOHDRS* option, the remote pool size is the sum of sizes of all its part files. In this case none of the parts contains internal metadata. For other consequences of using the *SINGLEHDR* and *NOHDRS* options see **rpmem_persist**(3). **RPMEM_MIN_PART** and **RPMEM_MIN_POOL** in **\** define the minimum size allowed by **librpmem** for a part file and a remote pool, respectively. ## LANES ## The term *lane* means an isolated path of execution. The underlying hardware utilized by both local and remote nodes may have limited resources that restrict the maximum number of parallel **rpmem_persist**(3) operations. The maximum number of supported lanes is returned by the **rpmem_open**() and **rpmem_create**() function calls. The caller passes the maximum number of lanes requested in \**nlanes*. If the pool is successfully created or opened, \**nlanes* is updated to reflect the minimum of the number of lanes requested by the caller and the maximum number of lanes supported by underlying hardware. The application is obligated to use at most the returned number of lanes in parallel. **rpmem_persist**(3) does not provide any locking mechanism; thus any serialization of calls must be performed by the application if required. Each lane requires a separate connection, represented by a file descriptor. If the system runs out of free file descriptors during **rpmem_create**() or **rpmem_open**(), these functions will fail. See **nofile** in **limits.conf**(5) for more details. # SEE ALSO # **rpmem_persist**(3), **sysconf**(3), **limits.conf**(5), **libpmemobj**(7), **librpmem**(7) and **** pmdk-1.11.1/doc/daxio/0000775000000000000000000000000014123364746013111 5ustar rootrootpmdk-1.11.1/doc/daxio/daxio.10000664000000000000000000000575514123364746014313 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "DAXIO" "1" "2021-09-24" "PMDK - daxio version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018, Intel Corporation .SH NAME .PP \f[B]daxio\f[] \- Perform I/O on Device DAX devices or zero a Device DAX device .SH SYNOPSIS .IP .nf \f[C] $\ daxio\ [] \f[] .fi .SH DESCRIPTION .PP The daxio utility performs I/O on Device DAX devices or zero a Device DAX device. Since the standard I/O APIs (read/write) cannot be used with Device DAX, data transfer is performed on a memory\-mapped device. The \f[B]daxio\f[] may be used to dump Device DAX data to a file, restore data from a backup copy, move/copy data to another device or to erase data from a device. .PP There must be at least one Device DAX device involved either as the input or output. If input or output is not specified, it will default to stdin or stdout respectively. .PP No length specified will default to input file/device length or to the output file/device length, if input is a special char file or stdin. .PP For a Device DAX device, \f[B]daxio\f[] will attempt to clear bad blocks within the range of writes before performing the I/O (it can be turned off using the `\[en]clear\-bad\-blocks=no' option). .SH OPTIONS .PP \f[C]\-i,\ \-\-input\f[] Input device or file to read from. .PP \f[C]\-o,\ \-\-output\f[] Output device or file to write to. .PP \f[C]\-z,\ \-\-zero\f[] Zero the output device for \f[I]len\f[] size, or the entire device if no length was provided. The output device must be a Device DAX device. .PP \f[C]\-b,\ \-\-clear\-bad\-blocks=\f[] Clear bad blocks within the range of writes before performing the I/O (default: yes). .PP \f[C]\-l,\ \-\-len\f[] The length in bytes to perform the I/O. To make passing in size easier for kibi, mebi, gibi, and tebi bytes, \f[I]len\f[] may include unit suffix. The \f[I]len\f[] format must be compliant with the format specified in IEC 80000\-13, IEEE 1541 or the Metric Interchange Format. These standards accept SI units with obligatory B \- kB, MB, GB, \&... (multiplier by 1000) suffixes, and IEC units with optional \[lq]iB\[rq] \- KiB, MiB, GiB, \&..., K, M, G, \&... (multiplier by 1024) suffixes. .PP \f[C]\-s,\ \-\-seek\f[] The number of bytes to skip over on the output before performing a write. The same suffixes are accepted as for \f[I]len\f[]. .PP \f[C]\-k,\ \-\-skip\f[] The number of bytes to skip over on the input before performing a read. The same suffixes are accepted as for \f[I]len\f[]. .PP \f[C]\-V,\ \-\-version\f[] .PP Prints the version of \f[B]daxio\f[]. .PP \f[C]\-h,\ \-\-help\f[] .PP Prints synopsis and list of options. .SH EXAMPLE .IP .nf \f[C] #\ daxio\ \-\-zero\ /dev/dax1.0 #\ daxio\ \-\-input=/dev/dax1.0\ \-\-output=/home/myfile\ \-\-len=2M\ \-\-seek=4096 #\ cat\ /dev/zero\ |\ daxio\ \-\-output=/dev/dax1.0 #\ daxio\ \-\-input=/dev/zero\ \-\-output=/dev/dax1.0\ \-\-skip=4096 \f[] .fi .SH SEE ALSO .PP \f[B]daxctl\f[](1), \f[B]ndctl\f[](1) and \f[B]\f[] pmdk-1.11.1/doc/daxio/daxio.1.md0000664000000000000000000000564214123364546014703 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(DAXIO, 1) collection: daxio header: PMDK date: daxio version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018, Intel Corporation) [comment]: <> (daxio.1 -- man page for daxio) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[OPTIONS](#options)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **daxio** - Perform I/O on Device DAX devices or zero a Device DAX device # SYNOPSIS # ``` $ daxio [] ``` # DESCRIPTION # The daxio utility performs I/O on Device DAX devices or zero a Device DAX device. Since the standard I/O APIs (read/write) cannot be used with Device DAX, data transfer is performed on a memory-mapped device. The **daxio** may be used to dump Device DAX data to a file, restore data from a backup copy, move/copy data to another device or to erase data from a device. There must be at least one Device DAX device involved either as the input or output. If input or output is not specified, it will default to stdin or stdout respectively. No length specified will default to input file/device length or to the output file/device length, if input is a special char file or stdin. For a Device DAX device, **daxio** will attempt to clear bad blocks within the range of writes before performing the I/O (it can be turned off using the '--clear-bad-blocks=no' option). # OPTIONS # `-i, --input` Input device or file to read from. `-o, --output` Output device or file to write to. `-z, --zero` Zero the output device for *len* size, or the entire device if no length was provided. The output device must be a Device DAX device. `-b, --clear-bad-blocks=` Clear bad blocks within the range of writes before performing the I/O (default: yes). `-l, --len` The length in bytes to perform the I/O. To make passing in size easier for kibi, mebi, gibi, and tebi bytes, *len* may include unit suffix. The *len* format must be compliant with the format specified in IEC 80000-13, IEEE 1541 or the Metric Interchange Format. These standards accept SI units with obligatory B - kB, MB, GB, ... (multiplier by 1000) suffixes, and IEC units with optional "iB" - KiB, MiB, GiB, ..., K, M, G, ... (multiplier by 1024) suffixes. `-s, --seek` The number of bytes to skip over on the output before performing a write. The same suffixes are accepted as for *len*. `-k, --skip` The number of bytes to skip over on the input before performing a read. The same suffixes are accepted as for *len*. `-V, --version` Prints the version of **daxio**. `-h, --help` Prints synopsis and list of options. # EXAMPLE # ``` # daxio --zero /dev/dax1.0 # daxio --input=/dev/dax1.0 --output=/home/myfile --len=2M --seek=4096 # cat /dev/zero | daxio --output=/dev/dax1.0 # daxio --input=/dev/zero --output=/dev/dax1.0 --skip=4096 ``` # SEE ALSO # **daxctl**(1), **ndctl**(1) and **** pmdk-1.11.1/doc/daxio/.gitignore0000664000000000000000000000001014123364546015066 0ustar rootrootdaxio.1 pmdk-1.11.1/doc/RELEASE_STEPS.md0000664000000000000000000000411614123364546014365 0ustar rootroot# PMDK release steps This document contains all the steps required to make a new release of PMDK. Make a release locally: - add an entry to ChangeLog, remember to change the day of the week in the release date - for major releases mention compatibility with the previous release - update reference to stable release in README.md (update `git checkout tags/$VERSION-1`) - git rm GIT_VERSION - echo $VERSION > VERSION - git add VERSION - git commit -a -S -m "common: $VERSION release" - git tag -a -s -m "PMDK Version $VERSION" $VERSION Make a package: - git archive --prefix="pmdk-$VERSION/" -o pmdk-$VERSION.tar.gz $VERSION - uncompress the created archive in a new directory and create the final package: ``` $ cd pmdk-$VERSION $ make doc $ touch .skip-doc $ cd .. $ tar czf pmdk-$VERSION.tar.gz pmdk-$VERSION/ --owner=root --group=root ``` - verify the created archive (uncompress & build one last time) - gpg --armor --detach-sign pmdk-$VERSION.tar.gz Undo temporary release changes: - git cherry-pick 1a620814f6affe0535441565007c352a67f995c0 - git rm VERSION - git commit --reset-author Publish changes: - for major release: - git push upstream HEAD:master $VERSION - create and push stable-$VERSION branch - create PR from stable-$VERSION to master - for minor release: - git push upstream HEAD:stable-$VER $VERSION - create PR from stable-$VER to next stable (or master, if release is from last stable branch) Publish package and make it official: - go to https://github.com/pmem/pmdk/releases/new: - tag version: $VERSION, release title: PMDK Version $VERSION, description: copy entry from ChangeLog - upload pmdk-$VERSION.tar.gz & pmdk-$VERSION.tar.gz.asc - announce the release on pmem group Later, for major release: - bump version of Docker images (utils/docker/images/set-images-version.sh) to $VERSION+1 - once gh-pages contains new documentation, add $VERSION section in _data/releases_linux.yml and _data/releases_windows.yml on gh-pages branch - update library version in [vcpkg](https://github.com/microsoft/vcpkg/blob/master/ports/pmdk) - file an issue for their maintainers pmdk-1.11.1/doc/pmreorder/0000775000000000000000000000000014123364745014003 5ustar rootrootpmdk-1.11.1/doc/pmreorder/pmreorder.10000664000000000000000000002452514123364745016074 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMREORDER" "1" "2021-09-24" "PMDK - pmreorder version 1.5" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018-2020, Intel Corporation .SH NAME .PP \f[B]pmreorder\f[] \- performs a persistent consistency check using a store reordering mechanism .SH SYNOPSIS .IP .nf \f[C] $\ python\ pmreorder\ \f[] .fi .SH DESCRIPTION .PP The pmreorder tool is a collection of python scripts designed to parse and replay operations logged by pmemcheck \- a persistent memory checking tool. .PP Pmreorder performs the store reordering between persistent memory barriers \- a sequence of flush\-fence operations. It uses a consistency checking routine provided in the command line options to check whether files are in a consistent state. .PP Considering that logging, replaying and reordering of operations are very time consuming, it is recommended to use as few stores as possible in test workloads. .SH OPTIONS .PP \f[C]\-h,\ \-\-help\f[] .PP Prints synopsis and list of options. .PP \f[C]\-l\ ,\ \-\-logfile\ \f[] .PP The pmemcheck log file to process. .PP \f[C]\-c\ ,\ \-\-checker\ \f[] .PP Consistency checker type. .PP \f[C]\-p\ ,\ \-\-path\ \f[] .PP Path to the consistency checker. Checker function has to return 0 for consistent cases and 1 otherwise. .PP \f[C]\-n\ ,\ \-\-name\ \f[] .PP The symbol name of the consistency checking function in the library. Valid only if the checker type is \f[C]lib\f[]. .PP \f[C]\-o\ ,\ \-\-output\ \f[] .PP Set the logger output file. .PP \f[C]\-e\ ,\f[] .PP \f[C]\-\-output\-level\ \f[] .PP Set the output log level. .PP \f[C]\-r\ \ ,\f[] .PP \f[C]\-\-default\-engine\ \ \f[] .PP Set the initial reorder engine. Default value is \f[C]NoReorderNoCheck\f[]. .PP \f[C]\-x\ ,\ \-\-extended\-macros\ \f[] .PP Assign an engine types to the defined marker. .PP \f[C]\-v,\ \-\-version\f[] .PP Prints current version of pmreorder. .SH ENGINES .PP By default, the \f[B]NoReorderNoCheck\f[] engine is used, which means that for each set of stores, the tool will pass\-through all sequences of stores not reordered and will not run consistency checker on them. .PP To enable different types of the reorder engine and begin proper reordering tests, a number of other engines exist: .IP \[bu] 2 \f[B]NoReorderDoCheck\f[] \- pass\-through of unchanged operations. Checks correctness of the stores as they were logged. Useful for operations that do not require fail safety. .IP .nf \f[C] Example: \ \ \ \ \ \ \ \ input:\ (a,\ b,\ c) \ \ \ \ \ \ \ \ output:\ (a,\ b,\ c) \f[] .fi .IP \[bu] 2 \f[B]ReorderAccumulative\f[] \- checks correctness on a growing subset of the original sequence. .IP .nf \f[C] Example: \ \ \ \ \ \ \ \ input:\ (a,\ b,\ c) \ \ \ \ \ \ \ \ output: \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ () \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ b,\ c) \f[] .fi .IP \[bu] 2 \f[B]ReorderReverseAccumulative\f[] \- checks correctness on a reverted growing subset of the original sequence. .IP .nf \f[C] Example: \ \ \ \ \ \ \ \ input:\ (a,\ b,\ c) \ \ \ \ \ \ \ \ output: \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ () \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ b,\ a) \f[] .fi .IP \[bu] 2 \f[B]ReorderPartial\f[] \- checks consistency on 3 randomly selected sequences from a set of 1000 combinations of the original log, without repetitions. .IP .nf \f[C] \ Example: \ \ \ \ \ \ \ \ \ input:\ (a,\ b,\ c) \ \ \ \ \ \ \ \ \ output: \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b,\ c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ b,\ c) \f[] .fi .IP \[bu] 2 \f[B]ReorderFull\f[] \- for each set of stores generates and checks consistency of all possible store permutations. This might prove to be very computationally expensive for most workloads. It can be useful for critical sections of code with limited number of stores. .IP .nf \f[C] \ Example: \ \ \ \ \ \ \ \ input:\ (a,\ b,\ c) \ \ \ \ \ \ \ \ output: \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ () \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b,\ a) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b,\ c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ a) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ b,\ c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (a,\ c,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b,\ a,\ c) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (b,\ c,\ a) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ a,\ b) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (c,\ b,\ a) \f[] .fi .PP When the engine is passed with an \f[C]\-r\f[] option, it will be used for each logged set of stores. Additionally, the \f[C]\-x\f[] parameter can be used to switch engines separately for any marked code sections. For more details about \f[C]\-x\f[] extended macros functionality see section INSTRUMENTATION below. .SH INSTRUMENTATION .PP The core of \f[B]pmreorder\f[] is based on user\-provided named markers. Sections of code can be `marked' depending on their importance, and the degree of reordering can be customized by the use of various provided engines. .PP For this purpose, Valgrind's pmemcheck tool exposes a generic marker macro: .IP \[bu] 2 \f[B]VALGRIND_PMC_EMIT_LOG(value)\f[] .PP It emits log to \f[I]store_log\f[] during pmemcheck processing. \f[I]value\f[] is a user\-defined marker name. For more details about pmemcheck execution see PMEMCHECK STORE LOG section below. .PP Example: .IP .nf \f[C] main.c \&. \&. \&. VALGRIND_PMC_EMIT_LOG("PMREORDER_MEMSET_PERSIST.BEGIN"); pmem_memset_persist(...); VALGRIND_PMC_EMIT_LOG("PMREORDER_MEMSET_PERSIST.END"); \&. \&. \&. \f[] .fi .PP There are a few rules for macros creation: .IP \[bu] 2 Valid macro can have any name, but begin and end section have to match \- they are case sensitive. .IP \[bu] 2 Macro must have \f[C]\&.BEGIN\f[] or \f[C]\&.END\f[] suffix. .IP \[bu] 2 Macros can't be crossed. .PP Defined markers can be assigned engines types and configured through the \f[B]pmreorder\f[] tool using the \f[C]\-x\f[] parameter. .PP There are two ways to set macro options: .IP \[bu] 2 Using command line interface in format: .IP .nf \f[C] PMREORDER_MARKER_NAME1=Marker1,PMREORDER_MARKER_NAME2=Marker2 \f[] .fi .IP \[bu] 2 Using configuration file in .json format: .IP .nf \f[C] { \ \ \ \ "PMREORDER_MARKER_NAME1":"Marker1", \ \ \ \ "PMREORDER_MARKER_NAME2":"Marker2" } \f[] .fi .PP For more details about available engines types, see ENGINES section above. .PP \f[B]libpmemobj\f[](7), \f[B]libpmem\f[](7) and \f[B]libpmem2\f[](7) also provide set of macros that allow to change reordering engine on library or function level: .PP \f[C]\f[] .PP Example of configuration on function level: .IP .nf \f[C] { \ \ \ \ "pmemobj_open":"NoReorderNoCheck", \ \ \ \ "pmemobj_memcpy_persist":"ReorderPartial" } \f[] .fi .PP Example of configuration on library level (affecting all library functions): .IP .nf \f[C] { \ \ \ \ "libpmemobj":"NoReorderNoCheck" } \f[] .fi .PP List of marked \f[B]libpmemobj\f[](7) API functions: .IP .nf \f[C] pmemobj_alloc pmemobj_cancel pmemobj_check pmemobj_close pmemobj_create pmemobj_ctl_exec pmemobj_ctl_set pmemobj_free pmemobj_list_insert pmemobj_list_insert_new pmemobj_list_move pmemobj_list_remove pmemobj_memcpy pmemobj_memmove pmemobj_memset pmemobj_memcpy_persist pmemobj_memset_persist pmemobj_open pmemobj_publish pmemobj_realloc pmemobj_reserve pmemobj_root pmemobj_root_construct pmemobj_strdup pmemobj_tx_abort pmemobj_tx_add_range pmemobj_tx_add_range_direct pmemobj_tx_alloc pmemobj_tx_commit pmemobj_tx_free pmemobj_tx_publish pmemobj_tx_realloc pmemobj_tx_strdup pmemobj_tx_wcsdup pmemobj_tx_xadd_range pmemobj_tx_xadd_range_direct pmemobj_tx_xalloc pmemobj_tx_zalloc pmemobj_tx_zrealloc pmemobj_wcsdup pmemobj_xalloc pmemobj_xreserve pmemobj_zalloc pmemobj_zrealloc \f[] .fi .PP List of marked \f[B]libpmem\f[](7) API functions: .IP .nf \f[C] pmem_memmove pmem_memcpy pmem_memset pmem_memmove_nodrain pmem_memcpy_nodrain pmem_memset_nodrain pmem_memmove_persist pmem_memcpy_persist pmem_memset_persist \f[] .fi .PP List of \f[B]libpmem2\f[](7) API functions, which return marked functions: .IP .nf \f[C] pmem2_get_memcpy_fn\ (marker\ for\ the\ returned\ function\ has\ "pmem2_memmove"\ name) pmem2_get_memmove_fn\ (marker\ for\ the\ returned\ function\ has\ "pmem2_memmove"\ name) pmem2_get_memset_fn\ (marker\ for\ the\ returned\ function\ has\ "pmem2_memset"\ name) \f[] .fi .SH PMEMCHECK STORE LOG .PP To generate \f[I]store_log\f[] for \f[B]pmreorder\f[] run pmemcheck with additional parameters: .IP .nf \f[C] valgrind\ \\ \ \ \ \ \-\-tool=pmemcheck\ \\ \ \ \ \ \-q\ \\ \ \ \ \ \-\-log\-stores=yes\ \\ \ \ \ \ \-\-print\-summary=no\ \\ \ \ \ \ \-\-log\-file=store_log.log\ \\ \ \ \ \ \-\-log\-stores\-stacktraces=yes\ \\ \ \ \ \ \-\-log\-stores\-stacktraces\-depth=2\ \\ \ \ \ \ \-\-expect\-fence\-after\-clflush=yes\ \\ \ \ \ \ test_binary\ writer_parameter \f[] .fi .PP For further details of pmemcheck parameters see pmemcheck documentation (https://pmem.io/valgrind/generated/pmc-manual.html) .SH ENVIRONMENT .PP By default all logging from PMDK libraries is disabled. To enable API macros logging set environment variable: .IP \[bu] 2 \f[B]PMREORDER_EMIT_LOG\f[]=1 .SH EXAMPLE .IP .nf \f[C] python\ pmreorder.py\ \\ \ \ \ \ \ \ \ \ \-l\ store_log.log\ \\ \ \ \ \ \ \ \ \ \-r\ NoReorderDoCheck\ \\ \ \ \ \ \ \ \ \ \-o\ pmreorder_out.log\ \\ \ \ \ \ \ \ \ \ \-c\ prog\ \\ \ \ \ \ \ \ \ \ \-x\ PMREORDER_MARKER_NAME=ReorderPartial\ \\ \ \ \ \ \ \ \ \ \-p\ checker_binary\ checker_parameter \f[] .fi .PP Checker binary will be used to run consistency checks on \[lq]store_log.log\[rq], output of pmemcheck tool. Any inconsistent stores found during \f[B]pmreorder\f[] analysis will be logged to \f[C]pmreorder_out.log\f[]. .SH SEE ALSO .PP \f[B]\f[] pmdk-1.11.1/doc/pmreorder/.gitignore0000664000000000000000000000001414123364546015765 0ustar rootrootpmreorder.1 pmdk-1.11.1/doc/pmreorder/pmreorder.1.md0000664000000000000000000002210214123364546016457 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMREORDER, 1) collection: pmreorder header: PMDK date: pmreorder version 1.5 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018-2020, Intel Corporation) [comment]: <> (pmreorder.1 -- man page for pmreorder) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[OPTIONS](#options)
[ENGINES](#engines)
[INSTRUMENTATION](#instrumentation)
[PMEMCHECK STORE LOG](#pmemcheck-store-log)
[ENVIRONMENT](#environment)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmreorder** - performs a persistent consistency check using a store reordering mechanism # SYNOPSIS # ``` $ python pmreorder ``` # DESCRIPTION # The pmreorder tool is a collection of python scripts designed to parse and replay operations logged by pmemcheck - a persistent memory checking tool. Pmreorder performs the store reordering between persistent memory barriers - a sequence of flush-fence operations. It uses a consistency checking routine provided in the command line options to check whether files are in a consistent state. Considering that logging, replaying and reordering of operations are very time consuming, it is recommended to use as few stores as possible in test workloads. # OPTIONS # `-h, --help` Prints synopsis and list of options. `-l , --logfile ` The pmemcheck log file to process. `-c , --checker ` Consistency checker type. `-p , --path ` Path to the consistency checker. Checker function has to return 0 for consistent cases and 1 otherwise. `-n , --name ` The symbol name of the consistency checking function in the library. Valid only if the checker type is `lib`. `-o , --output ` Set the logger output file. `-e ,` ` --output-level ` Set the output log level. `-r ,` `--default-engine ` Set the initial reorder engine. Default value is `NoReorderNoCheck`. `-x , --extended-macros ` Assign an engine types to the defined marker. `-v, --version` Prints current version of pmreorder. # ENGINES # By default, the **NoReorderNoCheck** engine is used, which means that for each set of stores, the tool will pass-through all sequences of stores not reordered and will not run consistency checker on them. To enable different types of the reorder engine and begin proper reordering tests, a number of other engines exist: + **NoReorderDoCheck** - pass-through of unchanged operations. Checks correctness of the stores as they were logged. Useful for operations that do not require fail safety. ``` Example: input: (a, b, c) output: (a, b, c) ``` + **ReorderAccumulative** - checks correctness on a growing subset of the original sequence. ``` Example: input: (a, b, c) output: () (a) (a, b) (a, b, c) ``` + **ReorderReverseAccumulative** - checks correctness on a reverted growing subset of the original sequence. ``` Example: input: (a, b, c) output: () (c) (c, b) (c, b, a) ``` + **ReorderPartial** - checks consistency on 3 randomly selected sequences from a set of 1000 combinations of the original log, without repetitions. ``` Example: input: (a, b, c) output: (b, c) (b) (a, b, c) ``` + **ReorderFull** - for each set of stores generates and checks consistency of all possible store permutations. This might prove to be very computationally expensive for most workloads. It can be useful for critical sections of code with limited number of stores. ``` Example: input: (a, b, c) output: () (a) (b) (c) (a, b) (a, c) (b, a) (b, c) (c, a) (c, b) (a, b, c) (a, c, b) (b, a, c) (b, c, a) (c, a, b) (c, b, a) ``` When the engine is passed with an `-r` option, it will be used for each logged set of stores. Additionally, the `-x` parameter can be used to switch engines separately for any marked code sections. For more details about `-x` extended macros functionality see section INSTRUMENTATION below. # INSTRUMENTATION # The core of **pmreorder** is based on user-provided named markers. Sections of code can be 'marked' depending on their importance, and the degree of reordering can be customized by the use of various provided engines. For this purpose, Valgrind's pmemcheck tool exposes a generic marker macro: + **VALGRIND_PMC_EMIT_LOG(value)** It emits log to *store_log* during pmemcheck processing. *value* is a user-defined marker name. For more details about pmemcheck execution see PMEMCHECK STORE LOG section below. Example: ``` main.c . . . VALGRIND_PMC_EMIT_LOG("PMREORDER_MEMSET_PERSIST.BEGIN"); pmem_memset_persist(...); VALGRIND_PMC_EMIT_LOG("PMREORDER_MEMSET_PERSIST.END"); . . . ``` There are a few rules for macros creation: + Valid macro can have any name, but begin and end section have to match - they are case sensitive. + Macro must have `.BEGIN` or `.END` suffix. + Macros can't be crossed. Defined markers can be assigned engines types and configured through the **pmreorder** tool using the `-x` parameter. There are two ways to set macro options: + Using command line interface in format: ``` PMREORDER_MARKER_NAME1=Marker1,PMREORDER_MARKER_NAME2=Marker2 ``` + Using configuration file in .json format: ``` { "PMREORDER_MARKER_NAME1":"Marker1", "PMREORDER_MARKER_NAME2":"Marker2" } ``` For more details about available engines types, see ENGINES section above. **libpmemobj**(7), **libpmem**(7) and **libpmem2**(7) also provide set of macros that allow to change reordering engine on library or function level: `` Example of configuration on function level: ``` { "pmemobj_open":"NoReorderNoCheck", "pmemobj_memcpy_persist":"ReorderPartial" } ``` Example of configuration on library level (affecting all library functions): ``` { "libpmemobj":"NoReorderNoCheck" } ``` List of marked **libpmemobj**(7) API functions: ``` pmemobj_alloc pmemobj_cancel pmemobj_check pmemobj_close pmemobj_create pmemobj_ctl_exec pmemobj_ctl_set pmemobj_free pmemobj_list_insert pmemobj_list_insert_new pmemobj_list_move pmemobj_list_remove pmemobj_memcpy pmemobj_memmove pmemobj_memset pmemobj_memcpy_persist pmemobj_memset_persist pmemobj_open pmemobj_publish pmemobj_realloc pmemobj_reserve pmemobj_root pmemobj_root_construct pmemobj_strdup pmemobj_tx_abort pmemobj_tx_add_range pmemobj_tx_add_range_direct pmemobj_tx_alloc pmemobj_tx_commit pmemobj_tx_free pmemobj_tx_publish pmemobj_tx_realloc pmemobj_tx_strdup pmemobj_tx_wcsdup pmemobj_tx_xadd_range pmemobj_tx_xadd_range_direct pmemobj_tx_xalloc pmemobj_tx_zalloc pmemobj_tx_zrealloc pmemobj_wcsdup pmemobj_xalloc pmemobj_xreserve pmemobj_zalloc pmemobj_zrealloc ``` List of marked **libpmem**(7) API functions: ``` pmem_memmove pmem_memcpy pmem_memset pmem_memmove_nodrain pmem_memcpy_nodrain pmem_memset_nodrain pmem_memmove_persist pmem_memcpy_persist pmem_memset_persist ``` List of **libpmem2**(7) API functions, which return marked functions: ``` pmem2_get_memcpy_fn (marker for the returned function has "pmem2_memmove" name) pmem2_get_memmove_fn (marker for the returned function has "pmem2_memmove" name) pmem2_get_memset_fn (marker for the returned function has "pmem2_memset" name) ``` # PMEMCHECK STORE LOG # To generate *store_log* for **pmreorder** run pmemcheck with additional parameters: ``` valgrind \ --tool=pmemcheck \ -q \ --log-stores=yes \ --print-summary=no \ --log-file=store_log.log \ --log-stores-stacktraces=yes \ --log-stores-stacktraces-depth=2 \ --expect-fence-after-clflush=yes \ test_binary writer_parameter ``` For further details of pmemcheck parameters see [pmemcheck documentation](https://pmem.io/valgrind/generated/pmc-manual.html) # ENVIRONMENT # By default all logging from PMDK libraries is disabled. To enable API macros logging set environment variable: + **PMREORDER_EMIT_LOG**=1 # EXAMPLE # ``` python pmreorder.py \ -l store_log.log \ -r NoReorderDoCheck \ -o pmreorder_out.log \ -c prog \ -x PMREORDER_MARKER_NAME=ReorderPartial \ -p checker_binary checker_parameter ``` Checker binary will be used to run consistency checks on "store_log.log", output of pmemcheck tool. Any inconsistent stores found during **pmreorder** analysis will be logged to `pmreorder_out.log`. # SEE ALSO # **** pmdk-1.11.1/doc/libpmem/0000775000000000000000000000000014123364727013431 5ustar rootrootpmdk-1.11.1/doc/libpmem/pmem_is_pmem.30000664000000000000000000001617014123364727016171 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_IS_PMEM" "3" "2021-09-24" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2019, Intel Corporation .SH NAME .PP \f[B]pmem_is_pmem\f[](), \f[B]pmem_map_file\f[](), \f[B]pmem_unmap\f[]() \- check persistency, create and delete mappings .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem_is_pmem(const\ void\ *addr,\ size_t\ len); void\ *pmem_map_file(const\ char\ *path,\ size_t\ len,\ int\ flags, \ \ \ \ mode_t\ mode,\ size_t\ *mapped_lenp,\ int\ *is_pmemp); int\ pmem_unmap(void\ *addr,\ size_t\ len); \f[] .fi .SH DESCRIPTION .PP Most pmem\-aware applications will take advantage of higher level libraries that alleviate the need for the application to call into \f[B]libpmem\f[] directly. Application developers that wish to access raw memory mapped persistence directly (via \f[B]mmap\f[](2)) and that wish to take on the responsibility for flushing stores to persistence will find the functions described in this section to be the most commonly used. .PP The \f[B]pmem_is_pmem\f[]() function detects if the entire range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) consists of persistent memory. Calling this function with a memory range that originates from a source different than \f[B]pmem_map_file()\f[] is undefined. The implementation of \f[B]pmem_is_pmem\f[]() requires a non\-trivial amount of work to determine if the given range is entirely persistent memory. For this reason, it is better to call \f[B]pmem_is_pmem\f[]() once when a range of memory is first encountered, save the result, and use the saved result to determine whether \f[B]pmem_persist\f[](3) or \f[B]msync\f[](2) is appropriate for flushing changes to persistence. Calling \f[B]pmem_is_pmem\f[]() each time changes are flushed to persistence will not perform well. .PP The \f[B]pmem_map_file\f[]() function creates a new read/write mapping for a file. If \f[B]PMEM_FILE_CREATE\f[] is not specified in \f[I]flags\f[], the entire existing file \f[I]path\f[] is mapped, \f[I]len\f[] must be zero, and \f[I]mode\f[] is ignored. Otherwise, \f[I]path\f[] is opened or created as specified by \f[I]flags\f[] and \f[I]mode\f[], and \f[I]len\f[] must be non\-zero. \f[B]pmem_map_file\f[]() maps the file using \f[B]mmap\f[](2), but it also takes extra steps to make large page mappings more likely. .PP On success, \f[B]pmem_map_file\f[]() returns a pointer to the mapped area. If \f[I]mapped_lenp\f[] is not NULL, the length of the mapping is stored into *\f[I]mapped_lenp\f[]. If \f[I]is_pmemp\f[] is not NULL, a flag indicating whether the mapped file is actual pmem, or if \f[B]msync\f[]() must be used to flush writes for the mapped range, is stored into *\f[I]is_pmemp\f[]. .PP The \f[I]flags\f[] argument is 0 or the bitwise OR of one or more of the following file creation flags: .IP \[bu] 2 \f[B]PMEM_FILE_CREATE\f[] \- Create the file named \f[I]path\f[] if it does not exist. \f[I]len\f[] must be non\-zero and specifies the size of the file to be created. If the file already exists, it will be extended or truncated to \f[I]len.\f[] The new or existing file is then fully allocated to size \f[I]len\f[] using \f[B]posix_fallocate\f[](3). \f[I]mode\f[] specifies the mode to use in case a new file is created (see \f[B]creat\f[](2)). .PP The remaining flags modify the behavior of \f[B]pmem_map_file\f[]() when \f[B]PMEM_FILE_CREATE\f[] is specified. .IP \[bu] 2 \f[B]PMEM_FILE_EXCL\f[] \- If specified in conjunction with \f[B]PMEM_FILE_CREATE\f[], and \f[I]path\f[] already exists, then \f[B]pmem_map_file\f[]() will fail with \f[B]EEXIST\f[]. Otherwise, has the same meaning as \f[B]O_EXCL\f[] on \f[B]open\f[](2), which is generally undefined. .IP \[bu] 2 \f[B]PMEM_FILE_SPARSE\f[] \- When specified in conjunction with \f[B]PMEM_FILE_CREATE\f[], create a sparse (holey) file using \f[B]ftruncate\f[](2) rather than allocating it using \f[B]posix_fallocate\f[](3). Otherwise ignored. .IP \[bu] 2 \f[B]PMEM_FILE_TMPFILE\f[] \- Create a mapping for an unnamed temporary file. Must be specified with \f[B]PMEM_FILE_CREATE\f[]. \f[I]len\f[] must be non\-zero, \f[I]mode\f[] is ignored (the temporary file is always created with mode 0600), and \f[I]path\f[] must specify an existing directory name. If the underlying file system supports \f[B]O_TMPFILE\f[], the unnamed temporary file is created in the filesystem containing the directory \f[I]path\f[]; if \f[B]PMEM_FILE_EXCL\f[] is also specified, the temporary file may not subsequently be linked into the filesystem (see \f[B]open\f[](2)). Otherwise, the file is created in \f[I]path\f[] and immediately unlinked. .PP The \f[I]path\f[] can point to a Device DAX. In this case only the \f[B]PMEM_FILE_CREATE\f[] and \f[B]PMEM_FILE_SPARSE\f[] flags are valid, but they are both ignored. For Device DAX mappings, \f[I]len\f[] must be equal to either 0 or the exact size of the device. .PP To delete mappings created with \f[B]pmem_map_file\f[](), use \f[B]pmem_unmap\f[](). .PP The \f[B]pmem_unmap\f[]() function deletes all the mappings for the specified address range, and causes further references to addresses within the range to generate invalid memory references. It will use the address specified by the parameter \f[I]addr\f[], where \f[I]addr\f[] must be a previously mapped region. \f[B]pmem_unmap\f[]() will delete the mappings using \f[B]munmap\f[](2). .SH RETURN VALUE .PP The \f[B]pmem_is_pmem\f[]() function returns true only if the entire range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) consists of persistent memory. A true return from \f[B]pmem_is_pmem\f[]() means it is safe to use \f[B]pmem_persist\f[](3) and the related functions to make changes durable for that memory range. See also \f[B]CAVEATS\f[]. .PP On success, \f[B]pmem_map_file\f[]() returns a pointer to the memory\-mapped region and sets *\f[I]mapped_lenp\f[] and *\f[I]is_pmemp\f[] if they are not NULL. On error, it returns NULL, sets \f[I]errno\f[] appropriately, and does not modify *\f[I]mapped_lenp\f[] or *\f[I]is_pmemp\f[]. .PP On success, \f[B]pmem_unmap\f[]() returns 0. On error, it returns \-1 and sets \f[I]errno\f[] appropriately. .SH NOTES .PP On Linux, \f[B]pmem_is_pmem\f[]() returns true if the entire range was mapped directly from Device DAX (/dev/daxX.Y) without an intervening file system, or \f[B]MAP_SYNC\f[] flag of \f[B]mmap(2)\f[] is supported by the file system on Filesystem DAX. .SH CAVEATS .PP The result of \f[B]pmem_is_pmem\f[]() query is only valid for the mappings created using \f[B]pmem_map_file\f[](). For other memory regions, in particular those created by a direct call to \f[B]mmap\f[](2), \f[B]pmem_is_pmem\f[]() always returns false, even if the queried range is entirely persistent memory. .PP Not all file systems support \f[B]posix_fallocate\f[](3). \f[B]pmem_map_file\f[]() will fail if \f[B]PMEM_FILE_CREATE\f[] is specified without \f[B]PMEM_FILE_SPARSE\f[] and the underlying file system does not support \f[B]posix_fallocate\f[](3). .SH SEE ALSO .PP \f[B]creat\f[](2), \f[B]ftruncate\f[](2), \f[B]mmap\f[](2), \f[B]msync\f[](2), \f[B]munmap\f[](2), \f[B]open\f[](2), \f[B]pmem_persist\f[](3), \f[B]posix_fallocate\f[](3), \f[B]libpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem/pmem_flush.30000664000000000000000000001724214123364726015661 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_FLUSH" "3" "2021-09-24" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmem_flush\f[](), \f[B]pmem_drain\f[](), \f[B]pmem_persist\f[](), \f[B]pmem_msync\f[](), \f[B]pmem_deep_flush\f[](), \f[B]pmem_deep_drain\f[](), \f[B]pmem_deep_persist\f[](), \f[B]pmem_has_hw_drain\f[](), \f[B]pmem_has_auto_flush\f[]() \- check persistency, store persistent data and delete mappings .SH SYNOPSIS .IP .nf \f[C] #include\ void\ pmem_persist(const\ void\ *addr,\ size_t\ len); int\ pmem_msync(const\ void\ *addr,\ size_t\ len); void\ pmem_flush(const\ void\ *addr,\ size_t\ len); void\ pmem_deep_flush(const\ void\ *addr,\ size_t\ len);\ (EXPERIMENTAL) int\ pmem_deep_drain(const\ void\ *addr,\ size_t\ len);\ (EXPERIMENTAL) int\ pmem_deep_persist(const\ void\ *addr,\ size_t\ len);\ (EXPERIMENTAL) void\ pmem_drain(void); int\ pmem_has_auto_flush(void);\ (EXPERIMENTAL) int\ pmem_has_hw_drain(void); \f[] .fi .SH DESCRIPTION .PP The functions in this section provide access to the stages of flushing to persistence, for the less common cases where an application needs more control of the flushing operations than the \f[B]pmem_persist\f[]() function. .RS .PP WARNING: Using \f[B]pmem_persist\f[]() on a range where \f[B]pmem_is_pmem\f[](3) returns false may not do anything useful \[en] use \f[B]msync\f[](2) instead. .RE .PP The \f[B]pmem_persist\f[]() function force any changes in the range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) to be stored durably in persistent memory. This is equivalent to calling \f[B]msync\f[](2) but may be more optimal and will avoid calling into the kernel if possible. There are no alignment restrictions on the range described by \f[I]addr\f[] and \f[I]len\f[], but \f[B]pmem_persist\f[]() may expand the range as necessary to meet platform alignment requirements. .RS .PP WARNING: Like \f[B]msync\f[](2), there is nothing atomic or transactional about this call. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until \f[B]pmem_persist\f[]() is called to become persistent \[en] they can become persistent at any time before \f[B]pmem_persist\f[]() is called. .RE .PP The \f[B]pmem_msync\f[]() function is like \f[B]pmem_persist\f[]() in that it forces any changes in the range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) to be stored durably. Since it calls \f[B]msync\f[](), this function works on either persistent memory or a memory mapped file on traditional storage. \f[B]pmem_msync\f[]() takes steps to ensure the alignment of addresses and lengths passed to \f[B]msync\f[]() meet the requirements of that system call. It calls \f[B]msync\f[]() with the \f[B]MS_SYNC\f[] flag as described in \f[B]msync\f[](2). Typically the application only checks for the existence of persistent memory once, and then uses that result throughout the program, for example: .IP .nf \f[C] /*\ do\ this\ call\ once,\ after\ the\ pmem\ is\ memory\ mapped\ */ int\ is_pmem\ =\ pmem_is_pmem(rangeaddr,\ rangelen); /*\ ...\ make\ changes\ to\ a\ range\ of\ pmem\ ...\ */ /*\ make\ the\ changes\ durable\ */ if\ (is_pmem) \ \ \ \ pmem_persist(subrangeaddr,\ subrangelen); else \ \ \ \ pmem_msync(subrangeaddr,\ subrangelen); /*\ ...\ */ \f[] .fi .RS .PP WARNING: On Linux, \f[B]pmem_msync\f[]() and \f[B]msync\f[](2) have no effect on memory ranges mapped from Device DAX. In case of memory ranges where \f[B]pmem_is_pmem\f[](3) returns true use \f[B]pmem_persist\f[]() to force the changes to be stored durably in persistent memory. .RE .PP The \f[B]pmem_flush\f[]() and \f[B]pmem_drain\f[]() functions provide partial versions of the \f[B]pmem_persist\f[]() function. \f[B]pmem_persist\f[]() can be thought of as this: .IP .nf \f[C] void pmem_persist(const\ void\ *addr,\ size_t\ len) { \ \ \ \ /*\ flush\ the\ processor\ caches\ */ \ \ \ \ pmem_flush(addr,\ len); \ \ \ \ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ \ \ \ \ pmem_drain(); } \f[] .fi .PP These functions allow advanced programs to create their own variations of \f[B]pmem_persist\f[](). For example, a program that needs to flush several discontiguous ranges can call \f[B]pmem_flush\f[]() for each range and then follow up by calling \f[B]pmem_drain\f[]() once. .PP The semantics of \f[B]pmem_deep_flush\f[]() function is the same as \f[B]pmem_flush\f[]() function except that \f[B]pmem_deep_flush\f[]() is indifferent to \f[B]PMEM_NO_FLUSH\f[] environment variable (see \f[B]ENVIRONMENT\f[] section in \f[B]libpmem\f[](7)) and always flushes processor caches. .PP The behavior of \f[B]pmem_deep_persist\f[]() function is the same as \f[B]pmem_persist\f[](), except that it provides higher reliability by flushing persistent memory stores to the most reliable persistence domain available to software rather than depending on automatic WPQ (write pending queue) flush on power failure (ADR). .PP The \f[B]pmem_deep_flush\f[]() and \f[B]pmem_deep_drain\f[]() functions provide partial versions of \f[B]pmem_deep_persist\f[]() function. \f[B]pmem_deep_persist\f[]() can be thought of as this: .IP .nf \f[C] int\ pmem_deep_persist(const\ void\ *addr,\ size_t\ len) { \ \ \ \ /*\ flush\ the\ processor\ caches\ */ \ \ \ \ pmem_deep_flush(addr,\ len); \ \ \ \ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ \ \ \ \ return\ pmem_deep_drain(addr,\ len); } \f[] .fi .PP Since this operation is usually much more expensive than \f[B]pmem_persist\f[](), it should be used rarely. Typically the application should use this function only to flush the most critical data, which are required to recover after the power failure. .PP The \f[B]pmem_has_auto_flush\f[]() function checks if the machine supports automatic CPU cache flush on power failure or system crash. Function returns true only when each NVDIMM in the system is covered by this mechanism. .PP The \f[B]pmem_has_hw_drain\f[]() function checks if the machine supports an explicit \f[I]hardware drain\f[] instruction for persistent memory. .SH RETURN VALUE .PP The \f[B]pmem_persist\f[]() function returns no value. .PP The \f[B]pmem_msync\f[]() return value is the return value of \f[B]msync\f[](), which can return \-1 and set \f[I]errno\f[] to indicate an error. .PP The \f[B]pmem_flush\f[](), \f[B]pmem_drain\f[]() and \f[B]pmem_deep_flush\f[]() functions return no value. .PP The \f[B]pmem_deep_persist\f[]() and \f[B]pmem_deep_drain\f[]() return 0 on success. Otherwise it returns \-1 and sets \f[I]errno\f[] appropriately. If \f[I]len\f[] is equal zero \f[B]pmem_deep_persist\f[]() and \f[B]pmem_deep_drain\f[]() return 0 but no flushing take place. .PP The \f[B]pmem_has_auto_flush\f[]() function returns 1 if given platform supports processor cache flushing on a power loss event. Otherwise it returns 0. On error it returns \-1 and sets \f[I]errno\f[] appropriately. .PP The \f[B]pmem_has_hw_drain\f[]() function returns true if the machine supports an explicit \f[I]hardware drain\f[] instruction for persistent memory. On Intel processors with persistent memory, stores to persistent memory are considered persistent once they are flushed from the CPU caches, so this function always returns false. Despite that, programs using \f[B]pmem_flush\f[]() to flush ranges of memory should still follow up by calling \f[B]pmem_drain\f[]() once to ensure the flushes are complete. As mentioned above, \f[B]pmem_persist\f[]() handles calling both \f[B]pmem_flush\f[]() and \f[B]pmem_drain\f[](). .SH SEE ALSO .PP \f[B]msync\f[](2), \f[B]pmem_is_pmem\f[](3), \f[B]libpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem/pmem_memcpy.30000664000000000000000000000003314123364546016020 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_flush.3.md0000664000000000000000000001620714123364546016260 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM_FLUSH, 3) collection: libpmem header: PMDK date: pmem API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmem_flush.3 -- man page for partial flushing operations [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem_flush**(), **pmem_drain**(), **pmem_persist**(), **pmem_msync**(), **pmem_deep_flush**(), **pmem_deep_drain**(), **pmem_deep_persist**(), **pmem_has_hw_drain**(), **pmem_has_auto_flush**() - check persistency, store persistent data and delete mappings # SYNOPSIS # ```c #include void pmem_persist(const void *addr, size_t len); int pmem_msync(const void *addr, size_t len); void pmem_flush(const void *addr, size_t len); void pmem_deep_flush(const void *addr, size_t len); (EXPERIMENTAL) int pmem_deep_drain(const void *addr, size_t len); (EXPERIMENTAL) int pmem_deep_persist(const void *addr, size_t len); (EXPERIMENTAL) void pmem_drain(void); int pmem_has_auto_flush(void); (EXPERIMENTAL) int pmem_has_hw_drain(void); ``` # DESCRIPTION # The functions in this section provide access to the stages of flushing to persistence, for the less common cases where an application needs more control of the flushing operations than the **pmem_persist**() function. >WARNING: Using **pmem_persist**() on a range where **pmem_is_pmem**(3) returns false may not do anything useful -- use **msync**(2) instead. The **pmem_persist**() function force any changes in the range \[*addr*, *addr*+*len*) to be stored durably in persistent memory. This is equivalent to calling **msync**(2) but may be more optimal and will avoid calling into the kernel if possible. There are no alignment restrictions on the range described by *addr* and *len*, but **pmem_persist**() may expand the range as necessary to meet platform alignment requirements. >WARNING: Like **msync**(2), there is nothing atomic or transactional about this call. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until **pmem_persist**() is called to become persistent -- they can become persistent at any time before **pmem_persist**() is called. The **pmem_msync**() function is like **pmem_persist**() in that it forces any changes in the range \[*addr*, *addr*+*len*) to be stored durably. Since it calls **msync**(), this function works on either persistent memory or a memory mapped file on traditional storage. **pmem_msync**() takes steps to ensure the alignment of addresses and lengths passed to **msync**() meet the requirements of that system call. It calls **msync**() with the **MS_SYNC** flag as described in **msync**(2). Typically the application only checks for the existence of persistent memory once, and then uses that result throughout the program, for example: ```c /* do this call once, after the pmem is memory mapped */ int is_pmem = pmem_is_pmem(rangeaddr, rangelen); /* ... make changes to a range of pmem ... */ /* make the changes durable */ if (is_pmem) pmem_persist(subrangeaddr, subrangelen); else pmem_msync(subrangeaddr, subrangelen); /* ... */ ``` _WINUX(,=q= >WARNING: On Linux, **pmem_msync**() and **msync**(2) have no effect on memory ranges mapped from Device DAX. In case of memory ranges where **pmem_is_pmem**(3) returns true use **pmem_persist**() to force the changes to be stored durably in persistent memory. =e=) The **pmem_flush**() and **pmem_drain**() functions provide partial versions of the **pmem_persist**() function. **pmem_persist**() can be thought of as this: ```c void pmem_persist(const void *addr, size_t len) { /* flush the processor caches */ pmem_flush(addr, len); /* wait for any pmem stores to drain from HW buffers */ pmem_drain(); } ``` These functions allow advanced programs to create their own variations of **pmem_persist**(). For example, a program that needs to flush several discontiguous ranges can call **pmem_flush**() for each range and then follow up by calling **pmem_drain**() once. The semantics of **pmem_deep_flush**() function is the same as **pmem_flush**() function except that **pmem_deep_flush**() is indifferent to **PMEM_NO_FLUSH** environment variable (see **ENVIRONMENT** section in **libpmem**(7)) and always flushes processor caches. The behavior of **pmem_deep_persist**() function is the same as **pmem_persist**(), except that it provides higher reliability by flushing persistent memory stores to the most reliable persistence domain available to software rather than depending on automatic WPQ (write pending queue) flush on power failure (ADR). The **pmem_deep_flush**() and **pmem_deep_drain**() functions provide partial versions of **pmem_deep_persist**() function. **pmem_deep_persist**() can be thought of as this: ``` int pmem_deep_persist(const void *addr, size_t len) { /* flush the processor caches */ pmem_deep_flush(addr, len); /* wait for any pmem stores to drain from HW buffers */ return pmem_deep_drain(addr, len); } ``` Since this operation is usually much more expensive than **pmem_persist**(), it should be used rarely. Typically the application should use this function only to flush the most critical data, which are required to recover after the power failure. The **pmem_has_auto_flush**() function checks if the machine supports automatic CPU cache flush on power failure or system crash. Function returns true only when each NVDIMM in the system is covered by this mechanism. The **pmem_has_hw_drain**() function checks if the machine supports an explicit *hardware drain* instruction for persistent memory. # RETURN VALUE # The **pmem_persist**() function returns no value. The **pmem_msync**() return value is the return value of **msync**(), which can return -1 and set *errno* to indicate an error. The **pmem_flush**(), **pmem_drain**() and **pmem_deep_flush**() functions return no value. The **pmem_deep_persist**() and **pmem_deep_drain**() return 0 on success. Otherwise it returns -1 and sets *errno* appropriately. If *len* is equal zero **pmem_deep_persist**() and **pmem_deep_drain**() return 0 but no flushing take place. The **pmem_has_auto_flush**() function returns 1 if given platform supports processor cache flushing on a power loss event. Otherwise it returns 0. On error it returns -1 and sets *errno* appropriately. The **pmem_has_hw_drain**() function returns true if the machine supports an explicit *hardware drain* instruction for persistent memory. On Intel processors with persistent memory, stores to persistent memory are considered persistent once they are flushed from the CPU caches, so this function always returns false. Despite that, programs using **pmem_flush**() to flush ranges of memory should still follow up by calling **pmem_drain**() once to ensure the flushes are complete. As mentioned above, **pmem_persist**() handles calling both **pmem_flush**() and **pmem_drain**(). # SEE ALSO # **msync**(2), **pmem_is_pmem**(3), **libpmem**(7) and **** pmdk-1.11.1/doc/libpmem/pmem_check_version.30000664000000000000000000000002314123364546017347 0ustar rootroot.so man7/libpmem.7 pmdk-1.11.1/doc/libpmem/pmem_map_file.30000664000000000000000000000002314123364546016301 0ustar rootroot.so pmem_is_pmem.3 pmdk-1.11.1/doc/libpmem/pmem_memmove_persist.3.md0000664000000000000000000001342014123364546020347 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM_MEMMOVE_PERSIST, 3) collection: libpmem header: PMDK date: pmem API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2020, Intel Corporation) [comment]: <> (pmem_memmove_persist.3 -- man page for functions that provide optimized copying to persistent memory [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem_memmove**(), **pmem_memcpy**(), **pmem_memset**(), **pmem_memmove_persist**(), **pmem_memcpy_persist**(), **pmem_memset_persist**(), **pmem_memmove_nodrain**(), **pmem_memcpy_nodrain**(), **pmem_memset_nodrain**() - functions that provide optimized copying to persistent memory # SYNOPSIS # ```c #include void *pmem_memmove(void *pmemdest, const void *src, size_t len, unsigned flags); void *pmem_memcpy(void *pmemdest, const void *src, size_t len, unsigned flags); void *pmem_memset(void *pmemdest, int c, size_t len, unsigned flags); void *pmem_memmove_persist(void *pmemdest, const void *src, size_t len); void *pmem_memcpy_persist(void *pmemdest, const void *src, size_t len); void *pmem_memset_persist(void *pmemdest, int c, size_t len); void *pmem_memmove_nodrain(void *pmemdest, const void *src, size_t len); void *pmem_memcpy_nodrain(void *pmemdest, const void *src, size_t len); void *pmem_memset_nodrain(void *pmemdest, int c, size_t len); ``` # DESCRIPTION # **pmem_memmove**(), **pmem_memcpy**() and **pmem_memset**() functions provide the same memory copying as their namesakes **memmove**(3), **memcpy**(3) and **memset**(3), and ensure that the result has been flushed to persistence before returning (unless **PMEM_F_MEM_NOFLUSH** flag was used). For example, the following code is functionally equivalent to **pmem_memmove**() (with flags equal to 0): ```c memmove(dest, src, len); pmem_persist(dest, len); ``` Calling **pmem_memmove**() may out-perform the above code, because **libpmem**(7) implementation may take advantage of the fact that *pmemdest* is persistent memory and use instructions such as *non-temporal* stores to avoid the need to flush processor caches. >WARNING: Using these functions where **pmem_is_pmem**(3) returns false may not do anything useful. Use libc functions in that case. Unlike libc implementation, **libpmem** functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by **pmem_persist**(3) can be safely replaced by a single call to one of the above functions. The *flags* argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: + **PMEM_F_MEM_NODRAIN** - modifies the behavior to skip the final **pmem_drain**() step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to **pmem_drain**(). The following example illustrates how this flag might be used to avoid multiple calls to **pmem_drain**() when copying several ranges of memory to pmem: ```c /* ... write several ranges to pmem ... */ pmem_memcpy(pmemdest1, src1, len1, PMEM_F_MEM_NODRAIN); pmem_memcpy(pmemdest2, src2, len2, PMEM_F_MEM_NODRAIN); /* ... */ /* wait for any pmem stores to drain from HW buffers */ pmem_drain(); ``` + **PMEM_F_MEM_NOFLUSH** - Don't flush anything. This implies **PMEM_F_MEM_NODRAIN**. Using this flag only makes sense when it's followed by any function that flushes data. The remaining flags say *how* the operation should be done, and are merely hints. + **PMEM_F_MEM_NONTEMPORAL** - Use non-temporal instructions. This flag is mutually exclusive with **PMEM_F_MEM_TEMPORAL**. On x86\_64 this flag is mutually exclusive with **PMEM_F_MEM_NOFLUSH**. + **PMEM_F_MEM_TEMPORAL** - Use temporal instructions. This flag is mutually exclusive with **PMEM_F_MEM_NONTEMPORAL**. + **PMEM_F_MEM_WC** - Use write combining mode. This flag is mutually exclusive with **PMEM_F_MEM_WB**. On x86\_64 this flag is mutually exclusive with **PMEM_F_MEM_NOFLUSH**. + **PMEM_F_MEM_WB** - Use write back mode. This flag is mutually exclusive with **PMEM_F_MEM_WC**. On x86\_64 this is an alias for **PMEM_F_MEM_TEMPORAL**. Using an invalid combination of flags has undefined behavior. Without any of the above flags **libpmem** will try to guess the best strategy based on size. See **PMEM_MOVNT_THRESHOLD** description in **libpmem**(7) for details. **pmem_memmove_persist**() is an alias for **pmem_memmove**() with flags equal to 0. **pmem_memcpy_persist**() is an alias for **pmem_memcpy**() with flags equal to 0. **pmem_memset_persist**() is an alias for **pmem_memset**() with flags equal to 0. **pmem_memmove_nodrain**() is an alias for **pmem_memmove**() with flags equal to **PMEM_F_MEM_NODRAIN**. **pmem_memcpy_nodrain**() is an alias for **pmem_memcpy**() with flags equal to **PMEM_F_MEM_NODRAIN**. **pmem_memset_nodrain**() is an alias for **pmem_memset**() with flags equal to **PMEM_F_MEM_NODRAIN**. # RETURN VALUE # All of the above functions return address of the destination buffer. # CAVEATS # After calling any of the functions with **PMEM_F_MEM_NODRAIN** flag you should not expect memory to be visible to other threads before calling **pmem_drain**(3) or any of the *\_persist* functions. This is because on x86\_64 those functions may use non-temporal store instructions, which are weakly ordered. See "Intel 64 and IA-32 Architectures Software Developer's Manual", Volume 1, "Caching of Temporal vs. Non-Temporal Data" section for details. # SEE ALSO # **memcpy**(3), **memmove**(3), **memset**(3), **libpmem**(7) and **** pmdk-1.11.1/doc/libpmem/pmem_memcpy_persist.30000664000000000000000000000003314123364546017571 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_unmap.30000664000000000000000000000002314123364546015645 0ustar rootroot.so pmem_is_pmem.3 pmdk-1.11.1/doc/libpmem/pmem_msync.30000664000000000000000000000002114123364546015654 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_has_hw_drain.30000664000000000000000000000002114123364546017151 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_memmove_nodrain.30000664000000000000000000000003314123364546017705 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_persist.30000664000000000000000000000002114123364546016214 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_memset.30000664000000000000000000000003314123364546016020 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_memcpy_nodrain.30000664000000000000000000000003314123364546017532 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/libpmem.70000664000000000000000000003375614123364724015161 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEM" "7" "2021-09-24" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]libpmem\f[] \- persistent memory support library .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *pmem_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Error handling: .IP .nf \f[C] const\ char\ *pmem_errormsg(void); \f[] .fi .SS Other library functions: .PP A description of other \f[B]libpmem\f[] functions can be found on the following manual pages: .IP \[bu] 2 most commonly used functions: \f[B]pmem_is_pmem\f[](3) .IP \[bu] 2 partial flushing operations: \f[B]pmem_flush\f[](3) .IP \[bu] 2 copying to persistent memory: \f[B]pmem_memmove_persist\f[](3) .SH DESCRIPTION .PP \f[B]libpmem\f[] provides low\-level \f[I]persistent memory\f[] (pmem) support for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of \f[I]non\-volatile memory DIMMs\f[] (NVDIMMs) provide this type of byte addressable access to storage. A \f[I]persistent memory aware file system\f[] is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non\-paged access to pmem. .PP This library is for applications that use persistent memory directly, without the help of any library\-supplied transactions or memory allocation. Higher\-level libraries that build on \f[B]libpmem\f[] are available and are recommended for most applications, see: .IP \[bu] 2 \f[B]libpmemobj\f[](7), a general use persistent memory API, providing memory allocation and transactional operations on variable\-sized objects. .IP \[bu] 2 \f[B]libpmemblk\f[](7), providing pmem\-resident arrays of fixed\-sized blocks with atomic updates. .IP \[bu] 2 \f[B]libpmemlog\f[](7), providing a pmem\-resident log file. .PP Under normal usage, \f[B]libpmem\f[] will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under \f[B]DEBUGGING AND ERROR HANDLING\f[] below. .SH CAVEATS .PP \f[B]libpmem\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]pmem_check_version\f[]() function is used to determine whether the installed \f[B]libpmem\f[] supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile\-time version information, supplied by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ pmem_check_version(PMEM_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEM_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP When the version check performed by \f[B]pmem_check_version\f[]() is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by \f[B]pmem_check_version\f[]() must not be modified or freed. .SH ENVIRONMENT .PP \f[B]libpmem\f[] can change its default behavior based on the following environment variables. These are largely intended for testing and are not normally required. .IP \[bu] 2 \f[B]PMEM_IS_PMEM_FORCE\f[]=\f[I]val\f[] .PP If \f[I]val\f[] is 0 (zero), then \f[B]pmem_is_pmem\f[](3) will always return false. Setting \f[I]val\f[] to 1 causes \f[B]pmem_is_pmem\f[](3) to always return true. This variable is mostly used for testing but can be used to force pmem behavior on a system where a range of pmem is not detectable as pmem for some reason. .RS .PP NOTE: Unlike the other variables, the value of \f[B]PMEM_IS_PMEM_FORCE\f[] is not queried (and cached) at library initialization time, but on the first call to \f[B]pmem_is_pmem\f[](3). This means that in case of \f[B]libpmemlog\f[](7), \f[B]libpmemblk\f[](7), and \f[B]libpmemobj\f[](7), \f[B]PMEM_IS_PMEM_FORCE\f[] may still be set or modified by the program until the first attempt to create or open the persistent memory pool. .RE .IP \[bu] 2 \f[B]PMEM_NO_CLWB\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem\f[] to never issue the \f[B]CLWB\f[] instruction on Intel hardware, falling back to other cache flush instructions instead (\f[B]CLFLUSHOPT\f[] or \f[B]CLFLUSH\f[] on Intel hardware). Without this environment variable, \f[B]libpmem\f[] will always use the \f[B]CLWB\f[] instruction for flushing processor caches on platforms that support the instruction. This variable is intended for use during library testing but may be required for some rare cases where using \f[B]CLWB\f[] has a negative impact on performance. .IP \[bu] 2 \f[B]PMEM_NO_CLFLUSHOPT\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem\f[] to never issue the \f[B]CLFLUSHOPT\f[] instruction on Intel hardware, falling back to the \f[B]CLFLUSH\f[] instructions instead. Without this environment variable, \f[B]libpmem\f[] will always use the \f[B]CLFLUSHOPT\f[] instruction for flushing processor caches on platforms that support the instruction, but where \f[B]CLWB\f[] is not available. This variable is intended for use during library testing. .IP \[bu] 2 \f[B]PMEM_NO_FLUSH\f[]=1 .PP Setting this environment variable to 1 forces most \f[B]libpmem\f[] functions to never issue any of \f[B]CLFLUSH\f[], \f[B]CLFLUSHOPT\f[] or \f[B]CLWB\f[] instructions on Intel hardware. The only exceptions are \f[B]pmem_deep_flush\f[](3) and \f[B]pmem_deep_persist\f[](3) functions. .IP \[bu] 2 \f[B]PMEM_NO_FLUSH\f[]=0 .PP Setting this environment variable to 0 forces to always flush CPU caches using one of \f[B]CLFLUSH\f[], \f[B]CLFLUSHOPT\f[] or \f[B]CLWB\f[] instructions even if \f[B]pmem_has_auto_flush\f[](3) function returns true and the platform supports flushing the processor caches on power loss or system crash. .IP \[bu] 2 \f[B]PMEM_NO_MOVNT\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem\f[] to never use the \f[I]non\-temporal\f[] move instructions on Intel hardware. Without this environment variable, \f[B]libpmem\f[] will use the non\-temporal instructions for copying larger ranges to persistent memory on platforms that support the instructions. This variable is intended for use during library testing. .IP \[bu] 2 \f[B]PMEM_MOVNT_THRESHOLD\f[]=\f[I]val\f[] .PP This environment variable allows overriding the minimum length of the \f[B]pmem_memmove_persist\f[](3) operations, for which \f[B]libpmem\f[] uses \f[I]non\-temporal\f[] move instructions. Setting this environment variable to 0 forces \f[B]libpmem\f[] to always use the \f[I]non\-temporal\f[] move instructions if available. It has no effect if \f[B]PMEM_NO_MOVNT\f[] is set to 1. This variable is intended for use during library testing. .IP \[bu] 2 \f[B]PMEM_MMAP_HINT\f[]=\f[I]val\f[] .PP This environment variable allows overriding the hint address used by \f[B]pmem_map_file\f[](). If set, it also disables mapping address randomization. This variable is intended for use during library testing and debugging. Setting it to some fairly large value (i.e.\ 0x10000000000) will very likely result in mapping the file at the specified address (if not used) or at the first unused region above given address, without adding any random offset. When debugging, this makes it easier to calculate the actual address of the persistent memory block, based on its offset in the file. In case of \f[B]libpmemobj\f[] it simplifies conversion of a persistent object identifier (OID) into a direct pointer to the object. .RS .PP NOTE: \f[B]Setting this environment variable affects all the PMDK libraries,\f[] disabling mapping address randomization and causing the specified address to be used as a hint about where to place the mapping. .RE .SH DEBUGGING AND ERROR HANDLING .PP If an error is detected during the call to a \f[B]libpmem\f[] function, the application may retrieve an error message describing the reason of the failure from \f[B]pmem_errormsg\f[](). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmem\f[] function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. .PP Two versions of \f[B]libpmem\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmem\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]libpmem\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEM_LOG_LEVEL\f[] .PP The value of \f[B]PMEM_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEM_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmem_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmem\f[] developers. .PP Unless \f[B]PMEM_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEM_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEM_LOG_FILE\f[] is not set, output is written to \f[I]stderr\f[]. .SH EXAMPLE .PP The following example uses \f[B]libpmem\f[] to flush changes made to raw, memory\-mapped persistent memory. .RS .PP WARNING: There is nothing transactional about the \f[B]pmem_persist\f[](3) or \f[B]pmem_msync\f[](3) calls in this example. Interrupting the program may result in a partial write to pmem. Use a transactional library such as \f[B]libpmemobj\f[](7) to avoid torn updates. .RE .IP .nf \f[C] #include\ #include\ #include\ #include\ #include\ #include\ #include\ #include\ #include\ /*\ using\ 4k\ of\ pmem\ for\ this\ example\ */ #define\ PMEM_LEN\ 4096 #define\ PATH\ "/pmem\-fs/myfile" int main(int\ argc,\ char\ *argv[]) { \ \ \ \ char\ *pmemaddr; \ \ \ \ size_t\ mapped_len; \ \ \ \ int\ is_pmem; \ \ \ \ /*\ create\ a\ pmem\ file\ and\ memory\ map\ it\ */ \ \ \ \ if\ ((pmemaddr\ =\ pmem_map_file(PATH,\ PMEM_LEN,\ PMEM_FILE_CREATE, \ \ \ \ \ \ \ \ \ \ \ \ 0666,\ &mapped_len,\ &is_pmem))\ ==\ NULL)\ { \ \ \ \ \ \ \ \ perror("pmem_map_file"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ store\ a\ string\ to\ the\ persistent\ memory\ */ \ \ \ \ strcpy(pmemaddr,\ "hello,\ persistent\ memory"); \ \ \ \ /*\ flush\ above\ strcpy\ to\ persistence\ */ \ \ \ \ if\ (is_pmem) \ \ \ \ \ \ \ \ pmem_persist(pmemaddr,\ mapped_len); \ \ \ \ else \ \ \ \ \ \ \ \ pmem_msync(pmemaddr,\ mapped_len); \ \ \ \ /* \ \ \ \ \ *\ Delete\ the\ mappings.\ The\ region\ is\ also \ \ \ \ \ *\ automatically\ unmapped\ when\ the\ process\ is \ \ \ \ \ *\ terminated. \ \ \ \ \ */ \ \ \ \ pmem_unmap(pmemaddr,\ mapped_len); } \f[] .fi .PP See for more examples using the \f[B]libpmem\f[] API. .SH ACKNOWLEDGEMENTS .PP \f[B]libpmem\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]dlclose\f[](3), \f[B]pmem_flush\f[](3), \f[B]pmem_is_pmem\f[](3), \f[B]pmem_memmove_persist\f[](3), \f[B]pmem_msync\f[](3), \f[B]pmem_persist\f[](3), \f[B]strerror\f[](3), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem/pmem_deep_persist.30000664000000000000000000000002114123364546017211 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_memset_nodrain.30000664000000000000000000000003314123364546017532 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/.gitignore0000664000000000000000000000007514123364546015422 0ustar rootrootlibpmem.7 pmem_flush.3 pmem_is_pmem.3 pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_memset_persist.30000664000000000000000000000003314123364546017571 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_drain.30000664000000000000000000000002114123364546015620 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/libpmem.7.md0000664000000000000000000003177714123364546015563 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEM, 7) collection: libpmem header: PMDK date: pmem API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (libpmem.7 -- man page for libpmem) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[CAVEATS](#caveats)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[ENVIRONMENT](#environment)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also) # NAME # **libpmem** - persistent memory support library # SYNOPSIS # ```c #include cc ... -lpmem ``` _UNICODE() ##### Library API versioning: ##### ```c _UWFUNC(pmem_check_version, =q= unsigned major_required, unsigned minor_required=e=) ``` ##### Error handling: ##### ```c _UWFUNC(pmem_errormsg, void) ``` ##### Other library functions: ##### A description of other **libpmem** functions can be found on the following manual pages: + most commonly used functions: **pmem_is_pmem**(3) + partial flushing operations: **pmem_flush**(3) + copying to persistent memory: **pmem_memmove_persist**(3) # DESCRIPTION # **libpmem** provides low-level *persistent memory* (pmem) support for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of *non-volatile memory DIMMs* (NVDIMMs) provide this type of byte addressable access to storage. A *persistent memory aware file system* is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non-paged access to pmem. This library is for applications that use persistent memory directly, without the help of any library-supplied transactions or memory allocation. Higher-level libraries that build on **libpmem** are available and are recommended for most applications, see: + **libpmemobj**(7), a general use persistent memory API, providing memory allocation and transactional operations on variable-sized objects. + **libpmemblk**(7), providing pmem-resident arrays of fixed-sized blocks with atomic updates. + **libpmemlog**(7), providing a pmem-resident log file. Under normal usage, **libpmem** will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under **DEBUGGING AND ERROR HANDLING** below. # CAVEATS # **libpmem** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The _UW(pmem_check_version) function is used to determine whether the installed **libpmem** supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile-time version information, supplied by defines in **\**, like this: ```c reason = _U(pmem_check_version)(PMEM_MAJOR_VERSION, PMEM_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. When the version check performed by _UW(pmem_check_version) is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by _UW(pmem_check_version) must not be modified or freed. # ENVIRONMENT # **libpmem** can change its default behavior based on the following environment variables. These are largely intended for testing and are not normally required. + **PMEM_IS_PMEM_FORCE**=*val* If *val* is 0 (zero), then **pmem_is_pmem**(3) will always return false. Setting *val* to 1 causes **pmem_is_pmem**(3) to always return true. This variable is mostly used for testing but can be used to force pmem behavior on a system where a range of pmem is not detectable as pmem for some reason. >NOTE: Unlike the other variables, the value of **PMEM_IS_PMEM_FORCE** is not queried (and cached) at library initialization time, but on the first call to **pmem_is_pmem**(3). This means that in case of **libpmemlog**(7), **libpmemblk**(7), and **libpmemobj**(7), **PMEM_IS_PMEM_FORCE** may still be set or modified by the program until the first attempt to create or open the persistent memory pool. + **PMEM_NO_CLWB**=1 Setting this environment variable to 1 forces **libpmem** to never issue the **CLWB** instruction on Intel hardware, falling back to other cache flush instructions instead (**CLFLUSHOPT** or **CLFLUSH** on Intel hardware). Without this environment variable, **libpmem** will always use the **CLWB** instruction for flushing processor caches on platforms that support the instruction. This variable is intended for use during library testing but may be required for some rare cases where using **CLWB** has a negative impact on performance. + **PMEM_NO_CLFLUSHOPT**=1 Setting this environment variable to 1 forces **libpmem** to never issue the **CLFLUSHOPT** instruction on Intel hardware, falling back to the **CLFLUSH** instructions instead. Without this environment variable, **libpmem** will always use the **CLFLUSHOPT** instruction for flushing processor caches on platforms that support the instruction, but where **CLWB** is not available. This variable is intended for use during library testing. + **PMEM_NO_FLUSH**=1 Setting this environment variable to 1 forces most **libpmem** functions to never issue any of **CLFLUSH**, **CLFLUSHOPT** or **CLWB** instructions on Intel hardware. The only exceptions are **pmem_deep_flush**(3) and **pmem_deep_persist**(3) functions. + **PMEM_NO_FLUSH**=0 Setting this environment variable to 0 forces to always flush CPU caches using one of **CLFLUSH**, **CLFLUSHOPT** or **CLWB** instructions even if **pmem_has_auto_flush**(3) function returns true and the platform supports flushing the processor caches on power loss or system crash. + **PMEM_NO_MOVNT**=1 Setting this environment variable to 1 forces **libpmem** to never use the *non-temporal* move instructions on Intel hardware. Without this environment variable, **libpmem** will use the non-temporal instructions for copying larger ranges to persistent memory on platforms that support the instructions. This variable is intended for use during library testing. + **PMEM_MOVNT_THRESHOLD**=*val* This environment variable allows overriding the minimum length of the **pmem_memmove_persist**(3) operations, for which **libpmem** uses *non-temporal* move instructions. Setting this environment variable to 0 forces **libpmem** to always use the *non-temporal* move instructions if available. It has no effect if **PMEM_NO_MOVNT** is set to 1. This variable is intended for use during library testing. + **PMEM_MMAP_HINT**=*val* This environment variable allows overriding the hint address used by _UW(pmem_map_file). If set, it also disables mapping address randomization. This variable is intended for use during library testing and debugging. Setting it to some fairly large value (i.e. 0x10000000000) will very likely result in mapping the file at the specified address (if not used) or at the first unused region above given address, without adding any random offset. When debugging, this makes it easier to calculate the actual address of the persistent memory block, based on its offset in the file. In case of **libpmemobj** it simplifies conversion of a persistent object identifier (OID) into a direct pointer to the object. >NOTE: **Setting this environment variable affects all the PMDK libraries,** disabling mapping address randomization and causing the specified address to be used as a hint about where to place the mapping. # DEBUGGING AND ERROR HANDLING # If an error is detected during the call to a **libpmem** function, the application may retrieve an error message describing the reason of the failure from _UW(pmem_errormsg). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmem** function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. Two versions of **libpmem** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmem** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **libpmem**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEM_LOG_LEVEL** The value of **PMEM_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEM_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmem_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmem** developers. Unless **PMEM_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEM_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEM_LOG_FILE** is not set, output is written to *stderr*. # EXAMPLE # The following example uses **libpmem** to flush changes made to raw, memory-mapped persistent memory. >WARNING: There is nothing transactional about the **pmem_persist**(3) or **pmem_msync**(3) calls in this example. Interrupting the program may result in a partial write to pmem. Use a transactional library such as **libpmemobj**(7) to avoid torn updates. ```c #include #include #include #include #include #include #include #include #include /* using 4k of pmem for this example */ #define PMEM_LEN 4096 #define PATH "/pmem-fs/myfile" int main(int argc, char *argv[]) { char *pmemaddr; size_t mapped_len; int is_pmem; /* create a pmem file and memory map it */ if ((pmemaddr = _U(pmem_map_file)(PATH, PMEM_LEN, PMEM_FILE_CREATE, 0666, &mapped_len, &is_pmem)) == NULL) { perror("_U(pmem_map_file)"); exit(1); } /* store a string to the persistent memory */ strcpy(pmemaddr, "hello, persistent memory"); /* flush above strcpy to persistence */ if (is_pmem) pmem_persist(pmemaddr, mapped_len); else pmem_msync(pmemaddr, mapped_len); /* * Delete the mappings. The region is also * automatically unmapped when the process is * terminated. */ pmem_unmap(pmemaddr, mapped_len); } ``` See for more examples using the **libpmem** API. # ACKNOWLEDGEMENTS # **libpmem** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **dlclose**(3), **pmem_flush**(3), **pmem_is_pmem**(3), **pmem_memmove_persist**(3), **pmem_msync**(3), **pmem_persist**(3), **strerror**(3), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmem/pmem_memmove_persist.30000664000000000000000000001413514123364727017755 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_MEMMOVE_PERSIST" "3" "2021-09-24" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2020, Intel Corporation .SH NAME .PP \f[B]pmem_memmove\f[](), \f[B]pmem_memcpy\f[](), \f[B]pmem_memset\f[](), \f[B]pmem_memmove_persist\f[](), \f[B]pmem_memcpy_persist\f[](), \f[B]pmem_memset_persist\f[](), \f[B]pmem_memmove_nodrain\f[](), \f[B]pmem_memcpy_nodrain\f[](), \f[B]pmem_memset_nodrain\f[]() \- functions that provide optimized copying to persistent memory .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *pmem_memmove(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len,\ unsigned\ flags); void\ *pmem_memcpy(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len,\ unsigned\ flags); void\ *pmem_memset(void\ *pmemdest,\ int\ c,\ size_t\ len,\ unsigned\ flags); void\ *pmem_memmove_persist(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len); void\ *pmem_memcpy_persist(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len); void\ *pmem_memset_persist(void\ *pmemdest,\ int\ c,\ size_t\ len); void\ *pmem_memmove_nodrain(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len); void\ *pmem_memcpy_nodrain(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len); void\ *pmem_memset_nodrain(void\ *pmemdest,\ int\ c,\ size_t\ len); \f[] .fi .SH DESCRIPTION .PP \f[B]pmem_memmove\f[](), \f[B]pmem_memcpy\f[]() and \f[B]pmem_memset\f[]() functions provide the same memory copying as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3) and \f[B]memset\f[](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEM_F_MEM_NOFLUSH\f[] flag was used). .PP For example, the following code is functionally equivalent to \f[B]pmem_memmove\f[]() (with flags equal to 0): .IP .nf \f[C] \ \ \ \ memmove(dest,\ src,\ len); \ \ \ \ pmem_persist(dest,\ len); \f[] .fi .PP Calling \f[B]pmem_memmove\f[]() may out\-perform the above code, because \f[B]libpmem\f[](7) implementation may take advantage of the fact that \f[I]pmemdest\f[] is persistent memory and use instructions such as \f[I]non\-temporal\f[] stores to avoid the need to flush processor caches. .RS .PP WARNING: Using these functions where \f[B]pmem_is_pmem\f[](3) returns false may not do anything useful. Use libc functions in that case. .RE .PP Unlike libc implementation, \f[B]libpmem\f[] functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by \f[B]pmem_persist\f[](3) can be safely replaced by a single call to one of the above functions. .PP The \f[I]flags\f[] argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEM_F_MEM_NODRAIN\f[] \- modifies the behavior to skip the final \f[B]pmem_drain\f[]() step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to \f[B]pmem_drain\f[](). The following example illustrates how this flag might be used to avoid multiple calls to \f[B]pmem_drain\f[]() when copying several ranges of memory to pmem: .IP .nf \f[C] /*\ ...\ write\ several\ ranges\ to\ pmem\ ...\ */ pmem_memcpy(pmemdest1,\ src1,\ len1,\ PMEM_F_MEM_NODRAIN); pmem_memcpy(pmemdest2,\ src2,\ len2,\ PMEM_F_MEM_NODRAIN); /*\ ...\ */ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ pmem_drain(); \f[] .fi .IP \[bu] 2 \f[B]PMEM_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEM_F_MEM_NODRAIN\f[]. Using this flag only makes sense when it's followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEM_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WB\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEM_F_MEM_TEMPORAL\f[]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmem\f[] will try to guess the best strategy based on size. See \f[B]PMEM_MOVNT_THRESHOLD\f[] description in \f[B]libpmem\f[](7) for details. .PP \f[B]pmem_memmove_persist\f[]() is an alias for \f[B]pmem_memmove\f[]() with flags equal to 0. .PP \f[B]pmem_memcpy_persist\f[]() is an alias for \f[B]pmem_memcpy\f[]() with flags equal to 0. .PP \f[B]pmem_memset_persist\f[]() is an alias for \f[B]pmem_memset\f[]() with flags equal to 0. .PP \f[B]pmem_memmove_nodrain\f[]() is an alias for \f[B]pmem_memmove\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .PP \f[B]pmem_memcpy_nodrain\f[]() is an alias for \f[B]pmem_memcpy\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .PP \f[B]pmem_memset_nodrain\f[]() is an alias for \f[B]pmem_memset\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .SH RETURN VALUE .PP All of the above functions return address of the destination buffer. .SH CAVEATS .PP After calling any of the functions with \f[B]PMEM_F_MEM_NODRAIN\f[] flag you should not expect memory to be visible to other threads before calling \f[B]pmem_drain\f[](3) or any of the \f[I]_persist\f[] functions. This is because on x86_64 those functions may use non\-temporal store instructions, which are weakly ordered. See \[lq]Intel 64 and IA\-32 Architectures Software Developer's Manual\[rq], Volume 1, \[lq]Caching of Temporal vs.\ Non\-Temporal Data\[rq] section for details. .SH SEE ALSO .PP \f[B]memcpy\f[](3), \f[B]memmove\f[](3), \f[B]memset\f[](3), \f[B]libpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem/pmem_memmove.30000664000000000000000000000003314123364546016173 0ustar rootroot.so pmem_memmove_persist.3 pmdk-1.11.1/doc/libpmem/pmem_is_pmem.3.md0000664000000000000000000001603114123364546016563 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM_IS_PMEM, 3) collection: libpmem header: PMDK date: pmem API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2019, Intel Corporation) [comment]: <> (pmem_is_pmem.3 -- man page for libpmem persistence and mapping functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[NOTES](#notes)
[CAVEATS](#caveats)
[BUGS](#bugs)
[SEE ALSO](#see-also)
# NAME # **pmem_is_pmem**(), _UW(pmem_map_file), **pmem_unmap**() - check persistency, create and delete mappings # SYNOPSIS # ```c #include int pmem_is_pmem(const void *addr, size_t len); _UWFUNCR1(void, *pmem_map_file, *path, =q=size_t len, int flags, mode_t mode, size_t *mapped_lenp, int *is_pmemp=e=) int pmem_unmap(void *addr, size_t len); ``` _UNICODE() # DESCRIPTION # Most pmem-aware applications will take advantage of higher level libraries that alleviate the need for the application to call into **libpmem** directly. Application developers that wish to access raw memory mapped persistence directly (via **mmap**(2)) and that wish to take on the responsibility for flushing stores to persistence will find the functions described in this section to be the most commonly used. The **pmem_is_pmem**() function detects if the entire range \[*addr*, *addr*+*len*) consists of persistent memory. Calling this function with a memory range that originates from a source different than **pmem_map_file()** is undefined. The implementation of **pmem_is_pmem**() requires a non-trivial amount of work to determine if the given range is entirely persistent memory. For this reason, it is better to call **pmem_is_pmem**() once when a range of memory is first encountered, save the result, and use the saved result to determine whether **pmem_persist**(3) or **msync**(2) is appropriate for flushing changes to persistence. Calling **pmem_is_pmem**() each time changes are flushed to persistence will not perform well. The _UW(pmem_map_file) function creates a new read/write mapping for a file. If **PMEM_FILE_CREATE** is not specified in *flags*, the entire existing file *path* is mapped, *len* must be zero, and *mode* is ignored. Otherwise, *path* is opened or created as specified by *flags* and *mode*, and *len* must be non-zero. _UW(pmem_map_file) maps the file using **mmap**(2), but it also takes extra steps to make large page mappings more likely. On success, _UW(pmem_map_file) returns a pointer to the mapped area. If *mapped_lenp* is not NULL, the length of the mapping is stored into \**mapped_lenp*. If *is_pmemp* is not NULL, a flag indicating whether the mapped file is actual pmem, or if **msync**() must be used to flush writes for the mapped range, is stored into \**is_pmemp*. The *flags* argument is 0 or the bitwise OR of one or more of the following file creation flags: + **PMEM_FILE_CREATE** - Create the file named *path* if it does not exist. *len* must be non-zero and specifies the size of the file to be created. If the file already exists, it will be extended or truncated to *len.* The new or existing file is then fully allocated to size *len* using **posix_fallocate**(3). *mode* specifies the mode to use in case a new file is created (see **creat**(2)). The remaining flags modify the behavior of _UW(pmem_map_file) when **PMEM_FILE_CREATE** is specified. + **PMEM_FILE_EXCL** - If specified in conjunction with **PMEM_FILE_CREATE**, and *path* already exists, then _UW(pmem_map_file) will fail with **EEXIST**. Otherwise, has the same meaning as **O_EXCL** on **open**(2), which is generally undefined. + **PMEM_FILE_SPARSE** - When specified in conjunction with **PMEM_FILE_CREATE**, create a sparse (holey) file using **ftruncate**(2) rather than allocating it using **posix_fallocate**(3). Otherwise ignored. + **PMEM_FILE_TMPFILE** - Create a mapping for an unnamed temporary file. Must be specified with **PMEM_FILE_CREATE**. *len* must be non-zero, *mode* is ignored (the temporary file is always created with mode 0600), and *path* must specify an existing directory name. If the underlying file system supports **O_TMPFILE**, the unnamed temporary file is created in the filesystem containing the directory *path*; if **PMEM_FILE_EXCL** is also specified, the temporary file may not subsequently be linked into the filesystem (see **open**(2)). Otherwise, the file is created in *path* and immediately unlinked. The *path* can point to a Device DAX. In this case only the **PMEM_FILE_CREATE** and **PMEM_FILE_SPARSE** flags are valid, but they are both ignored. For Device DAX mappings, *len* must be equal to either 0 or the exact size of the device. To delete mappings created with _UW(pmem_map_file), use **pmem_unmap**(). The **pmem_unmap**() function deletes all the mappings for the specified address range, and causes further references to addresses within the range to generate invalid memory references. It will use the address specified by the parameter *addr*, where *addr* must be a previously mapped region. **pmem_unmap**() will delete the mappings using **munmap**(2). # RETURN VALUE # The **pmem_is_pmem**() function returns true only if the entire range \[*addr*, *addr*+*len*) consists of persistent memory. A true return from **pmem_is_pmem**() means it is safe to use **pmem_persist**(3) and the related functions to make changes durable for that memory range. See also **CAVEATS**. On success, _UW(pmem_map_file) returns a pointer to the memory-mapped region and sets \**mapped_lenp* and \**is_pmemp* if they are not NULL. On error, it returns NULL, sets *errno* appropriately, and does not modify \**mapped_lenp* or \**is_pmemp*. On success, **pmem_unmap**() returns 0. On error, it returns -1 and sets *errno* appropriately. # NOTES # On Linux, **pmem_is_pmem**() returns true if the entire range was mapped directly from Device DAX (/dev/daxX.Y) without an intervening file system, or **MAP_SYNC** flag of **mmap(2)** is supported by the file system on Filesystem DAX. # CAVEATS # The result of **pmem_is_pmem**() query is only valid for the mappings created using _UW(pmem_map_file). For other memory regions, in particular those created by a direct call to **mmap**(2), **pmem_is_pmem**() always returns false, even if the queried range is entirely persistent memory. Not all file systems support **posix_fallocate**(3). _UW(pmem_map_file) will fail if **PMEM_FILE_CREATE** is specified without **PMEM_FILE_SPARSE** and the underlying file system does not support **posix_fallocate**(3). _WINUX(=q= On Windows if **PMEM_FILE_CREATE** is specified without **PMEM_FILE_SPARSE** and the file exists, FILE_ATTRIBUTE_SPARSE_FILE and FILE_ATTRIBUTE_COMPRESSED will be removed if the file has any, to physically allocate space for the file. This is a workaround for _chsize() performance issues. =e=) # SEE ALSO # **creat**(2), **ftruncate**(2), **mmap**(2), **msync**(2), **munmap**(2), **open**(2), **pmem_persist**(3), **posix_fallocate**(3), **libpmem**(7) and **** pmdk-1.11.1/doc/libpmem/pmem_deep_flush.30000664000000000000000000000002114123364546016641 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_has_auto_flush.30000664000000000000000000000002114123364546017527 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/libpmem/pmem_errormsg.30000664000000000000000000000002314123364546016365 0ustar rootroot.so man7/libpmem.7 pmdk-1.11.1/doc/libpmem/pmem_deep_drain.30000664000000000000000000000002114123364546016615 0ustar rootroot.so pmem_flush.3 pmdk-1.11.1/doc/generated/0000775000000000000000000000000014123364546013741 5ustar rootrootpmdk-1.11.1/doc/generated/Makefile0000664000000000000000000000032514123364546015401 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # generated/Makefile -- Makefile for generate pmem.io aliases map # all: ../../utils/get_aliases.sh clean: $(RM) -rf libs_map.yml pmdk-1.11.1/doc/generated/.gitignore0000664000000000000000000000000614123364546015725 0ustar rootroot*.yml pmdk-1.11.1/doc/Makefile0000664000000000000000000004633414123364546013455 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2021, Intel Corporation # # # doc/Makefile -- Makefile for PMDK man pages # include ../src/common.inc MANPAGES_7_MD = libpmem/libpmem.7.md libpmemblk/libpmemblk.7.md libpmemlog/libpmemlog.7.md \ libpmemobj/libpmemobj.7.md libpmempool/libpmempool.7.md MANPAGES_5_MD = poolset/poolset.5.md pmem_ctl/pmem_ctl.5.md MANPAGES_3_MD = libpmem/pmem_flush.3.md libpmem/pmem_is_pmem.3.md libpmem/pmem_memmove_persist.3.md \ libpmemblk/pmemblk_bsize.3.md libpmemblk/pmemblk_create.3.md libpmemblk/pmemblk_ctl_get.3.md libpmemblk/pmemblk_read.3.md libpmemblk/pmemblk_set_zero.3.md \ libpmemlog/pmemlog_append.3.md libpmemlog/pmemlog_create.3.md libpmemlog/pmemlog_ctl_get.3.md libpmemlog/pmemlog_nbyte.3.md libpmemlog/pmemlog_tell.3.md \ libpmemobj/oid_is_null.3.md libpmemobj/pmemobj_action.3.md libpmemobj/pmemobj_alloc.3.md libpmemobj/pmemobj_ctl_get.3.md libpmemobj/pmemobj_first.3.md \ libpmemobj/pmemobj_list_insert.3.md libpmemobj/pmemobj_memcpy_persist.3.md libpmemobj/pmemobj_mutex_zero.3.md \ libpmemobj/pmemobj_open.3.md libpmemobj/pmemobj_root.3.md libpmemobj/pmemobj_tx_begin.3.md libpmemobj/pmemobj_tx_add_range.3.md \ libpmemobj/pmemobj_tx_alloc.3.md libpmemobj/pobj_layout_begin.3.md libpmemobj/pobj_list_head.3.md libpmemobj/toid_declare.3.md \ libpmempool/pmempool_check_init.3.md libpmempool/pmempool_feature_query.3.md libpmempool/pmempool_rm.3.md libpmempool/pmempool_sync.3.md MANPAGES_1_MD = pmempool/pmempool.1.md pmempool/pmempool-info.1.md pmempool/pmempool-create.1.md \ pmempool/pmempool-check.1.md pmempool/pmempool-dump.1.md pmempool/pmempool-rm.1.md \ pmempool/pmempool-convert.1.md pmempool/pmempool-sync.1.md pmempool/pmempool-transform.1.md \ pmempool/pmempool-feature.1.md pmreorder/pmreorder.1.md MANPAGES_3_DUMMY = libpmem/pmem_drain.3 libpmem/pmem_has_hw_drain.3 libpmem/pmem_has_auto_flush.3 \ libpmem/pmem_persist.3 libpmem/pmem_msync.3 libpmem/pmem_map_file.3 libpmem/pmem_deep_persist.3 libpmem/pmem_deep_flush.3 libpmem/pmem_deep_drain.3 libpmem/pmem_unmap.3 \ libpmem/pmem_memcpy_persist.3 libpmem/pmem_memset_persist.3 libpmem/pmem_memmove_nodrain.3 libpmem/pmem_memcpy_nodrain.3 libpmem/pmem_memset_nodrain.3 \ libpmem/pmem_memcpy.3 libpmem/pmem_memset.3 libpmem/pmem_memmove.3 \ libpmem/pmem_check_version.3 libpmem/pmem_errormsg.3 \ libpmemblk/pmemblk_nblock.3 \ libpmemblk/pmemblk_open.3 libpmemblk/pmemblk_close.3 \ libpmemblk/pmemblk_write.3 \ libpmemblk/pmemblk_set_error.3 \ libpmemblk/pmemblk_check_version.3 libpmemblk/pmemblk_check.3 libpmemblk/pmemblk_errormsg.3 libpmemblk/pmemblk_set_funcs.3 \ libpmemblk/pmemblk_ctl_set.3 libpmemblk/pmemblk_ctl_exec.3\ libpmemlog/pmemlog_rewind.3 libpmemlog/pmemlog_walk.3 \ libpmemlog/pmemlog_open.3 libpmemlog/pmemlog_close.3 \ libpmemlog/pmemlog_appendv.3 \ libpmemlog/pmemlog_check_version.3 libpmemlog/pmemlog_check.3 libpmemlog/pmemlog_errormsg.3 libpmemlog/pmemlog_set_funcs.3 \ libpmemlog/pmemlog_ctl_set.3 libpmemlog/pmemlog_ctl_exec.3\ libpmempool/pmempool_check.3 libpmempool/pmempool_check_end.3 \ libpmempool/pmempool_feature_enable.3 libpmempool/pmempool_feature_disable.3 \ libpmempool/pmempool_transform.3 \ libpmempool/pmempool_check_version.3 libpmempool/pmempool_errormsg.3 \ libpmemobj/oid_equals.3 libpmemobj/pmemobj_direct.3 libpmemobj/pmemobj_oid.3 libpmemobj/pmemobj_type_num.3 libpmemobj/pmemobj_pool_by_oid.3 libpmemobj/pmemobj_pool_by_ptr.3 libpmemobj/pmemobj_volatile.3\ libpmemobj/pmemobj_zalloc.3 libpmemobj/pmemobj_xalloc.3 libpmemobj/pmemobj_free.3 libpmemobj/pmemobj_realloc.3 libpmemobj/pmemobj_zrealloc.3 libpmemobj/pmemobj_strdup.3 libpmemobj/pmemobj_wcsdup.3 libpmemobj/pmemobj_alloc_usable_size.3 \ libpmemobj/pobj_new.3 libpmemobj/pobj_alloc.3 libpmemobj/pobj_znew.3 libpmemobj/pobj_zalloc.3 libpmemobj/pobj_realloc.3 libpmemobj/pobj_zrealloc.3 libpmemobj/pobj_free.3 \ libpmemobj/pobj_layout_toid.3 libpmemobj/pobj_layout_root.3 libpmemobj/pobj_layout_name.3 libpmemobj/pobj_layout_end.3 libpmemobj/pobj_layout_types_num.3 \ libpmemobj/pmemobj_ctl_set.3 libpmemobj/pmemobj_ctl_exec.3\ libpmemobj/pmemobj_create.3 libpmemobj/pmemobj_close.3 \ libpmemobj/pmemobj_list_insert_new.3 libpmemobj/pmemobj_list_remove.3 libpmemobj/pmemobj_list_move.3 \ libpmemobj/toid_declare_root.3 libpmemobj/toid.3 libpmemobj/toid_type_num.3 libpmemobj/toid_type_num_of.3 libpmemobj/toid_valid.3 libpmemobj/oid_instanceof.3 libpmemobj/toid_assign.3 libpmemobj/toid_is_null.3 libpmemobj/toid_equals.3 libpmemobj/toid_typeof.3 libpmemobj/toid_offsetof.3 libpmemobj/direct_rw.3 libpmemobj/d_rw.3 libpmemobj/direct_ro.3 libpmemobj/d_ro.3 \ libpmemobj/pmemobj_memcpy.3 libpmemobj/pmemobj_memmove.3 libpmemobj/pmemobj_memset.3 \ libpmemobj/pmemobj_memset_persist.3 libpmemobj/pmemobj_persist.3 libpmemobj/pmemobj_xpersist.3 libpmemobj/pmemobj_flush.3 libpmemobj/pmemobj_xflush.3 libpmemobj/pmemobj_drain.3 \ libpmemobj/pmemobj_tx_stage.3 libpmemobj/pmemobj_tx_lock.3 libpmemobj/pmemobj_tx_xlock.3 libpmemobj/pmemobj_tx_abort.3 libpmemobj/pmemobj_tx_commit.3 libpmemobj/pmemobj_tx_end.3 libpmemobj/pmemobj_tx_errno.3 \ libpmemobj/pmemobj_tx_process.3 libpmemobj/pmemobj_tx_add_range_direct.3 libpmemobj/pmemobj_tx_xadd_range.3 libpmemobj/pmemobj_tx_xadd_range_direct.3 \ libpmemobj/pmemobj_tx_zalloc.3 libpmemobj/pmemobj_tx_xalloc.3 libpmemobj/pmemobj_tx_realloc.3 libpmemobj/pmemobj_tx_zrealloc.3 libpmemobj/pmemobj_tx_strdup.3 libpmemobj/pmemobj_tx_xstrdup.3 libpmemobj/pmemobj_tx_wcsdup.3 libpmemobj/pmemobj_tx_xwcsdup.3 libpmemobj/pmemobj_tx_free.3 libpmemobj/pmemobj_tx_xfree.3\ libpmemobj/pmemobj_tx_log_append_buffer.3 libpmemobj/pmemobj_tx_xlog_append_buffer.3 libpmemobj/pmemobj_tx_log_auto_alloc.3 libpmemobj/pmemobj_tx_log_snapshots_max_size.3 libpmemobj/pmemobj_tx_log_intents_max_size.3 \ libpmemobj/tx_begin_param.3 libpmemobj/tx_begin_cb.3 libpmemobj/tx_begin.3 libpmemobj/tx_onabort.3 libpmemobj/tx_oncommit.3 libpmemobj/tx_finally.3 libpmemobj/tx_end.3 \ libpmemobj/tx_add.3 libpmemobj/tx_add_field.3 libpmemobj/tx_add_direct.3 libpmemobj/tx_add_field_direct.3 libpmemobj/tx_xadd.3 libpmemobj/tx_xadd_field.3 libpmemobj/tx_xadd_direct.3 libpmemobj/tx_xadd_field_direct.3 \ libpmemobj/tx_new.3 libpmemobj/tx_alloc.3 libpmemobj/tx_znew.3 libpmemobj/tx_zalloc.3 libpmemobj/tx_xalloc.3 libpmemobj/tx_realloc.3 libpmemobj/tx_zrealloc.3 libpmemobj/tx_strdup.3 libpmemobj/tx_wcsdup.3 libpmemobj/tx_free.3 libpmemobj/tx_set.3 libpmemobj/tx_set_direct.3 libpmemobj/tx_memcpy.3 libpmemobj/tx_memset.3 \ libpmemobj/pmemobj_f_mem_nodrain.3 libpmemobj/pmemobj_f_mem_nontemporal.3 libpmemobj/pmemobj_f_mem_temporal.3 libpmemobj/pmemobj_f_mem_wc.3 libpmemobj/pmemobj_f_mem_wb.3 libpmemobj/pmemobj_f_mem_noflush.3 libpmemobj/pmemobj_f_relaxed.3 \ libpmemobj/pmemobj_mutex_lock.3 libpmemobj/pmemobj_mutex_timedlock.3 libpmemobj/pmemobj_mutex_trylock.3 libpmemobj/pmemobj_mutex_unlock.3 \ libpmemobj/pmemobj_rwlock_zero.3 libpmemobj/pmemobj_rwlock_rdlock.3 libpmemobj/pmemobj_rwlock_wrlock.3 libpmemobj/pmemobj_rwlock_timedrdlock.3 libpmemobj/pmemobj_rwlock_timedwrlock.3 libpmemobj/pmemobj_rwlock_tryrdlock.3 libpmemobj/pmemobj_rwlock_trywrlock.3 libpmemobj/pmemobj_rwlock_unlock.3 \ libpmemobj/pmemobj_cond_zero.3 libpmemobj/pmemobj_cond_broadcast.3 libpmemobj/pmemobj_cond_signal.3 libpmemobj/pmemobj_cond_timedwait.3 libpmemobj/pmemobj_cond_wait.3 \ libpmemobj/pobj_list_entry.3 libpmemobj/pobj_list_first.3 libpmemobj/pobj_list_last.3 libpmemobj/pobj_list_empty.3 libpmemobj/pobj_list_next.3 libpmemobj/pobj_list_prev.3 libpmemobj/pobj_list_foreach.3 libpmemobj/pobj_list_foreach_reverse.3 \ libpmemobj/pobj_list_insert_head.3 libpmemobj/pobj_list_insert_tail.3 libpmemobj/pobj_list_insert_after.3 libpmemobj/pobj_list_insert_before.3 libpmemobj/pobj_list_insert_new_head.3 libpmemobj/pobj_list_insert_new_tail.3 \ libpmemobj/pobj_list_insert_new_after.3 libpmemobj/pobj_list_insert_new_before.3 libpmemobj/pobj_list_remove.3 libpmemobj/pobj_list_remove_free.3 \ libpmemobj/pobj_list_move_element_head.3 libpmemobj/pobj_list_move_element_tail.3 libpmemobj/pobj_list_move_element_after.3 libpmemobj/pobj_list_move_element_before.3 \ libpmemobj/pmemobj_next.3 libpmemobj/pobj_first_type_num.3 libpmemobj/pobj_first.3 libpmemobj/pobj_next_type_num.3 libpmemobj/pobj_next.3 libpmemobj/pobj_foreach.3 libpmemobj/pobj_foreach_safe.3 libpmemobj/pobj_foreach_type.3 libpmemobj/pobj_foreach_safe_type.3 \ libpmemobj/pmemobj_root_construct.3 libpmemobj/pobj_root.3 libpmemobj/pmemobj_root_size.3 \ libpmemobj/pmemobj_check_version.3 libpmemobj/pmemobj_check.3 libpmemobj/pmemobj_errormsg.3 libpmemobj/pmemobj_set_funcs.3 \ libpmemobj/pmemobj_reserve.3 libpmemobj/pmemobj_xreserve.3 libpmemobj/pmemobj_defer_free.3 libpmemobj/pmemobj_set_value.3 libpmemobj/pmemobj_publish.3 libpmemobj/pmemobj_tx_publish.3 libpmemobj/pmemobj_tx_xpublish.3 libpmemobj/pmemobj_cancel.3 libpmemobj/pobj_reserve_new.3 libpmemobj/pobj_reserve_alloc.3 libpmemobj/pobj_xreserve_new.3 libpmemobj/pobj_xreserve_alloc.3 \ libpmemobj/tx_xstrdup.3 libpmemobj/tx_xwcsdup.3 libpmemobj/tx_xfree.3 \ libpmemobj/pmemobj_defrag.3 libpmemobj/pmemobj_get_user_data.3 libpmemobj/pmemobj_set_user_data.3 libpmemobj/pmemobj_tx_get_user_data.3 libpmemobj/pmemobj_tx_set_user_data.3 libpmemobj/pmemobj_tx_get_failure_behavior.3 libpmemobj/pmemobj_tx_set_failure_behavior.3 MANPAGES_WEBDIR_LINUX = web_linux MANPAGES_WEBDIR_WINDOWS = web_windows # experimental MANPAGES_7_MD_EXP = MANPAGES_5_MD_EXP = MANPAGES_3_MD_EXP = MANPAGES_1_MD_EXP = MANPAGES_3_DUMMY_EXP = MANPAGES_1_DUMMY_EXP = # libpmem2 MANPAGES_7_MD_PMEM2 = libpmem2/libpmem2.7.md libpmem2/libpmem2_unsafe_shutdown.7.md MANPAGES_5_MD_PMEM2 = MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.md libpmem2/pmem2_map_new.3.md \ libpmem2/pmem2_map_delete.3.md libpmem2/pmem2_map_get_address.3.md libpmem2/pmem2_map_get_size.3.md \ libpmem2/pmem2_source_from_fd.3.md libpmem2/pmem2_config_set_required_store_granularity.3.md \ libpmem2/pmem2_source_size.3.md libpmem2/pmem2_source_alignment.3.md libpmem2/pmem2_source_numa_node.3.md \ libpmem2/pmem2_config_set_length.3.md libpmem2/pmem2_config_set_offset.3.md \ libpmem2/pmem2_map_get_store_granularity.3.md libpmem2/pmem2_get_flush_fn.3.md \ libpmem2/pmem2_get_drain_fn.3.md libpmem2/pmem2_get_persist_fn.3.md \ libpmem2/pmem2_perror.3.md libpmem2/pmem2_get_memmove_fn.3.md libpmem2/pmem2_config_set_sharing.3.md \ libpmem2/pmem2_config_set_vm_reservation.3.md libpmem2/pmem2_vm_reservation_new.3.md \ libpmem2/pmem2_vm_reservation_get_address.3.md libpmem2/pmem2_vm_reservation_get_size.3.md \ libpmem2/pmem2_badblock_context_new.3.md libpmem2/pmem2_badblock_next.3.md \ libpmem2/pmem2_badblock_clear.3.md libpmem2/pmem2_config_set_protection.3.md \ libpmem2/pmem2_deep_flush.3.md libpmem2/pmem2_source_from_anon.3.md \ libpmem2/pmem2_source_device_id.3.md libpmem2/pmem2_source_device_usc.3.md \ libpmem2/pmem2_map_from_existing.3.md libpmem2/pmem2_source_get_fd.3.md \ libpmem2/pmem2_source_get_handle.3.md libpmem2/pmem2_vm_reservation_extend.3.md \ libpmem2/pmem2_vm_reservation_map_find.3.md MANPAGES_1_MD_PMEM2 = MANPAGES_3_DUMMY += libpmem2/pmem2_config_delete.3 libpmem2/pmem2_source_from_handle.3 libpmem2/pmem2_source_delete.3 \ libpmem2/pmem2_get_memset_fn.3 libpmem2/pmem2_get_memcpy_fn.3 libpmem2/pmem2_vm_reservation_delete.3 \ libpmem2/pmem2_badblock_context_delete.3 libpmem2/pmem2_vm_reservation_shrink.3 \ libpmem2/pmem2_vm_reservation_map_find_first.3 libpmem2/pmem2_vm_reservation_map_find_last.3 \ libpmem2/pmem2_vm_reservation_map_find_next.3 libpmem2/pmem2_vm_reservation_map_find_prev.3 # libpmemset MANPAGES_7_MD_PMEMSET = libpmemset/libpmemset.7.md MANPAGES_5_MD_PMEMSET = MANPAGES_3_MD_PMEMSET = libpmemset/pmemset_errormsg.3.md libpmemset/pmemset_perror.3.md libpmemset/pmemset_config_new.3.md \ libpmemset/pmemset_source_from_pmem2.3.md libpmemset/pmemset_new.3.md \ libpmemset/pmemset_source_from_file.3.md libpmemset/pmemset_source_delete.3.md libpmemset/pmemset_part_new.3.md \ libpmemset/pmemset_config_set_required_store_granularity.3.md libpmemset/pmemset_part_map.3.md \ libpmemset/pmemset_first_part_map.3.md libpmemset/pmemset_descriptor_part_map.3.md libpmemset/pmemset_get_store_granularity.3.md \ libpmemset/pmemset_part_map_drop.3.md libpmemset/pmemset_part_map_by_address.3.md \ libpmemset/pmemset_persist.3.md libpmemset/pmemset_flush.3.md libpmemset/pmemset_drain.3.md \ libpmemset/pmemset_set_contiguous_part_coalescing.3.md libpmemset/pmemset_memmove.3.md \ libpmemset/pmemset_remove_part_map.3.md libpmemset/pmemset_deep_flush.3.md \ libpmemset/pmemset_source_from_temporary.3.md libpmemset/pmemset_remove_range.3.md \ libpmemset/pmemset_config_set_event_callback.3.md libpmemset/pmemset_config_set_reservation.3.md MANPAGES_1_MD_PMEMSET = ifeq ($(PMEMSET_INSTALL),y) MANPAGES_3_DUMMY += libpmemset/pmemset_config_delete.3 libpmemset/pmemset_delete.3 libpmemset/pmemset_part_delete.3 \ libpmemset/pmemset_next_part_map.3 libpmemset/pmemset_memcpy.3 libpmemset/pmemset_memset.3 \ libpmemset/pmemset_xsource_from_file.3 endif ifeq ($(BUILD_RPMEM),y) MANPAGES_7_MD += librpmem/librpmem.7.md MANPAGES_3_MD += librpmem/rpmem_create.3.md MANPAGES_3_MD += librpmem/rpmem_persist.3.md MANPAGES_1_MD += rpmemd/rpmemd.1.md MANPAGES_3_DUMMY += librpmem/rpmem_open.3 librpmem/rpmem_set_attr.3 librpmem/rpmem_close.3 \ librpmem/rpmem_read.3 librpmem/rpmem_remove.3 librpmem/rpmem_check_version.3 \ librpmem/rpmem_errormsg.3 librpmem/rpmem_deep_persist.3 librpmem/rpmem_flush.3 \ librpmem/rpmem_drain.3 endif ifeq ($(NDCTL_ENABLE),y) MANPAGES_1_MD += daxio/daxio.1.md endif MANPAGES_7_GROFF = $(MANPAGES_7_MD:.7.md=.7) MANPAGES_5_GROFF = $(MANPAGES_5_MD:.5.md=.5) MANPAGES_3_GROFF = $(MANPAGES_3_MD:.3.md=.3) MANPAGES_1_GROFF = $(MANPAGES_1_MD:.1.md=.1) MANPAGES_7_GROFF_EXP = $(MANPAGES_7_MD_EXP:.7.md=.7) MANPAGES_5_GROFF_EXP = $(MANPAGES_5_MD_EXP:.5.md=.5) MANPAGES_3_GROFF_EXP = $(MANPAGES_3_MD_EXP:.3.md=.3) MANPAGES_1_GROFF_EXP = $(MANPAGES_1_MD_EXP:.1.md=.1) MANPAGES_7_GROFF_PMEM2 = $(MANPAGES_7_MD_PMEM2:.7.md=.7) MANPAGES_5_GROFF_PMEM2 = $(MANPAGES_5_MD_PMEM2:.5.md=.5) MANPAGES_3_GROFF_PMEM2 = $(MANPAGES_3_MD_PMEM2:.3.md=.3) MANPAGES_1_GROFF_PMEM2 = $(MANPAGES_1_MD_PMEM2:.1.md=.1) MANPAGES_7_GROFF_PMEMSET = $(MANPAGES_7_MD_PMEMSET:.7.md=.7) MANPAGES_5_GROFF_PMEMSET = $(MANPAGES_5_MD_PMEMSET:.5.md=.5) MANPAGES_3_GROFF_PMEMSET = $(MANPAGES_3_MD_PMEMSET:.3.md=.3) MANPAGES_1_GROFF_PMEMSET = $(MANPAGES_1_MD_PMEMSET:.1.md=.1) ifeq ($(EXPERIMENTAL),y) MANPAGES_7_GROFF += $(MANPAGES_7_GROFF_EXP) MANPAGES_5_GROFF += $(MANPAGES_5_GROFF_EXP) MANPAGES_3_GROFF += $(MANPAGES_3_GROFF_EXP) MANPAGES_1_GROFF += $(MANPAGES_1_GROFF_EXP) else MANPAGES_7_NOINSTALL += $(MANPAGES_7_GROFF_EXP) MANPAGES_5_NOINSTALL += $(MANPAGES_5_GROFF_EXP) MANPAGES_3_NOINSTALL += $(MANPAGES_3_GROFF_EXP) MANPAGES_1_NOINSTALL += $(MANPAGES_1_GROFF_EXP) endif MANPAGES_7_GROFF += $(MANPAGES_7_GROFF_PMEM2) MANPAGES_5_GROFF += $(MANPAGES_5_GROFF_PMEM2) MANPAGES_3_GROFF += $(MANPAGES_3_GROFF_PMEM2) MANPAGES_1_GROFF += $(MANPAGES_1_GROFF_PMEM2) ifeq ($(PMEMSET_INSTALL),y) MANPAGES_7_GROFF += $(MANPAGES_7_GROFF_PMEMSET) MANPAGES_5_GROFF += $(MANPAGES_5_GROFF_PMEMSET) MANPAGES_3_GROFF += $(MANPAGES_3_GROFF_PMEMSET) MANPAGES_1_GROFF += $(MANPAGES_1_GROFF_PMEMSET) else MANPAGES_7_NOINSTALL += $(MANPAGES_7_GROFF_PMEMSET) MANPAGES_5_NOINSTALL += $(MANPAGES_5_GROFF_PMEMSET) MANPAGES_3_NOINSTALL += $(MANPAGES_3_GROFF_PMEMSET) MANPAGES_1_NOINSTALL += $(MANPAGES_1_GROFF_PMEMSET) endif MANPAGES_7_MD_WEB = $(MANPAGES_7_MD_PMEM2) + $(MANPAGES_7_MD_PMEMSET) + $(MANPAGES_7_MD) MANPAGES_5_MD_WEB = $(MANPAGES_5_MD_PMEM2) + $(MANPAGES_5_MD_PMEMSET) + $(MANPAGES_5_MD) MANPAGES_3_MD_WEB = $(MANPAGES_3_MD_PMEM2) + $(MANPAGES_3_MD_PMEMSET) + $(MANPAGES_3_MD) MANPAGES_1_MD_WEB = $(MANPAGES_1_MD_PMEM2) + $(MANPAGES_1_MD_PMEMSET) + $(MANPAGES_1_MD) MANPAGES = $(MANPAGES_7_GROFF) $(MANPAGES_5_GROFF) $(MANPAGES_3_GROFF) $(MANPAGES_1_GROFF) \ $(MANPAGES_7_NOINSTALL) $(MANPAGES_5_NOINSTALL) $(MANPAGES_3_NOINSTALL) $(MANPAGES_1_NOINSTALL) HTMLFILES = $(MANPAGES:=.html) TXTFILES = $(MANPAGES:=.txt) GZFILES_7 = $(MANPAGES_7_GROFF:=.gz) GZFILES_5 = $(MANPAGES_5_GROFF:=.gz) GZFILES_3 = $(MANPAGES_3_GROFF:=.gz) GZFILES_1 = $(MANPAGES_1_GROFF:=.gz) GZFILES_7_NOINSTALL = $(MANPAGES_7_NOINSTALL:=.gz) GZFILES_5_NOINSTALL = $(MANPAGES_5_NOINSTALL:=.gz) GZFILES_3_NOINSTALL = $(MANPAGES_3_NOINSTALL:=.gz) GZFILES_1_NOINSTALL = $(MANPAGES_1_NOINSTALL:=.gz) GZFILES_3_DUMMY = $(MANPAGES_3_DUMMY:=.gz) GZFILES = $(GZFILES_7) $(GZFILES_5) $(GZFILES_3) $(GZFILES_1) \ $(GZFILES_7_NOINSTALL) $(GZFILES_5_NOINSTALL) $(GZFILES_3_NOINSTALL) $(GZFILES_1_NOINSTALL) \ $(GZFILES_3_DUMMY) MANPAGES_DESTDIR_7 = $(DESTDIR)$(man7dir) MANPAGES_DESTDIR_5 = $(DESTDIR)$(man5dir) MANPAGES_DESTDIR_3 = $(DESTDIR)$(man3dir) MANPAGES_DESTDIR_1 = $(DESTDIR)$(man1dir) DOCS_DESTDIR = $(DESTDIR)$(docdir) txt: $(TXTFILES) all: | $(MANPAGES) $(MANPAGES_WEBDIR_LINUX) $(MANPAGES_WEBDIR_WINDOWS): $(MKDIR) -p $@ %.1: %.1.md ../utils/md2man.sh $< default.man $@ %.3: %.3.md ../utils/md2man.sh $< default.man $@ %.5: %.5.md ../utils/md2man.sh $< default.man $@ %.7: %.7.md ../utils/md2man.sh $< default.man $@ %.txt: % man ./$< > $@ %.gz: % gzip -nc ./$* > $@ %.html: % groff -mandoc -Thtml ./$< > $@ html: $(HTMLFILES) web: $(MANPAGES) | $(MANPAGES_WEBDIR_LINUX) $(MANPAGES_WEBDIR_WINDOWS) $(MAKE) -C generated all $(foreach f, $(MANPAGES_7_MD_WEB), WEB=1 WIN32="" ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_LINUX)/$(f);) $(foreach f, $(MANPAGES_5_MD_WEB), WEB=1 WIN32="" ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_LINUX)/$(f);) $(foreach f, $(MANPAGES_3_MD_WEB), WEB=1 WIN32="" ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_LINUX)/$(f);) $(foreach f, $(MANPAGES_1_MD_WEB), WEB=1 WIN32="" ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_LINUX)/$(f);) $(foreach f, $(MANPAGES_7_MD_WEB), WEB=1 WIN32=1 ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_WINDOWS)/$(f);) $(foreach f, $(MANPAGES_5_MD_WEB), WEB=1 WIN32=1 ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_WINDOWS)/$(f);) $(foreach f, $(MANPAGES_3_MD_WEB), WEB=1 WIN32=1 ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_WINDOWS)/$(f);) $(foreach f, $(MANPAGES_1_MD_WEB), WEB=1 WIN32=1 ../utils/md2man.sh $(f) default.man $(MANPAGES_WEBDIR_WINDOWS)/$(f);) compress: $(GZFILES) clean: clobber: clean $(RM) $(TXTFILES) $(HTMLFILES) $(GZFILES) $(MANPAGES) $(RM) -r $(MANPAGES_WEBDIR_LINUX) \ $(MANPAGES_WEBDIR_WINDOWS) install: compress install -d -v $(MANPAGES_DESTDIR_7) install -p -m 0644 $(GZFILES_7) $(MANPAGES_DESTDIR_7) install -d -v $(MANPAGES_DESTDIR_5) install -p -m 0644 $(GZFILES_5) $(MANPAGES_DESTDIR_5) install -d -v $(MANPAGES_DESTDIR_3) install -p -m 0644 $(GZFILES_3) $(GZFILES_3_DUMMY) $(MANPAGES_DESTDIR_3) install -d -v $(MANPAGES_DESTDIR_1) install -p -m 0644 $(GZFILES_1) $(MANPAGES_DESTDIR_1) uninstall: $(foreach f, $(notdir $(GZFILES_7)), $(RM) $(MANPAGES_DESTDIR_7)/$(f)) $(foreach f, $(notdir $(GZFILES_5)), $(RM) $(MANPAGES_DESTDIR_5)/$(f)) $(foreach f, $(notdir $(GZFILES_3) $(GZFILES_3_DUMMY)), $(RM) $(MANPAGES_DESTDIR_3)/$(f)) $(foreach f, $(notdir $(GZFILES_1)), $(RM) $(MANPAGES_DESTDIR_1)/$(f)) FORCE: .PHONY: all html clean compress clobber cstyle install uninstall pmdk-1.11.1/doc/libvmmalloc/0000775000000000000000000000000014123364546014304 5ustar rootrootpmdk-1.11.1/doc/libvmmalloc/README.md0000664000000000000000000000012614123364546015562 0ustar rootrootThis library has been moved to a [separate repository](https://github.com/pmem/vmem). pmdk-1.11.1/doc/rpmemd/0000775000000000000000000000000014123364745013270 5ustar rootrootpmdk-1.11.1/doc/rpmemd/rpmemd.1.md0000664000000000000000000001502614123364546015240 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(RPMEMD, 1) collection: rpmemd header: PMDK date: rpmemd version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (rpmemd.1.md -- man page for rpmemd) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[OPTIONS](#options)
[CONFIGURATION FILES](#configuration-files)
[EXAMPLE](#example)
[DEFAULT CONFIGURATION](#default-configuration)
[PERSISTENCY METHODS](#persistency-methods)
[SEE ALSO](#see-also)
# NAME # **rpmemd** - librpmem target node process (EXPERIMENTAL) # SYNOPSIS # ``` $ rpmemd [--help] [--version] [] ``` # DESCRIPTION # The **rpmemd** process is executed on target node by **librpmem**(7) library over **ssh**(1) and facilitates access to persistent memory over RDMA. The **rpmemd** should not be run manually under normal conditions. # OPTIONS # Command line options overwrite the default **rpmemd** configuration, the global configuration file and the user configuration file. `-V, --version` Displays **rpmemd** version and exits. `-h, --help` Prints synopsis and list of parameters and exits. `-c, --config ` Custom configuration file location. If the custom configuration file is provided others are omitted. See **CONFIGURATION FILES** section for details. All options described in **CONFIGURATION FILES** section are common for both the configuration file and the command line - the equivalent of the following line in the config file: `option = value` is `--option value` in the command line. The following command line options: **--persist-apm**, **--persist-general** and **--use-syslog** should not be followed by any value. Presence of each of them in the command line turns on an appropriate option. See **CONFIGURATION FILES** section for details. `-r, --remove ` Remove a pool described by given pool set file descriptor. It is interpreted as a path to the pool set file relative to the pool set directory. `-f, --force` Ignore errors when removing a pool file using **--remove** option. # CONFIGURATION FILES # The **rpmemd** searches for the configuration files with following priorities: + The global configuration file located in **/etc/rpmemd/rpmemd.conf**. + The user configuration file located in the user home directory (**$HOME/.rpmemd.conf**). The **rpmemd** can also read configuration from the custom configuration file provided using **--config** command line option. See **OPTIONS** section for details. The default configuration is described in the **DEFAULT CONFIGURATION** section. The configuration file is a plain text file. Each line of the configuration file can store only one configuration option defined as a *key=value* pair. Empty lines and lines starting with *#* are omitted. The allowed options are: + `log-file = ` - log file location + `poolset-dir = ` - pool set files directory + `persist-apm = {yes|no}` - enable **The Appliance Persistency Method**. This option must be set only if the target platform has non-allocating writes IO enabled. See **PERSISTENCY METHODS** section for details. + `persist-general = {yes|no}` - enable **The General Purpose Server Persistency Method**. See **PERSISTENCY METHODS** section for details. + `use-syslog = {yes|no}` - use **syslog**(3) for logging messages instead of log file + `log-level = ` - set log level value. Accepted *\* values are: + **err** - error conditions + **warn** - warning conditions + **notice** - normal, but significant conditions + **info** - informational message + **debug** - debug-level message The **$HOME** sub-string in the *poolset-dir* path is replaced with the current user home directory. # EXAMPLE # Example of the configuration file: ``` # This is an example of configuration file log-file = $HOME/.logs/rpmemd.log poolset-dir = $HOME/poolsets/ persist-apm = yes persist-general = no use-syslog = no # Use log file instead of syslog log-level = info ``` # DEFAULT CONFIGURATION # The **rpmemd** default configuration is equivalent of the following configuration file: ``` log-file = /var/log/rpmemd.log poolset-dir = $HOME persist-apm = no persist-general = yes use-syslog = yes log-level = err ``` # PERSISTENCY METHODS # The **librpmem**(7) supports two methods for making data written to remote persistent memory durable. The difference between the use of the two mechanisms is based on whether **librpmem**(7) will make use of non-allocating writes on the remote node. + **The General Purpose Server Persistency Method** does not have any requirements for the platform on which the target daemon runs and can be enabled by administrator using the *persist-general* option. This method utilize **libpmem**(7) persistency mechanisms on remote node and requires additional communication between initiator and remote node using the in-band connection. + **The Appliance Persistency Method** requires non-allocating writes enabled on the platform and can be enabled by administrator using *persist-apm* option. This method requires to issue an RDMA READ operation after the RDMA WRITE operations performed on requested chunk of memory. "Non-allocating write requests" is the Intel Integrated IO Controller mode where all incoming PCIe writes will utilize non-allocating buffers for the write requests. Non-allocating writes are guaranteed to bypass all of the CPU caches and force the write requests to flow directly to the Integrated Memory Controller without delay. The **rpmemd** dynamically choose the appropriate persistency method and the flushing to persistence primitive for GPSPM for each opened pool set name depending on available persistency methods and whether all pool set parts are stored in the persistent memory. If the **Appliance Persistency Method** is enabled and the pool set is stored in the persistent memory **rpmemd** will use the **Appliance Persistency Method**. If the pool set is NOT stored in the persistent memory it will fallback to the **General Puropose Server Persistency Method** with **pmem_msync**(3). If the **General Puropose Server Persistency Method** is enabled and the pool set is stored in the persistent memory **rpmemd** will use **pmem_persist**(3). If the pool set is NOT stored in the persistent momory it will use **pmem_msync**(3). See **pmem_persist**(3) and **pmem_msync**(3) for more details. # SEE ALSO # **ssh**(1), **pmem_msync**(3), **pmem_persist**(3), **syslog**(3), **libpmem**(7), **libpmemobj**(7), **librpmem**(7) and **** pmdk-1.11.1/doc/rpmemd/.gitignore0000664000000000000000000000001114123364546015247 0ustar rootrootrpmemd.1 pmdk-1.11.1/doc/rpmemd/rpmemd.10000664000000000000000000001573414123364745014650 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "RPMEMD" "1" "2021-09-24" "PMDK - rpmemd version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]rpmemd\f[] \- librpmem target node process (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] $\ rpmemd\ [\-\-help]\ [\-\-version]\ [] \f[] .fi .SH DESCRIPTION .PP The \f[B]rpmemd\f[] process is executed on target node by \f[B]librpmem\f[](7) library over \f[B]ssh\f[](1) and facilitates access to persistent memory over RDMA. The \f[B]rpmemd\f[] should not be run manually under normal conditions. .SH OPTIONS .PP Command line options overwrite the default \f[B]rpmemd\f[] configuration, the global configuration file and the user configuration file. .PP \f[C]\-V,\ \-\-version\f[] .PP Displays \f[B]rpmemd\f[] version and exits. .PP \f[C]\-h,\ \-\-help\f[] .PP Prints synopsis and list of parameters and exits. .PP \f[C]\-c,\ \-\-config\ \f[] .PP Custom configuration file location. If the custom configuration file is provided others are omitted. See \f[B]CONFIGURATION FILES\f[] section for details. .PP All options described in \f[B]CONFIGURATION FILES\f[] section are common for both the configuration file and the command line \- the equivalent of the following line in the config file: .PP \f[C]option\ =\ value\f[] .PP is .PP \f[C]\-\-option\ value\f[] .PP in the command line. .PP The following command line options: \f[B]\[en]persist\-apm\f[], \f[B]\[en]persist\-general\f[] and \f[B]\[en]use\-syslog\f[] should not be followed by any value. Presence of each of them in the command line turns on an appropriate option. See \f[B]CONFIGURATION FILES\f[] section for details. .PP \f[C]\-r,\ \-\-remove\ \f[] .PP Remove a pool described by given pool set file descriptor. It is interpreted as a path to the pool set file relative to the pool set directory. .PP \f[C]\-f,\ \-\-force\f[] .PP Ignore errors when removing a pool file using \f[B]\[en]remove\f[] option. .SH CONFIGURATION FILES .PP The \f[B]rpmemd\f[] searches for the configuration files with following priorities: .IP \[bu] 2 The global configuration file located in \f[B]/etc/rpmemd/rpmemd.conf\f[]. .IP \[bu] 2 The user configuration file located in the user home directory (\f[B]$HOME/.rpmemd.conf\f[]). .PP The \f[B]rpmemd\f[] can also read configuration from the custom configuration file provided using \f[B]\[en]config\f[] command line option. See \f[B]OPTIONS\f[] section for details. .PP The default configuration is described in the \f[B]DEFAULT CONFIGURATION\f[] section. .PP The configuration file is a plain text file. Each line of the configuration file can store only one configuration option defined as a \f[I]key=value\f[] pair. Empty lines and lines starting with \f[I]#\f[] are omitted. .PP The allowed options are: .IP \[bu] 2 \f[C]log\-file\ =\ \f[] \- log file location .IP \[bu] 2 \f[C]poolset\-dir\ =\ \f[] \- pool set files directory .IP \[bu] 2 \f[C]persist\-apm\ =\ {yes|no}\f[] \- enable \f[B]The Appliance Persistency Method\f[]. This option must be set only if the target platform has non\-allocating writes IO enabled. See \f[B]PERSISTENCY METHODS\f[] section for details. .IP \[bu] 2 \f[C]persist\-general\ =\ {yes|no}\f[] \- enable \f[B]The General Purpose Server Persistency Method\f[]. See \f[B]PERSISTENCY METHODS\f[] section for details. .IP \[bu] 2 \f[C]use\-syslog\ =\ {yes|no}\f[] \- use \f[B]syslog\f[](3) for logging messages instead of log file .IP \[bu] 2 \f[C]log\-level\ =\ \f[] \- set log level value. Accepted \f[I]\f[] values are: .RS 2 .IP \[bu] 2 \f[B]err\f[] \- error conditions .IP \[bu] 2 \f[B]warn\f[] \- warning conditions .IP \[bu] 2 \f[B]notice\f[] \- normal, but significant conditions .IP \[bu] 2 \f[B]info\f[] \- informational message .IP \[bu] 2 \f[B]debug\f[] \- debug\-level message .RE .PP The \f[B]$HOME\f[] sub\-string in the \f[I]poolset\-dir\f[] path is replaced with the current user home directory. .SH EXAMPLE .PP Example of the configuration file: .IP .nf \f[C] #\ This\ is\ an\ example\ of\ configuration\ file log\-file\ =\ $HOME/.logs/rpmemd.log poolset\-dir\ =\ $HOME/poolsets/ persist\-apm\ =\ yes persist\-general\ =\ no use\-syslog\ =\ no\ #\ Use\ log\ file\ instead\ of\ syslog log\-level\ =\ info \f[] .fi .SH DEFAULT CONFIGURATION .PP The \f[B]rpmemd\f[] default configuration is equivalent of the following configuration file: .IP .nf \f[C] log\-file\ =\ /var/log/rpmemd.log poolset\-dir\ =\ $HOME persist\-apm\ =\ no persist\-general\ =\ yes use\-syslog\ =\ yes log\-level\ =\ err \f[] .fi .SH PERSISTENCY METHODS .PP The \f[B]librpmem\f[](7) supports two methods for making data written to remote persistent memory durable. The difference between the use of the two mechanisms is based on whether \f[B]librpmem\f[](7) will make use of non\-allocating writes on the remote node. .IP \[bu] 2 \f[B]The General Purpose Server Persistency Method\f[] does not have any requirements for the platform on which the target daemon runs and can be enabled by administrator using the \f[I]persist\-general\f[] option. This method utilize \f[B]libpmem\f[](7) persistency mechanisms on remote node and requires additional communication between initiator and remote node using the in\-band connection. .IP \[bu] 2 \f[B]The Appliance Persistency Method\f[] requires non\-allocating writes enabled on the platform and can be enabled by administrator using \f[I]persist\-apm\f[] option. This method requires to issue an RDMA READ operation after the RDMA WRITE operations performed on requested chunk of memory. .PP \[lq]Non\-allocating write requests\[rq] is the Intel Integrated IO Controller mode where all incoming PCIe writes will utilize non\-allocating buffers for the write requests. Non\-allocating writes are guaranteed to bypass all of the CPU caches and force the write requests to flow directly to the Integrated Memory Controller without delay. .PP The \f[B]rpmemd\f[] dynamically choose the appropriate persistency method and the flushing to persistence primitive for GPSPM for each opened pool set name depending on available persistency methods and whether all pool set parts are stored in the persistent memory. .PP If the \f[B]Appliance Persistency Method\f[] is enabled and the pool set is stored in the persistent memory \f[B]rpmemd\f[] will use the \f[B]Appliance Persistency Method\f[]. If the pool set is NOT stored in the persistent memory it will fallback to the \f[B]General Puropose Server Persistency Method\f[] with \f[B]pmem_msync\f[](3). .PP If the \f[B]General Puropose Server Persistency Method\f[] is enabled and the pool set is stored in the persistent memory \f[B]rpmemd\f[] will use \f[B]pmem_persist\f[](3). If the pool set is NOT stored in the persistent momory it will use \f[B]pmem_msync\f[](3). .PP See \f[B]pmem_persist\f[](3) and \f[B]pmem_msync\f[](3) for more details. .SH SEE ALSO .PP \f[B]ssh\f[](1), \f[B]pmem_msync\f[](3), \f[B]pmem_persist\f[](3), \f[B]syslog\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemobj\f[](7), \f[B]librpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/default.man0000664000000000000000000000112214123364546014120 0ustar rootroot$if(has-tables)$ .\"t $endif$ $if(pandoc-version)$ .\" Automatically generated by Pandoc $pandoc-version$ .\" $endif$ $if(adjusting)$ .ad $adjusting$ $endif$ .TH "$title$" "$section$" "$date$" "PMDK - $version$" "PMDK Programmer's Manual" $if(hyphenate)$ .hy $else$ .nh \" Turn off hyphenation by default. $endif$ $for(header-includes)$ $header-includes$ $endfor$ .\" SPDX-License-Identifier: BSD-3-Clause .\" $copyright$ $for(include-before)$ $include-before$ $endfor$ $body$ $for(include-after)$ $include-after$ $endfor$ $if(author)$ .SH AUTHORS $for(author)$$author$$sep$; $endfor$. $endif$ pmdk-1.11.1/doc/.gitignore0000664000000000000000000000006214123364546013771 0ustar rootroot*.txt *.html *.gz LICENSE web_linux/ web_windows/ pmdk-1.11.1/doc/pmempool/0000775000000000000000000000000014123364745013634 5ustar rootrootpmdk-1.11.1/doc/pmempool/pmempool-create.1.md0000664000000000000000000000750114123364546017410 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-CREATE, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2019, Intel Corporation) [comment]: <> (pmempool-create.1 -- man page for pmempool-create) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-create** - create a persistent memory pool # SYNOPSIS # ``` $ pmempool create [] [] [] ``` # DESCRIPTION # The **pmempool** invoked with *create* command creates a pool file of specified type. Depending on a pool type it is possible to provide more properties of pool. Valid pool types are: **blk**, **log** and **obj** which stands for *pmemblk*, *pmemlog* and *pmemobj* pools respectively. By default the pool file is created with *minimum* allowed size for specified pool type. The minimum sizes for **blk**, **log** and **obj** pool types are **PMEMBLK_MIN_POOL**, **PMEMLOG_MIN_POOL** and **PMEMOBJ_MIN_POOL** respectively. See **libpmemblk**(7), **libpmemlog**(7) and **libpmemobj**(7) for details. For *pmemblk* pool type block size *\* is a required argument. In order to set custom size of pool use **-s** option, or use **-M** option to create a pool of maximum available size on underlying file system. The *size* argument may be passed in format that permits only the upper-case character for byte - B as specified in IEC 80000-13, IEEE 1541 and the Metric Interchange Format. Standards accept SI units with obligatory B - kB, MB, GB, ... which means multiplier by 1000 and IEC units with optional "iB" - KiB, MiB, GiB, ..., K, M, G, ... - which means multiplier by 1024. ##### Available options: ##### `-s, --size ` Size of pool file. `-M, --max-size` Set size of pool to available space of underlying file system. `-m, --mode ` Set permissions to (the default is 0664) when creating the files. If the file already exist the permissions are not changed. `-i, --inherit ` Create a new pool of the same size and other properties as *\*. `-b, --clear-bad-blocks` Clear bad blocks in existing files. `-f, --force` Remove the pool before creating. `-v, --verbose` Increase verbosity level. `-h, --help` Display help message and exit. ##### Options for PMEMBLK: ##### By default when creating a pmem **blk** pool, the **BTT** layout is *not* written until the first *write operation* of block entry is performed. Using **-w** option you can force writing the **BTT** layout by writing zero data to specified block number. By default the *write operation* is performed to block number 0. Please refer to **libpmemblk**(7) for details. `-w, --write-layout` Force writing the **BTT** layout by performing *write operation* to block number zero. ##### Options for PMEMOBJ: ##### By default when creating a pmem **obj** pool, the layout name provided to the **libpmemobj** library is an empty string. Please refer to **libpmemobj**(7) for details. `-l, --layout ` Layout name of the **pmemobj** pool. # EXAMPLE # ``` $ pmempool create blk 512 pool.blk ``` Create a blk pool file of minimum allowed size and block size 512 bytes ``` $ pmempool create log -M pool.log ``` Create a log pool file of maximum allowed size ``` $ pmempool create blk --size=4G --write-layout 1K pool.blk ``` Create a blk pool file of size 4G, block size 1K and write the BTT layout ``` $ pmempool create --layout my_layout obj pool.obj ``` Create an obj pool file of minimum allowed size and layout "my_layout" ``` $ pmempool create --inherit=pool.log new_pool.log ``` Create a pool file based on pool.log file # SEE ALSO # **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-convert.10000664000000000000000000000111214123364745017217 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-CONVERT" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-convert\f[] \- this is a wrapper around pmdk\-convert tool. More information can be found in \f[B]pmdk\-convert\f[](1) man page. .SH SEE ALSO .PP \f[B]pmdk\-convert\f[](1), \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7), \f[B]libpmempool\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-info.1.md0000664000000000000000000002724214123364546017104 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-INFO, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-info.1 -- man page for pmempool-info) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RANGE](#range)
[STATISTICS](#statistics)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-info** - show information about persistent memory pool # SYNOPSIS # ``` $ pmempool info [] ``` # DESCRIPTION # The **pmempool** invoked with *info* command analyzes an existing pool created by **PMDK** libraries provided by **file** parameter. The **file** can be either existing pool file, a part file or a poolset file. The main task of this command is to print all usable information from pool headers and user data in human readable format. It automatically recognizes the pool type by parsing and analyzing the pool header. The recognition is done by checking the signature in the pool header. The main job of *info* command is to present internal data structures as they are stored in file but *not* for checking consistency. For this purpose there is the **pmempool-check**(1) command available. The **pmempool** with *info* command analyzes pool file as long as it is possible regarding *correctness* of internal meta-data (correct offsets, sizes etc.). If it is *not* possible to analyze the rest of the file, **pmempool** exits with error code and prints appropriate error message. Currently there is lack of interprocess synchronization for pool files, so the *info* command should be invoked off-line. Using **pmempool** on pool file which may be modified by another process may lead to unexpected errors in pool file. A poolset file passed to **pmempool info** may contain multiple replicas, also remote ones, but **pmempool** currently does not read any data from remote replicas. It prints only a remote node address and a remote replica descriptor. **pmempool info** opens pool file in *read-only* mode so the file will remain untouched after processing. The *info* command may collect and print basic statistics about data usage. The statistics are specific to the type of pool. See **STATISTICS** section for details. Although the pool consistency is *not* checked by the *info* command, it prints information about checksum errors and/or offsets errors. ##### Common options: ##### By default the *info* command of **pmempool** prints information about the most important internal data structures from pool. The particular set of headers and meta-data depend on pool type. The pool type is recognized automatically and appropriate information is displayed in human-readable format. To force processing specified file(s) as desired pool type use **-f** option with appropriate name of pool type. The valid names off pool types are **blk**, **log**, **obj** or **btt**. This option may be useful when the pool header is corrupted and automatic recognition of pool type fails. `-f, --force blk|log|obj|btt` Force parsing pool as specified pool type. >NOTE: By default only pool headers and internal meta-data are displayed. To display user data use **-d** option. Using **-r** option you can specify number of blocks/bytes/data chunks or objects using special text format. See **RANGE** section for details. The range refers to *block numbers* in case of pmem blk pool type, to *chunk numbers* in case of pmem log pool type and to *object numbers* in case of pmem obj pool type. See **EXAMPLES** section for an example of usage of these options. `-d, --data` Dump user data in hexadecimal format. In case of pmem *blk* pool type data is dumped in *blocks*. In case of pmem *log* pool type data is dumped as a wholeor in *chunks* if **-w** option is used (See **Options for PMEMLOG** section for details). `-r, --range ` Range of blocks/data chunks/objects/zone headers/chunk headers/lanes. See **RANGE** section for details about range format. `-n, --human` Print sizes in human-readable format with appropriate units (e.g. 4k, 8M, 16G) `-x, --headers-hex` Print pool's internal data in mixed format which consists of hexadecimal dump of header's data and parsed format displayed in human-readable format. This allows one to see how data is stored in file. `-s, --stats` Print pool's statistics. See **STATISTICS** section for details. `-k, --bad-blocks=` Print bad blocks found in the pool. `-h, --help` Display help message and exit. ##### Options for PMEMLOG: ##### `-w, --walk ` Use this option to walk through used data with fixed data chunk size. See **pmemlog_walk**(3) in **libpmemlog**(7) for details. ##### Options for PMEMBLK: ##### By default the *info* command displays the **pmemblk** header and BTT (Block Translation Table) Info header in case of **pmemblk** pool type. To display BTT Map and/or BTT FLOG (Free List and Log) use **-m** and **-g** options respectively or increase verbosity level. In order to display BTT Info header backup use **-B** option. `-m, --map` Print BTT Map entries. `-g, --flog` Print BTT FLOG entries. `-B, --backup` Print BTT Info header backup. >NOTE: By default the *info* command displays all data blocks when **-d** options is used. However it is possible to skip blocks marked with *zero* and/or *error* flags. It is also possible to skip blocks which are *not* marked with any flag. Skipping blocks has impact on blocks ranges (e.g. display 10 blocks marked with error flag in the range from 0 to 10000) and statistics. `-z, --skip-zeros` Skip blocks marked with *zero* flag. `-e, --skip-error` Skip blocks marked with *error* flag. `-u, --skip-no-flag` Skip blocks *not* marked with any flag. ##### Options for PMEMOBJ: ##### By default the *info* command displays pool header and **pmemobj** pool descriptor. In order to print information about other data structures one of the following options may be used. `-l, --lanes []` Print information about lanes. If range is not specified all lanes are displayed. The range can be specified using **-r** option right after the **-l** option. See **RANGE** section for details about range format. `-R, --recovery` Print information about only those lanes which require recovery process. This option requires **-l**, **--lanes** option. `-O, --object-store` Print information about all allocated objects. `-t, --types ` Print information about allocated objects only from specified range of type numbers. If **-s**, **--stats** option is specified the objects statistics refer to objects from specified range of type numbers. This option requires **-O**, **--object-store** or **-s**, **--stats** options. See **RANGE** section for details about range format. `-E, --no-empty` Ignore empty lists of objects. This option requires **-O**, **--object-store** option. `-o, --root` Print information about a root object. `-A, --alloc-header` Print object's allocation header. This option requires **-O**, **--object-store** or **-l**, **--lanes** or **-o**, **--root** options. `-a, --oob-header` Print object's out of band header. This option requires **-O**, **--object-store** or **-l**, **--lanes** or **-o**, **--root** options. `-H, --heap` Print information about **pmemobj** heap. By default only a heap header is displayed. `-Z, --zones` If the **-H**, **--heap** option is used, print information about zones from specified range. If the **-O**, **--object-store** option is used, print information about objects only from specified range of zones. This option requires **-O**, **--object-store**, **-H**, **--heap** or **-s**, **--stats** options. The range can be specified using **-r** option right after the **-Z** option. See **RANGE** section for details about range format. `-C, --chunks []` If the **-H, --heap** option is used, print information about chunks from specified range. By default information about chunks of types *used* , *free* and *run* are displayed. If the **-O, --object-store** option is used, print information about objects from specified range of chunks within a zone. This option requires **-O, --object-store**, **-H, --heap** or **-s, --stats** options. The range can be specified using **-r** option right after the **-C** option. See **RANGE** section for details about range format. `-T, --chunk-type used,free,run,footer` Print only specified type(s) of chunks. The multiple types may be specified separated by comma. This option requires **-H, --heap** and **-C, --chunks** options. `-b, --bitmap` Print bitmap of used blocks in chunks of type run. This option requires **-H, --heap** and **-C, --chunks** options. `-p, --replica ` Print information from *\* replica. The 0 value means the master pool file. # RANGE # Using **-r, --range** option it is possible to dump only a range of user data. This section describes valid format of *\* string. You can specify multiple ranges separated by commas. `-` All blocks/bytes/data chunks from *\* to *\* will be dumped. `-` All blocks/bytes/data chunks up to *\* will be dumped. `-` All blocks/bytes/data chunks starting from *\* will be dumped. `` Only *\* block/byte/data chunk will be dumped. # STATISTICS # Below is the description of statistical measures for specific pool types. ##### PMEMLOG ##### + **Total** - Total space in pool. + **Available** - Size and percentage of available space. + **Used** - Size and percentage of used space. ##### PMEMBLK ##### + **Total blocks** - Total number of blocks in pool. + **Zeroed blocks** - Number and percentage of blocks marked with *zero* flag. + **Error blocks** - Number and percentage of blocks marked with *error* flag. + **Blocks without any flag** - Number and percentage of blocks *not* marked with any flag. >NOTE: In case of pmemblk, statistics are evaluated for blocks which meet requirements regarding: *range* of blocks (**-r** option), *skipped* types of blocks (**-z**, **-e**, **-u** options). ##### PMEMOBJ ##### + **Object store** + **Number of objects** - Total number of objects and number of objects per type number. + **Number of bytes** - Total number of bytes and number of bytes per type number. + **Heap** + **Number of zones** - Total number of zones in the pool. + **Number of used zones** - Number of used zones in the pool. + **Zone** The zone's statistics are presented for each zone separately and the aggregated results from all zones. + **Number of chunks** - Total number of chunks in the zone and number of chunks of specified type. + **Chunks size** - Total size of all chunks in the zone and sum of sizes of chunks of specified type. + **Allocation classes** + **Units** - Total number of units of specified class. + **Used units** - Number of used units of specified class. + **Bytes** - Total number of bytes of specified class. + **Used bytes** - Number of used bytes of specified class. + **Total bytes** - Total number of bytes of all classes. + **Total used bytes** - Total number of used bytes of all classes. # EXAMPLE # ``` $ pmempool info ./pmemblk ``` Parse and print information about "pmemblk" pool file. ``` $ pmempool info -f blk ./pmempool ``` Force parsing "pmempool" file as **pmemblk** pool type. ``` $ pmempool info -d ./pmemlog ``` Print information and data in hexadecimal dump format for file "pmemlog". ``` $ pmempool info -d -r10-100 -eu ./pmemblk ``` Print information from "pmemblk" file. Dump data blocks from 10 to 100, skip blocks marked with error flag and not marked with any flag. # SEE ALSO # **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-feature.1.md0000664000000000000000000000604414123364546017601 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-FEATURE, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018, Intel Corporation) [comment]: <> (pmempool-feature.1 -- man page for pmempool-feature) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[COMPATIBILITY](#compatibility)
[DISCLAIMER](#disclaimer)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-feature** - toggle or query pool set features # SYNOPSIS # ``` $ pmempool feature (-e|-d|-q feature-name) [options] ``` # DESCRIPTION # The **pmempool feature** command enables / disables or queries pool set features. Available pool *feature-names* are: + **SINGLEHDR** - only the first part in each replica contains the pool part internal metadata. This value can be used only with **-q**. It can not be enabled or disabled. For details see **poolset**(5). + **CHECKSUM_2K** - only the first 2KiB of pool part internal metadata is checksummed. Other features may depend on this one to store additional metadata in otherwise unused second 2KiB part of a header. When **CHECKSUM_2K** is disabled whole 4KiB is checksummed. + **SHUTDOWN_STATE** - enables additional check performed during pool open which verifies pool consistency in the presence of dirty shutdown. **CHECKSUM_2K** has to be enabled prior to **SHUTDOWN_STATE** otherwise enabling **SHUTDOWN_STATE** will fail. + **CHECK_BAD_BLOCKS** - enables checking bad blocks performed during opening a pool and fixing bad blocks performed by pmempool-sync during syncing a pool. Currently (Linux kernel v4.19, libndctl v62) checking and fixing bad blocks require read access to the following resource files (containing physical addresses) of NVDIMM devices which only root can read by default: ``` /sys/bus/nd/devices/ndbus*/region*/resource /sys/bus/nd/devices/ndbus*/region*/dax*/resource /sys/bus/nd/devices/ndbus*/region*/pfn*/resource /sys/bus/nd/devices/ndbus*/region*/namespace*/resource ``` It is possible to use poolset as *file* argument. But poolsets with remote replicas are not supported. ##### Available options: ##### `-h, --help` Print help message. `-v, --verbose` Increase verbosity level. `-e, --enable feature-name` Enable feature for pool set. `-d, --disable feature-name` Disable feature for pool set. `-q, --query feature-name` Print feature status. # COMPATIBILITY # Poolsets with features not defined in this document (e.g. enabled by the newer software version) are not supported. # DISCLAIMER # ```pmempool feature``` command is not fail safe. # EXAMPLE # ``` $ pmempool feature --enable CHECKSUM_2K pool.set ``` Enables POOL_FEAT_CKSUM_2K incompat feature flag. ``` $ pmempool feature --disable CHECKSUM_2K pool.set ``` Disables POOL_FEAT_CKSUM_2K incompat feature flag. ``` $ pmempool feature --query CHECKSUM_2K pool.set 0 ``` Prints POOL_FEAT_CKSUM_2K incompat feature flag value. # SEE ALSO # **poolset**(5) and **** pmdk-1.11.1/doc/pmempool/pmempool-dump.1.md0000664000000000000000000000502414123364546017110 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-DUMP, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-dump.1 -- man page for pmempool-dump) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RANGE](#range)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-dump** - dump user data from persistent memory pool # SYNOPSIS # ``` $ pmempool dump [] ``` # DESCRIPTION # The **pmempool** invoked with *dump* command dumps user data from specified pool file. The output format may be either binary or hexadecimal. By default the output format is hexadecimal. By default data is dumped to standard output. It is possible to dump data to other file by specifying **-o** option. In this case data will be appended to this file. Using **-r** option you can specify number of blocks/bytes/data chunks using special text format. See **RANGE** section for details. ##### Available options: ##### `-b, --binary` Dump data in binary format. `-r, --range ` Range of pool file to dump. This may be number of blocks for **blk** pool type or either number of bytes or number of data chunks for **log** pool type. `-c, --chunk ` Size of chunk for **log** pool type. See **pmemlog_walk**(3) in **libpmemlog**(7) for details. `-o, --output ` Name of output file. `-h, --help` Display help message and exit. # RANGE # Using **-r**, **--range** option it is possible to dump only a range of user data. This section describes valid format of *\* string. You can specify multiple ranges separated by commas. `-` All blocks/bytes/data chunks from *\* to *\* will be dumped. `-` All blocks/bytes/data chunks up to *\* will be dumped. `-` All blocks/bytes/data chunks starting from *\* will be dumped. `` Only *\* block/byte/data chunk will be dumped. # EXAMPLE # ``` $ pmempool dump pool.bin ``` Dump user data from pool.bin file to standard output ``` $ pmempool dump -o output.bin -r1,10-100 pool_blk.bin ``` Dump block number 1 and blocks from 10 to 100 from pool_blk.bin containing pmem blk pool to output.bin file ``` $ pmempool dump -r 1K-2K pool.bin ``` Dump data form 1K to 2K from pool.bin file. # SEE ALSO # **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-transform.1.md0000664000000000000000000001163014123364546020156 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-TRANSFORM, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-transform.1 -- man page for pmempool-transform) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLES](#examples)
[SEE ALSO](#see-also)
# NAME # **pmempool-transform** - Modify internal structure of a pool set. # SYNOPSIS # ``` pmempool transform [options] ``` # DESCRIPTION # The **pmempool transform** command modifies internal structure of a pool set defined by the `poolset_file_src` file, according to a structure described in the `poolset_file_dst` file. The following operations are supported: * adding replicas - one or more new replicas can be added and synchronized with other replicas in the pool set, * removing replicas - one or more replicas can be removed from the pool set _WINUX(.,=q=, * adding or removing pool set options.=e=) Only one of the above operations can be performed at a time. Currently adding and removing replicas are allowed only for **pmemobj** pools (see **libpmemobj**(7)). The *poolset_file_src* argument provides the source pool set to be changed. The *poolset_file_dst* argument points to the target pool set. _WINUX(=q=When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. One cannot add and remove replicas in the same step. Only one of these operations can be performed at a time. Reordering replicas is not supported Also, to add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. Effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files.=e=) _WINUX(,=q=When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. When adding or removing pool set options (see **poolset**(5)), the rest of both pool set files have to be of the same structure. The operation of adding/removing a pool set option can be performed on a pool set with local replicas only. To add/remove a pool set option to/from a pool set with remote replicas, one has to remove the remote replicas first, then add/remove the option, and finally recreate the remote replicas having added/removed the pool set option to/from the remote replicas' poolset files. To add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. If none of the poolset options is used, the effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files. If the option *SINGLEHDR* is used, the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. In this case only the first part contains internal metadata. If the option *NOHDRS* is used, the effective size of a replica is the sum of sizes of all its part files. In this case none of the parts contains internal metadata.=e=) ##### Available options: ##### `-d, --dry-run` : Enable dry run mode. In this mode no changes are applied, only check for viability of the operation is performed. `-v, --verbose` : Increase verbosity level. `-h, --help` : Display help message and exit. # EXAMPLES # ##### Example 1. ##### Let files `/path/poolset_file_src` and `/path/poolset_file_dst` have the following contents: ``` PMEMPOOLSET 20M /0/partfile1 20M /0/partfile2 25M /0/partfile3 REPLICA 40M /1/partfile1 20M /1/partfile2 ``` ``` PMEMPOOLSET 20M /0/partfile1 20M /0/partfile2 25M /0/partfile3 REPLICA 40M /1/partfile1 20M /1/partfile2 REPLICA 50M /2/partfile1 20M /2/partfile2 ``` Then, the command `pmempool transform /path/poolset_file_src /path/poolset_file_dst` adds a replica to the pool set. All other replicas remain unchanged and the size of the pool remains 60M. ##### Example 2. ##### Let files `/path/poolset_file_src` and `/path/poolset_file_dst` have the following contents: ``` PMEMPOOLSET 20M /0/partfile1 20M /0/partfile2 25M /0/partfile3 REPLICA 40M /1/partfile1 20M /1/partfile2 ``` ``` PMEMPOOLSET 20M /0/partfile1 20M /0/partfile2 25M /0/partfile3 ``` Then `pmempool_transform /path/poolset_file_src /path/poolset_file_dst` deletes the second replica from the pool set. The first replica remains unchanged and the size of the pool is still 60M. # SEE ALSO # **pmempool(1)**, **libpmemblk(7)**, **libpmemlog(7)**, **libpmempool(7)** and **** pmdk-1.11.1/doc/pmempool/pmempool-sync.1.md0000664000000000000000000000647014123364546017125 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-SYNC, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-sync.1 -- man page for pmempool-sync) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLES](#examples)
[SEE ALSO](#see-also)
# NAME # **pmempool-sync** - Synchronize replicas or their parts within a pool set. # SYNOPSIS # ``` pmempool sync [options] ``` NOTE: Only the pool set file used to create the pool should be used for syncing the pool. # DESCRIPTION # The **pmempool sync** command synchronizes data between replicas within a pool set. It checks if metadata of all replicas in a pool set are consistent, i.e. all parts are healthy, and if any of them is not, the corrupted or missing parts are recreated and filled with data from one of the healthy replicas. Currently synchronizing data is allowed only for **pmemobj** pools (see **libpmemobj**(7)). _WINUX(,=q=If a pool set has the option *SINGLEHDR* or *NOHDRS* (see **poolset**(5)), **pmempool sync** command has limited capability of checking its metadata. This is due to limited or no, respectively, internal metadata at the beginning of pool set parts in every replica when either of the options is used. In that cases, only missing parts or the ones which cannot be opened are recreated.=e=) ##### Available options: ##### `-b, --bad-blocks` : Fix bad blocks - it causes creating or reading special recovery files. When bad blocks are detected, special recovery files have to be created in order to fix them safely. A separate recovery file is created for each part of the pool. The recovery files are created in the same directory where the poolset file is located using the following name pattern: \ _r \ _p \ _badblocks.txt These recovery files are automatically removed if the sync operation finishes successfully. If the last sync operation was interrupted and not finished correctly (eg. the application crashed) and the bad blocks fixing procedure was in progress, the bad block recovery files may be left over. In such case bad blocks might have been cleared and zeroed, but the correct data from these blocks was not recovered (not copied from a healthy replica), so the recovery files MUST NOT be deleted manually, because it would cause a data loss. Pmempool-sync should be run again with the '-b' option set. It will finish the previously interrupted sync operation and copy correct data to zeroed bad blocks using the left-over bad block recovery files (the bad blocks will be read from the saved recovery files). Pmempool will delete the recovery files automatically at the end of the sync operation. Using this option may have limitations depending on the operating system. For details see description of the CHECK_BAD_BLOCKS feature in **pmempool-feature**(1). `-d, --dry-run` : Enable dry run mode. In this mode no changes are applied, only check for viability of synchronization. `-v, --verbose` : Increase verbosity level. `-h, --help` : Display help message and exit. # SEE ALSO # **pmempool(1)**, **libpmemblk(7)**, **libpmemlog(7)**, **libpmempool(7)** and **** pmdk-1.11.1/doc/pmempool/pmempool-info.10000664000000000000000000003256714123364744016513 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-INFO" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-info\f[] \- show information about persistent memory pool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ info\ []\ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool\f[] invoked with \f[I]info\f[] command analyzes an existing pool created by \f[B]PMDK\f[] libraries provided by \f[B]file\f[] parameter. The \f[B]file\f[] can be either existing pool file, a part file or a poolset file. .PP The main task of this command is to print all usable information from pool headers and user data in human readable format. It automatically recognizes the pool type by parsing and analyzing the pool header. The recognition is done by checking the signature in the pool header. The main job of \f[I]info\f[] command is to present internal data structures as they are stored in file but \f[I]not\f[] for checking consistency. For this purpose there is the \f[B]pmempool\-check\f[](1) command available. .PP The \f[B]pmempool\f[] with \f[I]info\f[] command analyzes pool file as long as it is possible regarding \f[I]correctness\f[] of internal meta\-data (correct offsets, sizes etc.). If it is \f[I]not\f[] possible to analyze the rest of the file, \f[B]pmempool\f[] exits with error code and prints appropriate error message. .PP Currently there is lack of interprocess synchronization for pool files, so the \f[I]info\f[] command should be invoked off\-line. Using \f[B]pmempool\f[] on pool file which may be modified by another process may lead to unexpected errors in pool file. .PP A poolset file passed to \f[B]pmempool info\f[] may contain multiple replicas, also remote ones, but \f[B]pmempool\f[] currently does not read any data from remote replicas. It prints only a remote node address and a remote replica descriptor. .PP \f[B]pmempool info\f[] opens pool file in \f[I]read\-only\f[] mode so the file will remain untouched after processing. .PP The \f[I]info\f[] command may collect and print basic statistics about data usage. The statistics are specific to the type of pool. See \f[B]STATISTICS\f[] section for details. .PP Although the pool consistency is \f[I]not\f[] checked by the \f[I]info\f[] command, it prints information about checksum errors and/or offsets errors. .SS Common options: .PP By default the \f[I]info\f[] command of \f[B]pmempool\f[] prints information about the most important internal data structures from pool. The particular set of headers and meta\-data depend on pool type. The pool type is recognized automatically and appropriate information is displayed in human\-readable format. .PP To force processing specified file(s) as desired pool type use \f[B]\-f\f[] option with appropriate name of pool type. The valid names off pool types are \f[B]blk\f[], \f[B]log\f[], \f[B]obj\f[] or \f[B]btt\f[]. This option may be useful when the pool header is corrupted and automatic recognition of pool type fails. .PP \f[C]\-f,\ \-\-force\ blk|log|obj|btt\f[] .PP Force parsing pool as specified pool type. .RS .PP NOTE: By default only pool headers and internal meta\-data are displayed. To display user data use \f[B]\-d\f[] option. Using \f[B]\-r\f[] option you can specify number of blocks/bytes/data chunks or objects using special text format. See \f[B]RANGE\f[] section for details. The range refers to \f[I]block numbers\f[] in case of pmem blk pool type, to \f[I]chunk numbers\f[] in case of pmem log pool type and to \f[I]object numbers\f[] in case of pmem obj pool type. See \f[B]EXAMPLES\f[] section for an example of usage of these options. .RE .PP \f[C]\-d,\ \-\-data\f[] .PP Dump user data in hexadecimal format. In case of pmem \f[I]blk\f[] pool type data is dumped in \f[I]blocks\f[]. In case of pmem \f[I]log\f[] pool type data is dumped as a wholeor in \f[I]chunks\f[] if \f[B]\-w\f[] option is used (See \f[B]Options for PMEMLOG\f[] section for details). .PP \f[C]\-r,\ \-\-range\ \f[] .PP Range of blocks/data chunks/objects/zone headers/chunk headers/lanes. See \f[B]RANGE\f[] section for details about range format. .PP \f[C]\-n,\ \-\-human\f[] .PP Print sizes in human\-readable format with appropriate units (e.g.\ 4k, 8M, 16G) .PP \f[C]\-x,\ \-\-headers\-hex\f[] .PP Print pool's internal data in mixed format which consists of hexadecimal dump of header's data and parsed format displayed in human\-readable format. This allows one to see how data is stored in file. .PP \f[C]\-s,\ \-\-stats\f[] .PP Print pool's statistics. See \f[B]STATISTICS\f[] section for details. .PP \f[C]\-k,\ \-\-bad\-blocks=\f[] .PP Print bad blocks found in the pool. .PP \f[C]\-h,\ \-\-help\f[] .PP Display help message and exit. .SS Options for PMEMLOG: .PP \f[C]\-w,\ \-\-walk\ \f[] .PP Use this option to walk through used data with fixed data chunk size. See \f[B]pmemlog_walk\f[](3) in \f[B]libpmemlog\f[](7) for details. .SS Options for PMEMBLK: .PP By default the \f[I]info\f[] command displays the \f[B]pmemblk\f[] header and BTT (Block Translation Table) Info header in case of \f[B]pmemblk\f[] pool type. .PP To display BTT Map and/or BTT FLOG (Free List and Log) use \f[B]\-m\f[] and \f[B]\-g\f[] options respectively or increase verbosity level. .PP In order to display BTT Info header backup use \f[B]\-B\f[] option. .PP \f[C]\-m,\ \-\-map\f[] .PP Print BTT Map entries. .PP \f[C]\-g,\ \-\-flog\f[] .PP Print BTT FLOG entries. .PP \f[C]\-B,\ \-\-backup\f[] .PP Print BTT Info header backup. .RS .PP NOTE: By default the \f[I]info\f[] command displays all data blocks when \f[B]\-d\f[] options is used. However it is possible to skip blocks marked with \f[I]zero\f[] and/or \f[I]error\f[] flags. It is also possible to skip blocks which are \f[I]not\f[] marked with any flag. Skipping blocks has impact on blocks ranges (e.g.\ display 10 blocks marked with error flag in the range from 0 to 10000) and statistics. .RE .PP \f[C]\-z,\ \-\-skip\-zeros\f[] .PP Skip blocks marked with \f[I]zero\f[] flag. .PP \f[C]\-e,\ \-\-skip\-error\f[] .PP Skip blocks marked with \f[I]error\f[] flag. .PP \f[C]\-u,\ \-\-skip\-no\-flag\f[] .PP Skip blocks \f[I]not\f[] marked with any flag. .SS Options for PMEMOBJ: .PP By default the \f[I]info\f[] command displays pool header and \f[B]pmemobj\f[] pool descriptor. In order to print information about other data structures one of the following options may be used. .PP \f[C]\-l,\ \-\-lanes\ []\f[] .PP Print information about lanes. If range is not specified all lanes are displayed. The range can be specified using \f[B]\-r\f[] option right after the \f[B]\-l\f[] option. See \f[B]RANGE\f[] section for details about range format. .PP \f[C]\-R,\ \-\-recovery\f[] .PP Print information about only those lanes which require recovery process. This option requires \f[B]\-l\f[], \f[B]\[en]lanes\f[] option. .PP \f[C]\-O,\ \-\-object\-store\f[] .PP Print information about all allocated objects. .PP \f[C]\-t,\ \-\-types\ \f[] .PP Print information about allocated objects only from specified range of type numbers. If \f[B]\-s\f[], \f[B]\[en]stats\f[] option is specified the objects statistics refer to objects from specified range of type numbers. This option requires \f[B]\-O\f[], \f[B]\[en]object\-store\f[] or \f[B]\-s\f[], \f[B]\[en]stats\f[] options. See \f[B]RANGE\f[] section for details about range format. .PP \f[C]\-E,\ \-\-no\-empty\f[] .PP Ignore empty lists of objects. This option requires \f[B]\-O\f[], \f[B]\[en]object\-store\f[] option. .PP \f[C]\-o,\ \-\-root\f[] .PP Print information about a root object. .PP \f[C]\-A,\ \-\-alloc\-header\f[] .PP Print object's allocation header. This option requires \f[B]\-O\f[], \f[B]\[en]object\-store\f[] or \f[B]\-l\f[], \f[B]\[en]lanes\f[] or \f[B]\-o\f[], \f[B]\[en]root\f[] options. .PP \f[C]\-a,\ \-\-oob\-header\f[] .PP Print object's out of band header. This option requires \f[B]\-O\f[], \f[B]\[en]object\-store\f[] or \f[B]\-l\f[], \f[B]\[en]lanes\f[] or \f[B]\-o\f[], \f[B]\[en]root\f[] options. .PP \f[C]\-H,\ \-\-heap\f[] .PP Print information about \f[B]pmemobj\f[] heap. By default only a heap header is displayed. .PP \f[C]\-Z,\ \-\-zones\f[] .PP If the \f[B]\-H\f[], \f[B]\[en]heap\f[] option is used, print information about zones from specified range. If the \f[B]\-O\f[], \f[B]\[en]object\-store\f[] option is used, print information about objects only from specified range of zones. This option requires \f[B]\-O\f[], \f[B]\[en]object\-store\f[], \f[B]\-H\f[], \f[B]\[en]heap\f[] or \f[B]\-s\f[], \f[B]\[en]stats\f[] options. The range can be specified using \f[B]\-r\f[] option right after the \f[B]\-Z\f[] option. See \f[B]RANGE\f[] section for details about range format. .PP \f[C]\-C,\ \-\-chunks\ []\f[] .PP If the \f[B]\-H, \[en]heap\f[] option is used, print information about chunks from specified range. By default information about chunks of types \f[I]used\f[] , \f[I]free\f[] and \f[I]run\f[] are displayed. If the \f[B]\-O, \[en]object\-store\f[] option is used, print information about objects from specified range of chunks within a zone. This option requires \f[B]\-O, \[en]object\-store\f[], \f[B]\-H, \[en]heap\f[] or \f[B]\-s, \[en]stats\f[] options. The range can be specified using \f[B]\-r\f[] option right after the \f[B]\-C\f[] option. See \f[B]RANGE\f[] section for details about range format. .PP \f[C]\-T,\ \-\-chunk\-type\ used,free,run,footer\f[] .PP Print only specified type(s) of chunks. The multiple types may be specified separated by comma. This option requires \f[B]\-H, \[en]heap\f[] and \f[B]\-C, \[en]chunks\f[] options. .PP \f[C]\-b,\ \-\-bitmap\f[] .PP Print bitmap of used blocks in chunks of type run. This option requires \f[B]\-H, \[en]heap\f[] and \f[B]\-C, \[en]chunks\f[] options. .PP \f[C]\-p,\ \-\-replica\ \f[] .PP Print information from \f[I]\f[] replica. The 0 value means the master pool file. .SH RANGE .PP Using \f[B]\-r, \[en]range\f[] option it is possible to dump only a range of user data. This section describes valid format of \f[I]\f[] string. .PP You can specify multiple ranges separated by commas. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks from \f[I]\f[] to \f[I]\f[] will be dumped. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks up to \f[I]\f[] will be dumped. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks starting from \f[I]\f[] will be dumped. .PP \f[C]\f[] .PP Only \f[I]\f[] block/byte/data chunk will be dumped. .SH STATISTICS .PP Below is the description of statistical measures for specific pool types. .SS PMEMLOG .IP \[bu] 2 \f[B]Total\f[] \- Total space in pool. .IP \[bu] 2 \f[B]Available\f[] \- Size and percentage of available space. .IP \[bu] 2 \f[B]Used\f[] \- Size and percentage of used space. .SS PMEMBLK .IP \[bu] 2 \f[B]Total blocks\f[] \- Total number of blocks in pool. .IP \[bu] 2 \f[B]Zeroed blocks\f[] \- Number and percentage of blocks marked with \f[I]zero\f[] flag. .IP \[bu] 2 \f[B]Error blocks\f[] \- Number and percentage of blocks marked with \f[I]error\f[] flag. .IP \[bu] 2 \f[B]Blocks without any flag\f[] \- Number and percentage of blocks \f[I]not\f[] marked with any flag. .RS .PP NOTE: In case of pmemblk, statistics are evaluated for blocks which meet requirements regarding: \f[I]range\f[] of blocks (\f[B]\-r\f[] option), \f[I]skipped\f[] types of blocks (\f[B]\-z\f[], \f[B]\-e\f[], \f[B]\-u\f[] options). .RE .SS PMEMOBJ .IP \[bu] 2 \f[B]Object store\f[] .RS 2 .IP \[bu] 2 \f[B]Number of objects\f[] \- Total number of objects and number of objects per type number. .IP \[bu] 2 \f[B]Number of bytes\f[] \- Total number of bytes and number of bytes per type number. .RE .IP \[bu] 2 \f[B]Heap\f[] .RS 2 .IP \[bu] 2 \f[B]Number of zones\f[] \- Total number of zones in the pool. .IP \[bu] 2 \f[B]Number of used zones\f[] \- Number of used zones in the pool. .RE .IP \[bu] 2 \f[B]Zone\f[] The zone's statistics are presented for each zone separately and the aggregated results from all zones. .RS 2 .IP \[bu] 2 \f[B]Number of chunks\f[] \- Total number of chunks in the zone and number of chunks of specified type. .IP \[bu] 2 \f[B]Chunks size\f[] \- Total size of all chunks in the zone and sum of sizes of chunks of specified type. .RE .IP \[bu] 2 \f[B]Allocation classes\f[] .RS 2 .IP \[bu] 2 \f[B]Units\f[] \- Total number of units of specified class. .IP \[bu] 2 \f[B]Used units\f[] \- Number of used units of specified class. .IP \[bu] 2 \f[B]Bytes\f[] \- Total number of bytes of specified class. .IP \[bu] 2 \f[B]Used bytes\f[] \- Number of used bytes of specified class. .IP \[bu] 2 \f[B]Total bytes\f[] \- Total number of bytes of all classes. .IP \[bu] 2 \f[B]Total used bytes\f[] \- Total number of used bytes of all classes. .RE .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ info\ ./pmemblk \f[] .fi .PP Parse and print information about \[lq]pmemblk\[rq] pool file. .IP .nf \f[C] $\ pmempool\ info\ \-f\ blk\ ./pmempool \f[] .fi .PP Force parsing \[lq]pmempool\[rq] file as \f[B]pmemblk\f[] pool type. .IP .nf \f[C] $\ pmempool\ info\ \-d\ ./pmemlog \f[] .fi .PP Print information and data in hexadecimal dump format for file \[lq]pmemlog\[rq]. .IP .nf \f[C] $\ pmempool\ info\ \-d\ \-r10\-100\ \-eu\ ./pmemblk \f[] .fi .PP Print information from \[lq]pmemblk\[rq] file. Dump data blocks from 10 to 100, skip blocks marked with error flag and not marked with any flag. .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool.1.md0000664000000000000000000000743114123364546016151 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2020, Intel Corporation) [comment]: <> (pmempool.1 -- man page for pmempool) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[OPTIONS](#options)
[COMMANDS](#commands)
[DEBUGGING](#debugging)
[SEE ALSO](#see-also)
# NAME # **pmempool** - Persistent Memory Pool Management Tool # SYNOPSIS # ``` $ pmempool [--help] [--version] [] ``` # DESCRIPTION # The **pmempool** is a management tool for *Persistent Memory* pool files created by **PMDK** libraries. The main purpose of **pmempool** is to provide a user with a set of utilities for off-line analysis and manipulation of pools created by pmem libraries. The pmempool is a generic command which consists of subcommands for specific purposes. Some of subcommands are required to work *without* any impact on processed pool, but some of them *may* create a new or modify an existing one. The **pmempool** may be useful for troubleshooting by system administrators and for software developers who work on applications based on **PMDK**. The latter may find these tools useful for testing and debugging purposes also. # OPTIONS # `-V, --version` Prints the version of **pmempool**. `-h, --help` Prints synopsis and list of commands. # COMMANDS # Currently there is a following set of commands available: + **pmempool-info**(1) - Prints information and statistics in human-readable format about specified pool. + **pmempool-check**(1) - Checks pool's consistency and repairs pool if it is not consistent. + **pmempool-create**(1) - Creates a pool of specified type with additional properties specific for this type of pool. + **pmempool-dump**(1) - Dumps usable data from pool in hexadecimal or binary format. + **pmempool-rm**(1) - Removes pool file or all pool files listed in pool set configuration file. + **pmempool-convert**(1) - Updates the pool to the latest available layout version. + **pmempool-sync**(1) - Synchronizes replicas within a poolset. + **pmempool-transform**(1) - Modifies internal structure of a poolset. + **pmempool-feature**(1) - Toggle or query a poolset features. In order to get more information about specific *command* you can use **pmempool help .** # DEBUGGING # The debug logs are available only in the debug version of the tool, which is not provided by binary packages, but can be built from sources. The **pmempool.static-debug** binary blob can be found in the 'src/tools/pmempool/' subdirectory. + **PMEMPOOL_TOOL_LOG_LEVEL** The value of **PMEMPOOL_TOOL_LOG_LEVEL** enables trace points in the debug version of the tool, as follows: + **0** - This is the default level when **PMEMPOOL_TOOL_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged (in addition to returning the *errno*-based errors as usual). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the tool. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **pmempool** developers. Unless **PMEMPOOL_TOOL_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMPOOL_TOOL_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEMPOOL_TOOL_LOG_FILE** is not set, output is written to *stderr*. # SEE ALSO # **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-convert.1.md0000664000000000000000000000136414123364546017626 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-CONVERT, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-convert.1 -- man page for pmempool-convert) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-convert** - this is a wrapper around pmdk-convert tool. More information can be found in **pmdk-convert**(1) man page. # SEE ALSO # **pmdk-convert**(1), **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7), **libpmempool**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-sync.10000664000000000000000000000641614123364745016527 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-SYNC" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-sync\f[] \- Synchronize replicas or their parts within a pool set. .SH SYNOPSIS .IP .nf \f[C] pmempool\ sync\ [options]\ \f[] .fi .PP NOTE: Only the pool set file used to create the pool should be used for syncing the pool. .SH DESCRIPTION .PP The \f[B]pmempool sync\f[] command synchronizes data between replicas within a pool set. It checks if metadata of all replicas in a pool set are consistent, i.e.\ all parts are healthy, and if any of them is not, the corrupted or missing parts are recreated and filled with data from one of the healthy replicas. Currently synchronizing data is allowed only for \f[B]pmemobj\f[] pools (see \f[B]libpmemobj\f[](7)). .PP If a pool set has the option \f[I]SINGLEHDR\f[] or \f[I]NOHDRS\f[] (see \f[B]poolset\f[](5)), \f[B]pmempool sync\f[] command has limited capability of checking its metadata. This is due to limited or no, respectively, internal metadata at the beginning of pool set parts in every replica when either of the options is used. In that cases, only missing parts or the ones which cannot be opened are recreated. .SS Available options: .TP .B \f[C]\-b,\ \-\-bad\-blocks\f[] Fix bad blocks \- it causes creating or reading special recovery files. When bad blocks are detected, special recovery files have to be created in order to fix them safely. A separate recovery file is created for each part of the pool. The recovery files are created in the same directory where the poolset file is located using the following name pattern: _r _p _badblocks.txt These recovery files are automatically removed if the sync operation finishes successfully. .RS .PP If the last sync operation was interrupted and not finished correctly (eg. the application crashed) and the bad blocks fixing procedure was in progress, the bad block recovery files may be left over. In such case bad blocks might have been cleared and zeroed, but the correct data from these blocks was not recovered (not copied from a healthy replica), so the recovery files MUST NOT be deleted manually, because it would cause a data loss. Pmempool\-sync should be run again with the `\-b' option set. It will finish the previously interrupted sync operation and copy correct data to zeroed bad blocks using the left\-over bad block recovery files (the bad blocks will be read from the saved recovery files). Pmempool will delete the recovery files automatically at the end of the sync operation. .PP Using this option may have limitations depending on the operating system. For details see description of the CHECK_BAD_BLOCKS feature in \f[B]pmempool\-feature\f[](1). .RE .TP .B \f[C]\-d,\ \-\-dry\-run\f[] Enable dry run mode. In this mode no changes are applied, only check for viability of synchronization. .RS .RE .TP .B \f[C]\-v,\ \-\-verbose\f[] Increase verbosity level. .RS .RE .TP .B \f[C]\-h,\ \-\-help\f[] Display help message and exit. .RS .RE .SH SEE ALSO .PP \f[B]pmempool(1)\f[], \f[B]libpmemblk(7)\f[], \f[B]libpmemlog(7)\f[], \f[B]libpmempool(7)\f[] and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-check.10000664000000000000000000000536014123364744016624 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-CHECK" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-check\f[] \- check and repair persistent memory pool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ check\ []\ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool\f[] invoked with \f[I]check\f[] command checks consistency of a given pool file. If the pool file is consistent \f[B]pmempool\f[] exits with 0 value. If the pool file is not consistent non\-zero error code is returned. .PP In case of any errors, the proper message is printed. The verbosity level may be increased using \f[B]\-v\f[] option. The output messages may be also suppressed using \f[B]\-q\f[] option. .PP It is possible to try to fix encountered problems using \f[B]\-r\f[] option. In order to be sure this will not corrupt your data you can either create backup of the pool file using \f[B]\-b\f[] option or just print what would be fixed without modifying original pool using \f[B]\-N\f[] option. .RS .PP NOTE: Currently, checking the consistency of a \f[I]pmemobj\f[] pool is \f[B]not\f[] supported. .RE .SS Available options: .PP \f[C]\-r,\ \-\-repair\f[] .PP Try to repair a pool file if possible. .PP \f[C]\-y,\ \-\-yes\f[] .PP Answer yes on all questions. .PP \f[C]\-d,\ \-\-dry\-run\f[] .PP Don't execute, just show what would be done. Not supported on Device DAX. .PP \f[C]\-N,\ \-\-no\-exec\f[] .PP Deprecated alias for \f[C]dry\-run\f[]. .PP \f[C]\-b,\ \-\-backup\ \f[] .PP Create backup of a pool file before executing. Terminate if it is \f[I]not\f[] possible to create a backup file. This option requires \f[B]\-r\f[] option. .PP \f[C]\-a,\ \-\-advanced\f[] .PP Perform advanced repairs. This option enables more aggressive steps in attempts to repair a pool. This option requires \f[C]\-r,\ \-\-repair\f[]. .PP \f[C]\-q,\ \-\-quiet\f[] .PP Be quiet and don't print any messages. .PP \f[C]\-v,\ \-\-verbose\f[] .PP Be more verbose. .PP \f[C]\-h,\ \-\-help\f[] .PP Display help message and exit. .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ check\ pool.bin \f[] .fi .PP Check consistency of \[lq]pool.bin\[rq] pool file .IP .nf \f[C] $\ pmempool\ check\ \-\-repair\ \-\-backup\ pool.bin.backup\ pool.bin \f[] .fi .PP Check consistency of \[lq]pool.bin\[rq] pool file, create backup and repair if necessary. .IP .nf \f[C] $\ pmempool\ check\ \-rvN\ pool.bin \f[] .fi .PP Check consistency of \[lq]pool.bin\[rq] pool file, print what would be repaired with increased verbosity level. .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7), \f[B]libpmempool\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-transform.10000664000000000000000000001052114123364745017556 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-TRANSFORM" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-transform\f[] \- Modify internal structure of a pool set. .SH SYNOPSIS .IP .nf \f[C] pmempool\ transform\ [options]\ \ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool transform\f[] command modifies internal structure of a pool set defined by the \f[C]poolset_file_src\f[] file, according to a structure described in the \f[C]poolset_file_dst\f[] file. .PP The following operations are supported: .IP \[bu] 2 adding replicas \- one or more new replicas can be added and synchronized with other replicas in the pool set, .IP \[bu] 2 removing replicas \- one or more replicas can be removed from the pool set , .IP \[bu] 2 adding or removing pool set options. .PP Only one of the above operations can be performed at a time. .PP Currently adding and removing replicas are allowed only for \f[B]pmemobj\f[] pools (see \f[B]libpmemobj\f[](7)). .PP The \f[I]poolset_file_src\f[] argument provides the source pool set to be changed. .PP The \f[I]poolset_file_dst\f[] argument points to the target pool set. .PP When adding or deleting replicas, the two pool set files can differ only in the definitions of replicas which are to be added or deleted. When adding or removing pool set options (see \f[B]poolset\f[](5)), the rest of both pool set files have to be of the same structure. The operation of adding/removing a pool set option can be performed on a pool set with local replicas only. To add/remove a pool set option to/from a pool set with remote replicas, one has to remove the remote replicas first, then add/remove the option, and finally recreate the remote replicas having added/removed the pool set option to/from the remote replicas' poolset files. To add a replica it is necessary for its effective size to match or exceed the pool size. Otherwise the whole operation fails and no changes are applied. If none of the poolset options is used, the effective size of a replica is the sum of sizes of all its part files decreased by 4096 bytes per each part file. The 4096 bytes of each part file is utilized for storing internal metadata of the pool part files. If the option \f[I]SINGLEHDR\f[] is used, the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. In this case only the first part contains internal metadata. If the option \f[I]NOHDRS\f[] is used, the effective size of a replica is the sum of sizes of all its part files. In this case none of the parts contains internal metadata. .SS Available options: .TP .B \f[C]\-d,\ \-\-dry\-run\f[] Enable dry run mode. In this mode no changes are applied, only check for viability of the operation is performed. .RS .RE .TP .B \f[C]\-v,\ \-\-verbose\f[] Increase verbosity level. .RS .RE .TP .B \f[C]\-h,\ \-\-help\f[] Display help message and exit. .RS .RE .SH EXAMPLES .SS Example 1. .PP Let files \f[C]/path/poolset_file_src\f[] and \f[C]/path/poolset_file_dst\f[] have the following contents: .IP .nf \f[C] PMEMPOOLSET 20M\ /0/partfile1 20M\ /0/partfile2 25M\ /0/partfile3 REPLICA 40M\ /1/partfile1 20M\ /1/partfile2 \f[] .fi .IP .nf \f[C] PMEMPOOLSET 20M\ /0/partfile1 20M\ /0/partfile2 25M\ /0/partfile3 REPLICA 40M\ /1/partfile1 20M\ /1/partfile2 REPLICA 50M\ /2/partfile1 20M\ /2/partfile2 \f[] .fi .PP Then, the command .PP \f[C]pmempool\ transform\ /path/poolset_file_src\ /path/poolset_file_dst\f[] .PP adds a replica to the pool set. All other replicas remain unchanged and the size of the pool remains 60M. .SS Example 2. .PP Let files \f[C]/path/poolset_file_src\f[] and \f[C]/path/poolset_file_dst\f[] have the following contents: .IP .nf \f[C] PMEMPOOLSET 20M\ /0/partfile1 20M\ /0/partfile2 25M\ /0/partfile3 REPLICA 40M\ /1/partfile1 20M\ /1/partfile2 \f[] .fi .IP .nf \f[C] PMEMPOOLSET 20M\ /0/partfile1 20M\ /0/partfile2 25M\ /0/partfile3 \f[] .fi .PP Then .PP \f[C]pmempool_transform\ /path/poolset_file_src\ /path/poolset_file_dst\f[] .PP deletes the second replica from the pool set. The first replica remains unchanged and the size of the pool is still 60M. .SH SEE ALSO .PP \f[B]pmempool(1)\f[], \f[B]libpmemblk(7)\f[], \f[B]libpmemlog(7)\f[], \f[B]libpmempool(7)\f[] and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-rm.10000664000000000000000000000533614123364744016170 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-RM" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-rm\f[] \- remove a persistent memory pool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ rm\ []\ .. \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool rm\f[] command removes each specified file. If the specified file is a pool set file, all pool files (single\-file pool or part files) and remote replicas are removed. By default the \f[B]pmempool rm\f[] does not remove pool set files. All local and remote pool files are removed using \f[B]unlink\f[](3) call, except the pools created on \f[B]device dax\f[] which are zeroed instead. If specified file does not exist, the remote pool is broken or not accessible, the \f[B]pmempool rm\f[] command terminates with an error code. By default it prompts before removing \f[I]write\-protected\f[] local files. See \f[B]REMOTE REPLICATION\f[] section for more details about support for remote pools. See \f[B]EXAMPLES\f[] section for example usage of the \f[I]rm\f[] command. .SS Available options: .PP \f[C]\-h,\ \-\-help\f[] .PP Print help message .PP \f[C]\-v,\ \-\-verbose\f[] .PP Be verbose and print all removing files. .PP \f[C]\-s,\ \-\-only\-pools\f[] .PP Remove only pool files and do not remove pool set files (default behaviour). .PP \f[C]\-a,\ \-\-all\f[] .PP Remove all pool set files \- local and remote. .PP \f[C]\-l,\ \-\-local\f[] .PP Remove local pool set files. .PP \f[C]\-r,\ \-\-remote\f[] .PP Remove remote pool set files. .PP \f[C]\-f,\ \-\-force\f[] .PP Remove all specified files, ignore nonexistent files, never prompt. .PP \f[C]\-i,\ \-\-interactive\f[] .PP Prompt before removing every single file or remote pool. .SH REMOTE REPLICATION .PP A remote pool is removed using \f[B]rpmem_remove\f[](3) function if \f[B]librpmem\f[](7) library is available. If a pool set file contains remote replication but \f[B]librpmem\f[](7) is not available, the \f[B]pmempool rm\f[] command terminates with an error code, unless the \f[B]\-f, \[en]force\f[] option is specified. .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ rm\ pool.obj\ pool.blk \f[] .fi .PP Remove specified pool files. .IP .nf \f[C] $\ pmempool\ rm\ pool.set \f[] .fi .PP Remove all pool files from the \[lq]pool.set\[rq], do not remove \f[I]pool.set\f[] itself. .IP .nf \f[C] $\ pmempool\ rm\ \-a\ pool.set \f[] .fi .PP Remove all pool files from the \[lq]pool.set\[rq], remove the local pool set file and all remote pool set files. .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7), \f[B]librpmem\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/.gitignore0000664000000000000000000000024714123364546015626 0ustar rootrootpmempool-check.1 pmempool-convert.1 pmempool-create.1 pmempool-dump.1 pmempool-feature.1 pmempool-info.1 pmempool-rm.1 pmempool-sync.1 pmempool-transform.1 pmempool.1 pmdk-1.11.1/doc/pmempool/pmempool-rm.1.md0000664000000000000000000000512014123364546016556 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-RM, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-rm.1 -- man page for pmempool-rm) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-rm** - remove a persistent memory pool # SYNOPSIS # ``` $ pmempool rm [] .. ``` # DESCRIPTION # The **pmempool rm** command removes each specified file. If the specified file is a pool set file, all pool files (single-file pool or part files) and remote replicas are removed. By default the **pmempool rm** does not remove pool set files. All local and remote pool files are removed using **unlink**(3) call, except the pools created on **device dax** which are zeroed instead. If specified file does not exist, the remote pool is broken or not accessible, the **pmempool rm** command terminates with an error code. By default it prompts before removing *write-protected* local files. See **REMOTE REPLICATION** section for more details about support for remote pools. See **EXAMPLES** section for example usage of the *rm* command. ##### Available options: ##### `-h, --help` Print help message `-v, --verbose` Be verbose and print all removing files. `-s, --only-pools` Remove only pool files and do not remove pool set files (default behaviour). `-a, --all` Remove all pool set files - local and remote. `-l, --local` Remove local pool set files. `-r, --remote` Remove remote pool set files. `-f, --force` Remove all specified files, ignore nonexistent files, never prompt. `-i, --interactive` Prompt before removing every single file or remote pool. # REMOTE REPLICATION # A remote pool is removed using **rpmem_remove**(3) function if **librpmem**(7) library is available. If a pool set file contains remote replication but **librpmem**(7) is not available, the **pmempool rm** command terminates with an error code, unless the **-f, --force** option is specified. # EXAMPLE # ``` $ pmempool rm pool.obj pool.blk ``` Remove specified pool files. ``` $ pmempool rm pool.set ``` Remove all pool files from the "pool.set", do not remove *pool.set* itself. ``` $ pmempool rm -a pool.set ``` Remove all pool files from the "pool.set", remove the local pool set file and all remote pool set files. # SEE ALSO # **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7), **librpmem**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool-check.1.md0000664000000000000000000000506614123364546017226 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMPOOL-CHECK, 1) collection: pmempool header: PMDK date: pmem Tools version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (pmempool-check.1 -- man page for pmempool-check) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **pmempool-check** - check and repair persistent memory pool # SYNOPSIS # ``` $ pmempool check [] ``` # DESCRIPTION # The **pmempool** invoked with *check* command checks consistency of a given pool file. If the pool file is consistent **pmempool** exits with 0 value. If the pool file is not consistent non-zero error code is returned. In case of any errors, the proper message is printed. The verbosity level may be increased using **-v** option. The output messages may be also suppressed using **-q** option. It is possible to try to fix encountered problems using **-r** option. In order to be sure this will not corrupt your data you can either create backup of the pool file using **-b** option or just print what would be fixed without modifying original pool using **-N** option. > NOTE: Currently, checking the consistency of a *pmemobj* pool is **not** supported. ##### Available options: ##### `-r, --repair` Try to repair a pool file if possible. `-y, --yes` Answer yes on all questions. `-d, --dry-run` Don't execute, just show what would be done. Not supported on Device DAX. `-N, --no-exec` Deprecated alias for `dry-run`. `-b, --backup ` Create backup of a pool file before executing. Terminate if it is *not* possible to create a backup file. This option requires **-r** option. `-a, --advanced` Perform advanced repairs. This option enables more aggressive steps in attempts to repair a pool. This option requires `-r, --repair`. `-q, --quiet` Be quiet and don't print any messages. `-v, --verbose` Be more verbose. `-h, --help` Display help message and exit. # EXAMPLE # ``` $ pmempool check pool.bin ``` Check consistency of "pool.bin" pool file ``` $ pmempool check --repair --backup pool.bin.backup pool.bin ``` Check consistency of "pool.bin" pool file, create backup and repair if necessary. ``` $ pmempool check -rvN pool.bin ``` Check consistency of "pool.bin" pool file, print what would be repaired with increased verbosity level. # SEE ALSO # **pmempool**(1), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7), **libpmempool**(7) and **** pmdk-1.11.1/doc/pmempool/pmempool.10000664000000000000000000000776014123364743015556 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2020, Intel Corporation .SH NAME .PP \f[B]pmempool\f[] \- Persistent Memory Pool Management Tool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ [\-\-help]\ [\-\-version]\ \ [] \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool\f[] is a management tool for \f[I]Persistent Memory\f[] pool files created by \f[B]PMDK\f[] libraries. .PP The main purpose of \f[B]pmempool\f[] is to provide a user with a set of utilities for off\-line analysis and manipulation of pools created by pmem libraries. The pmempool is a generic command which consists of subcommands for specific purposes. Some of subcommands are required to work \f[I]without\f[] any impact on processed pool, but some of them \f[I]may\f[] create a new or modify an existing one. .PP The \f[B]pmempool\f[] may be useful for troubleshooting by system administrators and for software developers who work on applications based on \f[B]PMDK\f[]. The latter may find these tools useful for testing and debugging purposes also. .SH OPTIONS .PP \f[C]\-V,\ \-\-version\f[] .PP Prints the version of \f[B]pmempool\f[]. .PP \f[C]\-h,\ \-\-help\f[] .PP Prints synopsis and list of commands. .SH COMMANDS .PP Currently there is a following set of commands available: .IP \[bu] 2 \f[B]pmempool\-info\f[](1) \- Prints information and statistics in human\-readable format about specified pool. .IP \[bu] 2 \f[B]pmempool\-check\f[](1) \- Checks pool's consistency and repairs pool if it is not consistent. .IP \[bu] 2 \f[B]pmempool\-create\f[](1) \- Creates a pool of specified type with additional properties specific for this type of pool. .IP \[bu] 2 \f[B]pmempool\-dump\f[](1) \- Dumps usable data from pool in hexadecimal or binary format. .IP \[bu] 2 \f[B]pmempool\-rm\f[](1) \- Removes pool file or all pool files listed in pool set configuration file. .IP \[bu] 2 \f[B]pmempool\-convert\f[](1) \- Updates the pool to the latest available layout version. .IP \[bu] 2 \f[B]pmempool\-sync\f[](1) \- Synchronizes replicas within a poolset. .IP \[bu] 2 \f[B]pmempool\-transform\f[](1) \- Modifies internal structure of a poolset. .IP \[bu] 2 \f[B]pmempool\-feature\f[](1) \- Toggle or query a poolset features. .PP In order to get more information about specific \f[I]command\f[] you can use \f[B]pmempool help .\f[] .SH DEBUGGING .PP The debug logs are available only in the debug version of the tool, which is not provided by binary packages, but can be built from sources. The \f[B]pmempool.static\-debug\f[] binary blob can be found in the `src/tools/pmempool/' subdirectory. .IP \[bu] 2 \f[B]PMEMPOOL_TOOL_LOG_LEVEL\f[] .PP The value of \f[B]PMEMPOOL_TOOL_LOG_LEVEL\f[] enables trace points in the debug version of the tool, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEMPOOL_TOOL_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged (in addition to returning the \f[I]errno\f[]\-based errors as usual). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the tool. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]pmempool\f[] developers. .PP Unless \f[B]PMEMPOOL_TOOL_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMPOOL_TOOL_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEMPOOL_TOOL_LOG_FILE\f[] is not set, output is written to \f[I]stderr\f[]. .SH SEE ALSO .PP \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-dump.10000664000000000000000000000522614123364744016515 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-DUMP" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-dump\f[] \- dump user data from persistent memory pool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ dump\ []\ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool\f[] invoked with \f[I]dump\f[] command dumps user data from specified pool file. The output format may be either binary or hexadecimal. .PP By default the output format is hexadecimal. .PP By default data is dumped to standard output. It is possible to dump data to other file by specifying \f[B]\-o\f[] option. In this case data will be appended to this file. .PP Using \f[B]\-r\f[] option you can specify number of blocks/bytes/data chunks using special text format. See \f[B]RANGE\f[] section for details. .SS Available options: .PP \f[C]\-b,\ \-\-binary\f[] .PP Dump data in binary format. .PP \f[C]\-r,\ \-\-range\ \f[] .PP Range of pool file to dump. This may be number of blocks for \f[B]blk\f[] pool type or either number of bytes or number of data chunks for \f[B]log\f[] pool type. .PP \f[C]\-c,\ \-\-chunk\ \f[] .PP Size of chunk for \f[B]log\f[] pool type. See \f[B]pmemlog_walk\f[](3) in \f[B]libpmemlog\f[](7) for details. .PP \f[C]\-o,\ \-\-output\ \f[] .PP Name of output file. .PP \f[C]\-h,\ \-\-help\f[] .PP Display help message and exit. .SH RANGE .PP Using \f[B]\-r\f[], \f[B]\[en]range\f[] option it is possible to dump only a range of user data. This section describes valid format of \f[I]\f[] string. .PP You can specify multiple ranges separated by commas. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks from \f[I]\f[] to \f[I]\f[] will be dumped. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks up to \f[I]\f[] will be dumped. .PP \f[C]\-\f[] .PP All blocks/bytes/data chunks starting from \f[I]\f[] will be dumped. .PP \f[C]\f[] .PP Only \f[I]\f[] block/byte/data chunk will be dumped. .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ dump\ pool.bin \f[] .fi .PP Dump user data from pool.bin file to standard output .IP .nf \f[C] $\ pmempool\ dump\ \-o\ output.bin\ \-r1,10\-100\ pool_blk.bin \f[] .fi .PP Dump block number 1 and blocks from 10 to 100 from pool_blk.bin containing pmem blk pool to output.bin file .IP .nf \f[C] $\ pmempool\ dump\ \-r\ 1K\-2K\ pool.bin \f[] .fi .PP Dump data form 1K to 2K from pool.bin file. .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-feature.10000664000000000000000000000612214123364745017200 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-FEATURE" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018, Intel Corporation .SH NAME .PP \f[B]pmempool\-feature\f[] \- toggle or query pool set features .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ feature\ (\-e|\-d|\-q\ feature\-name)\ [options]\ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool feature\f[] command enables / disables or queries pool set features. .PP Available pool \f[I]feature\-names\f[] are: .IP \[bu] 2 \f[B]SINGLEHDR\f[] \- only the first part in each replica contains the pool part internal metadata. This value can be used only with \f[B]\-q\f[]. It can not be enabled or disabled. For details see \f[B]poolset\f[](5). .IP \[bu] 2 \f[B]CHECKSUM_2K\f[] \- only the first 2KiB of pool part internal metadata is checksummed. Other features may depend on this one to store additional metadata in otherwise unused second 2KiB part of a header. When \f[B]CHECKSUM_2K\f[] is disabled whole 4KiB is checksummed. .IP \[bu] 2 \f[B]SHUTDOWN_STATE\f[] \- enables additional check performed during pool open which verifies pool consistency in the presence of dirty shutdown. \f[B]CHECKSUM_2K\f[] has to be enabled prior to \f[B]SHUTDOWN_STATE\f[] otherwise enabling \f[B]SHUTDOWN_STATE\f[] will fail. .IP \[bu] 2 \f[B]CHECK_BAD_BLOCKS\f[] \- enables checking bad blocks performed during opening a pool and fixing bad blocks performed by pmempool\-sync during syncing a pool. Currently (Linux kernel v4.19, libndctl v62) checking and fixing bad blocks require read access to the following resource files (containing physical addresses) of NVDIMM devices which only root can read by default: .IP .nf \f[C] /sys/bus/nd/devices/ndbus*/region*/resource /sys/bus/nd/devices/ndbus*/region*/dax*/resource /sys/bus/nd/devices/ndbus*/region*/pfn*/resource /sys/bus/nd/devices/ndbus*/region*/namespace*/resource \f[] .fi .PP It is possible to use poolset as \f[I]file\f[] argument. But poolsets with remote replicas are not supported. .SS Available options: .PP \f[C]\-h,\ \-\-help\f[] .PP Print help message. .PP \f[C]\-v,\ \-\-verbose\f[] .PP Increase verbosity level. .PP \f[C]\-e,\ \-\-enable\ feature\-name\f[] .PP Enable feature for pool set. .PP \f[C]\-d,\ \-\-disable\ feature\-name\f[] .PP Disable feature for pool set. .PP \f[C]\-q,\ \-\-query\ feature\-name\f[] .PP Print feature status. .SH COMPATIBILITY .PP Poolsets with features not defined in this document (e.g.\ enabled by the newer software version) are not supported. .SH DISCLAIMER .PP \f[C]pmempool\ feature\f[] command is not fail safe. .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ feature\ \-\-enable\ CHECKSUM_2K\ pool.set \f[] .fi .PP Enables POOL_FEAT_CKSUM_2K incompat feature flag. .IP .nf \f[C] $\ pmempool\ feature\ \-\-disable\ CHECKSUM_2K\ pool.set \f[] .fi .PP Disables POOL_FEAT_CKSUM_2K incompat feature flag. .IP .nf \f[C] $\ pmempool\ feature\ \-\-query\ CHECKSUM_2K\ pool.set 0 \f[] .fi .PP Prints POOL_FEAT_CKSUM_2K incompat feature flag value. .SH SEE ALSO .PP \f[B]poolset\f[](5) and \f[B]\f[] pmdk-1.11.1/doc/pmempool/pmempool-create.10000664000000000000000000001025114123364744017005 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMPOOL-CREATE" "1" "2021-09-24" "PMDK - pmem Tools version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2019, Intel Corporation .SH NAME .PP \f[B]pmempool\-create\f[] \- create a persistent memory pool .SH SYNOPSIS .IP .nf \f[C] $\ pmempool\ create\ []\ []\ []\ \f[] .fi .SH DESCRIPTION .PP The \f[B]pmempool\f[] invoked with \f[I]create\f[] command creates a pool file of specified type. Depending on a pool type it is possible to provide more properties of pool. .PP Valid pool types are: \f[B]blk\f[], \f[B]log\f[] and \f[B]obj\f[] which stands for \f[I]pmemblk\f[], \f[I]pmemlog\f[] and \f[I]pmemobj\f[] pools respectively. By default the pool file is created with \f[I]minimum\f[] allowed size for specified pool type. The minimum sizes for \f[B]blk\f[], \f[B]log\f[] and \f[B]obj\f[] pool types are \f[B]PMEMBLK_MIN_POOL\f[], \f[B]PMEMLOG_MIN_POOL\f[] and \f[B]PMEMOBJ_MIN_POOL\f[] respectively. See \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7) and \f[B]libpmemobj\f[](7) for details. .PP For \f[I]pmemblk\f[] pool type block size \f[I]\f[] is a required argument. .PP In order to set custom size of pool use \f[B]\-s\f[] option, or use \f[B]\-M\f[] option to create a pool of maximum available size on underlying file system. .PP The \f[I]size\f[] argument may be passed in format that permits only the upper\-case character for byte \- B as specified in IEC 80000\-13, IEEE 1541 and the Metric Interchange Format. Standards accept SI units with obligatory B \- kB, MB, GB, \&... which means multiplier by 1000 and IEC units with optional \[lq]iB\[rq] \- KiB, MiB, GiB, \&..., K, M, G, \&... \- which means multiplier by 1024. .SS Available options: .PP \f[C]\-s,\ \-\-size\ \f[] .PP Size of pool file. .PP \f[C]\-M,\ \-\-max\-size\f[] .PP Set size of pool to available space of underlying file system. .PP \f[C]\-m,\ \-\-mode\ \f[] .PP Set permissions to (the default is 0664) when creating the files. If the file already exist the permissions are not changed. .PP \f[C]\-i,\ \-\-inherit\ \f[] .PP Create a new pool of the same size and other properties as \f[I]\f[]. .PP \f[C]\-b,\ \-\-clear\-bad\-blocks\f[] .PP Clear bad blocks in existing files. .PP \f[C]\-f,\ \-\-force\f[] .PP Remove the pool before creating. .PP \f[C]\-v,\ \-\-verbose\f[] .PP Increase verbosity level. .PP \f[C]\-h,\ \-\-help\f[] .PP Display help message and exit. .SS Options for PMEMBLK: .PP By default when creating a pmem \f[B]blk\f[] pool, the \f[B]BTT\f[] layout is \f[I]not\f[] written until the first \f[I]write operation\f[] of block entry is performed. Using \f[B]\-w\f[] option you can force writing the \f[B]BTT\f[] layout by writing zero data to specified block number. By default the \f[I]write operation\f[] is performed to block number 0. Please refer to \f[B]libpmemblk\f[](7) for details. .PP \f[C]\-w,\ \-\-write\-layout\f[] .PP Force writing the \f[B]BTT\f[] layout by performing \f[I]write operation\f[] to block number zero. .SS Options for PMEMOBJ: .PP By default when creating a pmem \f[B]obj\f[] pool, the layout name provided to the \f[B]libpmemobj\f[] library is an empty string. Please refer to \f[B]libpmemobj\f[](7) for details. .PP \f[C]\-l,\ \-\-layout\ \f[] .PP Layout name of the \f[B]pmemobj\f[] pool. .SH EXAMPLE .IP .nf \f[C] $\ pmempool\ create\ blk\ 512\ pool.blk \f[] .fi .PP Create a blk pool file of minimum allowed size and block size 512 bytes .IP .nf \f[C] $\ pmempool\ create\ log\ \-M\ pool.log \f[] .fi .PP Create a log pool file of maximum allowed size .IP .nf \f[C] $\ pmempool\ create\ blk\ \-\-size=4G\ \-\-write\-layout\ 1K\ pool.blk \f[] .fi .PP Create a blk pool file of size 4G, block size 1K and write the BTT layout .IP .nf \f[C] $\ pmempool\ create\ \-\-layout\ my_layout\ obj\ pool.obj \f[] .fi .PP Create an obj pool file of minimum allowed size and layout \[lq]my_layout\[rq] .IP .nf \f[C] $\ pmempool\ create\ \-\-inherit=pool.log\ new_pool.log \f[] .fi .PP Create a pool file based on pool.log file .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/README0000664000000000000000000000506714123364546012673 0ustar rootrootPersistent Memory Development Kit This is doc/README. Subdirectories of this directory contain source for the man pages for the Persistent Memory Development Kit in markdown format (.md files). If you're looking for documentation to get you started using PMDK, start here: https://pmem.io/pmdk and follow the links to examples and man pages. Developers new to PMDK are probably looking for libpmemobj. To generate web-based documentation or Linux/FreeBSD man pages, you need to have groff and pandoc installed. m4 macros are used in the document sources to generate OS-specific variants of man pages and web-based documentation. The macros are defined in macros.man. Processing is performed by the ../utils/md2man.sh script. All files in the *generated* directory are automatically generated and updated by the pmdk-bot. **DO NOT MODIFY THE FILES IN THAT DIRECTORY**. All changes to the documentation must be made by modifying the *.md files in the following document subdirectories: libpmem -- low-level persistent memory support libpmem2 -- low-level persistent memory support libpmemblk -- pmem-resident arrays of blocks libpmemlog -- pmem-resident log files libpmemobj -- transactional object store libpmempool -- persistent memory pool management library pmempool -- persistent memory pool management tool libpmemset -- core functionality for any persistent application (EXPERIMENTAL) librpmem -- remote access to persistent memory (EXPERIMENTAL) rpmemd -- remote persistent memory daemon (EXPERIMENTAL) daxio -- perform I/O on Device DAX device These man pages provide the API specification for the corresponding libraries and commands in this source tree, so any updates to one should be tested, reviewed, and committed with changes to the other. To create more readable text files from the source, use: $ [g]make NOTE: This will write man page output into the *generated* subdirectory. Files in this directory MUST NOT be included in any pull requests. The man(1) command may be used to format generated man pages for viewing in a terminal window (includes bold, underline, etc.), for example: $ man generated/libpmem.7 $ man generated/pmemobj_create.3 In addition, for testing purposes ../utils/md2man.sh will generate a preprocessed markdown file with the headers stripped off if the TESTOPTS variable is set. For example: $ export TESTOPTS="-DWIN32 -UFREEBSD -UWEB" $ ../utils/md2man.sh libpmemobj/libpmemobj.7.md x libpmemobj.7.win.md will generate a version of the libpmemobj.7 man page for Windows in markdown format. The resulting file may be viewed with a markdown-enabled browser. pmdk-1.11.1/doc/libpmemset/0000775000000000000000000000000014123364752014143 5ustar rootrootpmdk-1.11.1/doc/libpmemset/pmemset_config_new.30000664000000000000000000000302214123364746020077 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_CONFIG_NEW" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_config_new\f[](), \f[B]pmemset_config_delete\f[]() \- allocate and free a configuration structure for a pmemset object .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_config; int\ pmemset_config_new(struct\ pmemset_config\ **cfg); int\ pmemset_config_delete(struct\ pmemset_config\ **cfg); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_config_new\f[]() function instantiates a new (opaque) configuration structure, \f[I]pmemset_config\f[], which is used to define \f[I]set\f[] parameters for a \f[B]pmemset_new\f[](3) function, and returns it through the pointer in \f[I]*cfg\f[]. .PP The \f[B]pmemset_config_delete\f[]() function frees \f[I]*cfg\f[] returned by \f[B]pmemset_config_new\f[]() and sets \f[I]*cfg\f[] to NULL. If \f[I]*cfg\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmemset_config_new\f[]() function returns 0 on success or a negative error code on failure. \f[B]pmemset_config_new\f[]() does set \f[I]*cfg\f[] to NULL on failure. .PP The \f[B]pmemset_config_delete\f[]() function always returns 0. .SH ERRORS .PP \f[B]pmemset_config_new\f[]() can fail with the following error: \- \f[B]\-ENOMEM\f[] \- out of memory .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmemset_new\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_source_from_file.3.md0000664000000000000000000000515514123364546021711 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_SOURCE_FROM_FILE, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020-2021, Intel Corporation) [comment]: <> (pmemset_source_from_file.3 -- man page for pmemset_source_from_file) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # _UW(pmemset_source_from_file) - creates an instance of persistent memory data source # SYNOPSIS # ```c #include _UWFUNCR20(int, pmemset_source_from_file, struct pmemset_source **src, *file) _UWFUNCR2(int, pmemset_xsource_from_file, struct pmemset_source **src, *file, unsigned flags) int pmemset_source_delete(struct pmemset_source **src); ``` # DESCRIPTION # _UW(pmemset_source_from_file) function instantiates a new *struct pmemset_source** object describing the data source and sets a path to the file in it. _UW(pmemset_xsource_from_file) is equivalent to _UW(pmemset_source_from_file), but with additional *flags* argument that is a bitmask of the following values: * **PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED** - a new file will be created only if the specified file does not already exist, * **PMEMSET_SOURCE_FILE_CREATE_ALWAYS** - always a new file will be created. If the specified file exists, the file will be overwritten, * **PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED** - the specified file will be truncated during **pmemset_part_map**(3) to designated part size and offset. Obtained source is ready to be passed on to the **pmemset_part_new**() function. See **pmemset_part_new**(3) for details. The **pmemset_source_delete**() function frees *\*src* and sets *\*src* to NULL. If *\*src* is NULL, no operation is performed. # RETURN VALUE # The _UW(pmemset_source_from_file) and _UW(pmemset_xsource_from_file) functions return 0 on success or negative error code on failure. The **pmemset_source_delete**() function always returns 0. # ERRORS # The _UW(pmemset_source_from_file) and _UW(pmemset_xsource_from_file) can fail with the following errors: * **PMEMSET_E_INVALID_SOURCE_PATH** - when the provided file path string is NULL. * **-ENOMEM** - in case of insufficient memory to allocate an instance of *struct pmemset_source*. The _UW(pmemset_xsource_from_file) can also fail with the error: * **PMEMSET_E_INVALID_SOURCE_FILE_CREATE_FLAGS** - in case of invalid *flags* parameter. # SEE ALSO # **pmemset_part_map**(3), **pmemset_part_new**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_set_contiguous_part_coalescing.30000664000000000000000000000555014123364751024254 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_SET_CONTIGUOUS_PART_COALESCING" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_set_contiguous_part_coalescing\f[]() \- set part coalescing feature in the pmemset .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ pmemset_coalescing; struct\ pmemset; int\ pmemset_set_contiguous_part_coalescing(struct\ pmemset\ *set, \ \ \ \ \ \ \ \ enum\ pmemset_coalescing\ value); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_set_contiguous_part_coalescing\f[]() sets part coalescing feature flag in pmemset to the provided \f[I]value\f[]. The possible values are \f[I]PMEMSET_COALESCING_NONE\f[], \f[I]PMEMSET_COALESCING_OPPORTUNISTIC\f[] and \f[I]PMEMSET_COALESCING_FULL\f[]. .PP When part coalescing is enabled, the \f[B]pmemset_part_map\f[](3) function will try to coalesce each new mapped part with the previously mapped part, that means it will try to map the part directly after the previous mapping. The behavior of part mapping can be changed by setting one of possible values in pmemset: .IP \[bu] 2 \f[I]PMEMSET_COALESCING_NONE\f[] \- default behavior, no new mapped part will be coalesced, the position of each mapped part in virtual address space is chosen arbitrarily by the operating system .IP \[bu] 2 \f[I]PMEMSET_COALESCING_OPPORTUNISTIC\f[] \- each new mapped part will possibly be coalesced but if it's not possible it will be handled like with \f[I]PMEMSET_COALESCING_NONE\f[] value set .IP \[bu] 2 \f[I]PMEMSET_COALESCING_FULL\f[] \- each new mapped part will be coalesced, if it's not possible the mapping will fail .PP Mapping parts contiguously allows modifying the virtual address space of multiple parts with one operation using for example \f[B]memset\f[](3). The success of the part coalescing depends on the operating system and is not guaranteed. For more information see \f[B]pmemset_part_map\f[](3). .PP Coalesced parts appear as single \f[I]struct pmemset_part_map\f[] and can be retrieved by iterating over the pmemset using \f[B]pmemset_first_part_map\f[](3) and \f[B]pmemset_next_part_map\f[](3) or simply by retrieving part by its mapping address with \f[B]pmemset_part_map_by_address\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmemset_set_contiguous_part_coalescing\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_set_contiguous_part_coalescing\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_COALESCING_VALUE\f[] \- contiguous part coalescing value not one of the possible values. .SH SEE ALSO .PP \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]pmemset_part_map(3)\f[], \f[B]pmemset_part_map_by_address\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_part_map_drop.30000664000000000000000000000225114123364750020606 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PART_MAP_DROP" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_part_map_drop\f[]() \- drops the reference to the part mapping .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_part_map; void\ pmemset_part_map_drop(struct\ pmemset_part_map\ **pmap); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_part_map_drop\f[]() function drops the address reference to the part mapping. Address of a pointer to the part mapping object is passed to the function via the \f[I]pmap\f[] pointer. Pointer to the part mapping object can be retrieved using either \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3) or \f[B]pmemset_part_map_by_address\f[](3) functions. .SH RETURN VALUE .PP The \f[B]pmemset_part_map_drop\f[]() does not return any value. \f[I]*pmap\f[] is always set to NULL. .SH SEE ALSO .PP \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]pmemset_part_map_by_address\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/libpmemset.7.md0000664000000000000000000000331114123364546016772 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEMSET, 7) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (libpmemset.7 -- man page for libpmemset) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[DEBUGGING](#debugging)
[SEE ALSO](#see-also) # NAME # **libpmemset** - provides core functionality any persistent application should reasonably have (EXPERIMENTAL) # SYNOPSIS # ```c #include cc ... -lpmemset -lpmem2 ``` # DESCRIPTION # **libpmemset** is still in progress. # DEBUGGING # + **PMEMSET_LOG_LEVEL** Value assigned to the **PMEMSET_LOG_LEVEL** controls the level of log details presented in the debug version of the library, as follows: + **0** - This is the default level of logging, when **PMEMSET_LOG_LEVEL** is not set. No log messages are presented at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmemset_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmemset** developers. Unless **PMEMSET_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMSET_LOG_FILE** Specifies the name of a file where all logging information should be written. If **PMEMSET_LOG_FILE** is not set, output is written to *stderr*. # SEE ALSO # **** pmdk-1.11.1/doc/libpmemset/pmemset_descriptor_part_map.30000664000000000000000000000217214123364750022022 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_DESCRIPTOR_PART_MAP" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_descriptor_part_map\f[]() \- reads the address and size of part mapping .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_part_map; struct\ pmemset_part_descriptor\ pmemset_descriptor_part_map(struct\ pmemset_part_map\ *pmap); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_descriptor_part_map\f[]() function reads address and size of the part mapping via \f[I]pmap\f[] parameter pointing to the structure describing part mapping. It can be obtained using the \f[B]pmemset_first_part_map\f[](3) or the \f[B]pmemset_next_part_map\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmemset_descriptor_part_map\f[]() returns a \f[I]pmemset_part_descriptor\f[] struct containing descriptive information abot the part mapping. .SH SEE ALSO .PP \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_remove_part_map.3.md0000664000000000000000000000421214123364546021540 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_REMOVE_PART_MAP, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_remove_part_map.3 -- man page for libpmemset pmemset_remove_part_map operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_remove_part_map**() - removes part mapping from the pmemset # SYNOPSIS # ```c #include struct pmemset; struct pmemset_part_map; int pmemset_remove_part_map(struct pmemset *set, struct pmemset_part_map **pmap_ptr); ``` # DESCRIPTION # The **pmemset_remove_part_map**() function removes provided part mapping from the pmemset. Mapping to be removed can be retrieved using either **pmemset_first_part_map**(3), **pmemset_next_part_map**(3) or **pmemset_part_map_by_address**(3) functions. Provided part mapping can't be referenced more than once for this function to succeed. Reference to the previously retrieved part mapping can be dropped using **pmemset_part_map_drop**(3) function. Note that a retrieved part mapping could be coalesced from multiple parts therefore removing it also removes each part making up this part mapping. For more information see **pmemset_set_contiguous_part_coalescing**(3) and **pmemset_part_map**(3). When the **pmemset_remove_part_map**() function succeeds it the part mapping and sets the pointer passed via *pmap_ptr* variable to *NULL*. # RETURN VALUE # The **pmemset_remove_part_map**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_remove_part_map**() can fail with the following errors: * **PMEMSET_E_PART_NOT_FOUND** - provided part wasn't found in the pmemset # SEE ALSO # **pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **pmemset_part_map**(3), **pmemset_part_map_by_address**(3), **pmemset_part_map_drop**(3) **pmemset_set_contiguous_part_coalescing**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_part_map_by_address.30000664000000000000000000000215714123364750021766 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PART_MAP_BY_ADDRESS" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_part_map_by_address\f[]() \- returns part map object .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; struct\ pmemset_part_map; int\ pmemset_part_map_by_address(struct\ pmemset\ *set,\ struct\ pmemset_part_map\ **pmap, \ \ \ \ \ \ \ \ void\ *addr); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_part_map_by_address\f[]() \- returns \f[I]part_map\f[] object from the \f[I]set\f[]. The \f[I]part_map\f[] has to contain address \f[I]addr\f[]. .SH RETURN VALUE .PP The \f[B]pmemset_part_map_by_address\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_part_new\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_FIND_PART_MAP\f[] \- \f[I]set\f[] does not contain part map at address \f[I]addr\f[]. .SH SEE ALSO .PP \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_config_delete.30000664000000000000000000000003114123364546020543 0ustar rootroot.so pmemset_config_new.3 pmdk-1.11.1/doc/libpmemset/pmemset_deep_flush.3.md0000664000000000000000000000335114123364546020501 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_DEEP_FLUSH, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_deep_flush.3 -- man page for libpmemset pmemset_deep_flush function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_deep_flush**() - performs deep flush on the range # SYNOPSIS # ```c #include int pmemset_deep_flush(struct pmemset *set, const void *ptr, size_t size); ``` # DESCRIPTION # The **pmemset_deep_flush**() function forces any changes in the range [ptr, ptr+size) from the *set* to be stored durably in the most reliable persistence domain available to software. In particular, on supported platforms, this enables the code not to rely on automatic cache or WPQ (write pending queue) flush on power failure (ADR/eADR). Since this operation is usually much more expensive than regular persist, it should be used sparingly. Typically, the application should only ever use this function as a precaution against hardware failures, e.g., in code that detects silent data corruption caused by unsafe shutdown. # RETURN VALUE # The **pmemset_deep_flush**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_deep_flush**() can fail with the following errors: * **PMEMSET_E_DEEP_FLUSH_FAIL** - the underlying device region id cannot be detected or cannot perform msync on a regular DAX volume. # SEE ALSO # **pmem2_get_persist_fn**(3), **libpmemset**(7), **libpmem2**(7), and **** pmdk-1.11.1/doc/libpmemset/pmemset_perror.3.md0000664000000000000000000000231414123364546017672 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PERROR, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_perror.3 -- man page for the error printing in libpmemset) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[SEE ALSO](#see-also)
# NAME # _UW(pmemset_perror) - prints a descriptive error message to stderr # SYNOPSIS # ```c #include _UWFUNCR1(void, pmemset_perror, *format, ...) ``` _UNICODE() # DESCRIPTION # The _UW(pmemset_perror) function produces a message on standard error stream describing the last error encountered during library call. _UW(pmemset_perror) takes a variable number of arguments. First, the argument string *format* is printed - similarly to the **printf**(3), followed by a colon and a blank. Then an error message retrieved from the _UW(pmemset_errormsg), and a new-line. To see how the error message is generated, please see **pmemset_errormsg**(3). # SEE ALSO # **libpmemset**(7), **perror**(3), **pmemset_errormsg**(3), **printf**(3) and **** pmdk-1.11.1/doc/libpmemset/pmemset_config_new.3.md0000664000000000000000000000322514123364546020501 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_CONFIG_NEW, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_config_new.3 -- man page for pmemset_config_new and pmemset_config_delete) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_config_new**(), **pmemset_config_delete**() - allocate and free a configuration structure for a pmemset object # SYNOPSIS # ```c #include struct pmemset_config; int pmemset_config_new(struct pmemset_config **cfg); int pmemset_config_delete(struct pmemset_config **cfg); ``` # DESCRIPTION # The **pmemset_config_new**() function instantiates a new (opaque) configuration structure, *pmemset_config*, which is used to define *set* parameters for a **pmemset_new**(3) function, and returns it through the pointer in *\*cfg*. The **pmemset_config_delete**() function frees *\*cfg* returned by **pmemset_config_new**() and sets *\*cfg* to NULL. If *\*cfg* is NULL, no operation is performed. # RETURN VALUE # The **pmemset_config_new**() function returns 0 on success or a negative error code on failure. **pmemset_config_new**() does set *\*cfg* to NULL on failure. The **pmemset_config_delete**() function always returns 0. # ERRORS # **pmemset_config_new**() can fail with the following error: - **-ENOMEM** - out of memory # SEE ALSO # **errno**(3), **pmemset_new**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_part_map.3.md0000664000000000000000000001074314123364546020171 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PART_MAP, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_part_map.3 -- man page for libpmemset pmemset_part_map operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_part_map**() - creates a part mapping # SYNOPSIS # ```c #include struct pmemset_extras; struct pmemset_part; struct pmemset_part_descriptor; struct pmemset_source; int pmemset_part_map(struct pmemset_part **part_ptr, struct pmemset_extras *extra, struct pmemset_part_descriptor *desc); ``` # DESCRIPTION # The **pmemset_part_map**() function creates new part mapping in the virtual address space of the calling process and adds structure describing this mapping to the pmemset. It requires an address of a pointer to initialized part provided in the *part_ptr* parameter. A part can be created using **pmemset_part_new**(3) function. The mapping can later be retrieved using **pmemset_first_part_map**(3), **pmemset_next_part_map**(3) and **pmemset_part_map_by_address**(3) functions. Optionally **pmemset_part_map**() function can take a part descriptor object passed via *desc* parameter. If an optional descriptor was provided then address and size of the part mapping are stored in the descriptor when this function succeeds. Before the initialization of pmemset, a virtual memory reservation can be set in its configuration. This limits the future part mappings of initialized pmemset to the virtual address space spanned by the provided reservation. Provided reservation's address and size will not be changed on pmemset operations. For more information about this configuration please see **pmemset_config_set_reservation**(3). During the lifespan of initialized pmemset, a contiguous part coalescing feature value can be set using **pmemset_set_contiguous_part_coalescing**() function, modifying the default behavior of part mapping. With contiguous part coalescing feature enabled, **pmemset_part_map**() function tries to map each new part at the virtual memory region that is situated right after the previous mapped part memory range. When the **pmemset_part_map**() function succeeds it consumes the part thereby deleting it and the variable pointed by *part_ptr* is set to NULL. # RETURN VALUE # The **pmemset_part_map**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_part_map**() can fail with the following errors: * **PMEMSET_E_CANNOT_ALLOCATE_INTERNAL_STRUCTURE** - an internal structure needed by the function cannot be allocated. * **PMEMSET_E_INVALID_OFFSET_VALUE** - the offset value assigned to the part is invalid. Offset value is bigger than INT64_MAX. * **PMEMSET_E_GRANULARITY_NOT_SUPPORTED** - the granularity stored in the provided part *part_ptr* is invalid. The concept of granularity is explained in **libpmem2**(7) manpage. * **PMEMSET_E_INVALID_PMEM2_MAP** - the pmem2 mapping that pmemset mapping relies on cannot be created. The error code of **libpmem2**(7) error is printed in the logs and can be checked for further information. * **PMEMSET_E_LENGTH_UNALIGNED** - the length of the part to be mapped is not aligned to the allocation granularity. * **PMEMSET_E_CANNOT_COALESCE_PARTS** - new part couldn't be coalesced with previously mapped part in the pmemset. The memory range after the ending address of previous mapped part is occupied. * **PMEMSET_E_CANNOT_TRUNCATE_SOURCE_FILE** - in case of **pmemset_source_from_temporary**(3) or **pmemset_xsource_from_file**(3) *PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED* flag, temporary file created in *dir* cannot be truncated for the defined part size and offset. * **-ENOMEM** in case of insufficient memory to allocate an instance of *struct pmemset_part_map*. * **PMEMSET_E_CANNOT_FIT_PART_MAP** - in case of pmemset created from config with a reservation set, provided reservation has no space for a new part mapping # SEE ALSO # **pmemset_config_set_reservation**(3),**pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **pmemset_part_map_by_address**(3), **pmemset_part_new**(3), **pmemset_set_contiguous_part_coalescing**(3), **pmemset_source_from_temporary**(3), **pmemset_xsource_from_file**(3), **libpmemset**(7), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_config_set_event_callback.30000664000000000000000000001157014123364752023122 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "pmemset_config_set_event_callback" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_config_set_event_callback\f[]() \- set an event callback .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ PMEMSET_EVENT_CONTEXT_SIZE\ (64) struct\ pmemset_event_context\ { \ \ \ \ enum\ pmemset_event\ type; \ \ \ \ union\ { \ \ \ \ \ \ \ \ char\ _data[PMEMSET_EVENT_CONTEXT_SIZE]; \ \ \ \ \ \ \ \ struct\ pmemset_event_copy\ copy; \ \ \ \ \ \ \ \ struct\ pmemset_event_move\ move; \ \ \ \ \ \ \ \ struct\ pmemset_event_set\ set; \ \ \ \ \ \ \ \ struct\ pmemset_event_flush\ flush; \ \ \ \ \ \ \ \ struct\ pmemset_event_drain\ drain; \ \ \ \ \ \ \ \ struct\ pmemset_event_persist\ persist; \ \ \ \ \ \ \ \ struct\ pmemset_event_bad_block\ bad_block; \ \ \ \ \ \ \ \ struct\ pmemset_event_part_remove\ part_remove; \ \ \ \ \ \ \ \ struct\ pmemset_event_part_add\ part_add; \ \ \ \ }\ data; }; typedef\ int\ pmemset_event_callback(struct\ pmemset\ *set, \ \ \ \ \ \ \ \ struct\ pmemset_event_context\ *ctx, \ \ \ \ \ \ \ \ void\ *arg); void\ pmemset_config_set_event_callback(struct\ pmemset_config\ *cfg, \ \ \ \ \ \ \ \ pmemset_event_callback\ *callback,\ void\ *arg); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_config_set_event_callback\f[]() sets an user provided \f[I]callback\f[] in \f[I]cfg\f[]. \f[I]arg\f[] will be passed to the \f[I]callback\f[] each time it will be called by the library. .PP The callback will be called by \f[I]pmemset\f[] each time an event occurs. Events are only fired during the user's calls of the \f[B]libpmemset\f[](7) methods. The detailed list of events and its description can be found in \f[I]Events\f[] section below. The \f[I]callback\f[] function should return 0 in case of success. If the event supports error handling, the \f[I]callback\f[] can return a non\-zero value in case of error, otherwise return value is ignored. Struct \f[I]pmemset_event_context\f[] is a tagged union, which contains all event structures, in \f[B]libpmemset\f[](7). The \f[I]type\f[] field contains information of the type of the event fired, where the data union contains event\-specific information. .PP There's no guarantee that accessing pointers in \f[I]ctx\f[] inside of the callback is thread\-safe. The library user must guarantee this by not having multiple threads accessing the same region on the set. Once the function exits \f[I]ctx\f[] and its data are invalid. .SH RETURN VALUE .PP The \f[B]pmemset_config_set_event_callback\f[]() returns no value. .SH EVENTS .IP \[bu] 2 \f[B]PMEMSET_EVENT_PART_ADD\f[] \- occurs for each new part added to the pmemset using \f[B]pmemset_part_map\f[](3) function. .IP .nf \f[C] struct\ pmemset_event_flush\ { \ \ \ \ void\ *addr; \ \ \ \ size_t\ len; }; \f[] .fi .PP \f[B]PMEMSET_EVENT_FLUSH\f[] is fired before \f[B]pmemset_flush\f[](3) or \f[B]pmemset_persist\f[](3) completes its work. The \f[I]flush\f[] field in \f[I]data\f[] union contains \f[I]addr\f[] and \f[I]len\f[] passed to those functions. This event doesn't support error handling, which means that the value returned by the \f[I]callback\f[] function is ignored. .PP \f[B]PMEMSET_EVENT_DRAIN\f[] is fired after \f[B]pmemset_drain\f[](3) or \f[B]pmemset_persist\f[](3) completes its work. In case of \f[B]pmemset_persist\f[](3) this event is fired after \f[B]PMEMSET_EVENT_FLUSH\f[]. This event doesn't support error handling, which means that the value returned by the \f[I]callback\f[] function is ignored. .IP .nf \f[C] struct\ pmemset_event_copy\ { \ \ \ \ void\ *src; \ \ \ \ void\ *dest; \ \ \ \ size_t\ len; \ \ \ \ unsigned\ flags; }; struct\ pmemset_event_move\ { \ \ \ \ void\ *src; \ \ \ \ void\ *dest; \ \ \ \ size_t\ len; \ \ \ \ unsigned\ flags; }; struct\ pmemset_event_set\ { \ \ \ \ void\ *dest; \ \ \ \ int\ value; \ \ \ \ size_t\ len; \ \ \ \ unsigned\ flags; }; \f[] .fi .PP \f[B]PMEMSET_EVENT_COPY\f[], \f[B]PMEMSET_EVENT_MOVE\f[], \f[B]PMEMSET_EVENT_SET\f[] are fired, respectively, before \f[B]pmemset_memcpy\f[](3), \f[B]pmemset_memmove\f[](3), \f[B]pmemset_memset\f[](3) completed its work. Similarly, \f[I]copy\f[], \f[I]move\f[], or \f[I]set\f[] fields in the \f[I]data\f[] union contain all arguments passed to these functions. If \f[B]PMEMSET_F_MEM_NODRAIN\f[] flag is \f[B]not\f[] passed to these functions, a single \f[B]PMEMSET_EVENT_DRAIN\f[] will be fired on the end of opperation. During these functions \[lq]flush\[rq] and \[lq]drain\[rq] operations are performed, but they will not trigger any additional events. \f[B]PMEMSET_EVENT_FLUSH\f[] and \f[B]PMEMSET_EVENT_DRAIN\f[] This event doesn't support error handling, which means that the value returned by the \f[I]callback\f[] function is ignored. .SH SEE ALSO .PP \f[B]pmemset_part_map\f[], \f[B]libpmem2\f[](7), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_remove_part_map.30000664000000000000000000000402214123364752021137 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_REMOVE_PART_MAP" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_remove_part_map\f[]() \- removes part mapping from the pmemset .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; struct\ pmemset_part_map; int\ pmemset_remove_part_map(struct\ pmemset\ *set, \ \ \ \ \ \ \ \ struct\ pmemset_part_map\ **pmap_ptr); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_remove_part_map\f[]() function removes provided part mapping from the pmemset. Mapping to be removed can be retrieved using either \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3) or \f[B]pmemset_part_map_by_address\f[](3) functions. Provided part mapping can't be referenced more than once for this function to succeed. Reference to the previously retrieved part mapping can be dropped using \f[B]pmemset_part_map_drop\f[](3) function. .PP Note that a retrieved part mapping could be coalesced from multiple parts therefore removing it also removes each part making up this part mapping. For more information see \f[B]pmemset_set_contiguous_part_coalescing\f[](3) and \f[B]pmemset_part_map\f[](3). .PP When the \f[B]pmemset_remove_part_map\f[]() function succeeds it the part mapping and sets the pointer passed via \f[I]pmap_ptr\f[] variable to \f[I]NULL\f[]. .SH RETURN VALUE .PP The \f[B]pmemset_remove_part_map\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_remove_part_map\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_PART_NOT_FOUND\f[] \- provided part wasn't found in the pmemset .SH SEE ALSO .PP \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]pmemset_part_map\f[](3), \f[B]pmemset_part_map_by_address\f[](3), \f[B]pmemset_part_map_drop\f[](3) \f[B]pmemset_set_contiguous_part_coalescing\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_memmove.3.md0000664000000000000000000001032414123364546020026 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_MEMMOVE, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_memmove.3 -- man page for libpmemset pmemset_memmove function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_memmove**(), **pmemset_memcpy**(), **pmemset_pmemset**() - performs memmove/memcpy/memset on memory from the *pmemset*. # SYNOPSIS # ```c #include void *pmemset_memmove(struct pmemset *set, void *pmemdest, const void *src, size_t len, unsigned flags); void *pmemset_memcpy(struct pmemset *set, void *pmemdest, const void *src, size_t len, unsigned flags); void *pmemset_memset(struct pmemset *set, void *pmemdest, int c, size_t len, unsigned flags); ``` # DESCRIPTION # The **pmemset_memmove**(), **pmemset_memcpy**() and **pmemset_memset**() functions provide the same memory copying functionalities as their namesakes **memmove**(3), **memcpy**(3) and **memset**(3), and ensure that the result has been flushed to persistence before returning (unless **PMEM2_F_MEM_NOFLUSH** flag was used). For example, the following code: ```c memmove(dest, src, len); pmemset_persist(set, dest, len); ``` is functionally equivalent to: ```c pmemset_memmove(set, dest, src, len, 0); ``` Unlike libc implementation, **libpmemset** functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by *pmemset_persist* can be safely replaced by a single *pmemset_memmove* call. The *flags* argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: + **PMEMSET_F_MEM_NODRAIN** - modifies the behavior to skip the final *pmemset_drain* step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to **pmemset_drain**(3). The following example illustrates how this flag might be used to avoid multiple calls to **pmemset_drain**(3) when copying several ranges of memory to pmem: ```c /* ... write several ranges to pmem ... */ pmemset_memcpy(set, pmemdest1, src1, len1, PMEMSET_F_MEM_NODRAIN); pmemset_memcpy(set, pmemdest2, src2, len2, PMEMSET_F_MEM_NODRAIN); /* ... */ /* wait for any pmem stores to drain from HW buffers */ pmemset_drain(set); ``` + **PMEMSET_F_MEM_NOFLUSH** - Don't flush anything. This implies **PMEMSET_F_MEM_NODRAIN**. Using this flag only makes sense when it's followed by any function that flushes data. The remaining flags say *how* the operation should be done, and are merely hints. + **PMEMSET_F_MEM_NONTEMPORAL** - Use non-temporal instructions. This flag is mutually exclusive with **PMEMSET_F_MEM_TEMPORAL**. On x86\_64 this flag is mutually exclusive with **PMEMSET_F_MEM_NOFLUSH**. + **PMEMSET_F_MEM_TEMPORAL** - Use temporal instructions. This flag is mutually exclusive with **PMEMSET_F_MEM_NONTEMPORAL**. + **PMEMSET_F_MEM_WC** - Use write combining mode. This flag is mutually exclusive with **PMEMSET_F_MEM_WB**. On x86\_64 this flag is mutually exclusive with **PMEMSET_F_MEM_NOFLUSH**. + **PMEMSET_F_MEM_WB** - Use write back mode. This flag is mutually exclusive with **PMEMSET_F_MEM_WC**. On x86\_64 this is an alias for **PMEMSET_F_MEM_TEMPORAL**. Using an invalid combination of flags has undefined behavior. Without any of the above flags **libpmemset** will try to guess the best strategy based on the data size. See **PMEM_MOVNT_THRESHOLD** description in **libpmem2**(7) for details. # RETURN VALUE # The **pmemset_memmove**(), **pmemset_memset**(), **pmemset_memcpy**() function returns a pointer to the memory area *pmemdest* in the same way as their namesakes **memmove**(3), **memcpy**(3) and **memset**(3). # SEE ALSO # **memcpy**(3), **memmove**(3), **memset**(3), **pmemset_drain**(3), **pmemset_persist**(3), **libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_source_from_temporary.3.md0000664000000000000000000000375314123364546023016 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_SOURCE_FROM_TEMPORARY, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_source_from_temporary.3 -- man page for pmemset_source_from_temporary) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # _UW(pmemset_source_from_temporary) - creates an instance of persistent memory data source # SYNOPSIS # ```c #include _UWFUNCR20(int, pmemset_source_from_temporary, struct pmemset_source **src, const char *dir) ``` # DESCRIPTION # _UW(pmemset_source_from_temporary) function instantiates a new *struct pmemset_source** object describing the data source and creates a unnamed temporary file in the provided directory *dir*. The temporary file is always created with mode 0600, and the *dir* must specify an existing directory name. The created file has size 0 and is extended dynamically based on required part size during **pmemset_part_map**(3). In case of source from temporary file the **pmemset_source_delete**(3) function frees *\*src* and sets *\*src* to NULL and closes the temporary file as a result the file is immediately deleted. # RETURN VALUE # The _UW(pmemset_source_from_temporary) function return 0 on success or negative error code on failure. # ERRORS # The _UW(pmemset_source_from_temporary) can fail with the following errors: * **PMEMSET_E_INVALID_SOURCE_PATH** - the provided directory path string is NULL or provided path does not exists. * **PMEMSET_E_CANNOT_CREATE_TEMP_FILE** - cannot create a unique temporary filename. * **-ENOMEM** - in case of insufficient memory to allocate an instance of *struct pmemset_source*. # SEE ALSO # **pmemset_part_map**(3), **pmemset_source_delete**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_new.3.md0000664000000000000000000000311014123364546017145 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_NEW, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_new.3 -- man page for pmemset_new and pmemset_delete) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_new**(), **pmemset_delete**() - allocate and free a structure for a pmemset object # SYNOPSIS # ```c #include struct pmemset; struct pmemset_config; int pmemset_new(struct pmemset **set, struct pmemset_config *cfg); int pmemset_delete(struct pmemset **set); ``` # DESCRIPTION # The **pmemset_new**() function creates a new set by allocating and initializing set structure, *pmemset*, and returns it through the pointer in *\*set*. Configuration data, passed by the *\*cfg*, is copied into the set structure. The **pmemset_delete**() function frees *\*set* returned by **pmemset_new**() and sets *\*set* to NULL. If *\*set* is NULL, no operation is performed. # RETURN VALUE # The **pmemset_new**() function returns 0 on success or a negative error code on failure. **pmemset_new**() does set *\*set* to NULL on failure. The **pmemset_delete**() function always returns 0. # ERRORS # **pmemset_new**() can fail with the following error: - **-ENOMEM** - out of memory # SEE ALSO # **errno**(3), **pmemset_config_new**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_source_delete.3.md0000664000000000000000000000225714123364546021211 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_SOURCE_DELETE, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_source_delete.3 -- man page for pmemset_source_delete) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_source_delete**() - delete an instance of persistent memory data source # SYNOPSIS # ```c #include struct pmemset_source; int pmemset_source_delete(struct pmemset_source **src); ``` # DESCRIPTION # The **pmemset_source_delete**() function frees the data source obtained using either **pmemset_source_from_file**(3) or **pmemset_source_from_pmem2**(3) function. The user-provided variable pointed by *\*src* is set to NULL. If *\*src* is NULL, no operation is performed. # RETURN VALUE # The **pmemset_source_delete**() function always returns 0. # SEE ALSO # **pmemset_source_from_file**(3), **pmemset_source_from_pmem2**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_config_set_required_store_granularity.30000664000000000000000000000436514123364747025652 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_CONFIG_SET_REQUIRED_STORE_GRANULARITY" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020-2021, Intel Corporation .SH NAME .PP \f[B]pmemset_config_set_required_store_granularity\f[]() \- set granularity required for pmemset structure. .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_config_set_required_store_granularity(struct\ pmemset_config\ *cfg, \ \ \ \ enum\ pmem2_granularity\ g); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_config_set_required_store_granularity\f[]() sets maximum permitted granularity value \f[I]g\f[] requested for entire pmemset object. .PP Each part has to have the same effective granularity of mapped parts \- detected and initialized during \f[B]pmemset_part_map(3)\f[]. It means that the user cannot use \f[I]parts\f[] with a different effective granularity within one \f[I]pmemset\f[]. To read effective granularity of the \f[I]pmemset\f[] after mapping the first, use \f[B]pmemset_get_store_granularity\f[](3). .PP Regardless of the pmemset source type, the \f[B]libpmemset(7)\f[] library uses \f[B]libpmem2(7)\f[] API to map parts. .PP For this reason, the granularity concept is also valid for \f[B]libpmemset(7)\f[] functions, and granularity \f[I]g\f[] must be one of the following values: .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_BYTE\f[] .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_CACHE_LINE\f[] .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_PAGE\f[] .PP For more information please read \f[B]pmem2_config_set_required_store_granularity(3)\f[] man page and section \f[B]GRANULARITY\f[] in the \f[B]libpmem2(7)\f[] man. .SH RETURN VALUE .PP The \f[B]pmemset_config_set_required_store_granularity\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_config_set_required_store_granularity\f[]() can fail with the following error: .IP \[bu] 2 \f[B]PMEMSET_E_GRANULARITY_NOT_SUPPORTED\f[] \- granularity \f[I]g\f[] is not a valid value. .SH SEE ALSO .PP \f[B]pmem2_config_set_required_store_graularity\f[](3), \f[B]pmemset_get_store_granularity\f[](3), \f[B]pmemset_part_map(3)\f[], \f[B]libpmem2\f[](7), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_part_map.30000664000000000000000000001113114123364750017557 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PART_MAP" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_part_map\f[]() \- creates a part mapping .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_extras; struct\ pmemset_part; struct\ pmemset_part_descriptor; struct\ pmemset_source; int\ pmemset_part_map(struct\ pmemset_part\ **part_ptr, \ \ \ \ \ \ \ \ struct\ pmemset_extras\ *extra, \ \ \ \ \ \ \ \ struct\ pmemset_part_descriptor\ *desc); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_part_map\f[]() function creates new part mapping in the virtual address space of the calling process and adds structure describing this mapping to the pmemset. It requires an address of a pointer to initialized part provided in the \f[I]part_ptr\f[] parameter. A part can be created using \f[B]pmemset_part_new\f[](3) function. The mapping can later be retrieved using \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3) and \f[B]pmemset_part_map_by_address\f[](3) functions. .PP Optionally \f[B]pmemset_part_map\f[]() function can take a part descriptor object passed via \f[I]desc\f[] parameter. If an optional descriptor was provided then address and size of the part mapping are stored in the descriptor when this function succeeds. .PP Before the initialization of pmemset, a virtual memory reservation can be set in its configuration. This limits the future part mappings of initialized pmemset to the virtual address space spanned by the provided reservation. Provided reservation's address and size will not be changed on pmemset operations. For more information about this configuration please see \f[B]pmemset_config_set_reservation\f[](3). .PP During the lifespan of initialized pmemset, a contiguous part coalescing feature value can be set using \f[B]pmemset_set_contiguous_part_coalescing\f[]() function, modifying the default behavior of part mapping. With contiguous part coalescing feature enabled, \f[B]pmemset_part_map\f[]() function tries to map each new part at the virtual memory region that is situated right after the previous mapped part memory range. .PP When the \f[B]pmemset_part_map\f[]() function succeeds it consumes the part thereby deleting it and the variable pointed by \f[I]part_ptr\f[] is set to NULL. .SH RETURN VALUE .PP The \f[B]pmemset_part_map\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_part_map\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_ALLOCATE_INTERNAL_STRUCTURE\f[] \- an internal structure needed by the function cannot be allocated. .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_OFFSET_VALUE\f[] \- the offset value assigned to the part is invalid. Offset value is bigger than INT64_MAX. .IP \[bu] 2 \f[B]PMEMSET_E_GRANULARITY_NOT_SUPPORTED\f[] \- the granularity stored in the provided part \f[I]part_ptr\f[] is invalid. The concept of granularity is explained in \f[B]libpmem2\f[](7) manpage. .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_PMEM2_MAP\f[] \- the pmem2 mapping that pmemset mapping relies on cannot be created. The error code of \f[B]libpmem2\f[](7) error is printed in the logs and can be checked for further information. .IP \[bu] 2 \f[B]PMEMSET_E_LENGTH_UNALIGNED\f[] \- the length of the part to be mapped is not aligned to the allocation granularity. .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_COALESCE_PARTS\f[] \- new part couldn't be coalesced with previously mapped part in the pmemset. The memory range after the ending address of previous mapped part is occupied. .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_TRUNCATE_SOURCE_FILE\f[] \- in case of \f[B]pmemset_source_from_temporary\f[](3) or \f[B]pmemset_xsource_from_file\f[](3) \f[I]PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED\f[] flag, temporary file created in \f[I]dir\f[] cannot be truncated for the defined part size and offset. .IP \[bu] 2 \f[B]\-ENOMEM\f[] in case of insufficient memory to allocate an instance of \f[I]struct pmemset_part_map\f[]. .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_FIT_PART_MAP\f[] \- in case of pmemset created from config with a reservation set, provided reservation has no space for a new part mapping .SH SEE ALSO .PP \f[B]pmemset_config_set_reservation\f[](3),\f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]pmemset_part_map_by_address\f[](3), \f[B]pmemset_part_new\f[](3), \f[B]pmemset_set_contiguous_part_coalescing\f[](3), \f[B]pmemset_source_from_temporary\f[](3), \f[B]pmemset_xsource_from_file\f[](3), \f[B]libpmemset\f[](7), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_get_store_granularity.3.md0000664000000000000000000000317314123364546023001 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_GET_STORE_GRANULARITY, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_get_store_granularity.3 -- man page for pmemset_get_store_granularity) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_get_store_granularity**() - reads effective mappings granularity for pmemset # SYNOPSIS # ```c #include int pmemset_get_store_granularity(struct pmemset *set, enum pmem2_granularity *g); ``` # DESCRIPTION # The **pmemset_get_store_granularity**() function reads effective granularity of the *set* object and puts it in the *\*g*; The *set* object has to contain at least one mapped part using **pmemset_part_map**(3) function, otherwise reading granularity value is pointless and function **pmemset_get_store_granularity**(3) will fail. Concept of the granularity is described in **libpmem2**(7). # RETURN VALUE The **pmemset_get_store_granularity**() function returns 0 on success or a negative error code on failure. # ERRORS # **pmemset_get_store_granularity**() can fail with the following error: - **PMEMSET_E_NO_PART_MAPPED** - cannot read effective granularity of the *set* because it does not contain any mapped *parts*. # SEE ALSO # **pmemset_config_set_required_store_graularity**(3), **pmemset_part_map(3)**, libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_source_from_file.30000664000000000000000000000516014123364747021311 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_SOURCE_FROM_FILE" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020-2021, Intel Corporation .SH NAME .PP \f[B]pmemset_source_from_file\f[]() \- creates an instance of persistent memory data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_source_from_file(struct\ pmemset_source\ **src,\ const\ char\ *file); int\ pmemset_xsource_from_file(struct\ pmemset_source\ **src,\ const\ char\ *file,\ unsigned\ flags); int\ pmemset_source_delete(struct\ pmemset_source\ **src); \f[] .fi .SH DESCRIPTION .PP \f[B]pmemset_source_from_file\f[]() function instantiates a new *struct pmemset_source\f[B] object describing the data source and sets a path to the file in it. \f[]pmemset_xsource_from_file\f[B]() is equivalent to \f[]pmemset_source_from_file**(), but with additional \f[I]flags\f[] argument that is a bitmask of the following values: .IP \[bu] 2 \f[B]PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED\f[] \- a new file will be created only if the specified file does not already exist, .IP \[bu] 2 \f[B]PMEMSET_SOURCE_FILE_CREATE_ALWAYS\f[] \- always a new file will be created. If the specified file exists, the file will be overwritten, .IP \[bu] 2 \f[B]PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED\f[] \- the specified file will be truncated during \f[B]pmemset_part_map\f[](3) to designated part size and offset. .PP Obtained source is ready to be passed on to the \f[B]pmemset_part_new\f[]() function. See \f[B]pmemset_part_new\f[](3) for details. .PP The \f[B]pmemset_source_delete\f[]() function frees \f[I]*src\f[] and sets \f[I]*src\f[] to NULL. If \f[I]*src\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmemset_source_from_file\f[]() and \f[B]pmemset_xsource_from_file\f[]() functions return 0 on success or negative error code on failure. .PP The \f[B]pmemset_source_delete\f[]() function always returns 0. .SH ERRORS .PP The \f[B]pmemset_source_from_file\f[]() and \f[B]pmemset_xsource_from_file\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_SOURCE_PATH\f[] \- when the provided file path string is NULL. .IP \[bu] 2 \f[B]\-ENOMEM\f[] \- in case of insufficient memory to allocate an instance of \f[I]struct pmemset_source\f[]. .PP The \f[B]pmemset_xsource_from_file\f[]() can also fail with the error: .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_SOURCE_FILE_CREATE_FLAGS\f[] \- in case of invalid \f[I]flags\f[] parameter. .SH SEE ALSO .PP \f[B]pmemset_part_map\f[](3), \f[B]pmemset_part_new\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_source_delete.30000664000000000000000000000201414123364747020604 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_SOURCE_DELETE" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_source_delete\f[]() \- delete an instance of persistent memory data source .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_source; int\ pmemset_source_delete(struct\ pmemset_source\ **src); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_source_delete\f[]() function frees the data source obtained using either \f[B]pmemset_source_from_file\f[](3) or \f[B]pmemset_source_from_pmem2\f[](3) function. The user\-provided variable pointed by \f[I]*src\f[] is set to NULL. If \f[I]*src\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmemset_source_delete\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]pmemset_source_from_file\f[](3), \f[B]pmemset_source_from_pmem2\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_persist.3.md0000664000000000000000000000340214123364546020051 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PERSIST, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_persist.3 -- man page for libpmemset pmemset_persist function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_persist**() - persist data from the range # SYNOPSIS # ```c #include int pmemset_persist(struct pmemset *set, const void *ptr, size_t size); ``` # DESCRIPTION # The **pmemset_persist**() function efficiently persists data from *set* in the range [ptr, ptr + size]. It works on either persistent memory or a memory mapped file on traditional storage. The **pmemset_persist**() function is combination of **pmemset_flush**(3) and **pmemset_drain**(3) functions and can be used interchangeably: ```c struct pmemset *set; ... /* save stores durably on underlying medium */ pmemset_persist(set, addr, len); ``` is an equivalent of: ```c struct pmemset *set; ... /* flush the processor caches */ pmemset_flush(set, addr, len); /* wait for any pmem stores to drain from HW buffers */ pmemset_drain(set); ``` >NOTE: In the underlying implementation **pmemset_persist**() uses *pmem2_persist_fn* returned by **pmemset_get_persist_fn**(3), so all flush principles are identical for **pmemset_persist**() function, and you can find them in the **pmem2_get_persist_fn(3)** man page. # RETURN VALUE # The **pmemset_persist**() function always returns 0. # SEE ALSO # **pmem2_get_persist_fn**(3), **libpmemset**(7), **libpmem2**(7), and **** pmdk-1.11.1/doc/libpmemset/pmemset_delete.30000664000000000000000000000002214123364546017216 0ustar rootroot.so pmemset_new.3 pmdk-1.11.1/doc/libpmemset/pmemset_config_set_required_store_granularity.3.md0000664000000000000000000000450614123364546026243 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_CONFIG_SET_REQUIRED_STORE_GRANULARITY, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020-2021, Intel Corporation) [comment]: <> (pmemset_config_set_required_store_granularity.3 -- man page for pmemset_config_set_required_store_granularity) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_config_set_required_store_granularity**() - set granularity required for pmemset structure. # SYNOPSIS # ```c #include int pmemset_config_set_required_store_granularity(struct pmemset_config *cfg, enum pmem2_granularity g); ``` # DESCRIPTION # The **pmemset_config_set_required_store_granularity**() sets maximum permitted granularity value *g* requested for entire pmemset object. Each part has to have the same effective granularity of mapped parts - detected and initialized during **pmemset_part_map(3)**. It means that the user cannot use *parts* with a different effective granularity within one *pmemset*. To read effective granularity of the *pmemset* after mapping the first, use **pmemset_get_store_granularity**(3). Regardless of the pmemset source type, the **libpmemset(7)** library uses **libpmem2(7)** API to map parts. For this reason, the granularity concept is also valid for **libpmemset(7)** functions, and granularity *g* must be one of the following values: * **PMEM2_GRANULARITY_BYTE** * **PMEM2_GRANULARITY_CACHE_LINE** * **PMEM2_GRANULARITY_PAGE** For more information please read **pmem2_config_set_required_store_granularity(3)** man page and section **GRANULARITY** in the **libpmem2(7)** man. # RETURN VALUE The **pmemset_config_set_required_store_granularity**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_config_set_required_store_granularity**() can fail with the following error: * **PMEMSET_E_GRANULARITY_NOT_SUPPORTED** - granularity *g* is not a valid value. # SEE ALSO # **pmem2_config_set_required_store_graularity**(3), **pmemset_get_store_granularity**(3), **pmemset_part_map(3)**, **libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_perror.30000664000000000000000000000211114123364746017270 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PERROR" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_perror\f[]() \- prints a descriptive error message to stderr .SH SYNOPSIS .IP .nf \f[C] #include\ void\ pmemset_perror(const\ char\ *format,\ ...); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_perror\f[]() function produces a message on standard error stream describing the last error encountered during library call. .PP \f[B]pmemset_perror\f[]() takes a variable number of arguments. First, the argument string \f[I]format\f[] is printed \- similarly to the \f[B]printf\f[](3), followed by a colon and a blank. Then an error message retrieved from the \f[B]pmemset_errormsg\f[](), and a new\-line. To see how the error message is generated, please see \f[B]pmemset_errormsg\f[](3). .SH SEE ALSO .PP \f[B]libpmemset\f[](7), \f[B]perror\f[](3), \f[B]pmemset_errormsg\f[](3), \f[B]printf\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_memmove.30000664000000000000000000001073314123364751017431 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_MEMMOVE" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_memmove\f[](), \f[B]pmemset_memcpy\f[](), \f[B]pmemset_pmemset\f[]() \- performs memmove/memcpy/memset on memory from the \f[I]pmemset\f[]. .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *pmemset_memmove(struct\ pmemset\ *set,\ void\ *pmemdest,\ const\ void\ *src, \ \ \ \ \ \ \ \ size_t\ len,\ unsigned\ flags); void\ *pmemset_memcpy(struct\ pmemset\ *set,\ void\ *pmemdest,\ const\ void\ *src, \ \ \ \ \ \ \ \ size_t\ len,\ unsigned\ flags); void\ *pmemset_memset(struct\ pmemset\ *set,\ void\ *pmemdest,\ int\ c,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_memmove\f[](), \f[B]pmemset_memcpy\f[]() and \f[B]pmemset_memset\f[]() functions provide the same memory copying functionalities as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3) and \f[B]memset\f[](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEM2_F_MEM_NOFLUSH\f[] flag was used). .PP For example, the following code: .IP .nf \f[C] \ \ \ \ \ \ \ \ memmove(dest,\ src,\ len); \ \ \ \ \ \ \ \ pmemset_persist(set,\ dest,\ len); \f[] .fi .PP is functionally equivalent to: .IP .nf \f[C] \ \ \ \ \ \ \ \ pmemset_memmove(set,\ dest,\ src,\ len,\ 0); \f[] .fi .PP Unlike libc implementation, \f[B]libpmemset\f[] functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by \f[I]pmemset_persist\f[] can be safely replaced by a single \f[I]pmemset_memmove\f[] call. .PP The \f[I]flags\f[] argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEMSET_F_MEM_NODRAIN\f[] \- modifies the behavior to skip the final \f[I]pmemset_drain\f[] step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to \f[B]pmemset_drain\f[](3). The following example illustrates how this flag might be used to avoid multiple calls to \f[B]pmemset_drain\f[](3) when copying several ranges of memory to pmem: .IP .nf \f[C] /*\ ...\ write\ several\ ranges\ to\ pmem\ ...\ */ pmemset_memcpy(set,\ pmemdest1,\ src1,\ len1,\ PMEMSET_F_MEM_NODRAIN); pmemset_memcpy(set,\ pmemdest2,\ src2,\ len2,\ PMEMSET_F_MEM_NODRAIN); /*\ ...\ */ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ pmemset_drain(set); \f[] .fi .IP \[bu] 2 \f[B]PMEMSET_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEMSET_F_MEM_NODRAIN\f[]. Using this flag only makes sense when it's followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEMSET_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEMSET_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEMSET_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEMSET_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEMSET_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEMSET_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEMSET_F_MEM_WB\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEMSET_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEMSET_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEMSET_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEMSET_F_MEM_TEMPORAL\f[]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmemset\f[] will try to guess the best strategy based on the data size. See \f[B]PMEM_MOVNT_THRESHOLD\f[] description in \f[B]libpmem2\f[](7) for details. .SH RETURN VALUE .PP The \f[B]pmemset_memmove\f[](), \f[B]pmemset_memset\f[](), \f[B]pmemset_memcpy\f[]() function returns a pointer to the memory area \f[I]pmemdest\f[] in the same way as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3) and \f[B]memset\f[](3). .SH SEE ALSO .PP \f[B]memcpy\f[](3), \f[B]memmove\f[](3), \f[B]memset\f[](3), \f[B]pmemset_drain\f[](3), \f[B]pmemset_persist\f[](3), \f[B]libpmem2\f[](7), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_part_delete.30000664000000000000000000000002714123364546020251 0ustar rootroot.so pmemset_part_new.3 pmdk-1.11.1/doc/libpmemset/pmemset_errormsg.30000664000000000000000000000270214123364746017625 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_ERRORMSG" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_errormsg\f[]() \- returns last error message .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *pmemset_errormsg(void); \f[] .fi .SH DESCRIPTION .PP If an error is detected during the call to a \f[B]libpmemset\f[](7) function, the application may retrieve an error message describing the reason of the failure from \f[B]pmemset_errormsg\f[](). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmemset\f[](7) function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. .SH RETURN VALUE .PP The \f[B]pmemset_errormsg\f[]() function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). .SH SEE ALSO .PP \f[B]strerror\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_remove_range.30000664000000000000000000000447214123364752020441 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_REMOVE_RANGE" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_remove_range\f[]() \- removes mapped parts overlapping with the provided range .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; int\ pmemset_remove_range(struct\ pmemset\ *set,\ void\ *addr,\ size_t\ len); \f[] .fi .SH DESCRIPTION .PP \f[B]pmemset_remove_range\f[]() \- removes and unmaps existing parts that were mapped to the \f[I]set\f[], overlapping with virtual memory range described by the \f[I]addr\f[] and \f[I]len\f[] variables. The part mappings residing at the provided range can't be referenced by any of the threads for this function to succeed. References acquired using either \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3) or \f[B]pmemset_part_map_by_address\f[](3) can be dropped with \f[B]pmemset_part_map_drop\f[](3) function. .PP This function will work even if the part mappings contain underlying coalesced parts. It means that if the part map consists of two coalesced parts and the provided range intersects only with one of those parts, then only the intersected part will be removed. For more information about coalesced part mappings see \f[B]pmemset_set_contiguous_part_coalescing(3)\f[]. .SH RETURN VALUE .PP The \f[B]pmemset_remove_range\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_remove_range\f[]() function can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_FIND_PART_MAP\f[] \- provided range doesn't overlap with any part mapping stored in the pmemset .IP \[bu] 2 \f[B]PMEMSET_E_PART_MAP_POSSIBLE_USE_AFTER_DROP\f[] \- part mapping residing at the provided range is referenced by some thread .PP It can also return errors from the underlying \f[B]pmem2_map_delete\f[](3) function from the \f[B]libpmem2\f[](7) library. .SH SEE ALSO .PP \f[B]pmem2_map_delete\f[](3), \f[B]pmemset_first_part_map\f[](3), \f[B]pmemset_next_part_map\f[](3), \f[B]pmemset_part_map_by_address\f[](3), \f[B]pmemset_part_map_drop\f[](3), \f[B]pmemset_set_contiguous_part_coalescing(3)\f[], \f[B]libpmem2\f[](7), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_next_part_map.30000664000000000000000000000003514123364546020621 0ustar rootroot.so pmemset_first_part_map.3 pmdk-1.11.1/doc/libpmemset/pmemset_first_part_map.30000664000000000000000000000310014123364750020763 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_FIRST_PART_MAP" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_first_part_map\f[]() \- reads first mapping from a set \f[B]pmemset_next_part_map\f[]() \- reads next mapping from a set .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; struct\ pmemset_part_map; void\ pmemset_first_part_map(struct\ pmemset\ *set,\ struct\ pmemset_part_map\ **pmap); void\ pmemset_next_part_map(struct\ pmemset\ *set,\ struct\ pmemset_part_map\ *cur, \ \ \ \ \ \ \ \ struct\ pmemset_part_map\ **next) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_first_part_map\f[]() function reads first mapping from the \f[I]set\f[]. The \f[B]pmemset_next_part_map\f[]() function reads from the \f[I]set\f[] a mapping that succeeds the mapping provided in the \f[I]cur\f[] variable. The \f[I]set\f[] parameter points to the structure describing a set created with \f[B]pmemset_new\f[](3) function. Pointer to the retrieved mapping object in the \f[I]set\f[] is stored in the user\-provided variable via the \f[I]pmap\f[] or \f[I]next\f[] pointer depending on the used function. .SH RETURN VALUE .PP The \f[B]pmemset_first_part_map\f[]() does not return any value. \f[I]*pmap\f[] is set to NULL on failure. .PP The \f[B]pmemset_next_part_map\f[]() does not return any value. \f[I]*next\f[] is set to NULL on failure. .SH SEE ALSO .PP \f[B]pmemset_new\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_flush.3.md0000664000000000000000000000366114123364546017510 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_FLUSH, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_flush.3 -- man page for libpmemset pmemset_flush function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_flush**() - flushes data from the range # SYNOPSIS # ```c #include int pmemset_flush(struct pmemset *set, const void *ptr, size_t size); ``` # DESCRIPTION # The **pmemset_flush**() function efficiently flushes data from *set* in the range [ptr, ptr + size]. The **pmemset_flush**() function automatically decides what is the most appropriate mechanism for flushing stores directly to underlying storage. Based on *granularity* value of the *set* and available platform, **pmemset_flush**() will use system API calls such as msync(), fsync() on Linux, or FlushFileBuffers(), FlushViewOfFile() on Windows to flush data. Depending on the architecture and *power-fail protected domain*, **pmemset_flush**() function can also call machine instructions for flushing cache lines in more reliably way (e.g., CLWB, CLFLUSHOPT, CLFLUSH for Intel x86_64 architecture). >NOTE: For more detailed information about *granularity* and possible flushing operation please see *GRANULARITY* section in the **libpmem2**(7) man page. >NOTE: In the underlying implementation **pmemset_flush**() uses *pmem2_flush_fn* returned by **pmemset_get_flush_fn**(3), so all flush principles are identical for **pmemset_flush**() function, and you can find them in the **pmem2_get_flush_fn(3)** man page. # RETURN VALUE # The **pmemset_flush**() function always returns 0. # SEE ALSO # **pmem2_get_flush_fn**(3), **libpmemset**(7), **libpmem2**(7), and **** pmdk-1.11.1/doc/libpmemset/pmemset_descriptor_part_map.3.md0000664000000000000000000000247414123364546022431 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_DESCRIPTOR_PART_MAP, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_descriptor_part_map.3 -- man page for libpmemset pmemset_descriptor_part_map operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_descriptor_part_map**() - reads the address and size of part mapping # SYNOPSIS # ```c #include struct pmemset_part_map; struct pmemset_part_descriptor pmemset_descriptor_part_map(struct pmemset_part_map *pmap); ``` # DESCRIPTION # The **pmemset_descriptor_part_map**() function reads address and size of the part mapping via *pmap* parameter pointing to the structure describing part mapping. It can be obtained using the **pmemset_first_part_map**(3) or the **pmemset_next_part_map**(3) function. # RETURN VALUE # The **pmemset_descriptor_part_map**() returns a *pmemset_part_descriptor* struct containing descriptive information abot the part mapping. # SEE ALSO # **pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_xsource_from_file.30000664000000000000000000000003714123364546021474 0ustar rootroot.so pmemset_source_from_file.3 pmdk-1.11.1/doc/libpmemset/pmemset_flush.30000664000000000000000000000354614123364751017111 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_FLUSH" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_flush\f[]() \- flushes data from the range .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_flush(struct\ pmemset\ *set,\ const\ void\ *ptr,\ size_t\ size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_flush\f[]() function efficiently flushes data from \f[I]set\f[] in the range [ptr, ptr + size]. The \f[B]pmemset_flush\f[]() function automatically decides what is the most appropriate mechanism for flushing stores directly to underlying storage. Based on \f[I]granularity\f[] value of the \f[I]set\f[] and available platform, \f[B]pmemset_flush\f[]() will use system API calls such as msync(), fsync() on Linux, or FlushFileBuffers(), FlushViewOfFile() on Windows to flush data. Depending on the architecture and \f[I]power\-fail protected domain\f[], \f[B]pmemset_flush\f[]() function can also call machine instructions for flushing cache lines in more reliably way (e.g., CLWB, CLFLUSHOPT, CLFLUSH for Intel x86_64 architecture). .RS .PP NOTE: For more detailed information about \f[I]granularity\f[] and possible flushing operation please see \f[I]GRANULARITY\f[] section in the \f[B]libpmem2\f[](7) man page. .RE .RS .PP NOTE: In the underlying implementation \f[B]pmemset_flush\f[]() uses \f[I]pmem2_flush_fn\f[] returned by \f[B]pmemset_get_flush_fn\f[](3), so all flush principles are identical for \f[B]pmemset_flush\f[]() function, and you can find them in the \f[B]pmem2_get_flush_fn(3)\f[] man page. .RE .SH RETURN VALUE .PP The \f[B]pmemset_flush\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]pmem2_get_flush_fn\f[](3), \f[B]libpmemset\f[](7), \f[B]libpmem2\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_config_set_reservation.30000664000000000000000000000263114123364752022524 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_CONFIG_SET_RESERVATION" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_config_set_reservation\f[]() \- sets a reservation for entire pmemset to use .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset_config; void\ pmemset_config_set_reservation(struct\ pmemset_config\ *config, \ \ \ \ \ \ \ \ struct\ pmem2_vm_reservation\ *rsv); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_config_set_reservation\f[]() function sets a virtual memory reservation for entire pmemset object. .PP Setting the reservation in pmemset configuration limits the future part mappings to the virtual address space spanned by the provided reservation. Every part mapping is made to the provided reservation, instead of the virtual address space of the process calling \f[B]pmemset_part_map\f[](3). For more information about part mapping behavior and virtual memory reservation creation please see \f[B]pmemset_part_map\f[](3) and \f[B]pmem2_vm_reservation_new\f[](3), respectively. .SH RETURN VALUE .PP The \f[B]pmemset_config_set_reservation\f[]() does not return any value. .SH SEE ALSO .PP \f[B]pmem2_vm_reservation_new\f[](3), \f[B]pmemset_new\f[](3), \f[B]pmemset_part_map\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_remove_range.3.md0000664000000000000000000000463514123364546021042 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_REMOVE_RANGE, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_remove_range.3 -- man page for libpmemset pmemset_remove_range operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_remove_range**() - removes mapped parts overlapping with the provided range # SYNOPSIS # ```c #include struct pmemset; int pmemset_remove_range(struct pmemset *set, void *addr, size_t len); ``` # DESCRIPTION # **pmemset_remove_range**() - removes and unmaps existing parts that were mapped to the *set*, overlapping with virtual memory range described by the *addr* and *len* variables. The part mappings residing at the provided range can't be referenced by any of the threads for this function to succeed. References acquired using either **pmemset_first_part_map**(3), **pmemset_next_part_map**(3) or **pmemset_part_map_by_address**(3) can be dropped with **pmemset_part_map_drop**(3) function. This function will work even if the part mappings contain underlying coalesced parts. It means that if the part map consists of two coalesced parts and the provided range intersects only with one of those parts, then only the intersected part will be removed. For more information about coalesced part mappings see **pmemset_set_contiguous_part_coalescing(3)**. # RETURN VALUE # The **pmemset_remove_range**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_remove_range**() function can fail with the following errors: * **PMEMSET_E_CANNOT_FIND_PART_MAP** - provided range doesn't overlap with any part mapping stored in the pmemset * **PMEMSET_E_PART_MAP_POSSIBLE_USE_AFTER_DROP** - part mapping residing at the provided range is referenced by some thread It can also return errors from the underlying **pmem2_map_delete**(3) function from the **libpmem2**(7) library. # SEE ALSO # **pmem2_map_delete**(3), **pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **pmemset_part_map_by_address**(3), **pmemset_part_map_drop**(3), **pmemset_set_contiguous_part_coalescing(3)**, **libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/.gitignore0000664000000000000000000000123614123364546016136 0ustar rootrootlibpmemset.7 pmemset_config_new.3 pmemset_config_set_reservation.3 pmemset_config_set_required_store_granularity.3 pmemset_config_set_event_callback.3 pmemset_deep_flush.3 pmemset_descriptor_part_map.3 pmemset_drain.3 pmemset_errormsg.3 pmemset_first_part_map.3 pmemset_flush.3 pmemset_get_store_granularity.3 pmemset_memmove.3 pmemset_new.3 pmemset_part_map.3 pmemset_part_map_by_address.3 pmemset_part_map_drop.3 pmemset_part_new.3 pmemset_perror.3 pmemset_persist.3 pmemset_remove_part_map.3 pmemset_remove_range.3 pmemset_set_contiguous_part_coalescing.3 pmemset_source_delete.3 pmemset_source_from_file.3 pmemset_source_from_pmem2.3 pmemset_source_from_temporary.3 pmdk-1.11.1/doc/libpmemset/pmemset_get_store_granularity.30000664000000000000000000000275314123364750022402 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_GET_STORE_GRANULARITY" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_get_store_granularity\f[]() \- reads effective mappings granularity for pmemset .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_get_store_granularity(struct\ pmemset\ *set,\ enum\ pmem2_granularity\ *g); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_get_store_granularity\f[]() function reads effective granularity of the \f[I]set\f[] object and puts it in the \f[I]*g\f[]; .PP The \f[I]set\f[] object has to contain at least one mapped part using \f[B]pmemset_part_map\f[](3) function, otherwise reading granularity value is pointless and function \f[B]pmemset_get_store_granularity\f[](3) will fail. .PP Concept of the granularity is described in \f[B]libpmem2\f[](7). .SH RETURN VALUE .PP The \f[B]pmemset_get_store_granularity\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP \f[B]pmemset_get_store_granularity\f[]() can fail with the following error: .IP \[bu] 2 \f[B]PMEMSET_E_NO_PART_MAPPED\f[] \- cannot read effective granularity of the \f[I]set\f[] because it does not contain any mapped \f[I]parts\f[]. .SH SEE ALSO .PP \f[B]pmemset_config_set_required_store_graularity\f[](3), \f[B]pmemset_part_map(3)\f[], libpmem2\f[B](7), \f[]libpmemset\f[B](7) and \f[]** pmdk-1.11.1/doc/libpmemset/pmemset_errormsg.3.md0000664000000000000000000000316214123364546020223 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_ERRORMSG, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_errormsg.3 -- man page for error handling in libpmemset) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # _UW(pmemset_errormsg) - returns last error message # SYNOPSIS # ```c #include _UWFUNC(pmemset_errormsg, void) ``` _UNICODE() # DESCRIPTION # If an error is detected during the call to a **libpmemset**(7) function, the application may retrieve an error message describing the reason of the failure from _UW(pmemset_errormsg). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmemset**(7) function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. # RETURN VALUE # The _UW(pmemset_errormsg) function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). # SEE ALSO # **strerror**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_part_new.3.md0000664000000000000000000000535214123364546020205 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PART_NEW, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020-2021, Intel Corporation) [comment]: <> (pmemset_part_new.3 -- man page for libpmemset pmemset_part_new operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_part_new**(), **pmemset_part_delete**() - create and delete structure for a part object # SYNOPSIS # ```c #include struct pmemset; struct pmemset_part; struct pmemset_source; int pmemset_part_new(struct pmemset_part **part, struct pmemset *set, struct pmemset_source *src, size_t offset, size_t length); int pmemset_part_delete(struct pmemset_part **part); ``` # DESCRIPTION # The **pmemset_part_new**() creates new part based on the set specified in the *\*set* pointer. This function requires a data source *source*. For the operation to succeed the *src* structure must be created from a valid data source. See **pmemset_source_from_file**(3) and **pmemset_source_from_pmem2**(3) for possible sources. If the **pmemset_part_new**() function succeeds in creating a new part it instantiates a new *struct pmemset_part** object describing the part. The pointer to this newly created object is stored in the user-provided variable passed via the *part* pointer. If the mapping fails the variable pointed by *part* will contain a NULL value and appropriate error value will be returned. For a list of possible return values please see [RETURN VALUE](#return-value). The **pmemset_part_delete**() function frees *\*part* returned by **pmemset_part_new**() and sets *\*part* to NULL. # RETURN VALUE # The **pmemset_part_new**() function returns 0 on success or a negative error code on failure. The **pmemset_part_delete**() function always returns 0. # ERRORS # The **pmemset_part_new**() can fail with the following errors: * **PMEMSET_E_INVALID_PMEM2_SOURCE** - *pmem2_source* set in the *src* structure is invalid. * **PMEMSET_E_INVALID_SOURCE_PATH** - the path to the file set in the provided *src* structure points to invalid file. * **PMEMSET_E_INVALID_SOURCE_TYPE** - the source type in the provided *src* isn't recognized. * **-ENOMEM** in case of insufficient memory to allocate an instance of *struct pmemset_part*. It can also return **-EACCES**, **-EFAULT**, **-ELOOP**, **-ENAMETOOLONG**, **-ENOMEM**, **-ENOTDIR**, **-EOVERFLOW** from the underlying **stat**(2) function. # SEE ALSO # **stat**(2), **pmemset_source_from_pmem2**(), **pmemset_source_from_file**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/libpmemset.70000664000000000000000000000330114123364746016374 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEMSET" "7" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]libpmemset\f[] \- provides core functionality any persistent application should reasonably have (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lpmemset\ \-lpmem2 \f[] .fi .SH DESCRIPTION .PP \f[B]libpmemset\f[] is still in progress. .SH DEBUGGING .IP \[bu] 2 \f[B]PMEMSET_LOG_LEVEL\f[] .PP Value assigned to the \f[B]PMEMSET_LOG_LEVEL\f[] controls the level of log details presented in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level of logging, when \f[B]PMEMSET_LOG_LEVEL\f[] is not set. No log messages are presented at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmemset_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmemset\f[] developers. .PP Unless \f[B]PMEMSET_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMSET_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If \f[B]PMEMSET_LOG_FILE\f[] is not set, output is written to \f[I]stderr\f[]. .SH SEE ALSO .PP \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_deep_flush.30000664000000000000000000000310514123364752020076 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_DEEP_FLUSH" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_deep_flush\f[]() \- performs deep flush on the range .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_deep_flush(struct\ pmemset\ *set,\ const\ void\ *ptr,\ size_t\ size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_deep_flush\f[]() function forces any changes in the range [ptr, ptr+size) from the \f[I]set\f[] to be stored durably in the most reliable persistence domain available to software. In particular, on supported platforms, this enables the code not to rely on automatic cache or WPQ (write pending queue) flush on power failure (ADR/eADR). .PP Since this operation is usually much more expensive than regular persist, it should be used sparingly. Typically, the application should only ever use this function as a precaution against hardware failures, e.g., in code that detects silent data corruption caused by unsafe shutdown. .SH RETURN VALUE .PP The \f[B]pmemset_deep_flush\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_deep_flush\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_DEEP_FLUSH_FAIL\f[] \- the underlying device region id cannot be detected or cannot perform msync on a regular DAX volume. .SH SEE ALSO .PP \f[B]pmem2_get_persist_fn\f[](3), \f[B]libpmemset\f[](7), \f[B]libpmem2\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_config_set_event_callback.3.md0000664000000000000000000001065414123364546023524 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(pmemset_config_set_event_callback, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_config_set_event_callback.3 -- man page for pmemset_config_set_event_callback) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[EVENTS](#events)
[SEE ALSO](#see-also)
# NAME # **pmemset_config_set_event_callback**() - set an event callback # SYNOPSIS # ```c #include #define PMEMSET_EVENT_CONTEXT_SIZE (64) struct pmemset_event_context { enum pmemset_event type; union { char _data[PMEMSET_EVENT_CONTEXT_SIZE]; struct pmemset_event_copy copy; struct pmemset_event_move move; struct pmemset_event_set set; struct pmemset_event_flush flush; struct pmemset_event_drain drain; struct pmemset_event_persist persist; struct pmemset_event_bad_block bad_block; struct pmemset_event_part_remove part_remove; struct pmemset_event_part_add part_add; } data; }; typedef int pmemset_event_callback(struct pmemset *set, struct pmemset_event_context *ctx, void *arg); void pmemset_config_set_event_callback(struct pmemset_config *cfg, pmemset_event_callback *callback, void *arg); ``` # DESCRIPTION # The **pmemset_config_set_event_callback**() sets an user provided *callback* in *cfg*. *arg* will be passed to the *callback* each time it will be called by the library. The callback will be called by *pmemset* each time an event occurs. Events are only fired during the user's calls of the **libpmemset**(7) methods. The detailed list of events and its description can be found in *Events* section below. The *callback* function should return 0 in case of success. If the event supports error handling, the *callback* can return a non-zero value in case of error, otherwise return value is ignored. Struct *pmemset_event_context* is a tagged union, which contains all event structures, in **libpmemset**(7). The *type* field contains information of the type of the event fired, where the data union contains event-specific information. There's no guarantee that accessing pointers in *ctx* inside of the callback is thread-safe. The library user must guarantee this by not having multiple threads accessing the same region on the set. Once the function exits *ctx* and its data are invalid. # RETURN VALUE # The **pmemset_config_set_event_callback**() returns no value. # EVENTS # * **PMEMSET_EVENT_PART_ADD** - occurs for each new part added to the pmemset using **pmemset_part_map**(3) function. ```c struct pmemset_event_flush { void *addr; size_t len; }; ``` **PMEMSET_EVENT_FLUSH** is fired before **pmemset_flush**(3) or **pmemset_persist**(3) completes its work. The *flush* field in *data* union contains *addr* and *len* passed to those functions. This event doesn't support error handling, which means that the value returned by the *callback* function is ignored. **PMEMSET_EVENT_DRAIN** is fired after **pmemset_drain**(3) or **pmemset_persist**(3) completes its work. In case of **pmemset_persist**(3) this event is fired after **PMEMSET_EVENT_FLUSH**. This event doesn't support error handling, which means that the value returned by the *callback* function is ignored. ```c struct pmemset_event_copy { void *src; void *dest; size_t len; unsigned flags; }; struct pmemset_event_move { void *src; void *dest; size_t len; unsigned flags; }; struct pmemset_event_set { void *dest; int value; size_t len; unsigned flags; }; ``` **PMEMSET_EVENT_COPY**, **PMEMSET_EVENT_MOVE**, **PMEMSET_EVENT_SET** are fired, respectively, before **pmemset_memcpy**(3), **pmemset_memmove**(3), **pmemset_memset**(3) completed its work. Similarly, *copy*, *move*, or *set* fields in the *data* union contain all arguments passed to these functions. If **PMEMSET_F_MEM_NODRAIN** flag is **not** passed to these functions, a single **PMEMSET_EVENT_DRAIN** will be fired on the end of opperation. During these functions "flush" and "drain" operations are performed, but they will not trigger any additional events. **PMEMSET_EVENT_FLUSH** and **PMEMSET_EVENT_DRAIN** This event doesn't support error handling, which means that the value returned by the *callback* function is ignored. # SEE ALSO # **pmemset_part_map**, **libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_source_from_pmem2.30000664000000000000000000000255614123364747021420 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_SOURCE_FROM_PMEM2" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_source_from_pmem2\f[]() \- creates an instance of persistent set data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_source_from_pmem2(struct\ pmemset_source\ **src,\ struct\ pmem2_source\ *pmem2_src); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_source_from_pmem2\f[]() function instantiates a new \f[I]struct pmemset_source\f[] object describing set of data. The \f[I]pmemset_source\f[] is created using \f[I]pmem2_source\f[] from \f[B]libpmem2\f[](7) library. For more details see \f[B]pmem2_source\f[](3) man page. .SH RETURN VALUE .PP The \f[B]pmemset_source_from_pmem2\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP \f[B]pmemset_source_from_pmem2\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]\-ENOMEM\f[] \- in case of insufficient memory to allocate an instance of \f[I]struct pmemset_source\f[]. .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_PMEM2_SOURCE\f[] \- if the \f[I]struct pmem2_source\f[] is NULL. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmem2_source\f[](3), \f[B]libpmem2\f[](7), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_memcpy.30000664000000000000000000000002614123364546017252 0ustar rootroot.so pmemset_memmove.3 pmdk-1.11.1/doc/libpmemset/pmemset_part_map_drop.3.md0000664000000000000000000000252614123364546021215 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PART_MAP_DROP, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_part_map_drop.3 -- man page for libpmemset pmemset_part_map_drop operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_part_map_drop**() - drops the reference to the part mapping # SYNOPSIS # ```c #include struct pmemset_part_map; void pmemset_part_map_drop(struct pmemset_part_map **pmap); ``` # DESCRIPTION # The **pmemset_part_map_drop**() function drops the address reference to the part mapping. Address of a pointer to the part mapping object is passed to the function via the *pmap* pointer. Pointer to the part mapping object can be retrieved using either **pmemset_first_part_map**(3), **pmemset_next_part_map**(3) or **pmemset_part_map_by_address**(3) functions. # RETURN VALUE # The **pmemset_part_map_drop**() does not return any value. *\*pmap* is always set to NULL. # SEE ALSO # **pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **pmemset_part_map_by_address**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_drain.30000664000000000000000000000270714123364751017063 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_DRAIN" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_drain\f[]() \- drain flushes .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_drain(struct\ pmemset\ *set); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_drain\f[]() function efficiently draining flushes in the range owned by \f[I]set\f[]. Each program that flushes discontiguous ranges using \f[B]pmemset_flush\f[](3) should follow up them by calling \f[B]pmemset_drain\f[]() to wait for drain hw buffers. Calling \f[B]pmemset_drain\f[]() also guarantees proper ordering of the flushed stores. .RS .PP NOTE: For more detailed information about \f[I]granularity\f[] and underlying drain operation please see \f[I]GRANULARITY\f[] section in the \f[B]libpmem2\f[](7) man page. .RE .RS .PP NOTE: In the underlying implementation \f[B]pmemset_drain\f[]() uses \f[I]pmem2_drain_fn\f[] returned by \f[B]pmemset_get_drain_fn\f[](3), so all drain principles are identical for \f[B]pmemset_drain\f[]() function, and you can find them in the \f[B]pmem2_get_drain_fn(3)\f[] man page. .RE .SH RETURN VALUE .PP The \f[B]pmemset_drain\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmemset_flush\f[](3), \f[B]libpmemset\f[](7), \f[B]libpmem2\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_persist.30000664000000000000000000000340214123364751017450 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PERSIST" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_persist\f[]() \- persist data from the range .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_persist(struct\ pmemset\ *set,\ const\ void\ *ptr,\ size_t\ size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_persist\f[]() function efficiently persists data from \f[I]set\f[] in the range [ptr, ptr + size]. It works on either persistent memory or a memory mapped file on traditional storage. The \f[B]pmemset_persist\f[]() function is combination of \f[B]pmemset_flush\f[](3) and \f[B]pmemset_drain\f[](3) functions and can be used interchangeably: .IP .nf \f[C] \ \ \ \ struct\ pmemset\ *set; \ \ \ \ ... \ \ \ \ /*\ save\ stores\ durably\ on\ underlying\ medium\ */ \ \ \ \ pmemset_persist(set,\ addr,\ len); \f[] .fi .PP is an equivalent of: .IP .nf \f[C] \ \ \ \ struct\ pmemset\ *set; \ \ \ \ ... \ \ \ \ /*\ flush\ the\ processor\ caches\ */ \ \ \ \ pmemset_flush(set,\ addr,\ len); \ \ \ \ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ \ \ \ \ pmemset_drain(set); \f[] .fi .RS .PP NOTE: In the underlying implementation \f[B]pmemset_persist\f[]() uses \f[I]pmem2_persist_fn\f[] returned by \f[B]pmemset_get_persist_fn\f[](3), so all flush principles are identical for \f[B]pmemset_persist\f[]() function, and you can find them in the \f[B]pmem2_get_persist_fn(3)\f[] man page. .RE .SH RETURN VALUE .PP The \f[B]pmemset_persist\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]pmem2_get_persist_fn\f[](3), \f[B]libpmemset\f[](7), \f[B]libpmem2\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_source_from_temporary.30000664000000000000000000000357114123364752022414 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_SOURCE_FROM_TEMPORARY" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmemset_source_from_temporary\f[]() \- creates an instance of persistent memory data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemset_source_from_temporary(struct\ pmemset_source\ **src,\ const\ char\ const\ char\ *dir); \f[] .fi .SH DESCRIPTION .PP \f[B]pmemset_source_from_temporary\f[]() function instantiates a new *struct pmemset_source\f[B] object describing the data source and creates a unnamed temporary file in the provided directory \f[BI]dir\f[B]. The temporary file is always created with mode 0600, and the \f[BI]dir\f[B] must specify an existing directory name. The created file has size 0 and is extended dynamically based on required part size during \f[]pmemset_part_map**(3). .PP In case of source from temporary file the \f[B]pmemset_source_delete\f[](3) function frees \f[I]*src\f[] and sets \f[I]*src\f[] to NULL and closes the temporary file as a result the file is immediately deleted. .SH RETURN VALUE .PP The \f[B]pmemset_source_from_temporary\f[]() function return 0 on success or negative error code on failure. .SH ERRORS .PP The \f[B]pmemset_source_from_temporary\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_SOURCE_PATH\f[] \- the provided directory path string is NULL or provided path does not exists. .IP \[bu] 2 \f[B]PMEMSET_E_CANNOT_CREATE_TEMP_FILE\f[] \- cannot create a unique temporary filename. .IP \[bu] 2 \f[B]\-ENOMEM\f[] \- in case of insufficient memory to allocate an instance of \f[I]struct pmemset_source\f[]. .SH SEE ALSO .PP \f[B]pmemset_part_map\f[](3), \f[B]pmemset_source_delete\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_first_part_map.3.md0000664000000000000000000000324614123364546021400 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_FIRST_PART_MAP, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_first_part_map.3 -- man page for libpmemset pmemset_first_part_map operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_first_part_map**() - reads first mapping from a set **pmemset_next_part_map**() - reads next mapping from a set # SYNOPSIS # ```c #include struct pmemset; struct pmemset_part_map; void pmemset_first_part_map(struct pmemset *set, struct pmemset_part_map **pmap); void pmemset_next_part_map(struct pmemset *set, struct pmemset_part_map *cur, struct pmemset_part_map **next) ``` # DESCRIPTION # The **pmemset_first_part_map**() function reads first mapping from the *set*. The **pmemset_next_part_map**() function reads from the *set* a mapping that succeeds the mapping provided in the *cur* variable. The *set* parameter points to the structure describing a set created with **pmemset_new**(3) function. Pointer to the retrieved mapping object in the *set* is stored in the user-provided variable via the *pmap* or *next* pointer depending on the used function. # RETURN VALUE # The **pmemset_first_part_map**() does not return any value. *\*pmap* is set to NULL on failure. The **pmemset_next_part_map**() does not return any value. *\*next* is set to NULL on failure. # SEE ALSO # **pmemset_new**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_part_new.30000664000000000000000000000542414123364747017611 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_PART_NEW" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020-2021, Intel Corporation .SH NAME .PP \f[B]pmemset_part_new\f[](), \f[B]pmemset_part_delete\f[]() \- create and delete structure for a part object .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; struct\ pmemset_part; struct\ pmemset_source; int\ pmemset_part_new(struct\ pmemset_part\ **part,\ struct\ pmemset\ *set, \ \ \ \ \ \ \ \ struct\ pmemset_source\ *src,\ size_t\ offset,\ size_t\ length); int\ pmemset_part_delete(struct\ pmemset_part\ **part); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_part_new\f[]() creates new part based on the set specified in the \f[I]*set\f[] pointer. This function requires a data source \f[I]source\f[]. .PP For the operation to succeed the \f[I]src\f[] structure must be created from a valid data source. See \f[B]pmemset_source_from_file\f[](3) and \f[B]pmemset_source_from_pmem2\f[](3) for possible sources. .PP If the \f[B]pmemset_part_new\f[]() function succeeds in creating a new part it instantiates a new *struct pmemset_part** object describing the part. The pointer to this newly created object is stored in the user\-provided variable passed via the \f[I]part\f[] pointer. If the mapping fails the variable pointed by \f[I]part\f[] will contain a NULL value and appropriate error value will be returned. For a list of possible return values please see RETURN VALUE. .PP The \f[B]pmemset_part_delete\f[]() function frees \f[I]*part\f[] returned by \f[B]pmemset_part_new\f[]() and sets \f[I]*part\f[] to NULL. .SH RETURN VALUE .PP The \f[B]pmemset_part_new\f[]() function returns 0 on success or a negative error code on failure. .PP The \f[B]pmemset_part_delete\f[]() function always returns 0. .SH ERRORS .PP The \f[B]pmemset_part_new\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_PMEM2_SOURCE\f[] \- \f[I]pmem2_source\f[] set in the \f[I]src\f[] structure is invalid. .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_SOURCE_PATH\f[] \- the path to the file set in the provided \f[I]src\f[] structure points to invalid file. .IP \[bu] 2 \f[B]PMEMSET_E_INVALID_SOURCE_TYPE\f[] \- the source type in the provided \f[I]src\f[] isn't recognized. .IP \[bu] 2 \f[B]\-ENOMEM\f[] in case of insufficient memory to allocate an instance of \f[I]struct pmemset_part\f[]. .PP It can also return \f[B]\-EACCES\f[], \f[B]\-EFAULT\f[], \f[B]\-ELOOP\f[], \f[B]\-ENAMETOOLONG\f[], \f[B]\-ENOMEM\f[], \f[B]\-ENOTDIR\f[], \f[B]\-EOVERFLOW\f[] from the underlying \f[B]stat\f[](2) function. .SH SEE ALSO .PP \f[B]stat\f[](2), \f[B]pmemset_source_from_pmem2\f[](), \f[B]pmemset_source_from_file\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_part_map_by_address.3.md0000664000000000000000000000242614123364546022367 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_PART_MAP_BY_ADDRESS, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_part_map_by_address.3 -- man page for libpmemset pmemset_part_map_by_address function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_part_map_by_address**() - returns part map object # SYNOPSIS # ```c #include struct pmemset; struct pmemset_part_map; int pmemset_part_map_by_address(struct pmemset *set, struct pmemset_part_map **pmap, void *addr); ``` # DESCRIPTION # The **pmemset_part_map_by_address**() - returns *part_map* object from the *set*. The *part_map* has to contain address *addr*. # RETURN VALUE # The **pmemset_part_map_by_address**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_part_new**() can fail with the following errors: * **PMEMSET_E_CANNOT_FIND_PART_MAP** - *set* does not contain part map at address *addr*. # SEE ALSO # **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_source_from_pmem2.3.md0000664000000000000000000000276514123364546022016 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_SOURCE_FROM_PMEM2, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_source_from_pmem2.3 -- man page for pmemset_source_from_pmem2 function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_source_from_pmem2**() - creates an instance of persistent set data source # SYNOPSIS # ```c #include int pmemset_source_from_pmem2(struct pmemset_source **src, struct pmem2_source *pmem2_src); ``` # DESCRIPTION # The **pmemset_source_from_pmem2**() function instantiates a new *struct pmemset_source* object describing set of data. The *pmemset_source* is created using *pmem2_source* from **libpmem2**(7) library. For more details see **pmem2_source**(3) man page. # RETURN VALUE # The **pmemset_source_from_pmem2**() function returns 0 on success or a negative error code on failure. # ERRORS # **pmemset_source_from_pmem2**() can fail with the following errors: - **-ENOMEM** - in case of insufficient memory to allocate an instance of *struct pmemset_source*. - **PMEMSET_E_INVALID_PMEM2_SOURCE** - if the *struct pmem2_source* is NULL. # SEE ALSO # **errno**(3), **pmem2_source**(3), **libpmem2**(7), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_memset.30000664000000000000000000000002614123364546017252 0ustar rootroot.so pmemset_memmove.3 pmdk-1.11.1/doc/libpmemset/pmemset_config_set_reservation.3.md0000664000000000000000000000307314123364546023125 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_CONFIG_SET_RESERVATION, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_config_set_reservation.3 -- man page for pmemset_config_set_reservation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_config_set_reservation**() - sets a reservation for entire pmemset to use # SYNOPSIS # ```c #include struct pmemset_config; void pmemset_config_set_reservation(struct pmemset_config *config, struct pmem2_vm_reservation *rsv); ``` # DESCRIPTION # The **pmemset_config_set_reservation**() function sets a virtual memory reservation for entire pmemset object. Setting the reservation in pmemset configuration limits the future part mappings to the virtual address space spanned by the provided reservation. Every part mapping is made to the provided reservation, instead of the virtual address space of the process calling **pmemset_part_map**(3). For more information about part mapping behavior and virtual memory reservation creation please see **pmemset_part_map**(3) and **pmem2_vm_reservation_new**(3), respectively. # RETURN VALUE The **pmemset_config_set_reservation**() does not return any value. # SEE ALSO # **pmem2_vm_reservation_new**(3), **pmemset_new**(3), **pmemset_part_map**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/libpmemset/pmemset_drain.3.md0000664000000000000000000000305014123364546017454 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_DRAIN, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmemset_drain.3 -- man page for libpmemset pmemset_drain function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemset_drain**() - drain flushes # SYNOPSIS # ```c #include int pmemset_drain(struct pmemset *set); ``` # DESCRIPTION # The **pmemset_drain**() function efficiently draining flushes in the range owned by *set*. Each program that flushes discontiguous ranges using **pmemset_flush**(3) should follow up them by calling **pmemset_drain**() to wait for drain hw buffers. Calling **pmemset_drain**() also guarantees proper ordering of the flushed stores. >NOTE: For more detailed information about *granularity* and underlying drain operation please see *GRANULARITY* section in the **libpmem2**(7) man page. >NOTE: In the underlying implementation **pmemset_drain**() uses *pmem2_drain_fn* returned by **pmemset_get_drain_fn**(3), so all drain principles are identical for **pmemset_drain**() function, and you can find them in the **pmem2_get_drain_fn(3)** man page. # RETURN VALUE # The **pmemset_drain**() function always returns 0. # SEE ALSO # **pmem2_get_drain_fn**(3), **pmemset_flush**(3), **libpmemset**(7), **libpmem2**(7), and **** pmdk-1.11.1/doc/libpmemset/pmemset_new.30000664000000000000000000000273014123364747016560 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMSET_NEW" "3" "2021-09-24" "PMDK - pmemset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmemset_new\f[](), \f[B]pmemset_delete\f[]() \- allocate and free a structure for a pmemset object .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmemset; struct\ pmemset_config; int\ pmemset_new(struct\ pmemset\ **set,\ struct\ pmemset_config\ *cfg); int\ pmemset_delete(struct\ pmemset\ **set); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemset_new\f[]() function creates a new set by allocating and initializing set structure, \f[I]pmemset\f[], and returns it through the pointer in \f[I]*set\f[]. Configuration data, passed by the \f[I]*cfg\f[], is copied into the set structure. .PP The \f[B]pmemset_delete\f[]() function frees \f[I]*set\f[] returned by \f[B]pmemset_new\f[]() and sets \f[I]*set\f[] to NULL. If \f[I]*set\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmemset_new\f[]() function returns 0 on success or a negative error code on failure. \f[B]pmemset_new\f[]() does set \f[I]*set\f[] to NULL on failure. .PP The \f[B]pmemset_delete\f[]() function always returns 0. .SH ERRORS .PP \f[B]pmemset_new\f[]() can fail with the following error: \- \f[B]\-ENOMEM\f[] \- out of memory .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmemset_config_new\f[](3), \f[B]libpmemset\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemset/pmemset_set_contiguous_part_coalescing.3.md0000664000000000000000000000564414123364546024661 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMSET_SET_CONTIGUOUS_PART_COALESCING, 3) collection: libpmemset header: PMDK date: pmemset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmemset_set_contiguous_part_coalescing.3 -- man page for pmemset_set_contiguous_part_coalescing) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmemset_set_contiguous_part_coalescing**() - set part coalescing feature in the pmemset # SYNOPSIS # ```c #include enum pmemset_coalescing; struct pmemset; int pmemset_set_contiguous_part_coalescing(struct pmemset *set, enum pmemset_coalescing value); ``` # DESCRIPTION # The **pmemset_set_contiguous_part_coalescing**() sets part coalescing feature flag in pmemset to the provided *value*. The possible values are *PMEMSET_COALESCING_NONE*, *PMEMSET_COALESCING_OPPORTUNISTIC* and *PMEMSET_COALESCING_FULL*. When part coalescing is enabled, the **pmemset_part_map**(3) function will try to coalesce each new mapped part with the previously mapped part, that means it will try to map the part directly after the previous mapping. The behavior of part mapping can be changed by setting one of possible values in pmemset: * *PMEMSET_COALESCING_NONE* - default behavior, no new mapped part will be coalesced, the position of each mapped part in virtual address space is chosen arbitrarily by the operating system * *PMEMSET_COALESCING_OPPORTUNISTIC* - each new mapped part will possibly be coalesced but if it's not possible it will be handled like with *PMEMSET_COALESCING_NONE* value set * *PMEMSET_COALESCING_FULL* - each new mapped part will be coalesced, if it's not possible the mapping will fail Mapping parts contiguously allows modifying the virtual address space of multiple parts with one operation using for example **memset**(3). The success of the part coalescing depends on the operating system and is not guaranteed. For more information see **pmemset_part_map**(3). Coalesced parts appear as single *struct pmemset_part_map* and can be retrieved by iterating over the pmemset using **pmemset_first_part_map**(3) and **pmemset_next_part_map**(3) or simply by retrieving part by its mapping address with **pmemset_part_map_by_address**(3) function. # RETURN VALUE The **pmemset_set_contiguous_part_coalescing**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmemset_set_contiguous_part_coalescing**() can fail with the following errors: * **PMEMSET_E_INVALID_COALESCING_VALUE** - contiguous part coalescing value not one of the possible values. # SEE ALSO # **pmemset_first_part_map**(3), **pmemset_next_part_map**(3), **pmemset_part_map(3)**, **pmemset_part_map_by_address**(3), **libpmemset**(7) and **** pmdk-1.11.1/doc/poolset/0000775000000000000000000000000014123364726013470 5ustar rootrootpmdk-1.11.1/doc/poolset/poolset.5.md0000664000000000000000000002374714123364546015657 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(POOLSET, 5) collection: poolset header: PMDK date: poolset API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (poolset.5 -- man page that describes format of pool set file) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[REPLICAS](#replicas)
[POOL SET OPTIONS](#pool-set-options)
[NOTES](#notes)
[SEE ALSO](#see-also)
# NAME # poolset - persistent memory pool configuration file format # SYNOPSIS # ```c mypool.set ``` # DESCRIPTION # Depending on the configuration of the system, the available non-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the transactional object store could be limited by the capacity of a single memory device. Therefore, **libpmemobj**(7), **libpmemblk**(7) and **libpmemlog**(7) allow building object stores spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a *pool set* may be stored on a different pmem-aware filesystem. To improve reliability and eliminate single point of failure, **libpmemobj**(7) also allows all the data written to a persistent memory pool to be copied to local _WINUX(,or remote) pool *replicas*, thereby providing backup for the persistent memory pool by producing a *mirrored pool set*. In practice, the pool replicas may be considered as binary copies of the "master" pool set. Data replication is not supported in **libpmemblk**(7) and **libpmemlog**(7). The *set* file for each type of pool is a plain text file. Lines in the file are formatted as follows: + The first line of the file must be the literal string "PMEMPOOLSET" + The pool parts are specified, one per line, in the format: *size* *pathname* + *Replica* sections, if any, start with the literal string "REPLICA". See **REPLICAS**, below, for further details. + Pool set options, if any, start with literal string *OPTION*. See **POOL SET OPTIONS** below for details. + Lines starting with "#" are considered comments and are ignored. The *size* must be compliant with the format specified in IEC 80000-13, IEEE 1541 or the Metric Interchange Format. These standards accept SI units with obligatory B - kB, MB, GB, ... (multiplier by 1000) suffixes, and IEC units with optional "iB" - KiB, MiB, GiB, ..., K, M, G, ... - (multiplier by 1024) suffixes. *pathname* must be an absolute pathname. The *pathname* of a part can point to a Device DAX. Device DAX is the device-centric analogue of Filesystem DAX. It allows memory ranges to be allocated and mapped without need of an intervening file system. Pools created on Device DAX have additional options and restrictions: + The *size* may be set to "AUTO", in which case the size of the device will be automatically resolved at pool creation time. + To concatenate more than one Device DAX device into a single pool set, the configured internal alignment of the devices must be 4KiB, unless the *SINGLEHDR* or *NOHDRS* option is used in the pool set file. See **POOL SET OPTIONS** below for details. Please see **ndctl-create-namespace**(1) for more information on Device DAX, including how to configure desired alignment. The minimum file size of each part of the pool set is defined as follows: + For block pools, as **PMEMBLK_MIN_PART** in **\** + For object pools, as **PMEMOBJ_MIN_PART** in **\** + For log pools, as **PMEMLOG_MIN_PART** in **\** The net pool size of the pool set is equal to: ``` net_pool_size = sum_over_all_parts(page_aligned_part_size - 4KiB) + 4KiB ``` where ``` page_aligned_part_size = part_size & ~(page_size - 1) ``` Note that page size is OS specific. For more information please see **sysconf**(3). The minimum net pool size of a pool set is defined as follows: + For block pools, as **PMEMBLK_MIN_POOL** in **\** + For object pools, as **PMEMOBJ_MIN_POOL** in **\** + For log pools, as **PMEMLOG_MIN_POOL** in **\** Here is an example "mypool.set" file: ``` PMEMPOOLSET OPTION NOHDRS 100G /mountpoint0/myfile.part0 200G /mountpoint1/myfile.part1 400G /mountpoint2/myfile.part2 ``` The files in the set may be created by running one of the following commands. To create a block pool: ``` $ pmempool create blk mypool.set ``` To create a log pool: ``` $ pmempool create log mypool.set ``` # REPLICAS # Sections defining replica sets are optional. There may be multiple replica sections. Local replica sections begin with a line containing only the literal string "REPLICA", followed by one or more pool part lines as described above. _WINUX(, =q=Remote replica sections consist of the *REPLICA* keyword, followed on the same line by the address of a remote host and a relative path to a remote pool set file: ``` REPLICA [@] [/] ``` + *hostname* must be in the format recognized by the **ssh**(1) remote login client + *pathname* is relative to the root config directory on the target node - see **librpmem**(7) There are no other lines in the remote replica section - the REPLICA line defines a remote replica entirely. =e=) Here is an example "myobjpool.set" file with replicas: ``` PMEMPOOLSET 100G /mountpoint0/myfile.part0 200G /mountpoint1/myfile.part1 400G /mountpoint2/myfile.part2 # local replica REPLICA 500G /mountpoint3/mymirror.part0 200G /mountpoint4/mymirror.part1 _WINUX(,=q= # remote replica REPLICA user@example.com remote-objpool.set=e=) ``` The files in the object pool set may be created by running the following command: ``` $ pmempool create --layout="mylayout" obj myobjpool.set ``` _WINUX(, =q=Remote replica cannot have replicas, i.e. a remote pool set file cannot define any replicas.=e=) # POOL SET OPTIONS # Pool set options can appear anywhere after the line with *PMEMPOOLSET* string. Pool set file can contain several pool set options. The following options are supported: + *SINGLEHDR* + *NOHDRS* If the *SINGLEHDR* option is used, only the first part in each replica contains the pool part internal metadata. In that case the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. The *NOHDRS* option can appear only in the remote pool set file, when **librpmem** does not serve as a means of replication for **libpmemobj** pool. In that case none of the pool parts contains internal metadata. The effective size of such a replica is the sum of sizes of all its part files. Options *SINGLEHDR* and *NOHDRS* are mutually exclusive. If both are specified in a pool set file, creating or opening the pool will fail with an error. When using the *SINGLEHDR* or *NOHDRS* option, one can concatenate more than one Device DAX devices with any internal alignments in one replica. The *SINGLEHDR* option concerns only replicas that are local to the pool set file. That is if one wants to create a pool set with the *SINGLEHDR* option and with remote replicas, one has to add this option to the local pool set file as well as to every single remote pool set file. Using the *SINGLEHDR* and *NOHDRS* options has important implications for data integrity checking and recoverability in case of a pool set damage. See _UW(pmempool_sync) API for more information about pool set recovery. # DIRECTORIES # Providing a directory as a part's *pathname* allows the pool to dynamically create files and consequently removes the user-imposed limit on the size of the pool. The *size* argument of a part in a directory poolset becomes the size of the address space reservation required for the pool. In other words, the size argument is the maximum theoretical size of the mapping. This value can be freely increased between instances of the application, but decreasing it below the real required space will result in an error when attempting to open the pool. The directory must NOT contain user created files with extension *.pmem*, otherwise the behavior is undefined. If a file created by the library within the directory is in any way altered (resized, renamed) the behavior is undefined. A directory poolset must exclusively use directories to specify paths - combining files and directories will result in an error. A single replica can consist of one or more directories. If there are multiple directories, the address space reservation is equal to the sum of the sizes. The order in which the files are created is unspecified, but the library will try to maintain equal usage of the directories. By default pools grow in 128 megabyte increments. Only poolsets with the *SINGLEHDR* option can safely use directories. # NOTES # Creation of all the parts of the pool set and the associated replica sets can be done with the **pmemobj_create**(3), **pmemblk_create**(3) or **pmemlog_create**(3) function, or by using the **pmempool**(1) utility. Restoring data from a local _WINUX(,or remote) replica can be done by using the **pmempool-sync**(1) command or the _UW(pmempool_sync) API from the **libpmempool**(7) library. Modifications of a pool set file configuration can be done by using the **pmempool-transform**(1) command or the _UW(pmempool_transform) API from the **libpmempool**(7) library. When creating a pool set consisting of multiple files, or when creating a replicated pool set, the *path* argument passed to **pmemobj_create**(3), **pmemblk_create**(3) or **pmemlog_create**(3) must point to the special *set* file that defines the pool layout and the location of all the parts of the pool set. When opening a pool set consisting of multiple files, or when opening a replicated pool set, the *path* argument passed to **pmemobj_open**(3), **pmemblk_open**(3) or **pmemlog_open**(3) must point to the same *set* file that was used for pool set creation. # SEE ALSO # **ndctl-create-namespace**(1), **pmemblk_create**(3), **pmemlog_create**(3), **pmemobj_create**(3), **sysconf**(3), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/poolset/.gitignore0000664000000000000000000000001214123364546015451 0ustar rootrootpoolset.5 pmdk-1.11.1/doc/poolset/poolset.50000664000000000000000000002527314123364726015254 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "POOLSET" "5" "2021-09-24" "PMDK - poolset API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP poolset \- persistent memory pool configuration file format .SH SYNOPSIS .IP .nf \f[C] mypool.set \f[] .fi .SH DESCRIPTION .PP Depending on the configuration of the system, the available non\-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the transactional object store could be limited by the capacity of a single memory device. Therefore, \f[B]libpmemobj\f[](7), \f[B]libpmemblk\f[](7) and \f[B]libpmemlog\f[](7) allow building object stores spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a \f[I]pool set\f[] may be stored on a different pmem\-aware filesystem. .PP To improve reliability and eliminate single point of failure, \f[B]libpmemobj\f[](7) also allows all the data written to a persistent memory pool to be copied to local or remote pool \f[I]replicas\f[], thereby providing backup for the persistent memory pool by producing a \f[I]mirrored pool set\f[]. In practice, the pool replicas may be considered as binary copies of the \[lq]master\[rq] pool set. Data replication is not supported in \f[B]libpmemblk\f[](7) and \f[B]libpmemlog\f[](7). .PP The \f[I]set\f[] file for each type of pool is a plain text file. Lines in the file are formatted as follows: .IP \[bu] 2 The first line of the file must be the literal string \[lq]PMEMPOOLSET\[rq] .IP \[bu] 2 The pool parts are specified, one per line, in the format: .RS 2 .PP \f[I]size\f[] \f[I]pathname\f[] .RE .IP \[bu] 2 \f[I]Replica\f[] sections, if any, start with the literal string \[lq]REPLICA\[rq]. See \f[B]REPLICAS\f[], below, for further details. .IP \[bu] 2 Pool set options, if any, start with literal string \f[I]OPTION\f[]. See \f[B]POOL SET OPTIONS\f[] below for details. .IP \[bu] 2 Lines starting with \[lq]#\[rq] are considered comments and are ignored. .PP The \f[I]size\f[] must be compliant with the format specified in IEC 80000\-13, IEEE 1541 or the Metric Interchange Format. These standards accept SI units with obligatory B \- kB, MB, GB, \&... (multiplier by 1000) suffixes, and IEC units with optional \[lq]iB\[rq] \- KiB, MiB, GiB, \&..., K, M, G, \&... \- (multiplier by 1024) suffixes. .PP \f[I]pathname\f[] must be an absolute pathname. .PP The \f[I]pathname\f[] of a part can point to a Device DAX. Device DAX is the device\-centric analogue of Filesystem DAX. It allows memory ranges to be allocated and mapped without need of an intervening file system. .PP Pools created on Device DAX have additional options and restrictions: .IP \[bu] 2 The \f[I]size\f[] may be set to \[lq]AUTO\[rq], in which case the size of the device will be automatically resolved at pool creation time. .IP \[bu] 2 To concatenate more than one Device DAX device into a single pool set, the configured internal alignment of the devices must be 4KiB, unless the \f[I]SINGLEHDR\f[] or \f[I]NOHDRS\f[] option is used in the pool set file. See \f[B]POOL SET OPTIONS\f[] below for details. .PP Please see \f[B]ndctl\-create\-namespace\f[](1) for more information on Device DAX, including how to configure desired alignment. .PP The minimum file size of each part of the pool set is defined as follows: .IP \[bu] 2 For block pools, as \f[B]PMEMBLK_MIN_PART\f[] in \f[B]\f[] .IP \[bu] 2 For object pools, as \f[B]PMEMOBJ_MIN_PART\f[] in \f[B]\f[] .IP \[bu] 2 For log pools, as \f[B]PMEMLOG_MIN_PART\f[] in \f[B]\f[] .PP The net pool size of the pool set is equal to: .IP .nf \f[C] net_pool_size\ =\ sum_over_all_parts(page_aligned_part_size\ \-\ 4KiB)\ +\ 4KiB \f[] .fi .PP where .IP .nf \f[C] page_aligned_part_size\ =\ part_size\ &\ ~(page_size\ \-\ 1) \f[] .fi .PP Note that page size is OS specific. For more information please see \f[B]sysconf\f[](3). .PP The minimum net pool size of a pool set is defined as follows: .IP \[bu] 2 For block pools, as \f[B]PMEMBLK_MIN_POOL\f[] in \f[B]\f[] .IP \[bu] 2 For object pools, as \f[B]PMEMOBJ_MIN_POOL\f[] in \f[B]\f[] .IP \[bu] 2 For log pools, as \f[B]PMEMLOG_MIN_POOL\f[] in \f[B]\f[] .PP Here is an example \[lq]mypool.set\[rq] file: .IP .nf \f[C] PMEMPOOLSET OPTION\ NOHDRS 100G\ /mountpoint0/myfile.part0 200G\ /mountpoint1/myfile.part1 400G\ /mountpoint2/myfile.part2 \f[] .fi .PP The files in the set may be created by running one of the following commands. To create a block pool: .IP .nf \f[C] $\ pmempool\ create\ blk\ \ mypool.set \f[] .fi .PP To create a log pool: .IP .nf \f[C] $\ pmempool\ create\ log\ mypool.set \f[] .fi .SH REPLICAS .PP Sections defining replica sets are optional. There may be multiple replica sections. .PP Local replica sections begin with a line containing only the literal string \[lq]REPLICA\[rq], followed by one or more pool part lines as described above. .PP Remote replica sections consist of the \f[I]REPLICA\f[] keyword, followed on the same line by the address of a remote host and a relative path to a remote pool set file: .IP .nf \f[C] REPLICA\ [\@]\ [/] \f[] .fi .IP \[bu] 2 \f[I]hostname\f[] must be in the format recognized by the \f[B]ssh\f[](1) remote login client .IP \[bu] 2 \f[I]pathname\f[] is relative to the root config directory on the target node \- see \f[B]librpmem\f[](7) .PP There are no other lines in the remote replica section \- the REPLICA line defines a remote replica entirely. .PP Here is an example \[lq]myobjpool.set\[rq] file with replicas: .IP .nf \f[C] PMEMPOOLSET 100G\ /mountpoint0/myfile.part0 200G\ /mountpoint1/myfile.part1 400G\ /mountpoint2/myfile.part2 #\ local\ replica REPLICA 500G\ /mountpoint3/mymirror.part0 200G\ /mountpoint4/mymirror.part1\ #\ remote\ replica REPLICA\ user\@example.com\ remote\-objpool.set \f[] .fi .PP The files in the object pool set may be created by running the following command: .IP .nf \f[C] $\ pmempool\ create\ \-\-layout="mylayout"\ obj\ myobjpool.set \f[] .fi .PP Remote replica cannot have replicas, i.e.\ a remote pool set file cannot define any replicas. .SH POOL SET OPTIONS .PP Pool set options can appear anywhere after the line with \f[I]PMEMPOOLSET\f[] string. Pool set file can contain several pool set options. The following options are supported: .IP \[bu] 2 \f[I]SINGLEHDR\f[] .IP \[bu] 2 \f[I]NOHDRS\f[] .PP If the \f[I]SINGLEHDR\f[] option is used, only the first part in each replica contains the pool part internal metadata. In that case the effective size of a replica is the sum of sizes of all its part files decreased once by 4096 bytes. .PP The \f[I]NOHDRS\f[] option can appear only in the remote pool set file, when \f[B]librpmem\f[] does not serve as a means of replication for \f[B]libpmemobj\f[] pool. In that case none of the pool parts contains internal metadata. The effective size of such a replica is the sum of sizes of all its part files. .PP Options \f[I]SINGLEHDR\f[] and \f[I]NOHDRS\f[] are mutually exclusive. If both are specified in a pool set file, creating or opening the pool will fail with an error. .PP When using the \f[I]SINGLEHDR\f[] or \f[I]NOHDRS\f[] option, one can concatenate more than one Device DAX devices with any internal alignments in one replica. .PP The \f[I]SINGLEHDR\f[] option concerns only replicas that are local to the pool set file. That is if one wants to create a pool set with the \f[I]SINGLEHDR\f[] option and with remote replicas, one has to add this option to the local pool set file as well as to every single remote pool set file. .PP Using the \f[I]SINGLEHDR\f[] and \f[I]NOHDRS\f[] options has important implications for data integrity checking and recoverability in case of a pool set damage. See \f[B]pmempool_sync\f[]() API for more information about pool set recovery. .SH DIRECTORIES .PP Providing a directory as a part's \f[I]pathname\f[] allows the pool to dynamically create files and consequently removes the user\-imposed limit on the size of the pool. .PP The \f[I]size\f[] argument of a part in a directory poolset becomes the size of the address space reservation required for the pool. In other words, the size argument is the maximum theoretical size of the mapping. This value can be freely increased between instances of the application, but decreasing it below the real required space will result in an error when attempting to open the pool. .PP The directory must NOT contain user created files with extension \f[I].pmem\f[], otherwise the behavior is undefined. If a file created by the library within the directory is in any way altered (resized, renamed) the behavior is undefined. .PP A directory poolset must exclusively use directories to specify paths \- combining files and directories will result in an error. A single replica can consist of one or more directories. If there are multiple directories, the address space reservation is equal to the sum of the sizes. .PP The order in which the files are created is unspecified, but the library will try to maintain equal usage of the directories. .PP By default pools grow in 128 megabyte increments. .PP Only poolsets with the \f[I]SINGLEHDR\f[] option can safely use directories. .SH NOTES .PP Creation of all the parts of the pool set and the associated replica sets can be done with the \f[B]pmemobj_create\f[](3), \f[B]pmemblk_create\f[](3) or \f[B]pmemlog_create\f[](3) function, or by using the \f[B]pmempool\f[](1) utility. .PP Restoring data from a local or remote replica can be done by using the \f[B]pmempool\-sync\f[](1) command or the \f[B]pmempool_sync\f[]() API from the \f[B]libpmempool\f[](7) library. .PP Modifications of a pool set file configuration can be done by using the \f[B]pmempool\-transform\f[](1) command or the \f[B]pmempool_transform\f[]() API from the \f[B]libpmempool\f[](7) library. .PP When creating a pool set consisting of multiple files, or when creating a replicated pool set, the \f[I]path\f[] argument passed to \f[B]pmemobj_create\f[](3), \f[B]pmemblk_create\f[](3) or \f[B]pmemlog_create\f[](3) must point to the special \f[I]set\f[] file that defines the pool layout and the location of all the parts of the pool set. .PP When opening a pool set consisting of multiple files, or when opening a replicated pool set, the \f[I]path\f[] argument passed to \f[B]pmemobj_open\f[](3), \f[B]pmemblk_open\f[](3) or \f[B]pmemlog_open\f[](3) must point to the same \f[I]set\f[] file that was used for pool set creation. .SH SEE ALSO .PP \f[B]ndctl\-create\-namespace\f[](1), \f[B]pmemblk_create\f[](3), \f[B]pmemlog_create\f[](3), \f[B]pmemobj_create\f[](3), \f[B]sysconf\f[](3), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/0000775000000000000000000000000014123364743013511 5ustar rootrootpmdk-1.11.1/doc/libpmem2/pmem2_badblock_context_new.3.md0000664000000000000000000000704014123364546021454 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_BADBLOCK_CONTEXT_NEW, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_badblock_context_new.3 -- man page for) [comment]: <> (pmem2_badblock_context_new and pmem2_badblock_context_delete) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_badblock_context_new**(), **pmem2_badblock_context_delete**() - allocate and free a context for **pmem2_badblock_next**() and **pmem2_badblock_clear**() operations # SYNOPSIS # ```c #include struct pmem2_source; struct pmem2_badblock_context; int pmem2_badblock_context_new( struct pmem2_badblock_context **bbctx, const struct pmem2_source *src); void pmem2_badblock_context_delete( struct pmem2_badblock_context **bbctx); ``` # DESCRIPTION # The **pmem2_badblock_context_new**() function instantiates a new (opaque) bad block context structure, *pmem2_badblock_context*, which is used to read and clear bad blocks (by **pmem2_badblock_next**() and **pmem2_badblock_clear**()). The function returns the bad block context through the pointer in *\*bbctx*. New bad block context structure is initialized with values read from the source given as the first argument (*src*). A bad block is an uncorrectable media error - a part of a storage media that is either inaccessible or unwritable due to permanent physical damage. In case of memory-mapped I/O, if a process tries to access (read or write) the corrupted block, it will be terminated by the SIGBUS signal. The **pmem2_badblock_context_delete**() function frees *\*bbctx* returned by **pmem2_badblock_context_new**() and sets *\*bbctx* to NULL. If *\*bbctx* is NULL, no operation is performed. It is not supported on Windows. # RETURN VALUE # The **pmem2_badblock_context_new**() function returns 0 on success or a negative error code on failure. The **pmem2_badblock_context_new**() sets *\*bbctx* to NULL on failure. The **pmem2_badblock_context_delete**() does not return any value. # ERRORS # The **pmem2_badblock_context_new**() can fail with the following errors: * **PMEM2_E_INVALID_FILE_TYPE** - *src* is not a regular file nor a character device. * **PMEM2_E_DAX_REGION_NOT_FOUND** - cannot find a DAX region for the given *src*. * **PMEM2_E_CANNOT_READ_BOUNDS** - cannot read offset or size of the namespace of the given *src*. * **PMEM2_E_NOSUPP** - on Windows or when the OS does not support this functionality - **-ENOMEM** - out of memory * **-errno** - set by failing **ndctl_new**, while trying to create a new ndctl context. * **-errno** - set by failing **fstat**(2), while trying to validate the file descriptor of *src*. * **-errno** - set by failing **realpath**(3), while trying to get the canonicalized absolute sysfs pathname of DAX device given in *src*. * **-errno** - set by failing **open**(2), while trying to open the FSDAX device matching with the *src*. * **-errno** - set by failing **read**(2), while trying to read from the FSDAX device matching with the *src*. * **-errno** - set by failing **ndctl_region_get_resource**, while reading an offset of the region of the given *src*. * **-errno** - set by failing **fiemap ioctl(2)**, while reading file extents of the given *src*. # SEE ALSO # **pmem2_badblock_next**(3), **pmem2_badblock_clear**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_numa_node.30000664000000000000000000000410614123364737020226 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_NUMA_NODE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_numa_node\f[]() \- returns data source numa node .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; int\ pmem2_source_numa_node(const\ struct\ pmem2_source\ *source,\ int\ *numa_node); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_numa_node\f[]() function retrieves the numa node of the given data source. The numa node can be used to, e.g., pin threads to near\-memory cores. The numa node is stored in \f[I]*numa_node\f[]. It is the same value that is shown as \f[C]numa_node\f[] in \f[C]ndctl\ list\ \-v\f[]. .SH RETURN VALUE .PP The \f[B]pmem2_source_numa_node\f[]() function returns 0 on success. If the function fails, the \f[I]*numa_node\f[] variable is left unmodified and a negative error code is returned. .SH ERRORS .PP The \f[B]pmem2_source_numa_node\f[]() can fail with the following errors: .PP On all systems: .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- source type or operating system not supported (see #caveats for details.) .PP on Linux: .IP \[bu] 2 \f[B]PMEM2_E_DAX_REGION_NOT_FOUND\f[] \- no \f[B]ndctl_region\f[] could be determined for the source. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- if the source points to a directory. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]ndctl_new\f[], while trying to create a new context. .SH CAVEATS .PP This call requires \f[B]libndctl\f[] to retrieve the numa information. It only works for sources that are actually located on persistent memory, i.e., devdax or fsdax. As anonymous sources are not backed by files on persistent memory, this method is not supported for them. It also does not work under Windows or systems without \f[B]libndctl\f[]. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]ndctl_new\f[](3), \f[B]pmem2_source_from_handle\f[](3), \f[B]pmem2_source_from_fd\f[](3), \f[B]libpmem2\f[](7), \f[B]libndctl\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_badblock_clear.3.md0000664000000000000000000000406314123364546020207 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_BADBLOCK_CLEAR, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_badblock_clear.3 -- man page for pmem2_badblock_clear) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_badblock_clear**() - clear the given bad block # SYNOPSIS # ```c #include struct pmem2_badblock; struct pmem2_badblock_context; int pmem2_badblock_clear( struct pmem2_badblock_context *bbctx, struct pmem2_badblock *bb); ``` # DESCRIPTION # The **pmem2_badblock_clear**() function clears the given *\*bb* bad block. It means that the **pmem2_badblock_clear**() function unmaps bad blocks and maps new, healthy, blocks in place of the bad ones. The new blocks are zeroed. The content of the bad blocks is lost. It is not supported on Windows. # RETURN VALUE # The **pmem2_badblock_clear**() function clears the given *\*bb* bad block and returns 0 on success or a negative error code on failure. # ERRORS # **pmem2_badblock_clear**() can fail with the following errors: * **PMEM2_E_OFFSET_OUT_OF_RANGE** - bad block's offset is greater than INT64_MAX * **PMEM2_E_LENGTH_OUT_OF_RANGE** - bad block's length is greater than INT64_MAX * **PMEM2_E_NOSUPP** - on Windows or when the OS does not support this functionality * **-errno** - set by failing **fallocate**(2), while deallocating bad blocks or allocating new blocks * **-errno** - set by failing ndctl functions: **ndctl_bus_cmd_new_ars_cap**, **ndctl_cmd_submit**, **ndctl_cmd_ars_cap_get_range** or **ndctl_bus_cmd_new_clear_error** while trying to clear a bad block in a DAX device * **-ENXIO** - **ndctl_bus_cmd_new_clear_error** did not manage to clear all bad blocks # SEE ALSO # **pmem2_badblock_context_new**(3), **pmem2_badblock_next**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_device_usc.30000664000000000000000000000456014123364742020372 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_DEVICE_USC" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_device_usc\f[]() \- returns the \f[I]unsafe shutdown counter\f[] value of a device .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; int\ pmem2_source_device_usc(const\ struct\ pmem2_source\ *source,\ uint64_t\ *usc); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_device_usc\f[]() function retrieves the sum of the \f[I]unsafe shutdown count\f[](\f[B]USC\f[]) values of all hardware devices backing the data source and stores it in \f[I]*usc\f[]. .PP Please refer to \f[B]libpmem2_unsafe_shutdown\f[](7) for detailed description on how to properly consume this information. .SH RETURN VALUE .PP The \f[B]pmem2_source_device_usc\f[]() function returns 0 on success. If the function fails, the \f[I]*usc\f[] variable content is left unmodified and a negative error code is returned. .SH ERRORS .PP The \f[B]pmem2_source_device_usc\f[]() can fail with the following errors: .PP On all systems: .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- the underlying platform does not expose unsafe shutdown count information. .PP On Windows: .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]GetFinalPathNameByHandleW\f[](), while trying to resolve volume path from the file handle. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]malloc\f[](3), while trying to allocate a buffer for storing volume path. .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]CreateFileW\f[](), while trying to obtain a handle to the volume. .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]DeviceIoControl\f[](), while trying to obtain volume \f[B]USC\f[] value. .PP On Linux: .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]ndctl_new\f[](), while trying to initiate a new NDCTL library context. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]ndctl_dimm_get_dirty_shutdown\f[](), while trying to obtain DIMM \f[B]USC\f[] value. .SH SEE ALSO .PP \f[B]fstat\f[](2), \f[B]errno\f[](3), \f[B]malloc\f[](3), \f[B]libpmem2_unsafe_shutdown\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_protection.30000664000000000000000000000371014123364742021263 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_PROTECTION" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_protection\f[]() \- set a protection flags in pmem2_config structure. .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; #define\ PMEM2_PROT_EXEC\ \ \ \ \ (1U\ <<\ 29) #define\ PMEM2_PROT_READ\ \ \ \ \ (1U\ <<\ 30) #define\ PMEM2_PROT_WRITE\ \ \ \ (1U\ <<\ 31) #define\ PMEM2_PROT_NONE\ \ \ \ \ 0 int\ pmem2_config_set_protection(struct\ pmem2_config\ *cfg, \ \ \ \ \ \ \ \ unsigned\ prot); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_protection\f[]() function sets the protection flags which will be used for memory mapping. The default value in pmem2_config structure is \f[B]PMEM2_PROT_READ | PMEM2_PROT_WRITE\f[]. The \f[I]argument describes the desired memory protection of the mapping. The memory protection cannot conflict with the file opening\-mode. \f[]*config* should be already initialized, please see \f[B]pmem2_config_new\f[](3) for details. .PP It is either PROT_NONE or the bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEM2_PROT_EXEC\f[] \- Pages may be executed. .IP \[bu] 2 \f[B]PMEM2_PROT_READ\f[] \- Pages may be read. .IP \[bu] 2 \f[B]PMEM2_PROT_WRITE\f[] \- Pages may be written. .IP \[bu] 2 \f[B]PMEM2_PROT_NONE\f[] \- Pages may not be accessed. On Windows this flag is not supported. .SH RETURN VALUE .PP The \f[B]pmem2_config_set_protection\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_config_set_protection\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_PROT_FLAG\f[] \- some or all of the provided flags are not valid. .SH SEE ALSO .PP \f[B]libpmem2\f[](7), \f[B]pmem2_config_new\f[](3), \f[B]pmem2_map_new\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_perror.30000664000000000000000000000206414123364740016205 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_PERROR" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_perror\f[]() \- prints a descriptive error message to stderr .SH SYNOPSIS .IP .nf \f[C] #include\ void\ pmem2_perror(const\ char\ *format,\ ...); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_perror\f[]() function produces a message on standard error stream describing the last error encountered during library call. .PP \f[B]pmem2_perror\f[]() takes a variable number of arguments. First, the argument string \f[I]format\f[] is printed \- similarly to the \f[B]printf\f[](3), followed by a colon and a blank. Then an error message retrieved from the \f[B]pmem2_errormsg\f[](), and a new\-line. To see how the error message is generated, please see \f[B]pmem2_errormsg\f[](3). .SH SEE ALSO .PP \f[B]libpmem2\f[](7), \f[B]perror\f[](3), \f[B]pmem2_errormsg\f[](3), \f[B]printf\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_map_get_address.3.md0000664000000000000000000000201114123364546020410 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_GET_ADDRESS, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019, Intel Corporation) [comment]: <> (pmem2_map_get_address.3 -- man page for libpmem2 mapping operations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_get_address**() - reads mapping address # SYNOPSIS # ```c #include void *pmem2_map_get_address(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_map_get_address**() function reads address of the created mapping. The *map* parameter points to the structure describing mapping created using the **pmem2_map_new**(3) function. # RETURN VALUE # The **pmem2_map_get_address**() function returns a pointer to the mapped area. # SEE ALSO # **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_get_fd.30000664000000000000000000000234114123364743017505 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_GET_FD" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_get_fd\f[]() \- reads file descriptor of the data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_source_get_fd(const\ struct\ pmem2_source\ *src,\ int\ *fd); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_get_fd\f[]() function reads the file descriptor of *struct pmem2_source** object describing the data source and returns it by \f[I]fd\f[] parameter. .PP This function is Linux only, on Windows use \f[B]pmem2_source_get_handle\f[](3). .SH RETURN VALUE .PP The \f[B]pmem2_source_get_fd\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_source_get_fd\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_FILE_DESCRIPTOR_NOT_SET\f[] \- in case of an instance of \f[I]struct pmem2_source\f[] that does not come from source type that support file descriptors, eg. anonymous data source. .SH SEE ALSO .PP \f[B]pmem2_source_get_handle\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_map_delete.3.md0000664000000000000000000000343314123364546017377 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_DELETE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2019-2020, Intel Corporation) [comment]: <> (pmem2_map_delete.3 -- man page for libpmem2 pmem2_map_delete operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_delete**() - deletes a mapping # SYNOPSIS # ```c #include int pmem2_map_delete(struct pmem2_map **map_ptr); ``` # DESCRIPTION # The **pmem2_map_delete**() function deletes the mapping described by the *struct pmem2_map* object. If **pmem2_map_delete**() succeeds in deleting the mapping, it releases the *struct pmem2_map* object describing it and writes a NULL value to *map_ptr*. If the function fails, the *map_ptr* variable and the map object itself are left unmodified and appropriate error value is returned. For a list of possible return values please see [RETURN VALUE](#return-value). The **pmem2_map_delete**() function will not unmap mapping provided by the user by **pmem2_map_from_existing**() function. In such case it will only free *struct pmem2_map* object. # RETURN VALUE # The **pmem2_map_delete**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_map_delete**() can fail with the following errors: * **PMEM2_E_MAPPING_NOT_FOUND** - mapping was not found (it was already unmapped or pmem2_map state was corrupted) On systems other than Windows it can also return **-EINVAL** from the underlying **munmap**(2) function. # SEE ALSO # **pmem2_map_new(3)**, **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_get_store_granularity.30000664000000000000000000000216114123364737022151 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_GET_STORE_GRANULARITY" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_map_get_store_granularity\f[]() \- reads effective mapping granularity .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ pmem2_granularity\ { \ \ \ \ PMEM2_GRANULARITY_BYTE, \ \ \ \ PMEM2_GRANULARITY_CACHE_LINE, \ \ \ \ PMEM2_GRANULARITY_PAGE, }; enum\ pmem2_granularity\ pmem2_map_get_store_granularity(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_get_store_granularity\f[]() function reads granularity of the created mapping. The \f[I]map\f[] parameter points to the structure describing mapping created using the \f[B]pmem2_map_new\f[](3) function. Concept of the granularity is described in \f[B]libpmem2\f[](7). .SH RETURN VALUE .PP The \f[B]pmem2_map_get_store_granularity\f[]() function returns a granularity of the mapped area. .SH SEE ALSO .PP \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_errormsg.30000664000000000000000000000265614123364735016547 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_ERRORMSG" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019, Intel Corporation .SH NAME .PP \f[B]pmem2_errormsg\f[]() \- returns last error message .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *pmem2_errormsg(void); \f[] .fi .SH DESCRIPTION .PP If an error is detected during the call to a \f[B]libpmem2\f[](7) function, the application may retrieve an error message describing the reason of the failure from \f[B]pmem2_errormsg\f[](). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmem2\f[](7) function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. .SH RETURN VALUE .PP The \f[B]pmem2_errormsg\f[]() function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). .SH SEE ALSO .PP \f[B]strerror\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_get_size.3.md0000664000000000000000000000225214123364546022232 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_VM_RESERVATION_GET_SIZE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_vm_reservation_get_size.3 -- man page for libpmem2 virtual memory reservation operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_vm_reservation_get_size**() - reads virtual memory reservation size # SYNOPSIS # ```c #include size_t pmem2_vm_reservation_get_size(struct pmem2_vm_reservation *rsv); ``` # DESCRIPTION # The **pmem2_vm_reservation_get_size**() function reads size of the created virtual memory reservation. The *rsv* parameter points to the structure describing virtual memory reservation created using the **pmem2_vm_reservation_new**(3) function. # RETURN VALUE # The **pmem2_vm_reservation_get_size**() function returns a size of the virtual reservation area. # SEE ALSO # **pmem2_vm_reservation_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_new.3.md0000664000000000000000000001106514123364546016726 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_NEW, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019-2020, Intel Corporation) [comment]: <> (pmem2_map_new.3 -- man page for libpmem2 pmem2_map_new operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_new**() - creates a mapping # SYNOPSIS # ```c #include struct pmem2_config; struct pmem2_source; struct pmem2_map; int pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *config, const struct pmem2_source *source); ``` # DESCRIPTION # The **pmem2_map_new**() function creates a new mapping in the virtual address space of the calling process. This function requires a configuration *config* of the mapping and the data source *source*. Optionally, the mapping can be created at the offset of the virtual memory reservation set in the configuration *config*. See **pmem2_config_set_vm_reservation**(3) for details. For a mapping to succeed, the *config* structure must have the granularity parameter set to the appropriate level. See **pmem2_config_set_required_store_granularity**(3) and **libpmem2**(7) for more details. If the **pmem2_map_new**() function succeeds in creating a new mapping it instantiates a new *struct pmem2_map** object describing the mapping. The pointer to this newly created object is stored in the user-provided variable passed via the *map_ptr* pointer. If the mapping fails the variable pointed by *map_ptr* will contain a NULL value and appropriate error value will be returned. For a list of possible return values please see [RETURN VALUE](#return-value). All *struct pmem2_map* objects created via the **pmem2_map_new**() function have to be destroyed using the **pmem2_map_delete**() function. For details please see **pmem2_map_delete**(3) manual page. # RETURN VALUE # The **pmem2_map_new**() function returns 0 on succeeds or a negative error code on failure. # ERRORS # The **pmem2_map_new**() can fail with the following errors: * **PMEM2_E_GRANULARITY_NOT_SET** - the store granularity for the mapping was not set in the provided *config* structure. Please see **pmem2_config_set_required_store_granularity**(3) and **libpmem2**(7). * **PMEM2_E_MAP_RANGE** - *offset* + *length* is too big to represent it using *size_t* data type * **PMEM2_E_MAP_RANGE** - end of the mapping (*offset* + *length*) is outside of the file. The file is too small. * **PMEM2_E_SOURCE_EMPTY** - mapped file has size equal to 0. * **PMEM2_E_MAPPING_EXISTS** - if the object exists before the function call. For details please see **CreateFileMapping**() manual pages. (Windows only) * **PMEM2_E_OFFSET_UNALIGNED** - argument unaligned, offset is not a multiple of the alignment required for specific *\*source*. Please see **pmem2_source_alignement**(3). * **PMEM2_E_LENGTH_UNALIGNED** - argument unaligned, length is not a multiple of the alignment required for specific *\*source*. Please see **pmem2_source_alignement**(3). * **PMEM2_E_SRC_DEVDAX_PRIVATE** - device DAX mapped with MAP_PRIVATE. (Linux only) * **PMEM2_E_ADDRESS_UNALIGNED** - when mapping device DAX to a virtual memory reservation and the base mapping address (reservation address + reservation offset) is not aligned to the device DAX granularity. Please see **pmem2_config_set_vm_reservation**(3). (Linux only) * **PMEM2_E_ADDRESS_UNALIGNED** - when mapping to a virtual memory reservation and the region for the mapping exceeds reservation size. Please see **pmem2_config_set_vm_reservation**(3). * **PMEM2_E_NOSUPP** - when config-provided protection flags combination is not supported. * **PMEM2_E_NO_ACCESS** - there is a conflict between mapping protection and file opening mode. It can also return **-EACCES**, **-EAGAIN**, **-EBADF**, **-ENFILE**, **-ENODEV**, **-ENOMEM**, **-EPERM**, **-ETXTBSY** from the underlying **mmap**(2) function. It is used with and without **MAP_ANONYMOUS**. **-EACCES** may be returned only if the file descriptor points to an append-only file. It can also return all errors from the underlying **pmem2_source_size**() and **pmem2_source_alignment**() functions. # SEE ALSO # **mmap**(2), **open**(3), **pmem2_config_set_required_store_granularity**(3), **pmem2_source_alignment**(3), **pmem2_source_from_fd**(3), **pmem2_source_size**(3), **pmem2_map_delete**(3), **pmem2_config_set_vm_reservation**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_memcpy_fn.30000664000000000000000000000003314123364546017506 0ustar rootroot.so pmem2_get_memmove_fn.3 pmdk-1.11.1/doc/libpmem2/pmem2_badblock_clear.30000664000000000000000000000403614123364741017605 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_BADBLOCK_CLEAR" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_badblock_clear\f[]() \- clear the given bad block .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_badblock; struct\ pmem2_badblock_context; int\ pmem2_badblock_clear( \ \ \ \ \ \ \ \ struct\ pmem2_badblock_context\ *bbctx, \ \ \ \ \ \ \ \ struct\ pmem2_badblock\ *bb); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_badblock_clear\f[]() function clears the given \f[I]*bb\f[] bad block. .PP It means that the \f[B]pmem2_badblock_clear\f[]() function unmaps bad blocks and maps new, healthy, blocks in place of the bad ones. The new blocks are zeroed. The content of the bad blocks is lost. .PP It is not supported on Windows. .SH RETURN VALUE .PP The \f[B]pmem2_badblock_clear\f[]() function clears the given \f[I]*bb\f[] bad block and returns 0 on success or a negative error code on failure. .SH ERRORS .PP \f[B]pmem2_badblock_clear\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_OFFSET_OUT_OF_RANGE\f[] \- bad block's offset is greater than INT64_MAX .IP \[bu] 2 \f[B]PMEM2_E_LENGTH_OUT_OF_RANGE\f[] \- bad block's length is greater than INT64_MAX .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- on Windows or when the OS does not support this functionality .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]fallocate\f[](2), while deallocating bad blocks or allocating new blocks .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing ndctl functions: \f[B]ndctl_bus_cmd_new_ars_cap\f[], \f[B]ndctl_cmd_submit\f[], \f[B]ndctl_cmd_ars_cap_get_range\f[] or \f[B]ndctl_bus_cmd_new_clear_error\f[] while trying to clear a bad block in a DAX device .IP \[bu] 2 \f[B]\-ENXIO\f[] \- \f[B]ndctl_bus_cmd_new_clear_error\f[] did not manage to clear all bad blocks .SH SEE ALSO .PP \f[B]pmem2_badblock_context_new\f[](3), \f[B]pmem2_badblock_next\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_extend.30000664000000000000000000000731514123364743021315 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_VM_RESERVATION_EXTEND" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmem2_vm_reservation_extend\f[](), \f[B]pmem2_vm_reservation_shrink\f[]() \- extends and shrinks existing virtual memory reservation .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_vm_reservation; int\ pmem2_vm_reservation_extend(struct\ pmem2_vm_reservation\ *rsv,\ size_t\ size); int\ pmem2_vm_reservation_shrink(struct\ pmem2_vm_reservation\ *rsv,\ size_t\ offset, \ \ \ \ \ \ \ \ size_t\ size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_vm_reservation_extend\f[]() function extends an existing virtual memory reservation by the given \f[I]size\f[]. For the function to succeed the size has to be aligned to an appropriate allocation granularity. .PP If the \f[B]pmem2_vm_reservation_extend\f[]() succeeds in extending a reservation, it provides placeholder virtual memory range that starts from an address at the end of the old reservation. Mappings made to the reservation before extending are preserved. .PP The \f[B]pmem2_vm_reservation_shrink\f[]() function shrinks the reservation by a region specified by \f[I]offset\f[] into the reservation and the \f[I]size\f[]. For the function to succeed the \f[I]size\f[] and \f[I]offset\f[] variables have to be aligned to an appropriate allocation granularity. The region formed by \f[I]offset\f[] and \f[I]size\f[] has to belong to the reservation, be empty and it needs to cover the beggining or the end of the reservation. Shrinking reservation from the middle or shrinking the whole reservation is not supported. .PP If the \f[B]pmem2_vm_reservation_shrink\f[]() succeeds in shrinking a reservation, it releases placeholder virtual memory range that was designated by \f[I]offset\f[] and \f[I]size\f[] variables. Mappings made to the reservation before shrinking are preserved. .PP If either of those functions fails, reservation will be left as it was and appropriate error value will be returned. .SH RETURN VALUE .PP The \f[B]pmem2_vm_reservation_extend\f[]() and \f[B]pmem2_vm_reservation_shrink\f[]() functions return 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_vm_reservation_extend\f[]() function can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_MAPPING_EXISTS\f[] \- the range that the reservation would be extended by is already occupied by an existing mapping. .PP It can also return \f[B]\-EAGAIN\f[], \f[B]\-ENOMEM\f[] from the underlying \f[B]mmap\f[](2) function. .PP The \f[B]pmem2_vm_reservation_shrink\f[]() function can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_OFFSET_UNALIGNED\f[] \- provided offset isn't aligned to an appropriate allocation granularity. .IP \[bu] 2 \f[B]PMEM2_E_LENGTH_UNALIGNED\f[] \- provided size isn't aligned to an appropriate allocation granularity. .IP \[bu] 2 \f[B]PMEM2_E_OFFSET_OUT_OF_RANGE\f[] \- provided offset is out of reservation range available to be shrunk. .IP \[bu] 2 \f[B]PMEM2_E_LENGTH_OUT_OF_RANGE\f[] \- provided size is out of reservation range available to be shrunk. .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- interval designated by \f[I]offset\f[] and \f[I]size\f[] variables covers only the middle or the whole reservation range. .IP \[bu] 2 \f[B]PMEM2_VM_RESERVATION_NOT_EMPTY\f[] \- interval designated by \f[I]offset\f[] and \f[I]size\f[] variable is not empty. .PP It can also return \f[B]\-EAGAIN\f[] and \f[B]\-ENOMEM\f[] from the underlying \f[B]munmap\f[](2) function. .SH SEE ALSO .PP \f[B]pmem2_vm_reservation_new\f[](3), \f[B]pmem2_config_set_vm_reservation\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_get_flush_fn.3.md0000664000000000000000000000452414123364546017745 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_GET_FLUSH_FN, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_get_flush_fn.3 -- man page for pmem2_get_flush_fn) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_get_flush_fn**() - get a flush function # SYNOPSIS # ```c #include typedef void (*pmem2_flush_fn)(const void *ptr, size_t size); struct pmem2_map; pmem2_flush_fn pmem2_get_flush_fn(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_get_flush_fn**() function returns a pointer to a function responsible for efficiently flushing data in the range owned by the *map*. Flushing data using *pmem2_flush_fn* **does not** guarantee that the data is stored durably by the time it returns. To get this guarantee, application should either use the persist operation (see **pmem2_get_persist_fn**(3)) or follow *pmem2_flush_fn* by a drain operation (see **pmem2_get_drain_fn**(3)). There are no alignment restrictions on the range described by *ptr* and *size*, but *pmem2_flush_fn* may expand the range as necessary to meet platform alignment requirements. There is nothing atomic or transactional about *pmem2_flush_fn*. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until *pmem2_flush_fn* is called to be flushed -- they can be flushed at any time before *pmem2_flush_fn* is called. If two (or more) mappings share the same *pmem2_flush_fn* and they are adjacent to each other, it is safe to call this function for a range spanning those mappings. # RETURN VALUE # The **pmem2_get_flush_fn**() function never returns NULL. The **pmem2_get_flush_fn**() for the same *map* always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. # SEE ALSO # **pmem2_get_drain_fn**(3), **pmem2_get_persist_fn**(3), **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find.30000664000000000000000000000671514123364743021606 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_VM_RESERVATION_MAP_FIND" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2021, Intel Corporation .SH NAME .PP \f[B]pmem2_vm_reservation_map_find\f[](), \f[B]pmem2_vm_reservation_map_find_prev\f[](), \f[B]pmem2_vm_reservation_map_find_next\f[](), \f[B]pmem2_vm_reservation_map_find_first\f[]() and \f[B]pmem2_vm_reservation_map_find_last\f[]() \- search for the mapping located at the desirable location .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_map; struct\ pmem2_vm_reservation; int\ pmem2_vm_reservation_map_find(struct\ pmem2_vm_reservation\ *rsv, \ \ \ \ \ \ \ \ size_t\ reserv_offset,\ size_t\ len,\ struct\ pmem2_map\ **map_ptr); int\ pmem2_vm_reservation_map_find_prev(struct\ pmem2_vm_reservation\ *rsv, \ \ \ \ \ \ \ \ struct\ pmem2_map\ *map,\ struct\ pmem2_map\ **prev_map); int\ pmem2_vm_reservation_map_find_next(struct\ pmem2_vm_reservation\ *rsv, \ \ \ \ \ \ \ \ struct\ pmem2_map\ *map,\ struct\ pmem2_map\ **next_map); int\ pmem2_vm_reservation_map_find_first(struct\ pmem2_vm_reservation\ *rsv, \ \ \ \ \ \ \ \ struct\ pmem2_map\ **first_map); int\ pmem2_vm_reservation_map_find_last(struct\ pmem2_vm_reservation\ *rsv, \ \ \ \ \ \ \ \ struct\ pmem2_map\ **last_map); \f[] .fi .SH DESCRIPTION .PP Mappings are inserted to the virtual memory reservation in the order of their virtual address space location. First mapping represents the earliest mapping in the virtual addres space contained in a reservation, whereas the last mapping represents the last one. .PP The \f[B]pmem2_vm_reservation_map_find\f[]() function searches for the earliest mapping, stored in the virtual memory reservation, intersecting with the interval defined by \f[I]reserv_offset\f[] and \f[I]len\f[] variables and returns it via \f[I]map_ptr\f[] variable. .PP \f[B]pmem2_vm_reservation_map_find_prev\f[]() function searches for the map previous to the provided \f[I]map\f[] and returns it via provided \f[I]prev_map\f[] variable. .PP \f[B]pmem2_vm_reservation_map_find_next\f[]() function searches for the map next after the provided \f[I]map\f[] and returns it via \f[I]next_map\f[] variable. .PP \f[B]pmem2_vm_reservation_map_find_first\f[]() function searches for the first map in the reservation and returns it via provided \f[I]first_map\f[] variable. .PP \f[B]pmem2_vm_reservation_map_find_last\f[]() function searches for the last map in the reservation and returns it via provided \f[I]last_map\f[] variable. # RETURN VALUE # .PP The \f[B]pmem2_vm_reservation_map_find\f[](), \f[B]pmem2_vm_reservation_map_find_prev\f[](), \f[B]pmem2_vm_reservation_map_find_next\f[](), \f[B]pmem2_vm_reservation_map_find_first\f[]() and \f[B]pmem2_vm_reservation_map_find_last\f[]() return 0 on success or a negative error on failure. .PP It passes an address to the found mapping via user provided \f[I]map\f[] pointer variable on success, otherwise it passes \f[I]NULL\f[] value when no mapping was found. .SH ERRORS .PP The \f[B]pmem2_vm_reservation_map_find\f[](), \f[B]pmem2_vm_reservation_map_find_prev\f[](), \f[B]pmem2_vm_reservation_map_find_next\f[](), \f[B]pmem2_vm_reservation_map_find_first\f[]() and \f[B]pmem2_vm_reservation_map_find_last\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_MAPPING_NOT_FOUND\f[] \- no mapping found at the desirable location of the reservation .SH SEE ALSO .PP \f[B]libpmem2\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_sharing.3.md0000664000000000000000000000317214123364546021133 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_SHARING, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_set_sharing.3 -- man page for libpmem2 config API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_sharing**() - set sharing in the pmem2_config structure # SYNOPSIS # ```c #include struct pmem2_config; enum pmem2_sharing_type { PMEM2_SHARED, PMEM2_PRIVATE, }; int pmem2_config_set_sharing(struct pmem2_config *config, enum pmem2_sharing_type sharing); ``` # DESCRIPTION # The **pmem2_config_set_sharing**() function configures the behavior and visibility of writes to the mapping's pages. The possible values are listed below: * **PMEM2_SHARED** - Writes are made directly to the underlying memory, making them visible to other mappings of the same memory region. (default) * **PMEM2_PRIVATE** - Writes do not affect the underlying memory and are not visible to other mappings of the same memory region. # RETURN VALUE # The **pmem2_config_set_sharing**() function returns 0 on success or a negative error code on failure. # ERRORRS # The **pmem2_config_set_sharing**() can fail with the following errors: * **PMEM2_E_INVALID_SHARING_VALUE** - *sharing* value is invalid. # SEE ALSO # **libpmem2**(7), **pmem2_config_new**(3), **pmem2_map_new**(3), **sysconf**(3) and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_delete.30000664000000000000000000000002714123364546017464 0ustar rootroot.so pmem2_config_new.3 pmdk-1.11.1/doc/libpmem2/pmem2_map_get_address.30000664000000000000000000000152214123364736020020 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_GET_ADDRESS" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019, Intel Corporation .SH NAME .PP \f[B]pmem2_map_get_address\f[]() \- reads mapping address .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *pmem2_map_get_address(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_get_address\f[]() function reads address of the created mapping. The \f[I]map\f[] parameter points to the structure describing mapping created using the \f[B]pmem2_map_new\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmem2_map_get_address\f[]() function returns a pointer to the mapped area. .SH SEE ALSO .PP \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_deep_flush.30000664000000000000000000000357214123364742017021 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_DEEP_FLUSH" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_deep_flush\f[]() \- highly reliable persistent memory synchronization .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_deep_flush(struct\ pmem2_map\ *map,\ void\ *ptr,\ size_t\ size) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_deep_flush\f[]() function forces any changes in the range [\f[I]ptr\f[], \f[I]ptr\f[]+\f[I]len\f[]) from the \f[I]map\f[] to be stored durably in the most reliable persistence domain available to software. In particular, on supported platforms, this enables the code not to rely on automatic cache or WPQ (write pending queue) flush on power failure (ADR/eADR). .PP Since this operation is usually much more expensive than regular persist, it should be used sparingly. Typically, the application should only ever use this function as a precaution against hardware failures, e.g., in code that detects silent data corruption caused by unsafe shutdown (see more in \f[B]libpmem2_unsafe_shutdown\f[](7)). .SH RETURN VALUE .PP The \f[B]pmem2_deep_flush\f[]() function returns 0 on success or an error code on failure. .SH ERRORS .PP The \f[B]pmem2_deep_flush\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_DEEP_FLUSH_RANGE\f[] \- the provided flush range is not a subset of the map's address space. .IP \[bu] 2 \f[B]PMEM2_E_DAX_REGION_NOT_FOUND\f[] \- the underlying device region id cannot be detected. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]msync\f[](2), while trying to perform a deep flush on a regular DAX volume. .SH SEE ALSO .PP \f[B]msync\f[](2), \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_persist_fn\f[](3) \f[B]pmem2_map\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_offset.30000664000000000000000000000302314123364737020364 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_OFFSET" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_offset\f[]() \- set offset in the pmem2_config structure .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; int\ pmem2_config_set_offset(struct\ pmem2_config\ *config,\ size_t\ offset); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_offset\f[]() function configures the offset which will be used to map the contents from the specified location of the source. \f[I]*config\f[] should be already initialized, please see \f[B]pmem2_config_new\f[](3) for details. The \f[I]must be a multiple of the alignment required for the config. The alignment requirements are specific to a data source. To retrieve the alignment required for specific instance of \f[]pmem2_source** use \f[B]pmem2_source_alignment\f[](3). By default, the offset is 0. .SH RETURN VALUE .PP The \f[B]pmem2_config_set_offset\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_config_set_offset\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_OFFSET_OUT_OF_RANGE\f[] \- argument out of range, offset is greater than \f[B]INT64_MAX\f[] .SH SEE ALSO .PP \f[B]libpmem2\f[](7), \f[B]pmem2_source_alignment\f[](3), \f[B]pmem2_config_new\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]sysconf\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_delete.30000664000000000000000000000003714123364546021263 0ustar rootroot.so pmem2_vm_reservation_new.3 pmdk-1.11.1/doc/libpmem2/pmem2_source_size.3.md0000664000000000000000000000513314123364546017631 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_SIZE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019-2021, Intel Corporation) [comment]: <> (pmem2_source_size.3 -- man page for pmem2_source_size) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_size**() - returns the size of the data source # SYNOPSIS # ```c #include struct pmem2_source; int pmem2_source_size(const struct pmem2_source *source, size_t *size); ``` # DESCRIPTION # The **pmem2_source_size**() function retrieves the size of the file in bytes pointed by file descriptor or handle stored in the *source* and puts it in *\*size*. This function is a portable replacement for OS-specific APIs. On Linux, it hides the quirkiness of Device DAX size detection. # RETURN VALUE # The **pmem2_source_size**() function returns 0 on success. If the function fails, the *\*size* variable is left unmodified and a negative error code is returned. # ERRORS # The **pmem2_source_size**() can fail with the following errors: On all systems: * **PMEM2_E_INVALID_FILE_HANDLE** - source contains an invalid file handle. On Windows: * **PMEM2_E_INVALID_FILE_TYPE** - handle points to a resource that is not a regular file. On Linux: * **PMEM2_E_INVALID_FILE_TYPE** - file descriptor points to a directory, block device, pipe, or socket. * **PMEM2_E_INVALID_FILE_TYPE** - file descriptor points to a character device other than Device DAX. * **PMEM2_E_INVALID_SIZE_FORMAT** - kernel query for Device DAX size returned data in invalid format. * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. * -**errno** set by failing **realpath**(3), while trying to determine whether fd points to a Device DAX. * -**errno** set by failing **open**(2), while trying to determine Device DAX's size. * -**errno** set by failing **read**(2), while trying to determine Device DAX's size. * -**errno** set by failing **strtoull**(3), while trying to determine Device DAX's size. On FreeBSD: * **PMEM2_E_INVALID_FILE_TYPE** - file descriptor points to a directory, block device, pipe, socket, or character device. * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. # SEE ALSO # **errno**(3), **fstat**(2), **realpath**(3), **open**(2), **read**(2), **strtoull**(3), **pmem2_config_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_get_size.3.md0000664000000000000000000000175714123364546017755 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_GET_SIZE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019, Intel Corporation) [comment]: <> (pmem2_map_get_size.3 -- man page for libpmem2 mapping operations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_get_size**() - reads mapping size # SYNOPSIS # ```c #include size_t pmem2_map_get_size(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_map_get_size**() function reads size of the created mapping. The *map* parameter points to the structure describing mapping created using the **pmem2_map_new**(3) function. # RETURN VALUE # The **pmem2_map_get_size**() function returns a size of the mapped area. # SEE ALSO # **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_persist_fn.30000664000000000000000000000553114123364740017711 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_GET_PERSIST_FN" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_get_persist_fn\f[]() \- get a persist function .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ void\ (*pmem2_persist_fn)(const\ void\ *ptr,\ size_t\ size); struct\ pmem2_map; pmem2_persist_fn\ pmem2_get_persist_fn(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_get_persist_fn\f[]() function returns a pointer to a function responsible for efficiently persisting data in the range owned by the \f[I]map\f[]. .PP Persisting data using \f[I]pmem2_persist_fn\f[] guarantees that the data is stored durably by the time it returns. .PP There are no alignment restrictions on the range described by \f[I]ptr\f[] and \f[I]size\f[], but \f[I]pmem2_persist_fn\f[] may expand the range as necessary to meet platform alignment requirements. .PP There is nothing atomic or transactional about \f[I]pmem2_persist_fn\f[]. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until \f[I]pmem2_persist_fn\f[] is called to become persistent \[en] they can become persistent at any time before \f[I]pmem2_persist_fn\f[] is called. .PP If two (or more) mappings share the same \f[I]pmem2_persist_fn\f[] and they are adjacent to each other, it is safe to call this function for a range spanning those mappings. .PP Internally \f[I]pmem2_persist_fn\f[] performs two operations: .IP \[bu] 2 memory flush (\f[B]pmem2_get_flush_fn\f[](3)), which can be reordered by the CPU with other flushes .IP \[bu] 2 drain (\f[B]pmem2_get_drain_fn\f[](3)), which makes sure that the flushes before this operation won't be reordered after it .PP So this code: .IP .nf \f[C] pmem2_persist_fn\ persist_fn\ =\ pmem2_get_persist_fn(map); persist_fn(addr,\ len); \f[] .fi .PP is equivalent of: .IP .nf \f[C] pmem2_flush_fn\ flush_fn\ =\ pmem2_get_flush_fn(map); pmem2_drain_fn\ drain_fn\ =\ pmem2_get_drain_fn(map); flush_fn(addr,\ len); drain_fn(); \f[] .fi .PP Advanced applications may want to flush multiple discontiguous regions and perform the drain operation only once. .SH RETURN VALUE .PP The \f[B]pmem2_get_persist_fn\f[]() function never returns NULL. .PP The \f[B]pmem2_get_persist_fn\f[]() for the same \f[I]map\f[] always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. .SH SEE ALSO .PP \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_flush_fn\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find_next.30000664000000000000000000000004414123364546022632 0ustar rootroot.so pmem2_vm_reservation_map_find.3 pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_get_size.30000664000000000000000000000173114123364741021631 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_VM_RESERVATION_GET_SIZE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_vm_reservation_get_size\f[]() \- reads virtual memory reservation size .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ pmem2_vm_reservation_get_size(struct\ pmem2_vm_reservation\ *rsv); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_vm_reservation_get_size\f[]() function reads size of the created virtual memory reservation. The \f[I]rsv\f[] parameter points to the structure describing virtual memory reservation created using the \f[B]pmem2_vm_reservation_new\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmem2_vm_reservation_get_size\f[]() function returns a size of the virtual reservation area. .SH SEE ALSO .PP \f[B]pmem2_vm_reservation_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_source_alignment.3.md0000664000000000000000000000453414123364546020641 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_ALIGNMENT, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019-2020, Intel Corporation) [comment]: <> (pmem2_source_alignment.3 -- man page for pmem2_source_alignment) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_alignment**() - returns data source alignment # SYNOPSIS # ```c #include struct pmem2_source; int pmem2_source_alignment(const struct pmem2_source *source, size_t *alignment); ``` # DESCRIPTION # The **pmem2_source_alignment**() function retrieves the alignment of offset and length needed for **pmem2_map_new**(3) to succeed. The alignment is stored in *\*alignment*. # RETURN VALUE # The **pmem2_source_alignment**() function returns 0 on success. If the function fails, the *\*alignment* variable is left unmodified and a negative error code is returned. # ERRORS # The **pmem2_source_alignment**() can fail with the following errors: On all systems: * **PMEM2_E_INVALID_ALIGNMENT_VALUE** - operating system returned unexpected alignment value (eg. it is not a power of two). on Linux: * **PMEM2_E_INVALID_FILE_TYPE** - file descriptor points to a character device other than Device DAX. * **PMEM2_E_INVALID_ALIGNMENT_FORMAT** - kernel query for Device DAX alignment returned data in invalid format. * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. * -**errno** set by failing **realpath**(3), while trying to determine whether fd points to a Device DAX. * -**errno** set by failing **read**(2), while trying to determine Device DAX's alignment. * -**errno** set by failing **strtoull**(3), while trying to determine Device DAX's alignment. On FreeBSD: * **PMEM2_E_INVALID_FILE_TYPE** - file descriptor points to a directory, block device, pipe, socket, or character device. * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. # SEE ALSO # **errno**(3), **fstat**(2), **realpath**(3), **read**(2), **strtoull**(3), **pmem2_config_new**(3), **pmem2_source_from_handle**(3), **pmem2_source_from_fd**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_from_fd.3.md0000664000000000000000000000745414123364546020303 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_FROM_FD, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019-2021, Intel Corporation) [comment]: <> (pmem2_source_from_fd.3 -- man page for pmem2_source_from_fd [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_from_fd**(), **pmem2_source_from_handle**(), **pmem2_source_delete**() - creates or deletes an instance of persistent memory data source # SYNOPSIS # ```c #include int pmem2_source_from_fd(struct pmem2_source *src, int fd); int pmem2_source_from_handle(struct pmem2_source *src, HANDLE handle); /* Windows only */ int pmem2_source_delete(struct pmem2_source **src); ``` # DESCRIPTION # On Linux the **pmem2_source_from_fd**() function validates the file descriptor and instantiates a new *struct pmem2_source** object describing the data source. On Windows the **pmem2_source_from_fd**() function converts a file descriptor to a file handle (using **_get_osfhandle**()), and passes it to **pmem2_source_from_handle**(). By default **_get_osfhandle**() calls abort() in case of invalid file descriptor, but this behavior can be suppressed by **_set_abort_behavior**() and **SetErrorMode**() functions. Please check MSDN documentation for more information about Windows CRT error handling. *fd* must be opened with *O_RDONLY* or *O_RDWR* mode, but on Windows it is not validated. If *fd* is invalid, then the function fails. The **pmem2_source_from_handle**() function validates the handle and instantiates a new *struct pmem2_source** object describing the data source. If *handle* is *INVALID_HANDLE_VALUE*, then the function fails. The handle has to be created with an access mode of *GENERIC_READ* or *(GENERIC_READ | GENERIC_WRITE)*. For details please see the **CreateFile**() documentation. The **pmem2_source_delete**() function frees *\*src* returned by **pmem2_source_from_fd**() or **pmem2_source_from_handle**() and sets *\*src* to NULL. If *\*src* is NULL, no operation is performed. # RETURN VALUE # The **pmem2_source_from_fd**() and **pmem2_source_from_handle**() functions return 0 on success or a negative error code on failure. The **pmem2_source_delete**() function always returns 0. # ERRORS # The **pmem2_source_from_fd**()/**pmem2_source_from_handle**() functions can fail with the following errors: * **PMEM2_E_INVALID_FILE_HANDLE** - *fd* is not an open and valid file descriptor. On Windows the function can **abort**() on this failure based on CRT's abort() behavior. * **PMEM2_E_INVALID_FILE_HANDLE** - *fd* is opened in O_WRONLY mode. On Linux: * **PMEM2_E_INVALID_FILE_TYPE** - *fd* points to a directory, block device, pipe, or socket. * **PMEM2_E_INVALID_FILE_TYPE** - *fd* points to a character device other than Device DAX. On Windows: * **PMEM2_E_INVALID_FILE_TYPE** - *handle* points to a resource that is not a regular file. On Windows **pmem2_source_from_fd**() can return all errors from the underlying **pmem2_source_from_handle**() function. The **pmem2_source_from_handle**() can return the following errors: * **PMEM2_E_INVALID_FILE_HANDLE** - *handle* points to a resource that is not a file. * **PMEM2_E_INVALID_FILE_TYPE** - *handle* points to a directory. The **pmem2_source_from_fd**() and **pmem2_source_from_handle**() functions can also return **-ENOMEM** in case of insufficient memory to allocate an instance of *struct pmem2_source*. # CAVEATS # On non-DAX Windows volumes, *fd*/*handle* must remain open while the mapping is in use. # SEE ALSO # **errno**(3), **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_memmove_fn.3.md0000664000000000000000000001217314123364546020270 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_GET_MEMMOVE_FN, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_get_memmove_fn.3 -- man page for pmem2_get_memmove_fn) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_get_memmove_fn**(), **pmem2_get_memset_fn**(), **pmem2_get_memcpy_fn**() - get a function that provides optimized copying to persistent memory # SYNOPSIS # ```c #include typedef void *(*pmem2_memmove_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*pmem2_memcpy_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*pmem2_memset_fn)(void *pmemdest, int c, size_t len, unsigned flags); struct pmem2_map; pmem2_memmove_fn pmem2_get_memmove_fn(struct pmem2_map *map); pmem2_memset_fn pmem2_get_memset_fn(struct pmem2_map *map); pmem2_memcpy_fn pmem2_get_memcpy_fn(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_get_memmove_fn**(), **pmem2_get_memset_fn**(), **pmem2_get_memcpy_fn**() functions return a pointer to a function responsible for efficient storing and flushing of data for mapping *map*. **pmem2_memmove_fn**(), **pmem2_memset_fn**() and **pmem2_memcpy_fn**() functions provide the same memory copying functionalities as their namesakes **memmove**(3), **memcpy**(3) and **memset**(3), and ensure that the result has been flushed to persistence before returning (unless **PMEM2_F_MEM_NOFLUSH** flag was used). For example, the following code: ```c memmove(dest, src, len); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); persist_fn(dest, len); ``` is functionally equivalent to: ```c pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); memmove_fn(dest, src, len, 0); ``` Unlike libc implementation, **libpmem2** functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by *persist_fn* can be safely replaced by a single *memmove_fn* call. The *flags* argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: + **PMEM2_F_MEM_NODRAIN** - modifies the behavior to skip the final *pmem2_drain_fn* step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to *pmem2_drain_fn*. The following example illustrates how this flag might be used to avoid multiple calls to *pmem2_drain_fn* when copying several ranges of memory to pmem: ```c pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); pmem2_drain_fn drain_fn = pmem2_get_drain_fn(map); /* ... write several ranges to pmem ... */ memcpy_fn(pmemdest1, src1, len1, PMEM2_F_MEM_NODRAIN); memcpy_fn(pmemdest2, src2, len2, PMEM2_F_MEM_NODRAIN); /* ... */ /* wait for any pmem stores to drain from HW buffers */ drain_fn(); ``` + **PMEM2_F_MEM_NOFLUSH** - Don't flush anything. This implies **PMEM2_F_MEM_NODRAIN**. Using this flag only makes sense when it's followed by any function that flushes data. The remaining flags say *how* the operation should be done, and are merely hints. + **PMEM2_F_MEM_NONTEMPORAL** - Use non-temporal instructions. This flag is mutually exclusive with **PMEM2_F_MEM_TEMPORAL**. On x86\_64 this flag is mutually exclusive with **PMEM2_F_MEM_NOFLUSH**. + **PMEM2_F_MEM_TEMPORAL** - Use temporal instructions. This flag is mutually exclusive with **PMEM2_F_MEM_NONTEMPORAL**. + **PMEM2_F_MEM_WC** - Use write combining mode. This flag is mutually exclusive with **PMEM2_F_MEM_WB**. On x86\_64 this flag is mutually exclusive with **PMEM2_F_MEM_NOFLUSH**. + **PMEM2_F_MEM_WB** - Use write back mode. This flag is mutually exclusive with **PMEM2_F_MEM_WC**. On x86\_64 this is an alias for **PMEM2_F_MEM_TEMPORAL**. Using an invalid combination of flags has undefined behavior. Without any of the above flags **libpmem2** will try to guess the best strategy based on the data size. See **PMEM_MOVNT_THRESHOLD** description in **libpmem2**(7) for details. # RETURN VALUE # The **pmem2_get_memmove_fn**(), **pmem2_get_memset_fn**(), **pmem2_get_memcpy_fn**() functions never return NULL. They return the same function for the same mapping. This means that it's safe to cache their return values. However, these functions are very cheap (because their return values are precomputed), so caching may not be necessary. If two (or more) mappings share the same *pmem2_memmove_fn*, *pmem2_memset_fn*, *pmem2_memcpy_fn* and they are adjacent to each other, it is safe to call these functions for a range spanning those mappings. # SEE ALSO # **memcpy**(3), **memmove**(3), **memset**(3), **pmem2_get_drain_fn**(3), **pmem2_get_memcpy_fn**(3), **pmem2_get_memset_fn**(3), **pmem2_map_new**(3), **pmem2_get_persist_fn**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find_last.30000664000000000000000000000004414123364546022617 0ustar rootroot.so pmem2_vm_reservation_map_find.3 pmdk-1.11.1/doc/libpmem2/pmem2_source_from_anon.3.md0000664000000000000000000000334614123364546020641 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_FROM_ANON, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_from_anon.3 -- man page for pmem2_source_from_anon [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_from_anon**() - creates data source backed by anonymous memory pages # SYNOPSIS # ```c #include int pmem2_source_from_anon(struct pmem2_source **src, size_t size); ``` # DESCRIPTION # The **pmem2_source_from_anon**() function instantiates a new *struct pmem2_source* object describing an anonymous data source. Mappings created using this function are not backed by any file and are zero-initialized. The *size* argument for the function defines the length in bytes of the anonymous source, as returned by **pmem2_source_size**(3). The application should set this value so that it's greater than or equal to the size of any mapping created with the anonymous source. The offset value for mapping is ignored. # RETURN VALUE # The **pmem2_source_from_anon**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_source_form_anon**() can fail with the following errors: * **-ENOMEM** - in case of insufficient memory to allocate an instance of *struct pmem2_source*. # SEE ALSO # **errno**(3), **pmem2_config_set_length**(3), **pmem2_map_new**(3), **pmem2_source_size**(3), **pmem2_config_set_length**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find_prev.30000664000000000000000000000004414123364546022630 0ustar rootroot.so pmem2_vm_reservation_map_find.3 pmdk-1.11.1/doc/libpmem2/pmem2_source_device_id.3.md0000664000000000000000000000550514123364546020575 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_DEVICE_ID, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_device_id.3 -- man page for pmem2_source_device_id) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_device_id**() - returns the unique identifier of a device # SYNOPSIS # ```c #include struct pmem2_source; int pmem2_source_device_id(const struct pmem2_source *source, char *id, size_t *len); ``` # DESCRIPTION # The **pmem2_source_device_id**() function retrieves a unique identifier of all NVDIMMs backing the data source. This function has two operating modes: * if *\*id* is NULL the function calculates a buffer length required for storing the identifier of the *\*source* device and puts this length in *\*len* The more hardware devices back the data source, the longer the length is. * if *\*id* is not NULL it must point to a buffer of length *\*len* provided by the previous call to this function. On success, **pmem2_source_device_id**() will store a unique identifier of all hardware devices backing the data source. For details on how to use the unique identifier for detecting *the unsafe shutdown* please refer to **libpmem2_unsafe_shutdown**(7) manual page. # RETURN VALUE # The **pmem2_source_device_id**() function returns 0 on success. If the function fails, the *\*id* and *\*len* variables contents are left unmodified and a negative error code is returned. # ERRORS # The **pmem2_source_device_id**() can fail with the following errors: On all systems: * **PMEM2_E_BUFFER_TOO_SMALL** - the provided buffer of length *\*len* is too small to store the full identifier of the backing devices. * **PMEM2_E_NOSUPP** - the underlying platform does not expose hardware identification. On Windows: * -**errno** equivalent of return code set by failing **GetFinalPathNameByHandleW**(), while trying to resolve the volume path from the file handle. * -**errno** set by failing **malloc**(3), while trying to allocate a buffer for storing volume path. * -**errno** equivalent of return code set by failing **CreateFileW**(), while trying to obtain a handle to the volume. * -**errno** equivalent of return code set by failing **DeviceIoControl**(), while trying to obtain volume **USC** value. On Linux: * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. * -**errno** set by failing **ndctl_new**(), while trying to initiate a new NDCTL library context. # SEE ALSO # **fstat**(2), **errno**(3), **malloc**(3), **libpmem2_unsafe_shutdown**(7), and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_set_required_store_granularity.3.md0000664000000000000000000000331114123364546025150 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_REQUIRED_STORE_GRANULARITY, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_set_required_store_granularity.3 -- man page for pmem2_config_set_required_store_granularity [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_required_store_granularity**() - set a granularity in pmem2_config structure. # SYNOPSIS # ```c #include enum pmem2_granularity { PMEM2_GRANULARITY_BYTE, PMEM2_GRANULARITY_CACHE_LINE, PMEM2_GRANULARITY_PAGE, }; int pmem2_config_set_required_store_granularity(struct pmem2_config *cfg, enum pmem2_granularity g); ``` # DESCRIPTION # The **pmem2_config_set_required_store_granularity**() sets a maximum permitted granularity *g* requested by user in the *pmem2_config* structure. Granularity must be one of the following values: * **PMEM2_GRANULARITY_BYTE** * **PMEM2_GRANULARITY_CACHE_LINE** * **PMEM2_GRANULARITY_PAGE** A description of the granularity concept can be found in **libpmem2**(7) manpage. # RETURN VALUE # The **pmem2_config_set_required_store_granularity**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_config_set_required_store_granularity**() can fail with the following errors: * **PMEM2_E_GRANULARITY_NOT_SUPPORTED** - granularity *g* is not a valid value. # SEE ALSO # **pmem2_config_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_from_anon.30000664000000000000000000000310514123364742020231 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_FROM_ANON" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_from_anon\f[]() \- creates data source backed by anonymous memory pages .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_source_from_anon(struct\ pmem2_source\ **src,\ size_t\ size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_from_anon\f[]() function instantiates a new \f[I]struct pmem2_source\f[] object describing an anonymous data source. Mappings created using this function are not backed by any file and are zero\-initialized. .PP The \f[I]size\f[] argument for the function defines the length in bytes of the anonymous source, as returned by \f[B]pmem2_source_size\f[](3). The application should set this value so that it's greater than or equal to the size of any mapping created with the anonymous source. .PP The offset value for mapping is ignored. .SH RETURN VALUE .PP The \f[B]pmem2_source_from_anon\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_source_form_anon\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]\-ENOMEM\f[] \- in case of insufficient memory to allocate an instance of \f[I]struct pmem2_source\f[]. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmem2_config_set_length\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_source_size\f[](3), \f[B]pmem2_config_set_length\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_offset.3.md0000664000000000000000000000325514123364546020770 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_OFFSET, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_set_offset.3 -- man page for libpmem2 config API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_offset**() - set offset in the pmem2_config structure # SYNOPSIS # ```c #include struct pmem2_config; int pmem2_config_set_offset(struct pmem2_config *config, size_t offset); ``` # DESCRIPTION # The **pmem2_config_set_offset**() function configures the offset which will be used to map the contents from the specified location of the source. *\*config* should be already initialized, please see **pmem2_config_new**(3) for details. The *\offset* must be a multiple of the alignment required for the config. The alignment requirements are specific to a data source. To retrieve the alignment required for specific instance of *pmem2_source** use **pmem2_source_alignment**(3). By default, the offset is 0. # RETURN VALUE # The **pmem2_config_set_offset**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_config_set_offset**() can fail with the following errors: * **PMEM2_E_OFFSET_OUT_OF_RANGE** - argument out of range, offset is greater than **INT64_MAX** # SEE ALSO # **libpmem2**(7), **pmem2_source_alignment**(3), **pmem2_config_new**(3), **pmem2_map_new**(3), **sysconf**(3) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_numa_node.3.md0000664000000000000000000000424214123364546020624 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_NUMA_NODE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_numa_node.3 -- man page for pmem2_source_numa_node) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_numa_node**() - returns data source numa node # SYNOPSIS # ```c #include struct pmem2_source; int pmem2_source_numa_node(const struct pmem2_source *source, int *numa_node); ``` # DESCRIPTION # The **pmem2_source_numa_node**() function retrieves the numa node of the given data source. The numa node can be used to, e.g., pin threads to near-memory cores. The numa node is stored in *\*numa_node*. It is the same value that is shown as `numa_node` in `ndctl list -v`. # RETURN VALUE # The **pmem2_source_numa_node**() function returns 0 on success. If the function fails, the *\*numa_node* variable is left unmodified and a negative error code is returned. # ERRORS # The **pmem2_source_numa_node**() can fail with the following errors: On all systems: * **PMEM2_E_NOSUPP** - source type or operating system not supported (see #caveats for details.) on Linux: * **PMEM2_E_DAX_REGION_NOT_FOUND** - no **ndctl_region** could be determined for the source. * **PMEM2_E_INVALID_FILE_TYPE** - if the source points to a directory. * -**errno** set by failing **ndctl_new**, while trying to create a new context. # CAVEATS # This call requires **libndctl** to retrieve the numa information. It only works for sources that are actually located on persistent memory, i.e., devdax or fsdax. As anonymous sources are not backed by files on persistent memory, this method is not supported for them. It also does not work under Windows or systems without **libndctl**. # SEE ALSO # **errno**(3), **ndctl_new**(3), **pmem2_source_from_handle**(3), **pmem2_source_from_fd**(3), **libpmem2**(7), **libndctl**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_get_handle.3.md0000664000000000000000000000343314123364546020752 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_GET_HANDLE, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_get_handsle.3 -- man page for pmem2_source_get_handle [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_get_handle**() - reads file handler of the data source # SYNOPSIS # ```c #include int pmem2_source_get_handle(const struct pmem2_source *src, HANDLE *h); ``` # DESCRIPTION # The **pmem2_source_get_handle**() function reads the file handler of *struct pmem2_source** object describing the data source and returns it by *h* parameter. This function is Windows only, on Linux use **pmem2_source_get_fd**(3). If the source was created using **pmem2_source_from_fd**(3) then **pmem2_source_get_handle**() is also valid function to read handler, because file descriptor is converted to file handle during source creation. However, there are limitations to what you can do with a handle created from a file descriptor. For details refer to **DESCRIPTION** section in the **pmem2_source_from_fd**(3) manpage. # ERRORS # The **pmem2_source_get_handle**() can fail with the following errors: * **PMEM2_E_FILE_HANDLE_NOT_SET** - in case of an instance of *struct pmem2_source* that does not come from source type that support file handles, eg. anonymous data source. # RETURN VALUE # The **pmem2_source_get_handle**() returns a file handle of data source. # SEE ALSO # **pmem2_source_from_fd**(3), **pmem2_source_get_fd**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_set_length.3.md0000664000000000000000000000266714123364546020771 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_LENGTH, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019, Intel Corporation) [comment]: <> (pmem2_config_set_length.3 -- man page for libpmem2 config API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_length**() - set length in the pmem2_config structure # SYNOPSIS # ```c #include struct pmem2_config; int pmem2_config_set_length(struct pmem2_config *config, size_t length); ``` # DESCRIPTION # The **pmem2_config_set_length**() function configures the length which will be used for mapping. *\*config* should be already initialized, please see **pmem2_config_new**(3) for details. The *\length* must be a multiple of the alignment required for the data source which will be used for mapping alongside the config. To retrieve the alignment required for specific instance of *pmem2_source** use **pmem2_source_alignment**(3). By default, the length is equal to the size of the file that is being mapped. # RETURN VALUE # The **pmem2_config_set_length**() function always returns 0. # SEE ALSO # **libpmem2**(7), **pmem2_map_new**(3), **pmem2_source_alignment**(3), **pmem2_config_new**(3), **sysconf**(3) and **** pmdk-1.11.1/doc/libpmem2/pmem2_badblock_next.3.md0000664000000000000000000000306514123364546020100 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_BADBLOCK_NEXT, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_badblock_next.3 -- man page for pmem2_badblock_next) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_badblock_next**() - read the next bad block for the given bad block context *\*bbctx*. # SYNOPSIS # ```c #include struct pmem2_badblock; struct pmem2_badblock_context; int pmem2_badblock_next( struct pmem2_badblock_context *bbctx, struct pmem2_badblock *bb); ``` # DESCRIPTION # The **pmem2_badblock_next**() function reads the next bad block for the given bad block context *\*bbctx*. It is not supported on Windows. # RETURN VALUE # The **pmem2_badblock_next**() function returns 0 and stores the next bad block in *\*bb* on success or it returns a negative error code when there are no more bad blocks for the given bad block context *\*bbctx*. # ERRORS # **pmem2_badblock_next**() can fail with the following error: * **PMEM2_E_NO_BAD_BLOCK_FOUND** - there are no more bad blocks for the given bad block context *\*bbctx*, *\*bb* is undefined in this case. * **PMEM2_E_NOSUPP** - on Windows or when the OS does not support this functionality # SEE ALSO # **pmem2_badblock_context_new**(3), **pmem2_badblock_clear**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_set_protection.3.md0000664000000000000000000000400414123364546021661 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_PROTECTION, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_set_protection.3 -- man page for libpmem2 config API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_protection**() - set a protection flags in pmem2_config structure. # SYNOPSIS # ```c #include struct pmem2_config; #define PMEM2_PROT_EXEC (1U << 29) #define PMEM2_PROT_READ (1U << 30) #define PMEM2_PROT_WRITE (1U << 31) #define PMEM2_PROT_NONE 0 int pmem2_config_set_protection(struct pmem2_config *cfg, unsigned prot); ``` # DESCRIPTION # The **pmem2_config_set_protection**() function sets the protection flags which will be used for memory mapping. The default value in pmem2_config structure is **PMEM2_PROT_READ | PMEM2_PROT_WRITE**. The *\prot* argument describes the desired memory protection of the mapping. The memory protection cannot conflict with the file opening-mode. *\*config* should be already initialized, please see **pmem2_config_new**(3) for details. It is either PROT_NONE or the bitwise OR of one or more of the following flags: * **PMEM2_PROT_EXEC** - Pages may be executed. * **PMEM2_PROT_READ** - Pages may be read. * **PMEM2_PROT_WRITE** - Pages may be written. * **PMEM2_PROT_NONE** - Pages may not be accessed. On Windows this flag is not supported. # RETURN VALUE # The **pmem2_config_set_protection**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_config_set_protection**() can fail with the following errors: * **PMEM2_E_INVALID_PROT_FLAG** - some or all of the provided flags are not valid. # SEE ALSO # **libpmem2**(7), **pmem2_config_new**(3), **pmem2_map_new**(3) and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_set_vm_reservation.3.md0000664000000000000000000000247214123364546022545 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_SET_VM_RESERVATION, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_set_vm_reservation.3 -- man page for libpmem2 config API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_set_vm_reservation**() - sets the pmem2_vm_reservation structure basing on the values in the pmem2_config structure # SYNOPSIS # ```c #include struct pmem2_config; struct pmem2_vm_reservation; int pmem2_config_set_vm_reservation(struct pmem2_config *config, struct pmem2_vm_reservation *rsv, size_t rsv_offset); ``` # DESCRIPTION # The **pmem2_config_set_vm_reservation**() function sets the virtual memory reservation and an offset to be used during a mapping. *rsv* should be already initialized. Please see **pmem2_vm_reservation_new**(3) for details. *rsv_offset* marks the offset in the reservation for the mapping. # RETURN VALUE # **pmem2_config_set_vm_reservation**() function always returns 0. # SEE ALSO # **pmem2_vm_reservation_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_from_existing.30000664000000000000000000000357114123364743020415 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_FROM_EXISTING" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_map_from_existing\f[]() \- creates a pmem2_map object from an existing mapping .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_map_from_existing(struct\ pmem2_map\ **map,\ const\ struct\ pmem2_source\ *src, \ \ \ \ void\ *addr,\ size_t\ len,\ enum\ pmem2_granularity\ gran); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_from_existing\f[]() returns a new *struct pmem2_map\f[B] for mapping provided by the user. This function allows usage of \f[]libpmem2\f[B](7) API without \f[]pmem2_map_new\f[B](3) for mapping file. Mapping is defined by \f[BI]addr\f[B] and \f[BI]len\f[B]. You have to specify underlying file as a \f[BI]src\f[B], and define granularity of this mapping. See \f[]pmem2_config_set_required_store_granularity\f[B](3) and \f[]libpmem2**(7) for more details. .PP For the \f[I]pmem2_map\f[] object created by the \f[B]pmem2_map_from_existing\f[](3) function, the \f[B]pmem2_map_delete\f[](3) will only destroy the object, but it won't unmap the mapping this object describes. .SH RETURN VALUE .PP The \f[B]pmem2_map_from_existing\f[]() function returns 0 when it succeeds or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_map_from_existing\f[]() can fail with the following errors: .PP \f[B]PMEM2_E_MAPPING_EXISTS\f[] \- when contiguous region (\f[I]addr\f[], \f[I]addr\f[] + \f[I]len\f[]) is all ready registered by \f[I]libpmem2\f[] .PP It can also return \f[B]\-ENOMEM\f[] from the underlying \f[B]malloc\f[](2) function. .SH SEE ALSO .PP \f[B]malloc(2)\f[], \f[B]pmem2_map_delete\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_source_from_fd\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_map_delete.30000664000000000000000000000321114123364735016772 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_DELETE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2020, Intel Corporation .SH NAME .PP \f[B]pmem2_map_delete\f[]() \- deletes a mapping .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_map_delete(struct\ pmem2_map\ **map_ptr); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_delete\f[]() function deletes the mapping described by the \f[I]struct pmem2_map\f[] object. .PP If \f[B]pmem2_map_delete\f[]() succeeds in deleting the mapping, it releases the \f[I]struct pmem2_map\f[] object describing it and writes a NULL value to \f[I]map_ptr\f[]. If the function fails, the \f[I]map_ptr\f[] variable and the map object itself are left unmodified and appropriate error value is returned. For a list of possible return values please see RETURN VALUE. .PP The \f[B]pmem2_map_delete\f[]() function will not unmap mapping provided by the user by \f[B]pmem2_map_from_existing\f[]() function. In such case it will only free \f[I]struct pmem2_map\f[] object. .SH RETURN VALUE .PP The \f[B]pmem2_map_delete\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_map_delete\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_MAPPING_NOT_FOUND\f[] \- mapping was not found (it was already unmapped or pmem2_map state was corrupted) .PP On systems other than Windows it can also return \f[B]\-EINVAL\f[] from the underlying \f[B]munmap\f[](2) function. .SH SEE ALSO .PP \f[B]pmem2_map_new(3)\f[], \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_deep_flush.3.md0000664000000000000000000000372514123364546017422 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_DEEP_FLUSH, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_deep_flush.3 -- man page for pmem2_deep_flush) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_deep_flush**() - highly reliable persistent memory synchronization # SYNOPSIS # ```c #include int pmem2_deep_flush(struct pmem2_map *map, void *ptr, size_t size) ``` # DESCRIPTION # The **pmem2_deep_flush**() function forces any changes in the range \[*ptr*, *ptr*+*len*) from the *map* to be stored durably in the most reliable persistence domain available to software. In particular, on supported platforms, this enables the code not to rely on automatic cache or WPQ (write pending queue) flush on power failure (ADR/eADR). Since this operation is usually much more expensive than regular persist, it should be used sparingly. Typically, the application should only ever use this function as a precaution against hardware failures, e.g., in code that detects silent data corruption caused by unsafe shutdown (see more in **libpmem2_unsafe_shutdown**(7)). # RETURN VALUE # The **pmem2_deep_flush**() function returns 0 on success or an error code on failure. # ERRORS # The **pmem2_deep_flush**() can fail with the following errors: * **PMEM2_E_DEEP_FLUSH_RANGE** - the provided flush range is not a subset of the map's address space. * **PMEM2_E_DAX_REGION_NOT_FOUND** - the underlying device region id cannot be detected. * -**errno** set by failing **msync**(2), while trying to perform a deep flush on a regular DAX volume. # SEE ALSO # **msync**(2), **pmem2_get_drain_fn**(3), **pmem2_get_persist_fn**(3) **pmem2_map**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_drain_fn.3.md0000664000000000000000000000324614123364546017721 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_GET_DRAIN_FN, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_get_drain_fn.3 -- man page for pmem2_get_drain_fn) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_get_drain_fn**() - get a drain function # SYNOPSIS # ```c #include typedef void (*pmem2_drain_fn)(void); struct pmem2_map; pmem2_drain_fn pmem2_get_drain_fn(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_get_drain_fn**() function returns a pointer to a function responsible for efficiently draining flushes (see **pmem2_get_flush_fn**(3)) in the range owned by *map*. Draining, in this context, means making sure that the flushes before this operation won't be reordered after it. While it is not strictly true, draining can be thought of as waiting for previous flushes to complete. If two (or more) mappings share the same drain function, it is safe to call this function once for all flushes belonging to those mappings. # RETURN VALUE # The **pmem2_get_drain_fn**() function never returns NULL. The **pmem2_get_drain_fn**() for the same *map* always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. # SEE ALSO # **pmem2_get_flush_fn**(3), **pmem2_get_persist_fn**(3), **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_config_new.3.md0000664000000000000000000000362414123364546017420 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_CONFIG_NEW, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_config_new.3 -- man page for pmem2_config_new and pmem2_config_delete) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_config_new**(), **pmem2_config_delete**() - allocate and free a configuration structure for a libpmem2 mapping # SYNOPSIS # ```c #include struct pmem2_config; int pmem2_config_new(struct pmem2_config **cfg); int pmem2_config_delete(struct pmem2_config **cfg); ``` # DESCRIPTION # The **pmem2_config_new**() function instantiates a new (opaque) configuration structure, *pmem2_config*, which is used to define mapping parameters for a **pmem2_map_new**() function, and returns it through the pointer in *\*cfg*. New configuration is always initialized with default values for most parameters, which are specified alongside the corresponding setter function. The application must explicitly set the granularity value for the mapping. The **pmem2_config_delete**() function frees *\*cfg* returned by **pmem2_config_new**() and sets *\*cfg* to NULL. If *\*cfg* is NULL, no operation is performed. # RETURN VALUE # The **pmem2_config_new**() function returns 0 on success or a negative error code on failure. **pmem2_config_new**() does set *\*cfg* to NULL on failure. The **pmem2_config_delete**() function always returns 0. # ERRORS # **pmem2_config_new**() can fail with the following error: - **-ENOMEM** - out of memory # SEE ALSO # **errno**(3), **pmem2_map_new**(3), **pmem2_config_set_handle**(3), **pmem2_config_set_fd**(3), **pmem2_config_get_file_size**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_memset_fn.30000664000000000000000000000003314123364546017506 0ustar rootroot.so pmem2_get_memmove_fn.3 pmdk-1.11.1/doc/libpmem2/libpmem2_unsafe_shutdown.7.md0000664000000000000000000000731314123364546021210 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEM2_UNSAFE_SHUTDOWN, 7) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (libpmem2_unsafe_shutdown.7 -- man page for libpmem2 unsafe shutdown) [NAME](#name)
[DESCRIPTION](#description)
[UNSAFE SHUTDOWN DETECTION](#unsafe-shutdown-detection)
[SEE ALSO](#see-also) # NAME # **libpmem2_unsafe_shutdown** - libpmem2 unsafe shutdown # DESCRIPTION # In systems with the persistent memory support, *a power-fail protected domain* covers a set of resources from which the platform will flush data to the *a persistent medium* in case of *a power-failure*. Data stored on *the persistent medium* is preserved across power cycles. The hardware guarantees the feature to flush all data stored in *the power-fail protected domain* to *the persistent medium*. However, nothing is infallible, and Persistent Memory hardware can expose a monotonically increasing *unsafe shutdown counter* (**USC**) that is incremented every time a failure of the mechanism above is detected. This allows software to discover situations where a running application was interrupted by a power failure that led to an unsafe shutdown. Undiscovered unsafe shutdowns might cause silent data corruption. >Note: *The unsafe shutdown* may corrupt data stored on a device, in a file, in a set of files, and a mapping spanning only a part of a file. For the sake of simplicity, all of the above cases will be called *file* below. # UNSAFE SHUTDOWN DETECTION # Software can detect an unsafe shutdown by watching for the change between unsafe shutdown count value across application startups. Any changes can be indicative of unsafe shutdown occurrence. Applications can implement a detection mechanism by storing the **USC** retrieved from **pmem2_source_device_usc**(3) in Persistent Memory. Then, on subsequent startups, the stored value must be compared with a newly retrieved one. However, this detection method can result in false-positives. Moving the file to different Persistent Memory devices with possibly different **USC** values would lead to false unsafe shutdown detection. Additionally, relying on **USC** value alone could result in the detection of unsafe shutdown events that occur when such a shutdown has no chance of impacting the data used by the application, e.g., when nothing is actively using the file. Applications can avoid false-positives associated with moving the file by storing device identification, obtained through **pmem2_source_device_id**(3), alongside the **USC**. This enables the software to check if the underlying device has changed, and reinitialize the stored **USC** in such cases. The second behavior, detection of possibly irrelevant unsafe shutdown events, if undesirable, can be prevented by storing a flag indicating whether the file is in use, alongside all the rest of the relevant information. The application should use **pmem2_deep_flush**(3) when storing any data related to unsafe shutdown detection for higher reliability. This helps ensure that the detection mechanism is not reliant on the correct functioning of the same hardware features it is designed to safeguard. General-purpose software should not assume the presence of **USC** on the platform, and should instead appropriately handle any *PMEM2_E_NOSUPP* it encounters. Doing otherwise might cause the software to be unnecessarily restrictive about the hardware it supports and would prevent, e.g., testing on emulated PMEM. # SEE ALSO # **pmem2_deep_flush**(3), **pmem2_persist_fn**(3), **pmem2_source_device_id**(3), **pmem2_source_device_usc**(3) and **** pmdk-1.11.1/doc/libpmem2/libpmem2.7.md0000664000000000000000000003315514123364546015717 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEM2, 7) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2019-2021, Intel Corporation) [comment]: <> (libpmem2.7 -- man page for libpmem2) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[GRANULARITY](#granularity)
[CAVEATS](#caveats)
[ENVIRONMENT](#environment)
[DEBUGGING](#debugging)
[EXAMPLE](#example)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also) # NAME # **libpmem2** - persistent memory support library # SYNOPSIS # ```c #include cc ... -lpmem2 ``` # DESCRIPTION # **libpmem2** provides low-level *persistent memory* (pmem) support for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of *non-volatile memory DIMMs* (NVDIMMs) provide this type of byte addressable access to storage. A *persistent memory aware file system* is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non-paged access to pmem. This library is for applications that use persistent memory directly, without the help of any library-supplied transactions or memory allocation. Higher-level libraries that *currently* build on **libpmem** (previous variation of libpmem2) are available and are recommended for most applications, see: + **libpmemobj**(7), a general use persistent memory API, providing memory allocation and transactional operations on variable-sized objects. + **libpmemblk**(7), providing pmem-resident arrays of fixed-sized blocks with atomic updates. + **libpmemlog**(7), providing a pmem-resident log file. The **libpmem2** library provides a comprehensive set of functions for robust use of Persistent Memory. It relies on three core concepts: *struct pmem2_src source*, *struct pmem2_config config* and *struct pmem2_map map*: * *source* - an object describing the data source for mapping. The data source can be a file descriptor, a file handle, or an anonymous mapping. APIs dedicated for creating *source* are: **pmem2_source_from_fd**(3), **pmem2_source_from_handle**(3), **pmem2_source_from_anon**(3). * *config* - an object containing parameters that are used to create a mapping from a *source*. The configuration structure must always be provided to create a mapping, but the only required parameter to set in the *config* is *granularity*. The granularity should by set using dedicated **libpmem2** function **pmem2_config_set_required_store_granularity**(3) which defines a maximum permitted granularity requested by the user. For more information about the granularity concept read **GRANULARITY** section below. In addition to the granularity setting, libpmem2 provides multiple optional functions to configure target mapping, e.g., **pmem2_config_set_length**(3) to set length which will be used for mapping, or **pmem2_config_set_offset**(3) which will be used to map the contents from the specified location of the source, **pmem2_config_set_sharing**(3) which defines the behavior and visibility of writes to the mapping's pages. * *map* - an object created by **pmem2_map_new**(3) using *source* and *config* as an input parameters. The map structure can be then used to directly operate on the created mapping through the use of its associated set of functions: **pmem2_map_get_address**(3), **pmem2_map_get_size**(3), **pmem2_map_get_store_granularity**(3) - for getting address, size and effective mapping granularity. In addition to the basic functionality of managing the virtual address mapping, **libpmem2** also provides optimized functions for modifying the mapped data. This includes data flushing as well as memory copying. To get proper function for data flushing use: **pmem2_get_flush_fn**(3), **pmem2_get_persist_fn**(3) or **pmem2_get_drain_fn**(3). To get proper function for copying to persistent memory, use *map* getters: **pmem2_get_memcpy_fn**(3), **pmem2_get_memset_fn**(3), **pmem2_get_memmove_fn**(3). The **libpmem2** API also provides support for the badblock and unsafe shutdown state handling. To read or clear badblocks, the following functions are provided: **pmem2_badblock_context_new**(3), **pmem2_badblock_context_delete**(3), **pmem2_badblock_next**(3) and **pmem2_badblock_clear**(3). To handle unsafe shutdown in the application, the following functions are provided: **pmem2_source_device_id**(3), **pmem2_source_device_usc**(3). More detailed information about unsafe shutdown detection and unsafe shutdown count and can be found in the **libpmem2_unsafe_shutdown**(7) man page. # GRANULARITY # The **libpmem2** library introduces the concept of granularity through which you may easily distinguish between different levels of storage performance capabilities available to the application as related to *power-fail protected domain*. The way data reaches this protected domain differs based on the platform and storage device capabilities. Traditional block storage devices (SSD, HDD) must use system API calls such as `msync()`, `fsync()` on Linux, or `FlushFileBuffers()`,`FlushViewOfFile()` on Windows to write data reliably. Invoking these functions flushes the data to the medium with page granularity. In the **libpmem2** library, this type of flushing behavior is called **PMEM2_GRANULARITY_PAGE**. In systems with persistent memory support, a *power-fail protected domain* may cover different sets of resources: either the memory controller or the memory controller and CPU caches. For this reason, **libpmem2** distinguishes two types of granularity for persistent memory: **PMEM2_GRANULARITY_CACHE_LINE** and **PMEM2_GRANULARITY_BYTE**. If the *power-fail protected domain* covers only the memory controller, the CPU appropriate cache lines must be flushed for the data to be considered persistent. This granularity type is called **PMEM2_GRANULARITY_CACHE_LINE**. Depending on the architecture, there are different types of machine instructions for flushing *cache lines* (e.g., *CLWB*, *CLFLUSHOPT*, *CLFLUSH* for Intel x86_64 architecture). Usually, to ensure the ordering of stores, such instructions must be followed by a barrier (e.g., *SFENCE*). The third type of granularity **PMEM2_GRANULARITY_BYTE** applies to platforms where *power-fail protected domain* covers both the memory controller and CPU caches. In such cases, cache flush instructions are no longer needed, and the platform itself guarantees the persistence of data. But barriers might still be required for ordering. The library declares these granularity level in *pmem2_granularity* enum, which the application must set in *pmem2_config* to the appropriate level for a mapping a succeed. The software should set this config parameter to a value that most accurately represents the target hardware characteristics and the storage patterns of the application. For example, a database storage engine that operates on large logical pages that reside either on SSDs or PMEM should set this value to **PMEM2_GRANULARITY_PAGE**. The library will create mappings where the new map granularity is lower or equal to the requested one. For example, a mapping with **PMEM2_GRANULARITY_CACHE_LINE** can created for the required granularity **PMEM2_GRANULARITY_PAGE**, but not vice versa. # CAVEATS # **libpmem2** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. dlclose(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. # ENVIRONMENT # **libpmem2** can change its default behavior based on the following environment variables. These are primarily intended for testing and are generally not required. + **PMEM2_FORCE_GRANULARITY**=*val* Setting this environment variable to *val* forces **libpmem2** to use persist method specific for forced granularity and skip granularity autodetecting mechanism. The concept of the granularity is described in *GRANULARITY* section above. This variable is intended for use during library testing. The *val* argument accepts following text values: + **BYTE** - force byte granularity. + **CACHE_LINE** - force cache line granularity. + **PAGE** - force page granularity. Granularity values listed above are case-insensitive. >NOTE: The value of **PMEM2_FORCE_GRANULARITY** is not queried (and cached) at library initialization time, but read during each **pmem2_map_new**(3) call. This means that **PMEM2_FORCE_GRANULARITY** may still be set or modified by the program until the first attempt to map a file. + **PMEM_NO_CLWB**=1 Setting this environment variable to 1 forces **libpmem2** to never issue the **CLWB** instruction on Intel hardware, falling back to other cache flush instructions on that hardware instead (**CLFLUSHOPT** or **CLFLUSH**). Without this setting, **libpmem2** will always use the **CLWB** instruction for flushing processor caches on platforms that support this instruction. This variable is intended for use during library testing, but may be required for some rare cases when using **CLWB** has a negative impact on performance. + **PMEM_NO_CLFLUSHOPT**=1 Setting this environment variable to 1 forces **libpmem2** to never issue the **CLFLUSHOPT** instruction on Intel hardware, falling back to the **CLFLUSH** instructions instead. Without this environment variable, **libpmem2** will always use the **CLFLUSHOPT** instruction for flushing processor caches on platforms that support the instruction, but where **CLWB** is not available. This variable is intended for use during library testing. + **PMEM_NO_MOVNT**=1 Setting this environment variable to 1 forces **libpmem2** to never use the *non-temporal* move instructions on Intel hardware. Without this environment variable, **libpmem2** will use the non-temporal instructions for copying larger ranges to persistent memory on platforms that support these instructions. This variable is intended for use during library testing. + **PMEM_MOVNT_THRESHOLD**=*val* This environment variable allows overriding the minimum length of the *pmem2_memmove_fn* operations, for which **libpmem2** uses *non-temporal* move instructions. Setting this environment variable to 0 forces **libpmem2** to always use the *non-temporal* move instructions if available. It has no effect if **PMEM_NO_MOVNT** is set to 1. This variable is intended for use during library testing. # DEBUGGING # Two versions of **libpmem2** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmem2** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **libpmem2**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEM2_LOG_LEVEL** The value of **PMEM2_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEM2_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmem2_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmem2** developers. Unless **PMEM2_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEM2_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEM2_LOG_FILE** is not set, output is written to *stderr*. # EXAMPLE # The following example uses **libpmem2** to flush changes made to raw, memory-mapped persistent memory. >WARNING: There is nothing transactional about the *persist* from **pmem2_get_persist_fn**(3) call in this example. Interrupting the program may result in a partial write to pmem. Use a transactional library such as **libpmemobj**(7) to avoid torn updates. The above example is described in detail [here](https://pmem.io/pmdk/libpmem2/). # ACKNOWLEDGEMENTS # **libpmem2** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **FlushFileBuffers**(), **fsync**(2), **msync**(2), **pmem2_config_set_length**(3), **pmem2_config_set_offset**(3), **pmem2_config_set_required_store_granularity**(3), **pmem2_config_set_sharing**(3),**pmem2_get_drain_fn**(3), **pmem2_get_flush_fn**(3), **pmem2_get_memcpy_fn**(3), **pmem2_get_memmove_fn**(3), **pmem2_get_memset_fn**(3), **pmem2_get_persist_fn**(3),**pmem2_map_get_store_granularity**(3), **pmem2_map_new**(3), **pmem2_source_from_anon**(3), **pmem2_source_from_fd**(3), **pmem2_source_from_handle**(3), **libpmem2_unsafe_shutdown**(7), **libpmemblk**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_from_fd.30000664000000000000000000000774714123364736017712 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_FROM_FD" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2021, Intel Corporation .SH NAME .PP \f[B]pmem2_source_from_fd\f[](), \f[B]pmem2_source_from_handle\f[](), \f[B]pmem2_source_delete\f[]() \- creates or deletes an instance of persistent memory data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_source_from_fd(struct\ pmem2_source\ *src,\ int\ fd); int\ pmem2_source_from_handle(struct\ pmem2_source\ *src,\ HANDLE\ handle);\ /*\ Windows\ only\ */ int\ pmem2_source_delete(struct\ pmem2_source\ **src); \f[] .fi .SH DESCRIPTION .PP On Linux the \f[B]pmem2_source_from_fd\f[]() function validates the file descriptor and instantiates a new *struct pmem2_source** object describing the data source. .PP On Windows the \f[B]pmem2_source_from_fd\f[]() function converts a file descriptor to a file handle (using **_get_osfhandle\f[B]()), and passes it to \f[]pmem2_source_from_handle\f[B](). By default \f[]_get_osfhandle\f[B]() calls abort() in case of invalid file descriptor, but this behavior can be suppressed by \f[]_set_abort_behavior\f[B]() and \f[]SetErrorMode**() functions. Please check MSDN documentation for more information about Windows CRT error handling. .PP \f[I]fd\f[] must be opened with \f[I]O_RDONLY\f[] or \f[I]O_RDWR\f[] mode, but on Windows it is not validated. .PP If \f[I]fd\f[] is invalid, then the function fails. .PP The \f[B]pmem2_source_from_handle\f[]() function validates the handle and instantiates a new *struct pmem2_source\f[B] object describing the data source. If \f[BI]handle\f[B] is \f[BI]INVALID_HANDLE_VALUE\f[B], then the function fails. The handle has to be created with an access mode of \f[BI]GENERIC_READ\f[B] or \f[BI](GENERIC_READ | GENERIC_WRITE)\f[B]. For details please see the \f[]CreateFile**() documentation. .PP The \f[B]pmem2_source_delete\f[]() function frees \f[I]*src\f[] returned by \f[B]pmem2_source_from_fd\f[]() or \f[B]pmem2_source_from_handle\f[]() and sets \f[I]*src\f[] to NULL. If \f[I]*src\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmem2_source_from_fd\f[]() and \f[B]pmem2_source_from_handle\f[]() functions return 0 on success or a negative error code on failure. .PP The \f[B]pmem2_source_delete\f[]() function always returns 0. .SH ERRORS .PP The \f[B]pmem2_source_from_fd\f[]()/\f[B]pmem2_source_from_handle\f[]() functions can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_HANDLE\f[] \- \f[I]fd\f[] is not an open and valid file descriptor. On Windows the function can \f[B]abort\f[]() on this failure based on CRT's abort() behavior. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_HANDLE\f[] \- \f[I]fd\f[] is opened in O_WRONLY mode. .PP On Linux: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- \f[I]fd\f[] points to a directory, block device, pipe, or socket. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- \f[I]fd\f[] points to a character device other than Device DAX. .PP On Windows: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- \f[I]handle\f[] points to a resource that is not a regular file. .PP On Windows \f[B]pmem2_source_from_fd\f[]() can return all errors from the underlying \f[B]pmem2_source_from_handle\f[]() function. .PP The \f[B]pmem2_source_from_handle\f[]() can return the following errors: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_HANDLE\f[] \- \f[I]handle\f[] points to a resource that is not a file. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- \f[I]handle\f[] points to a directory. .PP The \f[B]pmem2_source_from_fd\f[]() and \f[B]pmem2_source_from_handle\f[]() functions can also return \f[B]\-ENOMEM\f[] in case of insufficient memory to allocate an instance of \f[I]struct pmem2_source\f[]. .SH CAVEATS .PP On non\-DAX Windows volumes, \f[I]fd\f[]/\f[I]handle\f[] must remain open while the mapping is in use. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find_first.30000664000000000000000000000004414123364546023003 0ustar rootroot.so pmem2_vm_reservation_map_find.3 pmdk-1.11.1/doc/libpmem2/pmem2_get_flush_fn.30000664000000000000000000000444214123364737017347 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_GET_FLUSH_FN" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_get_flush_fn\f[]() \- get a flush function .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ void\ (*pmem2_flush_fn)(const\ void\ *ptr,\ size_t\ size); struct\ pmem2_map; pmem2_flush_fn\ pmem2_get_flush_fn(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_get_flush_fn\f[]() function returns a pointer to a function responsible for efficiently flushing data in the range owned by the \f[I]map\f[]. .PP Flushing data using \f[I]pmem2_flush_fn\f[] \f[B]does not\f[] guarantee that the data is stored durably by the time it returns. To get this guarantee, application should either use the persist operation (see \f[B]pmem2_get_persist_fn\f[](3)) or follow \f[I]pmem2_flush_fn\f[] by a drain operation (see \f[B]pmem2_get_drain_fn\f[](3)). .PP There are no alignment restrictions on the range described by \f[I]ptr\f[] and \f[I]size\f[], but \f[I]pmem2_flush_fn\f[] may expand the range as necessary to meet platform alignment requirements. .PP There is nothing atomic or transactional about \f[I]pmem2_flush_fn\f[]. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until \f[I]pmem2_flush_fn\f[] is called to be flushed \[en] they can be flushed at any time before \f[I]pmem2_flush_fn\f[] is called. .PP If two (or more) mappings share the same \f[I]pmem2_flush_fn\f[] and they are adjacent to each other, it is safe to call this function for a range spanning those mappings. .SH RETURN VALUE .PP The \f[B]pmem2_get_flush_fn\f[]() function never returns NULL. .PP The \f[B]pmem2_get_flush_fn\f[]() for the same \f[I]map\f[] always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. .SH SEE ALSO .PP \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_persist_fn\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/.gitignore0000664000000000000000000000171414123364546015505 0ustar rootrootlibpmem2.7 libpmem2_unsafe_shutdown.7 pmem2_badblock_context_new.3 pmem2_badblock_next.3 pmem2_badblock_clear.3 pmem2_config_new.3 pmem2_config_set_length.3 pmem2_config_set_offset.3 pmem2_config_set_protection.3 pmem2_config_set_required_store_granularity.3 pmem2_config_set_sharing.3 pmem2_config_set_vm_reservation.3 pmem2_deep_flush.3 pmem2_errormsg.3 pmem2_get_drain_fn.3 pmem2_get_flush_fn.3 pmem2_get_memmove_fn.3 pmem2_get_persist_fn.3 pmem2_map_delete.3 pmem2_map_from_existing.3 pmem2_map_new.3 pmem2_map_get_address.3 pmem2_map_get_size.3 pmem2_map_get_store_granularity.3 pmem2_source_alignment.3 pmem2_source_from_fd.3 pmem2_source_from_anon.3 pmem2_source_get_fd.3 pmem2_source_get_handle.3 pmem2_source_numa_node.3 pmem2_source_size.3 pmem2_source_device_id.3 pmem2_source_device_usc.3 pmem2_perror.3 pmem2_vm_reservation_extend.3 pmem2_vm_reservation_get_address.3 pmem2_vm_reservation_get_size.3 pmem2_vm_reservation_map_find.3 pmem2_vm_reservation_new.3 pmdk-1.11.1/doc/libpmem2/pmem2_errormsg.3.md0000664000000000000000000000313014123364546017132 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_ERRORMSG, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2019, Intel Corporation) [comment]: <> (pmem2_errormsg.3 -- man page for error handling in libpmem2) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # _UW(pmem2_errormsg) - returns last error message # SYNOPSIS # ```c #include _UWFUNC(pmem2_errormsg, void) ``` _UNICODE() # DESCRIPTION # If an error is detected during the call to a **libpmem2**(7) function, the application may retrieve an error message describing the reason of the failure from _UW(pmem2_errormsg). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmem2**(7) function indicated an error. The application must not modify or free the error message string. Subsequent calls to other library functions may modify the previous message. # RETURN VALUE # The _UW(pmem2_errormsg) function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). # SEE ALSO # **strerror**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_from_existing.3.md0000664000000000000000000000371214123364546021012 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_FROM_EXISTING, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_map_from_existing.3 -- man page for libpmem2 pmem2_map_from_existing operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_from_existing**() - creates a pmem2_map object from an existing mapping # SYNOPSIS # ```c #include int pmem2_map_from_existing(struct pmem2_map **map, const struct pmem2_source *src, void *addr, size_t len, enum pmem2_granularity gran); ``` # DESCRIPTION # The **pmem2_map_from_existing**() returns a new *struct pmem2_map** for mapping provided by the user. This function allows usage of **libpmem2**(7) API without **pmem2_map_new**(3) for mapping file. Mapping is defined by *addr* and *len*. You have to specify underlying file as a *src*, and define granularity of this mapping. See **pmem2_config_set_required_store_granularity**(3) and **libpmem2**(7) for more details. For the *pmem2_map* object created by the **pmem2_map_from_existing**(3) function, the **pmem2_map_delete**(3) will only destroy the object, but it won't unmap the mapping this object describes. # RETURN VALUE # The **pmem2_map_from_existing**() function returns 0 when it succeeds or a negative error code on failure. # ERRORS # The **pmem2_map_from_existing**() can fail with the following errors: **PMEM2_E_MAPPING_EXISTS** - when contiguous region (*addr*, *addr* + *len*) is all ready registered by *libpmem2* It can also return **-ENOMEM** from the underlying **malloc**(2) function. # SEE ALSO # **malloc(2)**, **pmem2_map_delete**(3), **pmem2_map_new**(3), **pmem2_source_from_fd**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_memmove_fn.30000664000000000000000000001271314123364740017665 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_GET_MEMMOVE_FN" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() \- get a function that provides optimized copying to persistent memory .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ void\ *(*pmem2_memmove_fn)(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); typedef\ void\ *(*pmem2_memcpy_fn)(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); typedef\ void\ *(*pmem2_memset_fn)(void\ *pmemdest,\ int\ c,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); struct\ pmem2_map; pmem2_memmove_fn\ pmem2_get_memmove_fn(struct\ pmem2_map\ *map); pmem2_memset_fn\ pmem2_get_memset_fn(struct\ pmem2_map\ *map); pmem2_memcpy_fn\ pmem2_get_memcpy_fn(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() functions return a pointer to a function responsible for efficient storing and flushing of data for mapping \f[I]map\f[]. .PP \f[B]pmem2_memmove_fn\f[](), \f[B]pmem2_memset_fn\f[]() and \f[B]pmem2_memcpy_fn\f[]() functions provide the same memory copying functionalities as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3) and \f[B]memset\f[](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEM2_F_MEM_NOFLUSH\f[] flag was used). .PP For example, the following code: .IP .nf \f[C] \ \ \ \ \ \ \ \ memmove(dest,\ src,\ len); \ \ \ \ \ \ \ \ pmem2_persist_fn\ persist_fn\ =\ pmem2_get_persist_fn(map); \ \ \ \ \ \ \ \ persist_fn(dest,\ len); \f[] .fi .PP is functionally equivalent to: .IP .nf \f[C] \ \ \ \ \ \ \ \ pmem2_memmove_fn\ memmove_fn\ =\ pmem2_get_memmove_fn(map); \ \ \ \ \ \ \ \ memmove_fn(dest,\ src,\ len,\ 0); \f[] .fi .PP Unlike libc implementation, \f[B]libpmem2\f[] functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by \f[I]persist_fn\f[] can be safely replaced by a single \f[I]memmove_fn\f[] call. .PP The \f[I]flags\f[] argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEM2_F_MEM_NODRAIN\f[] \- modifies the behavior to skip the final \f[I]pmem2_drain_fn\f[] step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to \f[I]pmem2_drain_fn\f[]. The following example illustrates how this flag might be used to avoid multiple calls to \f[I]pmem2_drain_fn\f[] when copying several ranges of memory to pmem: .IP .nf \f[C] pmem2_memcpy_fn\ memcpy_fn\ =\ pmem2_get_memcpy_fn(map); pmem2_drain_fn\ drain_fn\ =\ pmem2_get_drain_fn(map); /*\ ...\ write\ several\ ranges\ to\ pmem\ ...\ */ memcpy_fn(pmemdest1,\ src1,\ len1,\ PMEM2_F_MEM_NODRAIN); memcpy_fn(pmemdest2,\ src2,\ len2,\ PMEM2_F_MEM_NODRAIN); /*\ ...\ */ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ drain_fn(); \f[] .fi .IP \[bu] 2 \f[B]PMEM2_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEM2_F_MEM_NODRAIN\f[]. Using this flag only makes sense when it's followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEM2_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM2_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_WB\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM2_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEM2_F_MEM_TEMPORAL\f[]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmem2\f[] will try to guess the best strategy based on the data size. See \f[B]PMEM_MOVNT_THRESHOLD\f[] description in \f[B]libpmem2\f[](7) for details. .SH RETURN VALUE .PP The \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() functions never return NULL. .PP They return the same function for the same mapping. .PP This means that it's safe to cache their return values. However, these functions are very cheap (because their return values are precomputed), so caching may not be necessary. .PP If two (or more) mappings share the same \f[I]pmem2_memmove_fn\f[], \f[I]pmem2_memset_fn\f[], \f[I]pmem2_memcpy_fn\f[] and they are adjacent to each other, it is safe to call these functions for a range spanning those mappings. .SH SEE ALSO .PP \f[B]memcpy\f[](3), \f[B]memmove\f[](3), \f[B]memset\f[](3), \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_memcpy_fn\f[](3), \f[B]pmem2_get_memset_fn\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_get_persist_fn\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_vm_reservation.30000664000000000000000000000223414123364740022136 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_VM_RESERVATION" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_vm_reservation\f[]() \- sets the pmem2_vm_reservation structure basing on the values in the pmem2_config structure .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; struct\ pmem2_vm_reservation; int\ pmem2_config_set_vm_reservation(struct\ pmem2_config\ *config, \ \ \ \ \ \ \ \ struct\ pmem2_vm_reservation\ *rsv,\ size_t\ rsv_offset); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_vm_reservation\f[]() function sets the virtual memory reservation and an offset to be used during a mapping. \f[I]rsv\f[] should be already initialized. Please see \f[B]pmem2_vm_reservation_new\f[](3) for details. \f[I]rsv_offset\f[] marks the offset in the reservation for the mapping. .SH RETURN VALUE .PP \f[B]pmem2_config_set_vm_reservation\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]pmem2_vm_reservation_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_get_address.30000664000000000000000000000176314123364741022311 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_VM_RESERVATION_GET_ADDRESS" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_vm_reservation_get_address\f[]() \- reads address of the virtual memory reservation .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *pmem2_vm_reservation_get_address(struct\ pmem2_vm_reservation\ *rsv); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_vm_reservation_get_address\f[]() function reads address of the created virtual memory reservation. The \f[I]rsv\f[] parameter points to the structure describing the reservation created using the \f[B]pmem2_vm_reservation_new\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmem2_vm_reservation_get_address\f[]() function returns a pointer to the virtual memory reservation area. .SH SEE ALSO .PP \f[B]pmem2_vm_reservation_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_badblock_context_delete.30000664000000000000000000000004114123364546021520 0ustar rootroot.so pmem2_badblock_context_new.3 pmdk-1.11.1/doc/libpmem2/pmem2_config_set_sharing.30000664000000000000000000000277514123364740020540 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_SHARING" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_sharing\f[]() \- set sharing in the pmem2_config structure .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; enum\ pmem2_sharing_type\ { \ \ \ \ PMEM2_SHARED, \ \ \ \ PMEM2_PRIVATE, }; int\ pmem2_config_set_sharing(struct\ pmem2_config\ *config,\ enum\ pmem2_sharing_type\ sharing); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_sharing\f[]() function configures the behavior and visibility of writes to the mapping's pages. The possible values are listed below: .IP \[bu] 2 \f[B]PMEM2_SHARED\f[] \- Writes are made directly to the underlying memory, making them visible to other mappings of the same memory region. (default) .IP \[bu] 2 \f[B]PMEM2_PRIVATE\f[] \- Writes do not affect the underlying memory and are not visible to other mappings of the same memory region. .SH RETURN VALUE .PP The \f[B]pmem2_config_set_sharing\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORRS .PP The \f[B]pmem2_config_set_sharing\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_SHARING_VALUE\f[] \- \f[I]sharing\f[] value is invalid. .SH SEE ALSO .PP \f[B]libpmem2\f[](7), \f[B]pmem2_config_new\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]sysconf\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_extend.3.md0000664000000000000000000000724614123364546021720 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_VM_RESERVATION_EXTEND, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmem2_vm_reservation_extend.3 -- man page for libpmem2 pmem2_vm_reservation_extend and pmem2_vm_reservation_shrink operations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_vm_reservation_extend**(), **pmem2_vm_reservation_shrink**() - extends and shrinks existing virtual memory reservation # SYNOPSIS # ```c #include struct pmem2_vm_reservation; int pmem2_vm_reservation_extend(struct pmem2_vm_reservation *rsv, size_t size); int pmem2_vm_reservation_shrink(struct pmem2_vm_reservation *rsv, size_t offset, size_t size); ``` # DESCRIPTION # The **pmem2_vm_reservation_extend**() function extends an existing virtual memory reservation by the given *size*. For the function to succeed the size has to be aligned to an appropriate allocation granularity. If the **pmem2_vm_reservation_extend**() succeeds in extending a reservation, it provides placeholder virtual memory range that starts from an address at the end of the old reservation. Mappings made to the reservation before extending are preserved. The **pmem2_vm_reservation_shrink**() function shrinks the reservation by a region specified by *offset* into the reservation and the *size*. For the function to succeed the *size* and *offset* variables have to be aligned to an appropriate allocation granularity. The region formed by *offset* and *size* has to belong to the reservation, be empty and it needs to cover the beggining or the end of the reservation. Shrinking reservation from the middle or shrinking the whole reservation is not supported. If the **pmem2_vm_reservation_shrink**() succeeds in shrinking a reservation, it releases placeholder virtual memory range that was designated by *offset* and *size* variables. Mappings made to the reservation before shrinking are preserved. If either of those functions fails, reservation will be left as it was and appropriate error value will be returned. # RETURN VALUE # The **pmem2_vm_reservation_extend**() and **pmem2_vm_reservation_shrink**() functions return 0 on success or a negative error code on failure. # ERRORS # The **pmem2_vm_reservation_extend**() function can fail with the following errors: * **PMEM2_E_MAPPING_EXISTS** - the range that the reservation would be extended by is already occupied by an existing mapping. It can also return **-EAGAIN**, **-ENOMEM** from the underlying **mmap**(2) function. The **pmem2_vm_reservation_shrink**() function can fail with the following errors: * **PMEM2_E_OFFSET_UNALIGNED** - provided offset isn't aligned to an appropriate allocation granularity. * **PMEM2_E_LENGTH_UNALIGNED** - provided size isn't aligned to an appropriate allocation granularity. * **PMEM2_E_OFFSET_OUT_OF_RANGE** - provided offset is out of reservation range available to be shrunk. * **PMEM2_E_LENGTH_OUT_OF_RANGE** - provided size is out of reservation range available to be shrunk. * **PMEM2_E_NOSUPP** - interval designated by *offset* and *size* variables covers only the middle or the whole reservation range. * **PMEM2_VM_RESERVATION_NOT_EMPTY** - interval designated by *offset* and *size* variable is not empty. It can also return **-EAGAIN** and **-ENOMEM** from the underlying **munmap**(2) function. # SEE ALSO # **pmem2_vm_reservation_new**(3), **pmem2_config_set_vm_reservation**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/libpmem2.70000664000000000000000000003471314123364726015321 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEM2" "7" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2021, Intel Corporation .SH NAME .PP \f[B]libpmem2\f[] \- persistent memory support library .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lpmem2 \f[] .fi .SH DESCRIPTION .PP \f[B]libpmem2\f[] provides low\-level \f[I]persistent memory\f[] (pmem) support for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of \f[I]non\-volatile memory DIMMs\f[] (NVDIMMs) provide this type of byte addressable access to storage. A \f[I]persistent memory aware file system\f[] is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non\-paged access to pmem. .PP This library is for applications that use persistent memory directly, without the help of any library\-supplied transactions or memory allocation. Higher\-level libraries that \f[I]currently\f[] build on \f[B]libpmem\f[] (previous variation of libpmem2) are available and are recommended for most applications, see: .IP \[bu] 2 \f[B]libpmemobj\f[](7), a general use persistent memory API, providing memory allocation and transactional operations on variable\-sized objects. .IP \[bu] 2 \f[B]libpmemblk\f[](7), providing pmem\-resident arrays of fixed\-sized blocks with atomic updates. .IP \[bu] 2 \f[B]libpmemlog\f[](7), providing a pmem\-resident log file. .PP The \f[B]libpmem2\f[] library provides a comprehensive set of functions for robust use of Persistent Memory. It relies on three core concepts: \f[I]struct pmem2_src source\f[], \f[I]struct pmem2_config config\f[] and \f[I]struct pmem2_map map\f[]: .IP \[bu] 2 \f[I]source\f[] \- an object describing the data source for mapping. The data source can be a file descriptor, a file handle, or an anonymous mapping. APIs dedicated for creating \f[I]source\f[] are: \f[B]pmem2_source_from_fd\f[](3), \f[B]pmem2_source_from_handle\f[](3), \f[B]pmem2_source_from_anon\f[](3). .IP \[bu] 2 \f[I]config\f[] \- an object containing parameters that are used to create a mapping from a \f[I]source\f[]. The configuration structure must always be provided to create a mapping, but the only required parameter to set in the \f[I]config\f[] is \f[I]granularity\f[]. The granularity should by set using dedicated \f[B]libpmem2\f[] function \f[B]pmem2_config_set_required_store_granularity\f[](3) which defines a maximum permitted granularity requested by the user. For more information about the granularity concept read \f[B]GRANULARITY\f[] section below. .PP In addition to the granularity setting, libpmem2 provides multiple optional functions to configure target mapping, e.g., \f[B]pmem2_config_set_length\f[](3) to set length which will be used for mapping, or \f[B]pmem2_config_set_offset\f[](3) which will be used to map the contents from the specified location of the source, \f[B]pmem2_config_set_sharing\f[](3) which defines the behavior and visibility of writes to the mapping's pages. .IP \[bu] 2 \f[I]map\f[] \- an object created by \f[B]pmem2_map_new\f[](3) using \f[I]source\f[] and \f[I]config\f[] as an input parameters. The map structure can be then used to directly operate on the created mapping through the use of its associated set of functions: \f[B]pmem2_map_get_address\f[](3), \f[B]pmem2_map_get_size\f[](3), \f[B]pmem2_map_get_store_granularity\f[](3) \- for getting address, size and effective mapping granularity. .PP In addition to the basic functionality of managing the virtual address mapping, \f[B]libpmem2\f[] also provides optimized functions for modifying the mapped data. This includes data flushing as well as memory copying. .PP To get proper function for data flushing use: \f[B]pmem2_get_flush_fn\f[](3), \f[B]pmem2_get_persist_fn\f[](3) or \f[B]pmem2_get_drain_fn\f[](3). To get proper function for copying to persistent memory, use \f[I]map\f[] getters: \f[B]pmem2_get_memcpy_fn\f[](3), \f[B]pmem2_get_memset_fn\f[](3), \f[B]pmem2_get_memmove_fn\f[](3). .PP The \f[B]libpmem2\f[] API also provides support for the badblock and unsafe shutdown state handling. .PP To read or clear badblocks, the following functions are provided: \f[B]pmem2_badblock_context_new\f[](3), \f[B]pmem2_badblock_context_delete\f[](3), \f[B]pmem2_badblock_next\f[](3) and \f[B]pmem2_badblock_clear\f[](3). .PP To handle unsafe shutdown in the application, the following functions are provided: \f[B]pmem2_source_device_id\f[](3), \f[B]pmem2_source_device_usc\f[](3). More detailed information about unsafe shutdown detection and unsafe shutdown count and can be found in the \f[B]libpmem2_unsafe_shutdown\f[](7) man page. .SH GRANULARITY .PP The \f[B]libpmem2\f[] library introduces the concept of granularity through which you may easily distinguish between different levels of storage performance capabilities available to the application as related to \f[I]power\-fail protected domain\f[]. The way data reaches this protected domain differs based on the platform and storage device capabilities. .PP Traditional block storage devices (SSD, HDD) must use system API calls such as \f[C]msync()\f[], \f[C]fsync()\f[] on Linux, or \f[C]FlushFileBuffers()\f[],\f[C]FlushViewOfFile()\f[] on Windows to write data reliably. Invoking these functions flushes the data to the medium with page granularity. In the \f[B]libpmem2\f[] library, this type of flushing behavior is called \f[B]PMEM2_GRANULARITY_PAGE\f[]. .PP In systems with persistent memory support, a \f[I]power\-fail protected domain\f[] may cover different sets of resources: either the memory controller or the memory controller and CPU caches. For this reason, \f[B]libpmem2\f[] distinguishes two types of granularity for persistent memory: \f[B]PMEM2_GRANULARITY_CACHE_LINE\f[] and \f[B]PMEM2_GRANULARITY_BYTE\f[]. .PP If the \f[I]power\-fail protected domain\f[] covers only the memory controller, the CPU appropriate cache lines must be flushed for the data to be considered persistent. This granularity type is called \f[B]PMEM2_GRANULARITY_CACHE_LINE\f[]. Depending on the architecture, there are different types of machine instructions for flushing \f[I]cache lines\f[] (e.g., \f[I]CLWB\f[], \f[I]CLFLUSHOPT\f[], \f[I]CLFLUSH\f[] for Intel x86_64 architecture). Usually, to ensure the ordering of stores, such instructions must be followed by a barrier (e.g., \f[I]SFENCE\f[]). .PP The third type of granularity \f[B]PMEM2_GRANULARITY_BYTE\f[] applies to platforms where \f[I]power\-fail protected domain\f[] covers both the memory controller and CPU caches. In such cases, cache flush instructions are no longer needed, and the platform itself guarantees the persistence of data. But barriers might still be required for ordering. .PP The library declares these granularity level in \f[I]pmem2_granularity\f[] enum, which the application must set in \f[I]pmem2_config\f[] to the appropriate level for a mapping a succeed. The software should set this config parameter to a value that most accurately represents the target hardware characteristics and the storage patterns of the application. For example, a database storage engine that operates on large logical pages that reside either on SSDs or PMEM should set this value to \f[B]PMEM2_GRANULARITY_PAGE\f[]. The library will create mappings where the new map granularity is lower or equal to the requested one. For example, a mapping with \f[B]PMEM2_GRANULARITY_CACHE_LINE\f[] can created for the required granularity \f[B]PMEM2_GRANULARITY_PAGE\f[], but not vice versa. .SH CAVEATS .PP \f[B]libpmem2\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g.\ dlclose(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .SH ENVIRONMENT .PP \f[B]libpmem2\f[] can change its default behavior based on the following environment variables. These are primarily intended for testing and are generally not required. .IP \[bu] 2 \f[B]PMEM2_FORCE_GRANULARITY\f[]=\f[I]val\f[] .PP Setting this environment variable to \f[I]val\f[] forces \f[B]libpmem2\f[] to use persist method specific for forced granularity and skip granularity autodetecting mechanism. The concept of the granularity is described in \f[I]GRANULARITY\f[] section above. This variable is intended for use during library testing. .PP The \f[I]val\f[] argument accepts following text values: .IP \[bu] 2 \f[B]BYTE\f[] \- force byte granularity. .IP \[bu] 2 \f[B]CACHE_LINE\f[] \- force cache line granularity. .IP \[bu] 2 \f[B]PAGE\f[] \- force page granularity. .PP Granularity values listed above are case\-insensitive. .RS .PP NOTE: The value of \f[B]PMEM2_FORCE_GRANULARITY\f[] is not queried (and cached) at library initialization time, but read during each \f[B]pmem2_map_new\f[](3) call. .RE .PP This means that \f[B]PMEM2_FORCE_GRANULARITY\f[] may still be set or modified by the program until the first attempt to map a file. .IP \[bu] 2 \f[B]PMEM_NO_CLWB\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem2\f[] to never issue the \f[B]CLWB\f[] instruction on Intel hardware, falling back to other cache flush instructions on that hardware instead (\f[B]CLFLUSHOPT\f[] or \f[B]CLFLUSH\f[]). Without this setting, \f[B]libpmem2\f[] will always use the \f[B]CLWB\f[] instruction for flushing processor caches on platforms that support this instruction. This variable is intended for use during library testing, but may be required for some rare cases when using \f[B]CLWB\f[] has a negative impact on performance. .IP \[bu] 2 \f[B]PMEM_NO_CLFLUSHOPT\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem2\f[] to never issue the \f[B]CLFLUSHOPT\f[] instruction on Intel hardware, falling back to the \f[B]CLFLUSH\f[] instructions instead. Without this environment variable, \f[B]libpmem2\f[] will always use the \f[B]CLFLUSHOPT\f[] instruction for flushing processor caches on platforms that support the instruction, but where \f[B]CLWB\f[] is not available. This variable is intended for use during library testing. .IP \[bu] 2 \f[B]PMEM_NO_MOVNT\f[]=1 .PP Setting this environment variable to 1 forces \f[B]libpmem2\f[] to never use the \f[I]non\-temporal\f[] move instructions on Intel hardware. Without this environment variable, \f[B]libpmem2\f[] will use the non\-temporal instructions for copying larger ranges to persistent memory on platforms that support these instructions. This variable is intended for use during library testing. .IP \[bu] 2 \f[B]PMEM_MOVNT_THRESHOLD\f[]=\f[I]val\f[] .PP This environment variable allows overriding the minimum length of the \f[I]pmem2_memmove_fn\f[] operations, for which \f[B]libpmem2\f[] uses \f[I]non\-temporal\f[] move instructions. Setting this environment variable to 0 forces \f[B]libpmem2\f[] to always use the \f[I]non\-temporal\f[] move instructions if available. It has no effect if \f[B]PMEM_NO_MOVNT\f[] is set to 1. This variable is intended for use during library testing. .SH DEBUGGING .PP Two versions of \f[B]libpmem2\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmem2\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]libpmem2\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEM2_LOG_LEVEL\f[] .PP The value of \f[B]PMEM2_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEM2_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmem2_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmem2\f[] developers. .PP Unless \f[B]PMEM2_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEM2_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEM2_LOG_FILE\f[] is not set, output is written to \f[I]stderr\f[]. .SH EXAMPLE .PP The following example uses \f[B]libpmem2\f[] to flush changes made to raw, memory\-mapped persistent memory. .RS .PP WARNING: There is nothing transactional about the \f[I]persist\f[] from \f[B]pmem2_get_persist_fn\f[](3) call in this example. Interrupting the program may result in a partial write to pmem. Use a transactional library such as \f[B]libpmemobj\f[](7) to avoid torn updates. .RE .PP .PP The above example is described in detail here (https://pmem.io/pmdk/libpmem2/). .SH ACKNOWLEDGEMENTS .PP \f[B]libpmem2\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]FlushFileBuffers\f[](), \f[B]fsync\f[](2), \f[B]msync\f[](2), \f[B]pmem2_config_set_length\f[](3), \f[B]pmem2_config_set_offset\f[](3), \f[B]pmem2_config_set_required_store_granularity\f[](3), \f[B]pmem2_config_set_sharing\f[](3),\f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_flush_fn\f[](3), \f[B]pmem2_get_memcpy_fn\f[](3), \f[B]pmem2_get_memmove_fn\f[](3), \f[B]pmem2_get_memset_fn\f[](3), \f[B]pmem2_get_persist_fn\f[](3),\f[B]pmem2_map_get_store_granularity\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_source_from_anon\f[](3), \f[B]pmem2_source_from_fd\f[](3), \f[B]pmem2_source_from_handle\f[](3), \f[B]libpmem2_unsafe_shutdown\f[](7), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_map_get_store_granularity.3.md0000664000000000000000000000244514123364546022553 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_MAP_GET_STORE_GRANULARITY, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_map_get_store_granularity.3 -- man page for libpmem2 mapping) [comment]: <> (operations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_map_get_store_granularity**() - reads effective mapping granularity # SYNOPSIS # ```c #include enum pmem2_granularity { PMEM2_GRANULARITY_BYTE, PMEM2_GRANULARITY_CACHE_LINE, PMEM2_GRANULARITY_PAGE, }; enum pmem2_granularity pmem2_map_get_store_granularity(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_map_get_store_granularity**() function reads granularity of the created mapping. The *map* parameter points to the structure describing mapping created using the **pmem2_map_new**(3) function. Concept of the granularity is described in **libpmem2**(7). # RETURN VALUE # The **pmem2_map_get_store_granularity**() function returns a granularity of the mapped area. # SEE ALSO # **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_device_usc.3.md0000664000000000000000000000454114123364546020772 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_DEVICE_USC, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_device_usc.3 -- man page for pmem2_source_device_usc) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_device_usc**() - returns the *unsafe shutdown counter* value of a device # SYNOPSIS # ```c #include struct pmem2_source; int pmem2_source_device_usc(const struct pmem2_source *source, uint64_t *usc); ``` # DESCRIPTION # The **pmem2_source_device_usc**() function retrieves the sum of the *unsafe shutdown count*(**USC**) values of all hardware devices backing the data source and stores it in *\*usc*. Please refer to **libpmem2_unsafe_shutdown**(7) for detailed description on how to properly consume this information. # RETURN VALUE # The **pmem2_source_device_usc**() function returns 0 on success. If the function fails, the *\*usc* variable content is left unmodified and a negative error code is returned. # ERRORS # The **pmem2_source_device_usc**() can fail with the following errors: On all systems: * **PMEM2_E_NOSUPP** - the underlying platform does not expose unsafe shutdown count information. On Windows: * -**errno** equivalent of return code set by failing **GetFinalPathNameByHandleW**(), while trying to resolve volume path from the file handle. * -**errno** set by failing **malloc**(3), while trying to allocate a buffer for storing volume path. * -**errno** equivalent of return code set by failing **CreateFileW**(), while trying to obtain a handle to the volume. * -**errno** equivalent of return code set by failing **DeviceIoControl**(), while trying to obtain volume **USC** value. On Linux: * -**errno** set by failing **fstat**(2), while trying to validate the file descriptor. * -**errno** set by failing **ndctl_new**(), while trying to initiate a new NDCTL library context. * -**errno** set by failing **ndctl_dimm_get_dirty_shutdown**(), while trying to obtain DIMM **USC** value. # SEE ALSO # **fstat**(2), **errno**(3), **malloc**(3), **libpmem2_unsafe_shutdown**(7), and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_device_id.30000664000000000000000000000557714123364742020205 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_DEVICE_ID" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_device_id\f[]() \- returns the unique identifier of a device .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; int\ pmem2_source_device_id(const\ struct\ pmem2_source\ *source,\ char\ *id,\ size_t\ *len); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_device_id\f[]() function retrieves a unique identifier of all NVDIMMs backing the data source. This function has two operating modes: .IP \[bu] 2 if \f[I]*id\f[] is NULL the function calculates a buffer length required for storing the identifier of the \f[I]*source\f[] device and puts this length in \f[I]*len\f[] The more hardware devices back the data source, the longer the length is. .IP \[bu] 2 if \f[I]*id\f[] is not NULL it must point to a buffer of length \f[I]*len\f[] provided by the previous call to this function. On success, \f[B]pmem2_source_device_id\f[]() will store a unique identifier of all hardware devices backing the data source. .PP For details on how to use the unique identifier for detecting \f[I]the unsafe shutdown\f[] please refer to \f[B]libpmem2_unsafe_shutdown\f[](7) manual page. .SH RETURN VALUE .PP The \f[B]pmem2_source_device_id\f[]() function returns 0 on success. If the function fails, the \f[I]*id\f[] and \f[I]*len\f[] variables contents are left unmodified and a negative error code is returned. .SH ERRORS .PP The \f[B]pmem2_source_device_id\f[]() can fail with the following errors: .PP On all systems: .IP \[bu] 2 \f[B]PMEM2_E_BUFFER_TOO_SMALL\f[] \- the provided buffer of length \f[I]*len\f[] is too small to store the full identifier of the backing devices. .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- the underlying platform does not expose hardware identification. .PP On Windows: .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]GetFinalPathNameByHandleW\f[](), while trying to resolve the volume path from the file handle. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]malloc\f[](3), while trying to allocate a buffer for storing volume path. .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]CreateFileW\f[](), while trying to obtain a handle to the volume. .IP \[bu] 2 \-\f[B]errno\f[] equivalent of return code set by failing \f[B]DeviceIoControl\f[](), while trying to obtain volume \f[B]USC\f[] value. .PP On Linux: .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]ndctl_new\f[](), while trying to initiate a new NDCTL library context. .SH SEE ALSO .PP \f[B]fstat\f[](2), \f[B]errno\f[](3), \f[B]malloc\f[](3), \f[B]libpmem2_unsafe_shutdown\f[](7), and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_map_find.3.md0000664000000000000000000000663314123364546022205 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_VM_RESERVATION_MAP_FIND, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2021, Intel Corporation) [comment]: <> (pmem2_vm_reservation_map_find.3 -- man page for libpmem2 pmem2_vm_reservation_map_find operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_vm_reservation_map_find**(), **pmem2_vm_reservation_map_find_prev**(), **pmem2_vm_reservation_map_find_next**(), **pmem2_vm_reservation_map_find_first**() and **pmem2_vm_reservation_map_find_last**() - search for the mapping located at the desirable location # SYNOPSIS # ```c #include struct pmem2_map; struct pmem2_vm_reservation; int pmem2_vm_reservation_map_find(struct pmem2_vm_reservation *rsv, size_t reserv_offset, size_t len, struct pmem2_map **map_ptr); int pmem2_vm_reservation_map_find_prev(struct pmem2_vm_reservation *rsv, struct pmem2_map *map, struct pmem2_map **prev_map); int pmem2_vm_reservation_map_find_next(struct pmem2_vm_reservation *rsv, struct pmem2_map *map, struct pmem2_map **next_map); int pmem2_vm_reservation_map_find_first(struct pmem2_vm_reservation *rsv, struct pmem2_map **first_map); int pmem2_vm_reservation_map_find_last(struct pmem2_vm_reservation *rsv, struct pmem2_map **last_map); ``` # DESCRIPTION # Mappings are inserted to the virtual memory reservation in the order of their virtual address space location. First mapping represents the earliest mapping in the virtual addres space contained in a reservation, whereas the last mapping represents the last one. The **pmem2_vm_reservation_map_find**() function searches for the earliest mapping, stored in the virtual memory reservation, intersecting with the interval defined by *reserv_offset* and *len* variables and returns it via *map_ptr* variable. **pmem2_vm_reservation_map_find_prev**() function searches for the map previous to the provided *map* and returns it via provided *prev_map* variable. **pmem2_vm_reservation_map_find_next**() function searches for the map next after the provided *map* and returns it via *next_map* variable. **pmem2_vm_reservation_map_find_first**() function searches for the first map in the reservation and returns it via provided *first_map* variable. **pmem2_vm_reservation_map_find_last**() function searches for the last map in the reservation and returns it via provided *last_map* variable. # RETURN VALUE # The **pmem2_vm_reservation_map_find**(), **pmem2_vm_reservation_map_find_prev**(), **pmem2_vm_reservation_map_find_next**(), **pmem2_vm_reservation_map_find_first**() and **pmem2_vm_reservation_map_find_last**() return 0 on success or a negative error on failure. It passes an address to the found mapping via user provided *map* pointer variable on success, otherwise it passes *NULL* value when no mapping was found. # ERRORS # The **pmem2_vm_reservation_map_find**(), **pmem2_vm_reservation_map_find_prev**(), **pmem2_vm_reservation_map_find_next**(), **pmem2_vm_reservation_map_find_first**() and **pmem2_vm_reservation_map_find_last**() can fail with the following errors: - **PMEM2_E_MAPPING_NOT_FOUND** - no mapping found at the desirable location of the reservation # SEE ALSO # **libpmem2**(7), and **** pmdk-1.11.1/doc/libpmem2/pmem2_map_new.30000664000000000000000000001152114123364735016324 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_NEW" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2020, Intel Corporation .SH NAME .PP \f[B]pmem2_map_new\f[]() \- creates a mapping .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; struct\ pmem2_source; struct\ pmem2_map; int\ pmem2_map_new(struct\ pmem2_map\ **map_ptr,\ const\ struct\ pmem2_config\ *config, \ \ \ \ \ \ \ \ const\ struct\ pmem2_source\ *source); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_new\f[]() function creates a new mapping in the virtual address space of the calling process. This function requires a configuration \f[I]config\f[] of the mapping and the data source \f[I]source\f[]. .PP Optionally, the mapping can be created at the offset of the virtual memory reservation set in the configuration \f[I]config\f[]. See \f[B]pmem2_config_set_vm_reservation\f[](3) for details. .PP For a mapping to succeed, the \f[I]config\f[] structure must have the granularity parameter set to the appropriate level. See \f[B]pmem2_config_set_required_store_granularity\f[](3) and \f[B]libpmem2\f[](7) for more details. .PP If the \f[B]pmem2_map_new\f[]() function succeeds in creating a new mapping it instantiates a new *struct pmem2_map** object describing the mapping. The pointer to this newly created object is stored in the user\-provided variable passed via the \f[I]map_ptr\f[] pointer. If the mapping fails the variable pointed by \f[I]map_ptr\f[] will contain a NULL value and appropriate error value will be returned. For a list of possible return values please see RETURN VALUE. .PP All \f[I]struct pmem2_map\f[] objects created via the \f[B]pmem2_map_new\f[]() function have to be destroyed using the \f[B]pmem2_map_delete\f[]() function. For details please see \f[B]pmem2_map_delete\f[](3) manual page. .SH RETURN VALUE .PP The \f[B]pmem2_map_new\f[]() function returns 0 on succeeds or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_map_new\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_GRANULARITY_NOT_SET\f[] \- the store granularity for the mapping was not set in the provided \f[I]config\f[] structure. Please see \f[B]pmem2_config_set_required_store_granularity\f[](3) and \f[B]libpmem2\f[](7). .IP \[bu] 2 \f[B]PMEM2_E_MAP_RANGE\f[] \- \f[I]offset\f[] + \f[I]length\f[] is too big to represent it using \f[I]size_t\f[] data type .IP \[bu] 2 \f[B]PMEM2_E_MAP_RANGE\f[] \- end of the mapping (\f[I]offset\f[] + \f[I]length\f[]) is outside of the file. The file is too small. .IP \[bu] 2 \f[B]PMEM2_E_SOURCE_EMPTY\f[] \- mapped file has size equal to 0. .IP \[bu] 2 \f[B]PMEM2_E_MAPPING_EXISTS\f[] \- if the object exists before the function call. For details please see \f[B]CreateFileMapping\f[]() manual pages. (Windows only) .IP \[bu] 2 \f[B]PMEM2_E_OFFSET_UNALIGNED\f[] \- argument unaligned, offset is not a multiple of the alignment required for specific \f[I]*source\f[]. Please see \f[B]pmem2_source_alignement\f[](3). .IP \[bu] 2 \f[B]PMEM2_E_LENGTH_UNALIGNED\f[] \- argument unaligned, length is not a multiple of the alignment required for specific \f[I]*source\f[]. Please see \f[B]pmem2_source_alignement\f[](3). .IP \[bu] 2 \f[B]PMEM2_E_SRC_DEVDAX_PRIVATE\f[] \- device DAX mapped with MAP_PRIVATE. (Linux only) .IP \[bu] 2 \f[B]PMEM2_E_ADDRESS_UNALIGNED\f[] \- when mapping device DAX to a virtual memory reservation and the base mapping address (reservation address + reservation offset) is not aligned to the device DAX granularity. Please see \f[B]pmem2_config_set_vm_reservation\f[](3). (Linux only) .IP \[bu] 2 \f[B]PMEM2_E_ADDRESS_UNALIGNED\f[] \- when mapping to a virtual memory reservation and the region for the mapping exceeds reservation size. Please see \f[B]pmem2_config_set_vm_reservation\f[](3). .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- when config\-provided protection flags combination is not supported. .IP \[bu] 2 \f[B]PMEM2_E_NO_ACCESS\f[] \- there is a conflict between mapping protection and file opening mode. .PP It can also return \f[B]\-EACCES\f[], \f[B]\-EAGAIN\f[], \f[B]\-EBADF\f[], \f[B]\-ENFILE\f[], \f[B]\-ENODEV\f[], \f[B]\-ENOMEM\f[], \f[B]\-EPERM\f[], \f[B]\-ETXTBSY\f[] from the underlying \f[B]mmap\f[](2) function. It is used with and without \f[B]MAP_ANONYMOUS\f[]. .PP \f[B]\-EACCES\f[] may be returned only if the file descriptor points to an append\-only file. .PP It can also return all errors from the underlying \f[B]pmem2_source_size\f[]() and \f[B]pmem2_source_alignment\f[]() functions. .SH SEE ALSO .PP \f[B]mmap\f[](2), \f[B]open\f[](3), \f[B]pmem2_config_set_required_store_granularity\f[](3), \f[B]pmem2_source_alignment\f[](3), \f[B]pmem2_source_from_fd\f[](3), \f[B]pmem2_source_size\f[](3), \f[B]pmem2_map_delete\f[](3), \f[B]pmem2_config_set_vm_reservation\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_source_get_handle.30000664000000000000000000000321514123364743020350 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_GET_HANDLE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_get_handle\f[]() \- reads file handler of the data source .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmem2_source_get_handle(const\ struct\ pmem2_source\ *src,\ HANDLE\ *h); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_get_handle\f[]() function reads the file handler of *struct pmem2_source** object describing the data source and returns it by \f[I]h\f[] parameter. .PP This function is Windows only, on Linux use \f[B]pmem2_source_get_fd\f[](3). If the source was created using \f[B]pmem2_source_from_fd\f[](3) then \f[B]pmem2_source_get_handle\f[]() is also valid function to read handler, because file descriptor is converted to file handle during source creation. .PP However, there are limitations to what you can do with a handle created from a file descriptor. For details refer to \f[B]DESCRIPTION\f[] section in the \f[B]pmem2_source_from_fd\f[](3) manpage. .SH ERRORS .PP The \f[B]pmem2_source_get_handle\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_FILE_HANDLE_NOT_SET\f[] \- in case of an instance of \f[I]struct pmem2_source\f[] that does not come from source type that support file handles, eg. anonymous data source. .SH RETURN VALUE .PP The \f[B]pmem2_source_get_handle\f[]() returns a file handle of data source. .SH SEE ALSO .PP \f[B]pmem2_source_from_fd\f[](3), \f[B]pmem2_source_get_fd\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/libpmem2_unsafe_shutdown.70000664000000000000000000000724114123364726020611 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEM2_UNSAFE_SHUTDOWN" "7" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]libpmem2_unsafe_shutdown\f[] \- libpmem2 unsafe shutdown .SH DESCRIPTION .PP In systems with the persistent memory support, \f[I]a power\-fail protected domain\f[] covers a set of resources from which the platform will flush data to the \f[I]a persistent medium\f[] in case of \f[I]a power\-failure\f[]. Data stored on \f[I]the persistent medium\f[] is preserved across power cycles. .PP The hardware guarantees the feature to flush all data stored in \f[I]the power\-fail protected domain\f[] to \f[I]the persistent medium\f[]. However, nothing is infallible, and Persistent Memory hardware can expose a monotonically increasing \f[I]unsafe shutdown counter\f[] (\f[B]USC\f[]) that is incremented every time a failure of the mechanism above is detected. This allows software to discover situations where a running application was interrupted by a power failure that led to an unsafe shutdown. Undiscovered unsafe shutdowns might cause silent data corruption. .RS .PP Note: \f[I]The unsafe shutdown\f[] may corrupt data stored on a device, in a file, in a set of files, and a mapping spanning only a part of a file. For the sake of simplicity, all of the above cases will be called \f[I]file\f[] below. .RE .SH UNSAFE SHUTDOWN DETECTION .PP Software can detect an unsafe shutdown by watching for the change between unsafe shutdown count value across application startups. Any changes can be indicative of unsafe shutdown occurrence. .PP Applications can implement a detection mechanism by storing the \f[B]USC\f[] retrieved from \f[B]pmem2_source_device_usc\f[](3) in Persistent Memory. Then, on subsequent startups, the stored value must be compared with a newly retrieved one. .PP However, this detection method can result in false\-positives. Moving the file to different Persistent Memory devices with possibly different \f[B]USC\f[] values would lead to false unsafe shutdown detection. .PP Additionally, relying on \f[B]USC\f[] value alone could result in the detection of unsafe shutdown events that occur when such a shutdown has no chance of impacting the data used by the application, e.g., when nothing is actively using the file. .PP Applications can avoid false\-positives associated with moving the file by storing device identification, obtained through \f[B]pmem2_source_device_id\f[](3), alongside the \f[B]USC\f[]. This enables the software to check if the underlying device has changed, and reinitialize the stored \f[B]USC\f[] in such cases. .PP The second behavior, detection of possibly irrelevant unsafe shutdown events, if undesirable, can be prevented by storing a flag indicating whether the file is in use, alongside all the rest of the relevant information. .PP The application should use \f[B]pmem2_deep_flush\f[](3) when storing any data related to unsafe shutdown detection for higher reliability. This helps ensure that the detection mechanism is not reliant on the correct functioning of the same hardware features it is designed to safeguard. .PP General\-purpose software should not assume the presence of \f[B]USC\f[] on the platform, and should instead appropriately handle any \f[I]PMEM2_E_NOSUPP\f[] it encounters. Doing otherwise might cause the software to be unnecessarily restrictive about the hardware it supports and would prevent, e.g., testing on emulated PMEM. .SH SEE ALSO .PP \f[B]pmem2_deep_flush\f[](3), \f[B]pmem2_persist_fn\f[](3), \f[B]pmem2_source_device_id\f[](3), \f[B]pmem2_source_device_usc\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_source_size.30000664000000000000000000000525314123364736017236 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_SIZE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2021, Intel Corporation .SH NAME .PP \f[B]pmem2_source_size\f[]() \- returns the size of the data source .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; int\ pmem2_source_size(const\ struct\ pmem2_source\ *source,\ size_t\ *size); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_size\f[]() function retrieves the size of the file in bytes pointed by file descriptor or handle stored in the \f[I]source\f[] and puts it in \f[I]*size\f[]. .PP This function is a portable replacement for OS\-specific APIs. On Linux, it hides the quirkiness of Device DAX size detection. .SH RETURN VALUE .PP The \f[B]pmem2_source_size\f[]() function returns 0 on success. If the function fails, the \f[I]*size\f[] variable is left unmodified and a negative error code is returned. .SH ERRORS .PP The \f[B]pmem2_source_size\f[]() can fail with the following errors: .PP On all systems: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_HANDLE\f[] \- source contains an invalid file handle. .PP On Windows: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- handle points to a resource that is not a regular file. .PP On Linux: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- file descriptor points to a directory, block device, pipe, or socket. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- file descriptor points to a character device other than Device DAX. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_SIZE_FORMAT\f[] \- kernel query for Device DAX size returned data in invalid format. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]realpath\f[](3), while trying to determine whether fd points to a Device DAX. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]open\f[](2), while trying to determine Device DAX's size. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]read\f[](2), while trying to determine Device DAX's size. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]strtoull\f[](3), while trying to determine Device DAX's size. .PP On FreeBSD: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- file descriptor points to a directory, block device, pipe, socket, or character device. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]fstat\f[](2), \f[B]realpath\f[](3), \f[B]open\f[](2), \f[B]read\f[](2), \f[B]strtoull\f[](3), \f[B]pmem2_config_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_badblock_context_new.30000664000000000000000000000733014123364741021054 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_BADBLOCK_CONTEXT_NEW" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_badblock_context_new\f[](), \f[B]pmem2_badblock_context_delete\f[]() \- allocate and free a context for \f[B]pmem2_badblock_next\f[]() and \f[B]pmem2_badblock_clear\f[]() operations .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; struct\ pmem2_badblock_context; int\ pmem2_badblock_context_new( \ \ \ \ \ \ \ \ struct\ pmem2_badblock_context\ **bbctx, \ \ \ \ \ \ \ \ const\ struct\ pmem2_source\ *src); void\ pmem2_badblock_context_delete( \ \ \ \ \ \ \ \ struct\ pmem2_badblock_context\ **bbctx); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_badblock_context_new\f[]() function instantiates a new (opaque) bad block context structure, \f[I]pmem2_badblock_context\f[], which is used to read and clear bad blocks (by \f[B]pmem2_badblock_next\f[]() and \f[B]pmem2_badblock_clear\f[]()). The function returns the bad block context through the pointer in \f[I]*bbctx\f[]. .PP New bad block context structure is initialized with values read from the source given as the first argument (\f[I]src\f[]). .PP A bad block is an uncorrectable media error \- a part of a storage media that is either inaccessible or unwritable due to permanent physical damage. In case of memory\-mapped I/O, if a process tries to access (read or write) the corrupted block, it will be terminated by the SIGBUS signal. .PP The \f[B]pmem2_badblock_context_delete\f[]() function frees \f[I]*bbctx\f[] returned by \f[B]pmem2_badblock_context_new\f[]() and sets \f[I]*bbctx\f[] to NULL. If \f[I]*bbctx\f[] is NULL, no operation is performed. .PP It is not supported on Windows. .SH RETURN VALUE .PP The \f[B]pmem2_badblock_context_new\f[]() function returns 0 on success or a negative error code on failure. .PP The \f[B]pmem2_badblock_context_new\f[]() sets \f[I]*bbctx\f[] to NULL on failure. .PP The \f[B]pmem2_badblock_context_delete\f[]() does not return any value. .SH ERRORS .PP The \f[B]pmem2_badblock_context_new\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- \f[I]src\f[] is not a regular file nor a character device. .IP \[bu] 2 \f[B]PMEM2_E_DAX_REGION_NOT_FOUND\f[] \- cannot find a DAX region for the given \f[I]src\f[]. .IP \[bu] 2 \f[B]PMEM2_E_CANNOT_READ_BOUNDS\f[] \- cannot read offset or size of the namespace of the given \f[I]src\f[]. .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- on Windows or when the OS does not support this functionality .IP \[bu] 2 \f[B]\-ENOMEM\f[] \- out of memory .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]ndctl_new\f[], while trying to create a new ndctl context. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor of \f[I]src\f[]. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]realpath\f[](3), while trying to get the canonicalized absolute sysfs pathname of DAX device given in \f[I]src\f[]. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]open\f[](2), while trying to open the FSDAX device matching with the \f[I]src\f[]. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]read\f[](2), while trying to read from the FSDAX device matching with the \f[I]src\f[]. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]ndctl_region_get_resource\f[], while reading an offset of the region of the given \f[I]src\f[]. .IP \[bu] 2 \f[B]\-errno\f[] \- set by failing \f[B]fiemap ioctl(2)\f[], while reading file extents of the given \f[I]src\f[]. .SH SEE ALSO .PP \f[B]pmem2_badblock_next\f[](3), \f[B]pmem2_badblock_clear\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_source_alignment.30000664000000000000000000000455414123364736020245 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_SOURCE_ALIGNMENT" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019-2020, Intel Corporation .SH NAME .PP \f[B]pmem2_source_alignment\f[]() \- returns data source alignment .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_source; int\ pmem2_source_alignment(const\ struct\ pmem2_source\ *source,\ size_t\ *alignment); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_source_alignment\f[]() function retrieves the alignment of offset and length needed for \f[B]pmem2_map_new\f[](3) to succeed. The alignment is stored in \f[I]*alignment\f[]. .SH RETURN VALUE .PP The \f[B]pmem2_source_alignment\f[]() function returns 0 on success. If the function fails, the \f[I]*alignment\f[] variable is left unmodified and a negative error code is returned. .SH ERRORS .PP The \f[B]pmem2_source_alignment\f[]() can fail with the following errors: .PP On all systems: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_ALIGNMENT_VALUE\f[] \- operating system returned unexpected alignment value (eg. it is not a power of two). .PP on Linux: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- file descriptor points to a character device other than Device DAX. .IP \[bu] 2 \f[B]PMEM2_E_INVALID_ALIGNMENT_FORMAT\f[] \- kernel query for Device DAX alignment returned data in invalid format. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]realpath\f[](3), while trying to determine whether fd points to a Device DAX. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]read\f[](2), while trying to determine Device DAX's alignment. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]strtoull\f[](3), while trying to determine Device DAX's alignment. .PP On FreeBSD: .IP \[bu] 2 \f[B]PMEM2_E_INVALID_FILE_TYPE\f[] \- file descriptor points to a directory, block device, pipe, socket, or character device. .IP \[bu] 2 \-\f[B]errno\f[] set by failing \f[B]fstat\f[](2), while trying to validate the file descriptor. .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]fstat\f[](2), \f[B]realpath\f[](3), \f[B]read\f[](2), \f[B]strtoull\f[](3), \f[B]pmem2_config_new\f[](3), \f[B]pmem2_source_from_handle\f[](3), \f[B]pmem2_source_from_fd\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_map_get_size.30000664000000000000000000000147314123364736017352 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_MAP_GET_SIZE" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019, Intel Corporation .SH NAME .PP \f[B]pmem2_map_get_size\f[]() \- reads mapping size .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ pmem2_map_get_size(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_map_get_size\f[]() function reads size of the created mapping. The \f[I]map\f[] parameter points to the structure describing mapping created using the \f[B]pmem2_map_new\f[](3) function. .SH RETURN VALUE .PP The \f[B]pmem2_map_get_size\f[]() function returns a size of the mapped area. .SH SEE ALSO .PP \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_source_delete.30000664000000000000000000000003314123364546017514 0ustar rootroot.so pmem2_source_from_fd.3 pmdk-1.11.1/doc/libpmem2/pmem2_config_set_required_store_granularity.30000664000000000000000000000311514123364736024554 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_REQUIRED_STORE_GRANULARITY" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_required_store_granularity\f[]() \- set a granularity in pmem2_config structure. .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ pmem2_granularity\ { \ \ \ \ PMEM2_GRANULARITY_BYTE, \ \ \ \ PMEM2_GRANULARITY_CACHE_LINE, \ \ \ \ PMEM2_GRANULARITY_PAGE, }; int\ pmem2_config_set_required_store_granularity(struct\ pmem2_config\ *cfg, \ \ \ \ \ \ \ \ enum\ pmem2_granularity\ g); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_required_store_granularity\f[]() sets a maximum permitted granularity \f[I]g\f[] requested by user in the \f[I]pmem2_config\f[] structure. .PP Granularity must be one of the following values: .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_BYTE\f[] .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_CACHE_LINE\f[] .IP \[bu] 2 \f[B]PMEM2_GRANULARITY_PAGE\f[] .PP A description of the granularity concept can be found in \f[B]libpmem2\f[](7) manpage. .SH RETURN VALUE .PP The \f[B]pmem2_config_set_required_store_granularity\f[]() function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_config_set_required_store_granularity\f[]() can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_GRANULARITY_NOT_SUPPORTED\f[] \- granularity \f[I]g\f[] is not a valid value. .SH SEE ALSO .PP \f[B]pmem2_config_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_perror.3.md0000664000000000000000000000226114123364546016607 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_PERROR, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_perror.3 -- man page for the error printing in libpmem2) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[SEE ALSO](#see-also)
# NAME # _UW(pmem2_perror) - prints a descriptive error message to stderr # SYNOPSIS # ```c #include _UWFUNCR1(void, pmem2_perror, *format, ...) ``` _UNICODE() # DESCRIPTION # The _UW(pmem2_perror) function produces a message on standard error stream describing the last error encountered during library call. _UW(pmem2_perror) takes a variable number of arguments. First, the argument string *format* is printed - similarly to the **printf**(3), followed by a colon and a blank. Then an error message retrieved from the _UW(pmem2_errormsg), and a new-line. To see how the error message is generated, please see **pmem2_errormsg**(3). # SEE ALSO # **libpmem2**(7), **perror**(3), **pmem2_errormsg**(3), **printf**(3) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_get_fd.3.md0000664000000000000000000000260214123364546020105 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_SOURCE_GET_FD, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_source_get_fd.3 -- man page for pmem2_source_get_fd [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_source_get_fd**() - reads file descriptor of the data source # SYNOPSIS # ```c #include int pmem2_source_get_fd(const struct pmem2_source *src, int *fd); ``` # DESCRIPTION # The **pmem2_source_get_fd**() function reads the file descriptor of *struct pmem2_source** object describing the data source and returns it by *fd* parameter. This function is Linux only, on Windows use **pmem2_source_get_handle**(3). # RETURN VALUE # The **pmem2_source_get_fd**() function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_source_get_fd**() can fail with the following errors: * **PMEM2_E_FILE_DESCRIPTOR_NOT_SET** - in case of an instance of *struct pmem2_source* that does not come from source type that support file descriptors, eg. anonymous data source. # SEE ALSO # **pmem2_source_get_handle**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_get_persist_fn.3.md0000664000000000000000000000552014123364546020312 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_GET_PERSIST_FN, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_get_persist_fn.3 -- man page for pmem2_get_persist_fn) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_get_persist_fn**() - get a persist function # SYNOPSIS # ```c #include typedef void (*pmem2_persist_fn)(const void *ptr, size_t size); struct pmem2_map; pmem2_persist_fn pmem2_get_persist_fn(struct pmem2_map *map); ``` # DESCRIPTION # The **pmem2_get_persist_fn**() function returns a pointer to a function responsible for efficiently persisting data in the range owned by the *map*. Persisting data using *pmem2_persist_fn* guarantees that the data is stored durably by the time it returns. There are no alignment restrictions on the range described by *ptr* and *size*, but *pmem2_persist_fn* may expand the range as necessary to meet platform alignment requirements. There is nothing atomic or transactional about *pmem2_persist_fn*. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until *pmem2_persist_fn* is called to become persistent -- they can become persistent at any time before *pmem2_persist_fn* is called. If two (or more) mappings share the same *pmem2_persist_fn* and they are adjacent to each other, it is safe to call this function for a range spanning those mappings. Internally *pmem2_persist_fn* performs two operations: - memory flush (**pmem2_get_flush_fn**(3)), which can be reordered by the CPU with other flushes - drain (**pmem2_get_drain_fn**(3)), which makes sure that the flushes before this operation won't be reordered after it So this code: ```c pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); persist_fn(addr, len); ``` is equivalent of: ```c pmem2_flush_fn flush_fn = pmem2_get_flush_fn(map); pmem2_drain_fn drain_fn = pmem2_get_drain_fn(map); flush_fn(addr, len); drain_fn(); ``` Advanced applications may want to flush multiple discontiguous regions and perform the drain operation only once. # RETURN VALUE # The **pmem2_get_persist_fn**() function never returns NULL. The **pmem2_get_persist_fn**() for the same *map* always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. # SEE ALSO # **pmem2_get_drain_fn**(3), **pmem2_get_flush_fn**(3), **pmem2_map_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_new.3.md0000664000000000000000000000631514123364546021216 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_VM_RESERVATION_NEW, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020-2021, Intel Corporation) [comment]: <> (pmem2_vm_reservation_new.3 -- man page for libpmem2 virtual memory reservation API) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[ERRORS](#errors)
[SEE ALSO](#see-also)
# NAME # **pmem2_vm_reservation_new**(), **pmem2_vm_reservation_delete**() - creates or deletes an instance of virtual memory reservation # SYNOPSIS # ```c #include struct pmem2_vm_reservation; int pmem2_vm_reservation_new(struct pmem2_vm_reservation **rsv_ptr, void *addr, size_t size); int pmem2_vm_reservation_delete(struct pmem2_vm_reservation **rsv_ptr); ``` # DESCRIPTION # The **pmem2_vm_reservation_new**() function creates a new blank mapping in the virtual address space of the calling process. Reservation serves as a placeholder of a given size on which sources can be mapped. For the function to succeed, the *addr* must be either aligned to an appropriate allocation granularity or **NULL**, the size always has to be aligned to an appropriate allocation granularity. If the **pmem2_vm_reservation_new**() succeeds in creating a reservation, it instantiates a new **struct pmem2_vm_reservation** object describing the reservation. The pointer to this object is stored in the user-provided variable via the *rsv_ptr* pointer. If the function fails, an appropriate error value will be returned. For a list of possible return values please see [RETURN VALUE](#return-value) After instantiating an object via the **pmem2_vm_reservation_new**() function, it may be disposed of using the **pmem2_vm_reservation_delete**() function. The **pmem2_vm_reservation_delete**() function destroys the object describing the reservation and unmaps virtual memory region the *struct pmem2_vm_reservation** had assigned during the initialization. For the delete function to succeed, it is required that the reservation passed via the *rsv_ptr* pointer does not contain any mappings. # RETURN VALUE # The **pmem2_vm_reservation_new**() and **pmem2_vm_reservation_delete**() functions return 0 on success or a negative error code on failure. The function returns 0 on success or a negative error code on failure. # ERRORS # The **pmem2_vm_reservation_new**() function can fail with the following errors: * **PMEM2_E_ADDRESS_UNALIGNED** - argument *addr* is not aligned to the appropriate allocation granularity. * **PMEM2_E_MAPPING_EXISTS** - mapping already exists in the range (*addr*, *addr* + *size*). It can also return **-EAGAIN**, **-ENOMEM** from the underlying **mmap**(2) function and **-ENOMEM** in case of insufficient memory to allocate an instance of *struct pmem2_vm_reservation*. The **pmem2_vm_reservation_delete**() function can fail with the following errors: * **PMEM2_E_RESERVATION_NOT_EMPTY** - reservation contains mappings. It can also return errors from the underlying **munmap**(2) function. # SEE ALSO # **pmem2_config_set_vm_reservation**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_source_from_handle.30000664000000000000000000000003314123364546020530 0ustar rootroot.so pmem2_source_from_fd.3 pmdk-1.11.1/doc/libpmem2/pmem2_config_new.30000664000000000000000000000347414123364735017024 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_NEW" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_config_new\f[](), \f[B]pmem2_config_delete\f[]() \- allocate and free a configuration structure for a libpmem2 mapping .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; int\ pmem2_config_new(struct\ pmem2_config\ **cfg); int\ pmem2_config_delete(struct\ pmem2_config\ **cfg); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_new\f[]() function instantiates a new (opaque) configuration structure, \f[I]pmem2_config\f[], which is used to define mapping parameters for a \f[B]pmem2_map_new\f[]() function, and returns it through the pointer in \f[I]*cfg\f[]. .PP New configuration is always initialized with default values for most parameters, which are specified alongside the corresponding setter function. The application must explicitly set the granularity value for the mapping. .PP The \f[B]pmem2_config_delete\f[]() function frees \f[I]*cfg\f[] returned by \f[B]pmem2_config_new\f[]() and sets \f[I]*cfg\f[] to NULL. If \f[I]*cfg\f[] is NULL, no operation is performed. .SH RETURN VALUE .PP The \f[B]pmem2_config_new\f[]() function returns 0 on success or a negative error code on failure. \f[B]pmem2_config_new\f[]() does set \f[I]*cfg\f[] to NULL on failure. .PP The \f[B]pmem2_config_delete\f[]() function always returns 0. .SH ERRORS .PP \f[B]pmem2_config_new\f[]() can fail with the following error: \- \f[B]\-ENOMEM\f[] \- out of memory .SH SEE ALSO .PP \f[B]errno\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_config_set_handle\f[](3), \f[B]pmem2_config_set_fd\f[](3), \f[B]pmem2_config_get_file_size\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_config_set_length.30000664000000000000000000000243214123364737020362 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_CONFIG_SET_LENGTH" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2019, Intel Corporation .SH NAME .PP \f[B]pmem2_config_set_length\f[]() \- set length in the pmem2_config structure .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_config; int\ pmem2_config_set_length(struct\ pmem2_config\ *config,\ size_t\ length); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_config_set_length\f[]() function configures the length which will be used for mapping. \f[I]*config\f[] should be already initialized, please see \f[B]pmem2_config_new\f[](3) for details. The \f[I]must be a multiple of the alignment required for the data source which will be used for mapping alongside the config. To retrieve the alignment required for specific instance of \f[]pmem2_source** use \f[B]pmem2_source_alignment\f[](3). By default, the length is equal to the size of the file that is being mapped. .SH RETURN VALUE .PP The \f[B]pmem2_config_set_length\f[]() function always returns 0. .SH SEE ALSO .PP \f[B]libpmem2\f[](7), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_source_alignment\f[](3), \f[B]pmem2_config_new\f[](3), \f[B]sysconf\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_get_address.3.md0000664000000000000000000000231514123364546022705 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM2_VM_RESERVATION_GET_ADDRESS, 3) collection: libpmem2 header: PMDK date: pmem2 API version 1.0 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2020, Intel Corporation) [comment]: <> (pmem2_vm_reservation_get_address.3 -- man page for libpmem2 pmem2_vm_reservation_get_address operation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmem2_vm_reservation_get_address**() - reads address of the virtual memory reservation # SYNOPSIS # ```c #include void *pmem2_vm_reservation_get_address(struct pmem2_vm_reservation *rsv); ``` # DESCRIPTION # The **pmem2_vm_reservation_get_address**() function reads address of the created virtual memory reservation. The *rsv* parameter points to the structure describing the reservation created using the **pmem2_vm_reservation_new**(3) function. # RETURN VALUE # The **pmem2_vm_reservation_get_address**() function returns a pointer to the virtual memory reservation area. # SEE ALSO # **pmem2_vm_reservation_new**(3), **libpmem2**(7) and **** pmdk-1.11.1/doc/libpmem2/pmem2_badblock_next.30000664000000000000000000000275514123364741017503 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_BADBLOCK_NEXT" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_badblock_next\f[]() \- read the next bad block for the given bad block context \f[I]*bbctx\f[]. .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_badblock; struct\ pmem2_badblock_context; int\ pmem2_badblock_next( \ \ \ \ \ \ \ \ struct\ pmem2_badblock_context\ *bbctx, \ \ \ \ \ \ \ \ struct\ pmem2_badblock\ *bb); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_badblock_next\f[]() function reads the next bad block for the given bad block context \f[I]*bbctx\f[]. .PP It is not supported on Windows. .SH RETURN VALUE .PP The \f[B]pmem2_badblock_next\f[]() function returns 0 and stores the next bad block in \f[I]*bb\f[] on success or it returns a negative error code when there are no more bad blocks for the given bad block context \f[I]*bbctx\f[]. .SH ERRORS .PP \f[B]pmem2_badblock_next\f[]() can fail with the following error: .IP \[bu] 2 \f[B]PMEM2_E_NO_BAD_BLOCK_FOUND\f[] \- there are no more bad blocks for the given bad block context \f[I]*bbctx\f[], \f[I]*bb\f[] is undefined in this case. .IP \[bu] 2 \f[B]PMEM2_E_NOSUPP\f[] \- on Windows or when the OS does not support this functionality .SH SEE ALSO .PP \f[B]pmem2_badblock_context_new\f[](3), \f[B]pmem2_badblock_clear\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_shrink.30000664000000000000000000000004214123364546021313 0ustar rootroot.so pmem2_vm_reservation_extend.3 pmdk-1.11.1/doc/libpmem2/pmem2_vm_reservation_new.30000664000000000000000000000626514123364741020620 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_VM_RESERVATION_NEW" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020-2021, Intel Corporation .SH NAME .PP \f[B]pmem2_vm_reservation_new\f[](), \f[B]pmem2_vm_reservation_delete\f[]() \- creates or deletes an instance of virtual memory reservation .SH SYNOPSIS .IP .nf \f[C] #include\ struct\ pmem2_vm_reservation; int\ pmem2_vm_reservation_new(struct\ pmem2_vm_reservation\ **rsv_ptr, \ \ \ \ \ \ \ \ void\ *addr,\ size_t\ size); int\ pmem2_vm_reservation_delete(struct\ pmem2_vm_reservation\ **rsv_ptr); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_vm_reservation_new\f[]() function creates a new blank mapping in the virtual address space of the calling process. Reservation serves as a placeholder of a given size on which sources can be mapped. .PP For the function to succeed, the \f[I]addr\f[] must be either aligned to an appropriate allocation granularity or \f[B]NULL\f[], the size always has to be aligned to an appropriate allocation granularity. .PP If the \f[B]pmem2_vm_reservation_new\f[]() succeeds in creating a reservation, it instantiates a new \f[B]struct pmem2_vm_reservation\f[] object describing the reservation. The pointer to this object is stored in the user\-provided variable via the \f[I]rsv_ptr\f[] pointer. If the function fails, an appropriate error value will be returned. For a list of possible return values please see RETURN VALUE .PP After instantiating an object via the \f[B]pmem2_vm_reservation_new\f[]() function, it may be disposed of using the \f[B]pmem2_vm_reservation_delete\f[]() function. .PP The \f[B]pmem2_vm_reservation_delete\f[]() function destroys the object describing the reservation and unmaps virtual memory region the *struct pmem2_vm_reservation** had assigned during the initialization. For the delete function to succeed, it is required that the reservation passed via the \f[I]rsv_ptr\f[] pointer does not contain any mappings. .SH RETURN VALUE .PP The \f[B]pmem2_vm_reservation_new\f[]() and \f[B]pmem2_vm_reservation_delete\f[]() functions return 0 on success or a negative error code on failure. .PP The function returns 0 on success or a negative error code on failure. .SH ERRORS .PP The \f[B]pmem2_vm_reservation_new\f[]() function can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_ADDRESS_UNALIGNED\f[] \- argument \f[I]addr\f[] is not aligned to the appropriate allocation granularity. .IP \[bu] 2 \f[B]PMEM2_E_MAPPING_EXISTS\f[] \- mapping already exists in the range (\f[I]addr\f[], \f[I]addr\f[] + \f[I]size\f[]). .PP It can also return \f[B]\-EAGAIN\f[], \f[B]\-ENOMEM\f[] from the underlying \f[B]mmap\f[](2) function and \f[B]\-ENOMEM\f[] in case of insufficient memory to allocate an instance of \f[I]struct pmem2_vm_reservation\f[]. .PP The \f[B]pmem2_vm_reservation_delete\f[]() function can fail with the following errors: .IP \[bu] 2 \f[B]PMEM2_E_RESERVATION_NOT_EMPTY\f[] \- reservation contains mappings. .PP It can also return errors from the underlying \f[B]munmap\f[](2) function. .SH SEE ALSO .PP \f[B]pmem2_config_set_vm_reservation\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmem2/pmem2_get_drain_fn.30000664000000000000000000000303314123364740017310 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_GET_DRAIN_FN" "3" "2021-09-24" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_get_drain_fn\f[]() \- get a drain function .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ void\ (*pmem2_drain_fn)(void); struct\ pmem2_map; pmem2_drain_fn\ pmem2_get_drain_fn(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_get_drain_fn\f[]() function returns a pointer to a function responsible for efficiently draining flushes (see \f[B]pmem2_get_flush_fn\f[](3)) in the range owned by \f[I]map\f[]. Draining, in this context, means making sure that the flushes before this operation won't be reordered after it. While it is not strictly true, draining can be thought of as waiting for previous flushes to complete. .PP If two (or more) mappings share the same drain function, it is safe to call this function once for all flushes belonging to those mappings. .SH RETURN VALUE .PP The \f[B]pmem2_get_drain_fn\f[]() function never returns NULL. .PP The \f[B]pmem2_get_drain_fn\f[]() for the same \f[I]map\f[] always returns the same function. This means that it's safe to cache its return value. However, this function is very cheap (because it returns a precomputed value), so caching may not be necessary. .SH SEE ALSO .PP \f[B]pmem2_get_flush_fn\f[](3), \f[B]pmem2_get_persist_fn\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/0000775000000000000000000000000014123364734014122 5ustar rootrootpmdk-1.11.1/doc/libpmemobj/pobj_next_type_num.30000664000000000000000000000002414123364546020113 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_defer_free.30000664000000000000000000000002514123364546020003 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/tx_xwcsdup.30000664000000000000000000000002714123364546016416 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_new_head.30000664000000000000000000000002514123364546021407 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_rdlock.30000664000000000000000000000003114123364546020551 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_list_move.30000664000000000000000000000003214123364546017714 0ustar rootroot.so pmemobj_list_insert.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_prev.30000664000000000000000000000002514123364546017225 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pobj_first_type_num.30000664000000000000000000000002414123364546020264 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_before.30000664000000000000000000000002514123364546021077 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_tail.30000664000000000000000000000002514123364546020566 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_set_funcs.30000664000000000000000000000002614123364546017707 0ustar rootroot.so man7/libpmemobj.7 pmdk-1.11.1/doc/libpmemobj/direct_rw.30000664000000000000000000000002314123364546016164 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_unlock.30000664000000000000000000000003114123364546020427 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/tx_begin.30000664000000000000000000000002714123364546016005 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_lock.30000664000000000000000000000003114123364546020064 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_zalloc.30000664000000000000000000000002714123364546017716 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/toid_declare.30000664000000000000000000000771114123364734016632 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "TOID_DECLARE" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]TOID_DECLARE\f[](), \f[B]TOID_DECLARE_ROOT\f[](), \f[B]TOID\f[](), \f[B]TOID_TYPE_NUM\f[](), \f[B]TOID_TYPE_NUM_OF\f[](), \f[B]TOID_VALID\f[](), \f[B]OID_INSTANCEOF\f[](), \f[B]TOID_ASSIGN\f[](), \f[B]TOID_IS_NULL\f[](), \f[B]TOID_EQUALS\f[](), \f[B]TOID_TYPEOF\f[](), \f[B]TOID_OFFSETOF\f[](), \f[B]DIRECT_RW\f[](), \f[B]D_RW\f[](), \f[B]DIRECT_RO\f[](), \f[B]D_RO\f[]() \- libpmemobj type safety mechanism .SH SYNOPSIS .IP .nf \f[C] #include\ TOID_DECLARE(TYPE,\ uint64_t\ type_num) TOID_DECLARE_ROOT(ROOT_TYPE) TOID(TYPE) TOID_TYPE_NUM(TYPE) TOID_TYPE_NUM_OF(TOID\ oid) TOID_VALID(TOID\ oid) OID_INSTANCEOF(PMEMoid\ oid,\ TYPE) TOID_ASSIGN(TOID\ o,\ VALUE) TOID_IS_NULL(TOID\ o) TOID_EQUALS(TOID\ lhs,\ TOID\ rhs) TOID_TYPEOF(TOID\ o) TOID_OFFSETOF(TOID\ o,\ FILED) DIRECT_RW(TOID\ oid) D_RW(TOID\ oid) DIRECT_RO(TOID\ oid) D_RO(TOID\ oid) \f[] .fi .SH DESCRIPTION .PP Operating on untyped object handles, as well as on direct untyped object pointers (\f[I]void*\f[]), may be confusing and error\-prone. To facilitate type safety, \f[B]libpmemobj\f[](7) defines a set of macros that provide static type enforcement, catching potential errors at compile time. For example, a compile\-time error is generated when an attempt is made to assign a handle to an object of one type to the object handle variable of another type of object. .PP The \f[B]TOID_DECLARE\f[]() macro declares a typed \f[I]OID\f[] of user\-defined type \f[I]TYPE\f[] and type number \f[I]type_num\f[]. .PP The \f[B]TOID_DECLARE_ROOT\f[]() macro declares a typed \f[I]OID\f[] of user\-defined type \f[I]ROOT_TYPE\f[] and root object type number \f[B]POBJ_ROOT_TYPE_NUM\f[]. .PP The \f[B]TOID\f[]() macro declares a handle to an object of type \f[I]TYPE\f[], where \f[I]TYPE\f[] is the name of a user\-defined structure. The typed \f[I]OID\f[] must be declared first using the \f[B]TOID_DECLARE\f[](), \f[B]TOID_DECLARE_ROOT\f[](), \f[B]POBJ_LAYOUT_TOID\f[](3) or \f[B]POBJ_LAYOUT_ROOT\f[](3) macros. .PP The \f[B]TOID_TYPE_NUM\f[]() macro returns the type number of the type specified by \f[I]TYPE\f[]. .PP The \f[B]TOID_TYPE_NUM_OF\f[]() macro returns the type number of the object specified by \f[I]oid\f[]. The type number is read from the typed \f[I]OID\f[]. .PP The \f[B]TOID_VALID\f[]() macro validates whether the type number stored in the object's metadata is equal to the type number read from the typed \f[I]OID\f[]. .PP The \f[B]OID_INSTANCEOF\f[]() macro checks whether the \f[I]oid\f[] is of type \f[I]TYPE\f[]. .PP The \f[B]TOID_ASSIGN\f[]() macro assigns the object handle \f[I]VALUE\f[] to typed \f[I]OID\f[] \f[I]o\f[]. .PP The \f[B]TOID_IS_NULL\f[]() macro evaluates to true if the object handle represented by \f[I]o\f[] is \f[B]OID_NULL\f[]. .PP The \f[B]TOID_EQUALS\f[]() macro evaluates to true if both the \f[I]lhs\f[] and \f[I]rhs\f[] object handles reference the same persistent object. .PP The \f[B]TOID_TYPEOF\f[]() macro returns the type of the object handle represented by typed \f[I]OID\f[] \f[I]o\f[]. .PP The \f[B]TOID_OFFSETOF\f[]() macro returns the offset of the \f[I]FIELD\f[] member from the start of the object represented by \f[I]o\f[]. .PP The \f[B]DIRECT_RW\f[]() macro and its shortened form \f[B]D_RW\f[]() return a typed write pointer (\f[I]TYPE*\f[]) to an object represented by \f[I]oid\f[]. If \f[I]oid\f[] is \f[B]OID_NULL\f[], the macro evaluates to NULL. .PP The \f[B]DIRECT_RO\f[]() macro and its shortened form \f[B]D_RO\f[]() return a typed read\-only (const) pointer (\f[I]TYPE*\f[]) to an object represented by \f[I]oid\f[]. If \f[I]oid\f[] is \f[B]OID_NULL\f[], the macro evaluates to NULL. .SH SEE ALSO .PP \f[B]OID_IS_NULL\f[](3), \f[B]POBJ_LAYOUT_ROOT\f[](3), \f[B]POBJ_LAYOUT_TOID\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_list_insert.30000664000000000000000000002003414123364732020253 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_LIST_INSERT" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemobj_list_insert\f[](), \f[B]pmemobj_list_insert_new\f[](), \f[B]pmemobj_list_move\f[](), \f[B]pmemobj_list_remove\f[]() \- non\-transactional persistent atomic lists functions .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemobj_list_insert(PMEMobjpool\ *pop,\ size_t\ pe_offset,\ void\ *head, \ \ \ \ PMEMoid\ dest,\ int\ before,\ PMEMoid\ oid); PMEMoid\ pmemobj_list_insert_new(PMEMobjpool\ *pop,\ size_t\ pe_offset, \ \ \ \ void\ *head,\ PMEMoid\ dest,\ int\ before,\ size_t\ size, \ \ \ \ uint64_t\ type_num,\ pmemobj_constr\ constructor,\ void\ arg); int\ pmemobj_list_move(PMEMobjpool\ *pop, \ \ \ \ size_t\ pe_old_offset,\ void\ *head_old, \ \ \ \ size_t\ pe_new_offset,\ void\ *head_new, \ \ \ \ PMEMoid\ dest,\ int\ before,\ PMEMoid\ oid); int\ pmemobj_list_remove(PMEMobjpool\ *pop,\ size_t\ pe_offset, \ \ \ \ void\ *head,\ PMEMoid\ oid,\ int\ free); \f[] .fi .SH DESCRIPTION .PP In addition to the container operations on internal object collections described in \f[B]pmemobj_first\f[](3), \f[B]libpmemobj\f[](7) provides a mechanism for organizing persistent objects in user\-defined, persistent, atomic, circular, doubly\-linked lists. All the routines and macros operating on the persistent lists provide atomicity with respect to any power\-fail interruptions. If any of those operations is torn by program failure or system crash, on recovery they are guaranteed to be entirely completed or discarded, leaving the lists, persistent memory heap and internal object containers in a consistent state. .PP The persistent atomic circular doubly linked lists support the following functionality: .IP \[bu] 2 Insertion of an object at the head of the list, or at the end of the list. .IP \[bu] 2 Insertion of an object before or after any element in the list. .IP \[bu] 2 Atomic allocation and insertion of a new object at the head of the list, or at the end of the list. .IP \[bu] 2 Atomic allocation and insertion of a new object before or after any element in the list. .IP \[bu] 2 Atomic moving of an element from one list to the specific location on another list. .IP \[bu] 2 Removal of any object in the list. .IP \[bu] 2 Atomic removal and freeing of any object in the list. .IP \[bu] 2 Forward or backward traversal through the list. .PP A list is headed by a \f[I]list_head\f[] structure containing the object handle of the first element on the list. The elements are doubly linked so that an arbitrary element can be removed without the need to traverse the list. New elements can be added to the list before or after an existing element, at the head of the list, or at the tail of the list. A list may be traversed in either direction. .PP The user\-defined structure of each element must contain a field of type \f[I]list_entry\f[] that holds the object handles to the previous and next element on the list. Both the \f[I]list_head\f[] and the \f[I]list_entry\f[] structures are declared in \f[B]\f[]. .PP The functions below are intended to be used outside transactions \- transactional variants are described in manpages to functions mentioned at \f[B]TRANSACTIONAL OBJECT MANIPULATION\f[] in \f[B]libpmemobj\f[](7). Note that operations performed using this non\-transactional API are independent from their transactional counterparts. If any non\-transactional allocations or list manipulations are performed within an open transaction, the changes will not be rolled back if such a transaction is aborted or interrupted. .PP The list insertion and move functions use a common set of arguments to define where an object will be inserted into the list. \f[I]dest\f[] identifies the element before or after which the object will be inserted, or, if \f[I]dest\f[] is \f[B]OID_NULL\f[], indicates that the object should be inserted at the head or tail of the list. \f[I]before\f[] determines where the object will be inserted: .IP \[bu] 2 \f[B]POBJ_LIST_DEST_BEFORE\f[] \- insert the element before the existing element \f[I]dest\f[] .IP \[bu] 2 \f[B]POBJ_LIST_DEST_AFTER\f[] \- insert the element after the existing element \f[I]dest\f[] .IP \[bu] 2 \f[B]POBJ_LIST_DEST_HEAD\f[] \- when \f[I]dest\f[] is \f[B]OID_NULL\f[], insert the element at the head of the list .IP \[bu] 2 \f[B]POBJ_LIST_DEST_TAIL\f[] \- when \f[I]dest\f[] is \f[B]OID_NULL\f[], insert the element at the tail of the list .RS .PP NOTE: Earlier versions of \f[B]libpmemobj\f[](7) do not define \f[B]POBJ_LIST_DEST_BEFORE\f[] and \f[B]POBJ_LIST_DEST_AFTER\f[]. Use 1 for before, and 0 for after. .RE .PP The \f[B]pmemobj_list_insert\f[]() function inserts the element represented by object handle \f[I]oid\f[] into the list referenced by \f[I]head\f[], at the location specified by \f[I]dest\f[] and \f[I]before\f[] as described above. \f[I]pe_offset\f[] specifies the offset of the structure that connects the elements in the list. All the handles \f[I]head\f[], \f[I]dest\f[] and \f[I]oid\f[] must point to objects allocated from memory pool \f[I]pop\f[]. \f[I]head\f[] and \f[I]oid\f[] cannot be \f[B]OID_NULL\f[]. .PP The \f[B]pmemobj_list_insert_new\f[]() function atomically allocates a new object of given \f[I]size\f[] and type \f[I]type_num\f[] and inserts it into the list referenced by \f[I]head\f[] at the location specified by \f[I]dest\f[] and \f[I]before\f[] as described above. \f[I]pe_offset\f[] specifies the offset of the structure that connects the elements in the list. The handles \f[I]head\f[] and \f[I]dest\f[] must point to objects allocated from memory pool \f[I]pop\f[]. Before returning, \f[B]pmemobj_list_insert_new\f[]() calls the \f[I]constructor\f[] function, passing the pool handle \f[I]pop\f[], the pointer to the newly allocated object \f[I]ptr\f[], and the \f[I]arg\f[] argument. It is guaranteed that the allocated object is either properly initialized or, if the allocation is interrupted before the constructor completes, the memory space reserved for the object is reclaimed. \f[I]head\f[] cannot be \f[B]OID_NULL\f[]. The allocated object is also added to the internal container associated with \f[I]type_num\f[], as described in \f[B]POBJ_FOREACH\f[](3). .PP The \f[B]pmemobj_list_move\f[]() function moves the object represented by object handle \f[I]oid\f[] from the list referenced by \f[I]head_old\f[] to the list referenced by \f[I]head_new\f[], inserting it at the location specified by \f[I]dest\f[] and \f[I]before\f[] as described above. \f[I]pe_old_offset\f[] and \f[I]pe_new_offset\f[] specify the offsets of the structures that connect the elements in the old and new lists, respectively. All the handles \f[I]head_old\f[], \f[I]head_new\f[], \f[I]dest\f[] and \f[I]oid\f[] must point to objects allocated from memory pool \f[I]pop\f[]. \f[I]head_old\f[], \f[I]head_new\f[] and \f[I]oid\f[] cannot be \f[B]OID_NULL\f[]. .PP The \f[B]pmemobj_list_remove\f[]() function removes the object represented by object handle \f[I]oid\f[] from the list referenced by \f[I]head\f[]. If \f[I]free\f[] is set, it also removes the object from the internal object container and frees the associated memory space. \f[I]pe_offset\f[] specifies the offset of the structure that connects the elements in the list. Both \f[I]head\f[] and \f[I]oid\f[] must point to objects allocated from memory pool \f[I]pop\f[] and cannot be \f[B]OID_NULL\f[]. .SH RETURN VALUE .PP On success, \f[B]pmemobj_list_insert\f[](), \f[B]pmemobj_list_remove\f[]() and \f[B]pmemobj_list_move\f[]() return 0. On error, they return \-1 and set \f[I]errno\f[] appropriately. .PP On success, \f[B]pmemobj_list_insert_new\f[]() returns a handle to the newly allocated object. If the constructor returns a non\-zero value, the allocation is canceled, \-1 is returned, and \f[I]errno\f[] is set to \f[B]ECANCELED\f[]. On other errors, \f[B]OID_NULL\f[] is returned and \f[I]errno\f[] is set appropriately. .SH SEE ALSO .PP \f[B]pmemobj_first\f[](3), \f[B]POBJ_FOREACH\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_cond_broadcast.30000664000000000000000000000003114123364546020657 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_zrealloc.30000664000000000000000000000002414123364546017527 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_begin.3.md0000664000000000000000000005764514123364546020137 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_TX_BEGIN, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2020, Intel Corporation) [comment]: <> (pmemobj_tx_begin.3 -- man page for transactional object manipulation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # **pmemobj_tx_stage**(), **pmemobj_tx_begin**(), **pmemobj_tx_lock**(), **pmemobj_tx_xlock**(), **pmemobj_tx_abort**(), **pmemobj_tx_commit**(), **pmemobj_tx_end**(), **pmemobj_tx_errno**(), **pmemobj_tx_process**(), **TX_BEGIN_PARAM**(), **TX_BEGIN_CB**(), **TX_BEGIN**(), **TX_ONABORT**, **TX_ONCOMMIT**, **TX_FINALLY**, **TX_END**, **pmemobj_tx_log_append_buffer**(), **pmemobj_tx_xlog_append_buffer**(), **pmemobj_tx_log_auto_alloc**(), **pmemobj_tx_log_snapshots_max_size**(), **pmemobj_tx_log_intents_max_size**(), **pmemobj_tx_set_user_data**(), **pmemobj_tx_get_user_data**(), **pmemobj_tx_set_failure_behavior**(), **pmemobj_tx_get_failure_behavior**() - transactional object manipulation # SYNOPSIS # ```c #include enum pobj_tx_stage pmemobj_tx_stage(void); int pmemobj_tx_begin(PMEMobjpool *pop, jmp_buf *env, enum pobj_tx_param, ...); int pmemobj_tx_lock(enum tx_lock lock_type, void *lockp); int pmemobj_tx_xlock(enum tx_lock lock_type, void *lockp, uint64_t flags); void pmemobj_tx_abort(int errnum); void pmemobj_tx_commit(void); int pmemobj_tx_end(void); int pmemobj_tx_errno(void); void pmemobj_tx_process(void); TX_BEGIN_PARAM(PMEMobjpool *pop, ...) TX_BEGIN_CB(PMEMobjpool *pop, cb, arg, ...) TX_BEGIN(PMEMobjpool *pop) TX_ONABORT TX_ONCOMMIT TX_FINALLY TX_END int pmemobj_tx_log_append_buffer(enum pobj_log_type type, void *addr, size_t size); int pmemobj_tx_xlog_append_buffer(enum pobj_log_type type, void *addr, size_t size, uint64_t flags); int pmemobj_tx_log_auto_alloc(enum pobj_log_type type, int on_off); size_t pmemobj_tx_log_snapshots_max_size(size_t *sizes, size_t nsizes); size_t pmemobj_tx_log_intents_max_size(size_t nintents); void pmemobj_tx_set_user_data(void *data); void *pmemobj_tx_get_user_data(void); void pmemobj_tx_set_failure_behavior(enum pobj_tx_failure_behavior behavior); enum pobj_tx_failure_behavior pmemobj_tx_get_failure_behavior(void); ``` # DESCRIPTION # The non-transactional functions and macros described in **pmemobj_alloc**(3), **pmemobj_list_insert**(3) and **POBJ_LIST_HEAD**(3) only guarantee the atomicity of a single operation on an object. In case of more complex changes involving multiple operations on an object, or allocation and modification of multiple objects, data consistency and fail-safety may be provided only by using *atomic transactions*. A transaction is defined as series of operations on persistent memory objects that either all occur, or nothing occurs. In particular, if the execution of a transaction is interrupted by a power failure or a system crash, it is guaranteed that after system restart, all the changes made as a part of the uncompleted transaction will be rolled back, restoring the consistent state of the memory pool from the moment when the transaction was started. Note that transactions do not provide atomicity with respect to other threads. All the modifications performed within the transactions are immediately visible to other threads. Therefore it is the responsibility of the application to implement a proper thread synchronization mechanism. Each thread may have only one transaction open at a time, but that transaction may be nested. Nested transactions are flattened. Committing the nested transaction does not commit the outer transaction; however, errors in the nested transaction are propagated up to the outermost level, resulting in the interruption of the entire transaction. Each transaction is visible only for the thread that started it. No other threads can add operations, commit or abort the transaction initiated by another thread. Multiple threads may have transactions open on a given memory pool at the same time. Please see the **CAVEATS** section below for known limitations of the transactional API. The **pmemobj_tx_stage**() function returns the current *transaction stage* for a thread. Stages are changed only by the **pmemobj_tx_\***() functions. Transaction stages are defined as follows: + **TX_STAGE_NONE** - no open transaction in this thread + **TX_STAGE_WORK** - transaction in progress + **TX_STAGE_ONCOMMIT** - successfully committed + **TX_STAGE_ONABORT** - starting the transaction failed or transaction aborted + **TX_STAGE_FINALLY** - ready for clean up The **pmemobj_tx_begin**() function starts a new transaction in the current thread. If called within an open transaction, it starts a nested transaction. The caller may use the *env* argument to provide a pointer to a calling environment to be restored in case of transaction abort. This information must be provided by the caller using the **setjmp**(3) macro. A new transaction may be started only if the current stage is **TX_STAGE_NONE** or **TX_STAGE_WORK**. If successful, the *transaction stage* changes to **TX_STAGE_WORK**. Otherwise, the stage is changed to **TX_STAGE_ONABORT**. Optionally, a list of parameters for the transaction may be provided. Each parameter consists of a type followed by a type-specific number of values. Currently there are 4 types: + **TX_PARAM_NONE**, used as a termination marker. No following value. + **TX_PARAM_MUTEX**, followed by one value, a pmem-resident PMEMmutex + **TX_PARAM_RWLOCK**, followed by one value, a pmem-resident PMEMrwlock + **TX_PARAM_CB**, followed by two values: a callback function of type *pmemobj_tx_callback*, and a void pointer Using **TX_PARAM_MUTEX** or **TX_PARAM_RWLOCK** causes the specified lock to be acquired at the beginning of the transaction. **TX_PARAM_RWLOCK** acquires the lock for writing. It is guaranteed that **pmemobj_tx_begin**() will acquire all locks prior to successful completion, and they will be held by the current thread until the outermost transaction is finished. Locks are taken in order from left to right. To avoid deadlocks, the user is responsible for proper lock ordering. **TX_PARAM_CB** registers the specified callback function to be executed at each transaction stage. For **TX_STAGE_WORK**, the callback is executed prior to commit. For all other stages, the callback is executed as the first operation after a stage change. It will also be called after each transaction; in this case the *stage* parameter will be set to **TX_STAGE_NONE**. *pmemobj_tx_callback* must be compatible with: ``` void func(PMEMobjpool *pop, enum pobj_tx_stage stage, void *arg) ``` *pop* is a pool identifier used in **pmemobj_tx_begin**(), *stage* is a current transaction stage and *arg* is the second parameter of **TX_PARAM_CB**. Without considering transaction nesting, this mechanism can be considered an alternative method for executing code between stages (instead of **TX_ONCOMMIT**, **TX_ONABORT**, etc). However, there are 2 significant differences when nested transactions are used: + The registered function is executed only in the outermost transaction, even if registered in an inner transaction. + There can be only one callback in the entire transaction, that is, the callback cannot be changed in an inner transaction. Note that **TX_PARAM_CB** does not replace the **TX_ONCOMMIT**, **TX_ONABORT**, etc. macros. They can be used together: the callback will be executed *before* a **TX_ONCOMMIT**, **TX_ONABORT**, etc. section. **TX_PARAM_CB** can be used when the code dealing with transaction stage changes is shared between multiple users or when it must be executed only in the outer transaction. For example it can be very useful when the application must synchronize persistent and transient state. The **pmemobj_tx_lock**() function acquires the lock *lockp* of type *lock_type* and adds it to the current transaction. *lock_type* may be **TX_LOCK_MUTEX** or **TX_LOCK_RWLOCK**; *lockp* must be of type *PMEMmutex* or *PMEMrwlock*, respectively. If *lock_type* is **TX_LOCK_RWLOCK** the lock is acquired for writing. If the lock is not successfully acquired, the function returns an error number. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xlock**() function behaves exactly the same as **pmemobj_tx_lock**() when *flags* equals **POBJ_XLOCK_NO_ABORT**. When *flags* equals 0 and if the lock is not successfully acquired,the transaction is aborted. *flags* is a bitmask of the following values: + **POBJ_XLOCK_NO_ABORT** - if the function does not end successfully, do not abort the transaction. **pmemobj_tx_abort**() aborts the current transaction and causes a transition to **TX_STAGE_ONABORT**. If *errnum* is equal to 0, the transaction error code is set to **ECANCELED**; otherwise, it is set to *errnum*. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_commit**() function commits the current open transaction and causes a transition to **TX_STAGE_ONCOMMIT**. If called in the context of the outermost transaction, all the changes may be considered as durably written upon successful completion. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_end**() function performs a cleanup of the current transaction. If called in the context of the outermost transaction, it releases all the locks acquired by **pmemobj_tx_begin**() for outer and nested transactions. If called in the context of a nested transaction, it returns to the context of the outer transaction in **TX_STAGE_WORK**, without releasing any locks. The **pmemobj_tx_end**() function can be called during **TX_STAGE_NONE** if transitioned to this stage using **pmemobj_tx_process**(). If not already in **TX_STAGE_NONE**, it causes the transition to **TX_STAGE_NONE**. **pmemobj_tx_end** must always be called for each **pmemobj_tx_begin**(), even if starting the transaction failed. This function must *not* be called during **TX_STAGE_WORK**. The **pmemobj_tx_errno**() function returns the error code of the last transaction. The **pmemobj_tx_process**() function performs the actions associated with the current stage of the transaction, and makes the transition to the next stage. It must be called in a transaction. The current stage must always be obtained by a call to **pmemobj_tx_stage**(). **pmemobj_tx_process**() performs the following transitions in the transaction stage flow: + **TX_STAGE_WORK** -> **TX_STAGE_ONCOMMIT** + **TX_STAGE_ONABORT** -> **TX_STAGE_FINALLY** + **TX_STAGE_ONCOMMIT** -> **TX_STAGE_FINALLY** + **TX_STAGE_FINALLY** -> **TX_STAGE_NONE** + **TX_STAGE_NONE** -> **TX_STAGE_NONE** **pmemobj_tx_process**() must not be called after calling **pmemobj_tx_end**() for the outermost transaction. In addition to the above API, **libpmemobj**(7) offers a more intuitive method of building transactions using the set of macros described below. When using these macros, the complete transaction flow looks like this: ```c TX_BEGIN(Pop) { /* the actual transaction code goes here... */ } TX_ONCOMMIT { /* * optional - executed only if the above block * successfully completes */ } TX_ONABORT { /* * optional - executed only if starting the transaction fails, * or if transaction is aborted by an error or a call to * pmemobj_tx_abort() */ } TX_FINALLY { /* * optional - if exists, it is executed after * TX_ONCOMMIT or TX_ONABORT block */ } TX_END /* mandatory */ ``` ```c TX_BEGIN_PARAM(PMEMobjpool *pop, ...) TX_BEGIN_CB(PMEMobjpool *pop, cb, arg, ...) TX_BEGIN(PMEMobjpool *pop) ``` The **TX_BEGIN_PARAM**(), **TX_BEGIN_CB**() and **TX_BEGIN**() macros start a new transaction in the same way as **pmemobj_tx_begin**(), except that instead of the environment buffer provided by a caller, they set up the local *jmp_buf* buffer and use it to catch the transaction abort. The **TX_BEGIN**() macro starts a transaction without any options. **TX_BEGIN_PARAM** may be used when there is a need to acquire locks prior to starting a transaction (such as for a multi-threaded program) or set up a transaction stage callback. **TX_BEGIN_CB** is just a wrapper around **TX_BEGIN_PARAM** that validates the callback signature. (For compatibility there is also a **TX_BEGIN_LOCK** macro, which is an alias for **TX_BEGIN_PARAM**). Each of these macros must be followed by a block of code with all the operations that are to be performed atomically. The **TX_ONABORT** macro starts a block of code that will be executed only if starting the transaction fails due to an error in **pmemobj_tx_begin**(), or if the transaction is aborted. This block is optional, but in practice it should not be omitted. If it is desirable to crash the application when a transaction aborts and there is no **TX_ONABORT** section, the application can define the **POBJ_TX_CRASH_ON_NO_ONABORT** macro before inclusion of **\**. This provides a default **TX_ONABORT** section which just calls **abort**(3). The **TX_ONCOMMIT** macro starts a block of code that will be executed only if the transaction is successfully committed, which means that the execution of code in the **TX_BEGIN**() block has not been interrupted by an error or by a call to **pmemobj_tx_abort**(). This block is optional. The **TX_FINALLY** macro starts a block of code that will be executed regardless of whether the transaction is committed or aborted. This block is optional. The **TX_END** macro cleans up and closes the transaction started by the **TX_BEGIN**() / **TX_BEGIN_PARAM**() / **TX_BEGIN_CB**() macros. It is mandatory to terminate each transaction with this macro. If the transaction was aborted, *errno* is set appropriately. ## TRANSACTION LOG TUNING ## From libpmemobj implementation perspective there are two types of operations in a transaction: + **snapshots**, where action must be persisted immediately, + **intents**, where action can be persisted at the transaction commit phase **pmemobj_tx_add_range**(3) and all its variants belong to the **snapshots** group. **pmemobj_tx_alloc**(3) (with its variants), **pmemobj_tx_free**(3), **pmemobj_tx_realloc**(3) (with its variants) and **pmemobj_tx_publish**(3) belong to the **intents** group. Even though **pmemobj_tx_alloc**() allocates memory immediately, it modifies only the runtime state and postpones persistent memory modifications to the commit phase. **pmemobj_tx_free**(3) cannot free the object immediately, because of possible transaction rollback, so it postpones both the action and persistent memory modifications to the commit phase. **pmemobj_tx_realloc**(3) is just a combination of those two. **pmemobj_tx_publish**(3) postpones reservations and deferred frees to the commit phase. Those two types of operations (snapshots and intents) require that libpmemobj builds a persistent log of operations. Intent log (also known as a "redo log") is applied on commit and snapshot log (also known as an "undo log") is applied on abort. When libpmemobj transaction starts, it's not possible to predict how much persistent memory space will be needed for those logs. This means that libpmemobj must internally allocate this space whenever it's needed. This has two downsides: + when transaction snapshots a lot of memory or does a lot of allocations, libpmemobj may need to do many internal allocations, which must be freed when transaction ends, adding time overhead when big transactions are frequent, + transactions can start to fail due to not enough space for logs - this can be especially problematic for transactions that want to **deallocate** objects, as those might also fail To solve both of these problems libpmemobj exposes the following functions: + **pmemobj_tx_log_append_buffer**(), + **pmemobj_tx_xlog_append_buffer**(), + **pmemobj_tx_log_auto_alloc**() **pmemobj_tx_log_append_buffer**() appends a given range of memory [*addr*, *addr* + *size*) to the log *type* of the current transaction. *type* can be one of the two values (with meanings described above): + **TX_LOG_TYPE_SNAPSHOT**, + **TX_LOG_TYPE_INTENT** The range of memory **must** belong to the same pool the transaction is on and **must not** be used by more than one thread at the same time. The latter condition can be verified with tx.debug.verify_user_buffers ctl (see **pmemobj_ctl_get**(3)). The **pmemobj_tx_xlog_append_buffer**() function behaves exactly the same as **pmemobj_tx_log_append_buffer**() when *flags* equals zero. *flags* is a bitmask of the following values: + **POBJ_XLOG_APPEND_BUFFER_NO_ABORT** - if the function does not end successfully, do not abort the transaction. **pmemobj_tx_log_snapshots_max_size** calculates the **maximum** size of a buffer which will be able to hold *nsizes* snapshots, each of size *sizes[i]*. Application should not expect this function to return the same value between restarts. In future versions of libpmemobj this function can return smaller (because of better accuracy or space optimizations) or higher (because of higher alignment required for better performance) value. This function is independent of transaction stage and can be called both inside and outside of transaction. If the returned value S is greater than **PMEMOBJ_MAX_ALLOC_SIZE**, the buffer should be split into N chunks of size **PMEMOBJ_MAX_ALLOC_SIZE**, where N is equal to (S / **PMEMOBJ_MAX_ALLOC_SIZE**) (rounded down) and the last chunk of size (S - (N * **PMEMOBJ_MAX_ALLOC_SIZE**)). **pmemobj_tx_log_intents_max_size** calculates the **maximum** size of a buffer which will be able to hold *nintents* intents. Just like with **pmemobj_tx_log_snapshots_max_size**, application should not expect this function to return the same value between restarts, for the same reasons. This function is independent of transaction stage and can be called both inside and outside of transaction. **pmemobj_tx_log_auto_alloc**() disables (*on_off* set to 0) or enables (*on_off* set to 1) automatic allocation of internal logs of given *type*. It can be used to verify that the buffer set with **pmemobj_tx_log_append_buffer**() is big enough to hold the log, without reaching out-of-space scenario. The **pmemobj_tx_set_user_data**() function associates custom volatile state, represented by pointer *data*, with the current transaction. This state can later be retrieved using **pmemobj_tx_get_user_data**() function. If **pmemobj_tx_set_user_data**() was not called for a current transaction, **pmemobj_tx_get_user_data**() will return NULL. These functions must be called during **TX_STAGE_WORK** or **TX_STAGE_ONABORT** or **TX_STAGE_ONCOMMIT** or **TX_STAGE_FINALLY**. **pmemobj_tx_set_failure_behavior**() specifies what should happen in case of an error within the transaction. It only affects functions which take a NO_ABORT flag. If **pmemobj_tx_set_failure_behavior**() is called with POBJ_TX_FAILURE_RETURN a NO_ABORT flag is implicitly passed to all functions which accept this flag. If called with POBJ_TX_FAILURE_ABORT then all functions abort the transaction (unless NO_ABORT flag is passed explicitly). This setting is inherited by inner transactions. It does not affect any of the outer transactions. Aborting on failure is the default behavior. **pmemobj_tx_get_failure_behavior**() returns failure behavior for the current transaction. Both **pmemobj_tx_set_failure_behavior**() and **pmemobj_tx_get_failure_behavior**() must be called during **TX_STAGE_WORK**. # RETURN VALUE # The **pmemobj_tx_stage**() function returns the stage of the current transaction stage for a thread. On success, **pmemobj_tx_begin**() returns 0. Otherwise, an error number is returned. The **pmemobj_tx_begin**() and **pmemobj_tx_lock**() functions return zero if *lockp* is successfully added to the transaction. Otherwise, an error number is returned. The **pmemobj_tx_xlock**() function return zero if *lockp* is successfully added to the transaction. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XLOCK_NO_ABORT**, the transaction is aborted. The **pmemobj_tx_abort**() and **pmemobj_tx_commit**() functions return no value. The **pmemobj_tx_end**() function returns 0 if the transaction was successful. Otherwise it returns the error code set by **pmemobj_tx_abort**(). Note that **pmemobj_tx_abort**() can be called internally by the library. The **pmemobj_tx_errno**() function returns the error code of the last transaction. The **pmemobj_tx_process**() function returns no value. On success, **pmemobj_tx_log_append_buffer**() returns 0. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **errno** is set appropriately and transaction is aborted. On success, **pmemobj_tx_xlog_append_buffer**() returns 0. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XLOG_NO_ABORT**, the transaction is aborted. On success, **pmemobj_tx_log_auto_alloc**() returns 0. Otherwise, the transaction is aborted and an error number is returned. On success, **pmemobj_tx_log_snapshots_max_size**() returns size of the buffer. On failure it returns *SIZE_MAX* and sets *errno* appropriately. On success, **pmemobj_tx_log_intents_max_size**() returns size of the buffer. On failure it returns *SIZE_MAX* and sets *errno* appropriately. # CAVEATS # Transaction flow control is governed by the **setjmp**(3) and **longjmp**(3) macros, and they are used in both the macro and function flavors of the API. The transaction will longjmp on transaction abort. This has one major drawback, which is described in the ISO C standard subsection 7.13.2.1. It says that **the values of objects of automatic storage duration that are local to the function containing the setjmp invocation that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.** The following example illustrates the issue described above. ```c int *bad_example_1 = (int *)0xBAADF00D; int *bad_example_2 = (int *)0xBAADF00D; int *bad_example_3 = (int *)0xBAADF00D; int * volatile good_example = (int *)0xBAADF00D; TX_BEGIN(pop) { bad_example_1 = malloc(sizeof(int)); bad_example_2 = malloc(sizeof(int)); bad_example_3 = malloc(sizeof(int)); good_example = malloc(sizeof(int)); /* manual or library abort called here */ pmemobj_tx_abort(EINVAL); } TX_ONCOMMIT { /* * This section is longjmp-safe */ } TX_ONABORT { /* * This section is not longjmp-safe */ free(good_example); /* OK */ free(bad_example_1); /* undefined behavior */ } TX_FINALLY { /* * This section is not longjmp-safe on transaction abort only */ free(bad_example_2); /* undefined behavior */ } TX_END free(bad_example_3); /* undefined behavior */ ``` Objects which are not volatile-qualified, are of automatic storage duration and have been changed between the invocations of **setjmp**(3) and **longjmp**(3) (that also means within the work section of the transaction after **TX_BEGIN**()) should not be used after a transaction abort, or should be used with utmost care. This also includes code after the **TX_END** macro. **libpmemobj**(7) is not cancellation-safe. The pool will never be corrupted because of a canceled thread, but other threads may stall waiting on locks taken by that thread. If the application wants to use **pthread_cancel**(3), it must disable cancellation before calling any **libpmemobj**(7) APIs (see **pthread_setcancelstate**(3) with **PTHREAD_CANCEL_DISABLE**), and re-enable it afterwards. Deferring cancellation (**pthread_setcanceltype**(3) with **PTHREAD_CANCEL_DEFERRED**) is not safe enough, because **libpmemobj**(7) internally may call functions that are specified as cancellation points in POSIX. **libpmemobj**(7) relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. # SEE ALSO # **dlclose**(3), **longjmp**(3), **pmemobj_tx_add_range**(3), **pmemobj_tx_alloc**(3), **pthread_setcancelstate**(3), **pthread_setcanceltype**(3), **setjmp**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pobj_list_foreach_reverse.30000664000000000000000000000002514123364546021413 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_publish.30000664000000000000000000000002514123364546020076 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_zero.30000664000000000000000000002403314123364732020120 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_MUTEX_ZERO" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemobj_mutex_zero\f[](), \f[B]pmemobj_mutex_lock\f[](), \f[B]pmemobj_mutex_timedlock\f[](), \f[B]pmemobj_mutex_trylock\f[](), \f[B]pmemobj_mutex_unlock\f[](), .PP \f[B]pmemobj_rwlock_zero\f[](), \f[B]pmemobj_rwlock_rdlock\f[](), \f[B]pmemobj_rwlock_wrlock\f[](), \f[B]pmemobj_rwlock_timedrdlock\f[](), \f[B]pmemobj_rwlock_timedwrlock\f[](), \f[B]pmemobj_rwlock_tryrdlock\f[](), \f[B]pmemobj_rwlock_trywrlock\f[](), \f[B]pmemobj_rwlock_unlock\f[](), .PP \f[B]pmemobj_cond_zero\f[](), \f[B]pmemobj_cond_broadcast\f[](), \f[B]pmemobj_cond_signal\f[](), \f[B]pmemobj_cond_timedwait\f[](), \f[B]pmemobj_cond_wait\f[]() \- pmemobj synchronization primitives .SH SYNOPSIS .IP .nf \f[C] #include\ void\ pmemobj_mutex_zero(PMEMobjpool\ *pop,\ PMEMmutex\ *mutexp); int\ pmemobj_mutex_lock(PMEMobjpool\ *pop,\ PMEMmutex\ *mutexp); int\ pmemobj_mutex_timedlock(PMEMobjpool\ *pop,\ PMEMmutex\ *restrict\ mutexp, \ \ \ \ const\ struct\ timespec\ *restrict\ abs_timeout); int\ pmemobj_mutex_trylock(PMEMobjpool\ *pop,\ PMEMmutex\ *mutexp); int\ pmemobj_mutex_unlock(PMEMobjpool\ *pop,\ PMEMmutex\ *mutexp); void\ pmemobj_rwlock_zero(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); int\ pmemobj_rwlock_rdlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); int\ pmemobj_rwlock_wrlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); int\ pmemobj_rwlock_timedrdlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *restrict\ rwlockp, \ \ \ \ const\ struct\ timespec\ *restrict\ abs_timeout); int\ pmemobj_rwlock_timedwrlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *restrict\ rwlockp, \ \ \ \ const\ struct\ timespec\ *restrict\ abs_timeout); int\ pmemobj_rwlock_tryrdlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); int\ pmemobj_rwlock_trywrlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); int\ pmemobj_rwlock_unlock(PMEMobjpool\ *pop,\ PMEMrwlock\ *rwlockp); void\ pmemobj_cond_zero(PMEMobjpool\ *pop,\ PMEMcond\ *condp); int\ pmemobj_cond_broadcast(PMEMobjpool\ *pop,\ PMEMcond\ *condp); int\ pmemobj_cond_signal(PMEMobjpool\ *pop,\ PMEMcond\ *condp); int\ pmemobj_cond_timedwait(PMEMobjpool\ *pop,\ PMEMcond\ *restrict\ condp, \ \ \ \ PMEMmutex\ *restrict\ mutexp,\ const\ struct\ timespec\ *restrict\ abs_timeout); int\ pmemobj_cond_wait(PMEMobjpool\ *pop,\ PMEMcond\ *restrict\ condp, \ \ \ \ PMEMmutex\ *restrict\ mutexp); \f[] .fi .SH DESCRIPTION .PP \f[B]libpmemobj\f[](7) provides several types of synchronization primitives designed to be used with persistent memory. The pmem\-aware lock implementation is based on the standard POSIX Threads Library, as described in \f[B]pthread_mutex_init\f[](3), \f[B]pthread_rwlock_init\f[](3) and \f[B]pthread_cond_init\f[](3). Pmem\-aware locks provide semantics similar to standard \f[B]pthread\f[] locks, except that they are embedded in pmem\-resident objects and are considered initialized by zeroing them. Therefore, locks allocated with \f[B]pmemobj_zalloc\f[](3) or \f[B]pmemobj_tx_zalloc\f[](3) do not require another initialization step. For performance reasons, they are also padded up to 64 bytes (cache line size). .PP On FreeBSD, since all \f[B]pthread\f[] locks are dynamically allocated, while the lock object is still padded up to 64 bytes for consistency with Linux, only the pointer to the lock is embedded in the pmem\-resident object. \f[B]libpmemobj\f[](7) transparently manages freeing of the locks when the pool is closed. .PP The fundamental property of pmem\-aware locks is their automatic reinitialization every time the persistent object store pool is opened. Thus, all the pmem\-aware locks may be considered initialized (unlocked) immediately after the pool is opened, regardless of their state at the time the pool was closed for the last time. .PP Pmem\-aware mutexes, read/write locks and condition variables must be declared with the \f[I]PMEMmutex\f[], \f[I]PMEMrwlock\f[], or \f[I]PMEMcond\f[] type, respectively. .PP The \f[B]pmemobj_mutex_zero\f[]() function explicitly initializes the pmem\-aware mutex \f[I]mutexp\f[] by zeroing it. Initialization is not necessary if the object containing the mutex has been allocated using \f[B]pmemobj_zalloc\f[](3) or \f[B]pmemobj_tx_zalloc\f[](3). .PP The \f[B]pmemobj_mutex_lock\f[]() function locks the pmem\-aware mutex \f[I]mutexp\f[]. If the mutex is already locked, the calling thread will block until the mutex becomes available. If this is the first use of the mutex since the opening of the pool \f[I]pop\f[], the mutex is automatically reinitialized and then locked. .PP \f[B]pmemobj_mutex_timedlock\f[]() performs the same action as \f[B]pmemobj_mutex_lock\f[](), but will not wait beyond \f[I]abs_timeout\f[] to obtain the lock before returning. .PP The \f[B]pmemobj_mutex_trylock\f[]() function locks pmem\-aware mutex \f[I]mutexp\f[]. If the mutex is already locked, \f[B]pthread_mutex_trylock\f[]() will not block waiting for the mutex, but will return an error. If this is the first use of the mutex since the opening of the pool \f[I]pop\f[], the mutex is automatically reinitialized and then locked. .PP The \f[B]pmemobj_mutex_unlock\f[]() function unlocks the pmem\-aware mutex \f[I]mutexp\f[]. Undefined behavior follows if a thread tries to unlock a mutex that has not been locked by it, or if a thread tries to release a mutex that is already unlocked or has not been initialized. .PP The \f[B]pmemobj_rwlock_zero\f[]() function is used to explicitly initialize the pmem\-aware read/write lock \f[I]rwlockp\f[] by zeroing it. Initialization is not necessary if the object containing the lock has been allocated using \f[B]pmemobj_zalloc\f[](3) or \f[B]pmemobj_tx_zalloc\f[](3). .PP The \f[B]pmemobj_rwlock_rdlock\f[]() function acquires a read lock on \f[I]rwlockp\f[], provided that the lock is not presently held for writing and no writer threads are presently blocked on the lock. If the read lock cannot be acquired immediately, the calling thread blocks until it can acquire the lock. If this is the first use of the lock since the opening of the pool \f[I]pop\f[], the lock is automatically reinitialized and then acquired. .PP \f[B]pmemobj_rwlock_timedrdlock\f[]() performs the same action as \f[B]pmemobj_rwlock_rdlock\f[](), but will not wait beyond \f[I]abs_timeout\f[] to obtain the lock before returning. A thread may hold multiple concurrent read locks. If so, \f[B]pmemobj_rwlock_unlock\f[]() must be called once for each lock obtained. The results of acquiring a read lock while the calling thread holds a write lock are undefined. .PP The \f[B]pmemobj_rwlock_wrlock\f[]() function blocks until a write lock can be acquired against read/write lock \f[I]rwlockp\f[]. If this is the first use of the lock since the opening of the pool \f[I]pop\f[], the lock is automatically reinitialized and then acquired. .PP \f[B]pmemobj_rwlock_timedwrlock\f[]() performs the same action, but will not wait beyond \f[I]abs_timeout\f[] to obtain the lock before returning. .PP The \f[B]pmemobj_rwlock_tryrdlock\f[]() function performs the same action as \f[B]pmemobj_rwlock_rdlock\f[](), but does not block if the lock cannot be immediately obtained. The results are undefined if the calling thread already holds the lock at the time the call is made. .PP The \f[B]pmemobj_rwlock_trywrlock\f[]() function performs the same action as \f[B]pmemobj_rwlock_wrlock\f[](), but does not block if the lock cannot be immediately obtained. The results are undefined if the calling thread already holds the lock at the time the call is made. .PP The \f[B]pmemobj_rwlock_unlock\f[]() function is used to release the read/write lock previously obtained by \f[B]pmemobj_rwlock_rdlock\f[](), \f[B]pmemobj_rwlock_wrlock\f[](), \f[B]pthread_rwlock_tryrdlock\f[](), or \f[B]pmemobj_rwlock_trywrlock\f[](). .PP The \f[B]pmemobj_cond_zero\f[]() function explicitly initializes the pmem\-aware condition variable \f[I]condp\f[] by zeroing it. Initialization is not necessary if the object containing the condition variable has been allocated using \f[B]pmemobj_zalloc\f[](3) or \f[B]pmemobj_tx_zalloc\f[](3). .PP The difference between \f[B]pmemobj_cond_broadcast\f[]() and \f[B]pmemobj_cond_signal\f[]() is that the former unblocks all threads waiting for the condition variable, whereas the latter blocks only one waiting thread. If no threads are waiting on \f[I]condp\f[], neither function has any effect. If more than one thread is blocked on a condition variable, the used scheduling policy determines the order in which threads are unblocked. The same mutex used for waiting must be held while calling either function. Although neither function strictly enforces this requirement, undefined behavior may follow if the mutex is not held. .PP The \f[B]pmemobj_cond_timedwait\f[]() and \f[B]pmemobj_cond_wait\f[]() functions block on a condition variable. They must be called with mutex \f[I]mutexp\f[] locked by the calling thread, or undefined behavior results. These functions atomically release mutex \f[I]mutexp\f[] and cause the calling thread to block on the condition variable \f[I]condp\f[]; atomically here means \[lq]atomically with respect to access by another thread to the mutex and then the condition variable\[rq]. That is, if another thread is able to acquire the mutex after the about\-to\-block thread has released it, then a subsequent call to \f[B]pmemobj_cond_broadcast\f[]() or \f[B]pmemobj_cond_signal\f[]() in that thread will behave as if it were issued after the about\-to\-block thread has blocked. Upon successful return, the mutex will be locked and owned by the calling thread. .SH RETURN VALUE .PP The \f[B]pmemobj_mutex_zero\f[](), \f[B]pmemobj_rwlock_zero\f[]() and \f[B]pmemobj_cond_zero\f[]() functions return no value. .PP Other locking functions return 0 on success. Otherwise, an error number will be returned to indicate the error. .SH SEE ALSO .PP \f[B]pmemobj_tx_zalloc\f[](3), \f[B]pmemobj_zalloc\f[](3), \f[B]pthread_cond_init\f[](3), \f[B]pthread_mutex_init\f[](3), \f[B]pthread_rwlock_init\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/toid_type_num.30000664000000000000000000000002314123364546017061 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_alloc.30000664000000000000000000003736714123364731017026 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_ALLOC" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2020, Intel Corporation .SH NAME .PP \f[B]pmemobj_alloc\f[](), \f[B]pmemobj_xalloc\f[](), \f[B]pmemobj_zalloc\f[](), \f[B]pmemobj_realloc\f[](), \f[B]pmemobj_zrealloc\f[](), \f[B]pmemobj_strdup\f[](), \f[B]pmemobj_wcsdup\f[](), \f[B]pmemobj_alloc_usable_size\f[](), \f[B]pmemobj_defrag\f[](), \f[B]POBJ_NEW\f[](), \f[B]POBJ_ALLOC\f[](), \f[B]POBJ_ZNEW\f[](), \f[B]POBJ_ZALLOC\f[](), \f[B]POBJ_REALLOC\f[](), \f[B]POBJ_ZREALLOC\f[](), \f[B]POBJ_FREE\f[]() \- non\-transactional atomic allocations .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ int\ (*pmemobj_constr)(**PMEMobjpool\ *pop,\ void\ *ptr,\ void\ *arg); int\ pmemobj_alloc(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ size_t\ size, \ \ \ \ uint64_t\ type_num,\ pmemobj_constr\ constructor,\ void\ *arg); int\ pmemobj_xalloc(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ size_t\ size, \ \ \ \ uint64_t\ type_num,\ uint64_t\ flags,\ pmemobj_constr\ constructor, \ \ \ \ void\ *arg);\ (EXPERIMENTAL) int\ pmemobj_zalloc(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ size_t\ size, \ \ \ \ uint64_t\ type_num); void\ pmemobj_free(PMEMoid\ *oidp); int\ pmemobj_realloc(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ size_t\ size, \ \ \ \ uint64_t\ type_num); int\ pmemobj_zrealloc(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ size_t\ size, \ \ \ \ uint64_t\ type_num); int\ pmemobj_strdup(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ const\ char\ *s, \ \ \ \ uint64_t\ type_num); int\ pmemobj_wcsdup(PMEMobjpool\ *pop,\ PMEMoid\ *oidp,\ const\ wchar_t\ *s, \ \ \ \ uint64_t\ type_num); size_t\ pmemobj_alloc_usable_size(PMEMoid\ oid); int\ pmemobj_defrag(PMEMobjpool\ *pop,\ PMEMoid\ **oidv,\ size_t\ oidcnt, \ \ \ \ struct\ pobj_defrag_result\ *result); POBJ_NEW(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE,\ pmemobj_constr\ constructor, \ \ \ \ void\ *arg) POBJ_ALLOC(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg) POBJ_ZNEW(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE) POBJ_ZALLOC(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE,\ size_t\ size) POBJ_REALLOC(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE,\ size_t\ size) POBJ_ZREALLOC(PMEMobjpool\ *pop,\ TOID\ *oidp,\ TYPE,\ size_t\ size) POBJ_FREE(TOID\ *oidp) \f[] .fi .SH DESCRIPTION .PP Functions described in this document provide the mechanism to allocate, resize and free objects from the persistent memory pool in a thread\-safe and fail\-safe manner. All the routines are atomic with respect to other threads and any power\-fail interruptions. If any of these operations is torn by program failure or system crash, on recovery they are guaranteed to be entirely completed or discarded, leaving the persistent memory heap and internal object containers in a consistent state. .PP All these functions should be used outside transactions. If executed within an open transaction they are considered durable immediately after completion. Changes made with these functions will not be rolled back if the transaction is aborted or interrupted. They have no information about other changes made by transactional API, so if the same data is modified in a single transaction using transactional and then non\-transactional API, transaction abort will likely corrupt the data. .PP The allocations are always aligned to a cache\-line boundary. .PP The \f[I]pmemobj_constr\f[] type represents a constructor for atomic allocation from the persistent memory heap associated with memory pool \f[I]pop\f[]. \f[I]ptr\f[] is a pointer to the allocated memory area and \f[I]arg\f[] is a user\-defined argument passed to the constructor. .PP The \f[B]pmemobj_alloc\f[]() function allocates a new object from the persistent memory heap associated with memory pool \f[I]pop\f[]. The \f[I]PMEMoid\f[] of the allocated object is stored in \f[I]oidp\f[]. If \f[I]oidp\f[] is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with the type number \f[I]type_num\f[], as described in \f[B]POBJ_FOREACH\f[](3). If \f[I]oidp\f[] points to a memory location from the \f[B]pmemobj\f[] heap, \f[I]oidp\f[] is modified atomically. Before returning, \f[B]pmemobj_alloc\f[]() calls the \f[I]constructor\f[] function, passing the pool handle \f[I]pop\f[], the pointer to the newly allocated object in \f[I]ptr\f[], and the \f[I]arg\f[] argument. It is guaranteed that the allocated object is either properly initialized, or if the allocation is interrupted before the constructor completes, the memory space reserved for the object is reclaimed. \f[I]size\f[] can be any non\-zero value; however, due to internal padding and object metadata, the actual size of the allocation will differ from the requested size by at least 64 bytes. For this reason, making allocations of a size less than 64 bytes is extremely inefficient and discouraged. The allocated object is added to the internal container associated with \f[I]type_num\f[]. .PP \f[B]pmemobj_xalloc\f[]() is equivalent to \f[B]pmemobj_alloc\f[](), but with an additional \f[I]flags\f[] argument that is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XALLOC_ZERO\f[] \- zero the allocated object (equivalent of \f[B]pmemobj_zalloc\f[]()) .IP \[bu] 2 \f[B]POBJ_CLASS_ID(class_id)\f[] \- allocate an object from the allocation class \f[I]class_id\f[]. The class id cannot be 0. .IP \[bu] 2 \f[B]POBJ_ARENA_ID(arena_id)\f[] \- allocate an object from the arena specified by \f[I]arena_id\f[]. The arena must exist, otherwise, the behavior is undefined. If \f[I]arena_id\f[] is equal 0, then arena assigned to the current thread will be used. .PP The \f[B]pmemobj_zalloc\f[]() function allocates a new zeroed object from the persistent memory heap associated with memory pool \f[I]pop\f[]. The \f[I]PMEMoid\f[] of the allocated object is stored in \f[I]oidp\f[]. If \f[I]oidp\f[] is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with the type number \f[I]type_num\f[], as described in \f[B]POBJ_FOREACH\f[](3). If \f[I]oidp\f[] points to a memory location from the \f[B]pmemobj\f[] heap, \f[I]oidp\f[] is modified atomically. \f[I]size\f[] can be any non\-zero value; however, due to internal padding and object metadata, the actual size of the allocation will differ from the requested one by at least 64 bytes. For this reason, making allocations of a size less than 64 bytes is extremely inefficient and discouraged. The allocated object is added to the internal container associated with \f[I]type_num\f[]. .PP The \f[B]pmemobj_free\f[]() function frees the memory space represented by \f[I]oidp\f[], which must have been allocated by a previous call to \f[B]pmemobj_alloc\f[](), \f[B]pmemobj_xalloc\f[](), \f[B]pmemobj_zalloc\f[](), \f[B]pmemobj_realloc\f[](), or \f[B]pmemobj_zrealloc\f[](). \f[B]pmemobj_free\f[]() provides the same semantics as \f[B]free\f[](3), but instead of operating on the process heap supplied by the system, it operates on the persistent memory heap. If \f[I]oidp\f[] is \f[B]OID_NULL\f[], no operation is performed. If \f[I]oidp\f[] is NULL or if it points to the root object's \f[I]OID\f[], the behavior of \f[B]pmemobj_free\f[]() is undefined. \f[I]oidp\f[] is set to \f[B]OID_NULL\f[] after the memory is freed. If \f[I]oidp\f[] points to a memory location from the \f[B]pmemobj\f[] heap, \f[I]oidp\f[] is modified atomically. .PP The \f[B]pmemobj_realloc\f[]() function changes the size of the object represented by \f[I]oidp\f[] to \f[I]size\f[] bytes. \f[B]pmemobj_realloc\f[]() provides similar semantics to \f[B]realloc\f[](3), but operates on the persistent memory heap associated with memory pool \f[I]pop\f[]. The resized object is also added or moved to the internal container associated with type number \f[I]type_num\f[]. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will \f[I]not\f[] be initialized. If \f[I]oidp\f[] is \f[I]OID_NULL\f[], then the call is equivalent to \f[I]pmemobj_alloc(pop, size, type_num)\f[]. If \f[I]size\f[] is equal to zero, and \f[I]oidp\f[] is not \f[B]OID_NULL\f[], then the call is equivalent to \f[I]pmemobj_free(oid)\f[]. Unless \f[I]oidp\f[] is \f[B]OID_NULL\f[], it must have been allocated by an earlier call to \f[B]pmemobj_alloc\f[](), \f[B]pmemobj_xalloc\f[](), \f[B]pmemobj_zalloc\f[](), \f[B]pmemobj_realloc\f[](), or \f[B]pmemobj_zrealloc\f[](). Note that the object handle value may change as a result of reallocation. If the object was moved, the memory space represented by \f[I]oid\f[] is reclaimed. If \f[I]oidp\f[] points to a memory location from the \f[B]pmemobj\f[] heap, \f[I]oidp\f[] is modified atomically. If \f[I]oidp\f[] is NULL or if it points to the root object's \f[I]OID\f[], the behavior of \f[B]pmemobj_realloc\f[]() is undefined. .PP \f[B]pmemobj_zrealloc\f[]() is equivalent to \f[B]pmemobj_realloc\f[](), except that if the new size is larger than the old size, the added memory will be zeroed. .PP The \f[B]pmemobj_strdup\f[]() function stores a handle to a new object in \f[I]oidp\f[] which is a duplicate of the string \f[I]s\f[]. \f[B]pmemobj_strdup\f[]() provides the same semantics as \f[B]strdup\f[](3), but operates on the persistent memory heap associated with memory pool \f[I]pop\f[]. If \f[I]oidp\f[] is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with type number \f[I]type_num\f[], as described in \f[B]POBJ_FOREACH\f[](3). If \f[I]oidp\f[] points to a memory location from the \f[B]pmemobj\f[] heap, \f[I]oidp\f[] is modified atomically. The allocated string object is also added to the internal container associated with type number \f[I]type_num\f[]. Memory for the new string is obtained with \f[B]pmemobj_alloc\f[](), on the given memory pool, and can be freed with \f[B]pmemobj_free\f[]() on the same memory pool. .PP \f[B]pmemobj_wcsdup\f[]() is equivalent to \f[B]pmemobj_strdup\f[](), but operates on a wide character string (wchar_t) rather than a standard character string. .PP The \f[B]pmemobj_alloc_usable_size\f[]() function provides the same semantics as \f[B]malloc_usable_size\f[](3), but instead of the process heap supplied by the system, it operates on the persistent memory heap. .PP The \f[B]POBJ_NEW\f[]() macro is a wrapper around the \f[B]pmemobj_alloc\f[]() function. Instead of taking a pointer to \f[I]PMEMoid\f[], it takes a pointer to the typed \f[I]OID\f[] of type name \f[I]TYPE\f[], and passes the size and type number from the typed \f[I]OID\f[] to \f[B]pmemobj_alloc\f[](). .PP The \f[B]POBJ_ALLOC\f[]() macro is equivalent to \f[B]POBJ_NEW\f[], except that instead of using the size of the typed \f[I]OID\f[], passes \f[I]size\f[] to \f[B]pmemobj_alloc\f[](). .PP The \f[B]POBJ_ZNEW\f[]() macro is a wrapper around the \f[B]pmemobj_zalloc\f[]() function. Instead of taking a pointer to \f[I]PMEMoid\f[], it takes a pointer to the typed \f[I]OID\f[] of type name \f[I]TYPE\f[], and passes the size and type number from the typed \f[I]OID\f[] to \f[B]pmemobj_zalloc\f[](). .PP The \f[B]POBJ_ZALLOC\f[]() macro is equivalent to \f[B]POBJ_ZNEW\f[], except that instead of using the size of the typed \f[I]OID\f[], passes \f[I]size\f[] to \f[B]pmemobj_zalloc\f[](). .PP The \f[B]POBJ_REALLOC\f[]() macro is a wrapper around the \f[B]pmemobj_realloc\f[]() function. Instead of taking a pointer to \f[I]PMEMoid\f[], it takes a pointer to the typed \f[I]OID\f[] of type name \f[I]TYPE\f[], and passes the type number from the typed \f[I]OID\f[] to \f[B]pmemobj_realloc\f[](). .PP The \f[B]POBJ_ZREALLOC\f[]() macro is a wrapper around the \f[B]pmemobj_zrealloc\f[]() function. Instead of taking a pointer to \f[I]PMEMoid\f[], it takes a pointer to the typed \f[I]OID\f[] of type name \f[I]TYPE\f[], and passes the type number from the typed \f[I]OID\f[] to \f[B]pmemobj_zrealloc\f[](). .PP The \f[B]POBJ_FREE\f[]() macro is a wrapper around the \f[B]pmemobj_free\f[]() function which takes a pointer to the typed \f[I]OID\f[] instead of to \f[I]PMEMoid\f[]. .PP The \f[B]pmemobj_defrag\f[]() function performs defragmentation on the objects provided through the array of pointers to PMEMoids \f[I]oidv\f[] with size \f[I]oidcnt\f[]. If an object from the provided array is selected to be moved to a new location in the heap, it is reallocated and all provided pointers to that object are atomically updated. To maintain data structure consistency, applications should always provide all pointers for an object to \f[B]pmemobj_defrag\f[] method. This ensures that, even in the presence of failures, all pointers to the object will either point to the old or a new location. All objects and pointers to objects should belong to the pool \f[I]pop\f[] or, in case of pointers, can also reside in volatile memory. Defragmentation across pools is not supported. Objects in the array that are \f[I]OID_NULL\f[] are skipped over and no operation is performed on them. All other objects must have been allocated by an earlier call to \f[B]pmemobj_alloc\f[](), \f[B]pmemobj_xalloc\f[](), \f[B]pmemobj_zalloc\f[](), \f[B]pmemobj_realloc\f[](), \f[B]pmemobj_zrealloc\f[](), \f[B]pmemobj_strdup\f[]() or \f[B]pmemobj_wcsdup\f[](). The \f[I]result\f[] variable is an instance of \f[I]struct pobj_defrag_result\f[] and, if not NULL, can be used to read \f[I]total\f[], the number of objects found that were processed, and \f[I]relocated\f[], the number of objects that were relocated during defragmentation. These variables are always initialized and can be non\-zero, even if the return value of \f[B]pmemobj_defrag\f[]() indicated a failure. This is because the failure might have occurred after some objects were already processed. .SH RETURN VALUE .PP On success, \f[B]pmemobj_alloc\f[]() and \f[B]pmemobj_xalloc\f[] return 0. If \f[I]oidp\f[] is not NULL, the \f[I]PMEMoid\f[] of the newly allocated object is stored in \f[I]oidp\f[]. If the allocation fails, \-1 is returned and \f[I]errno\f[] is set appropriately. If the constructor returns a non\-zero value, the allocation is canceled, \-1 is returned, and \f[I]errno\f[] is set to \f[B]ECANCELED\f[]. If \f[I]size\f[] equals 0, or the \f[I]flags\f[] for \f[B]pmemobj_xalloc\f[] are invalid, \-1 is returned, \f[I]errno\f[] is set to \f[B]EINVAL\f[], and \f[I]oidp\f[] is left untouched. .PP On success, \f[B]pmemobj_zalloc\f[]() returns 0. If \f[I]oidp\f[] is not NULL, the \f[I]PMEMoid\f[] of the newly allocated object is stored in \f[I]oidp\f[]. If the allocation fails, it returns \-1 and sets \f[I]errno\f[] appropriately. If \f[I]size\f[] equals 0, it returns \-1, sets \f[I]errno\f[] to \f[B]EINVAL\f[], and leaves \f[I]oidp\f[] untouched. .PP The \f[B]pmemobj_free\f[]() function returns no value. .PP On success, \f[B]pmemobj_realloc\f[]() and \f[B]pmemobj_zrealloc\f[]() return 0 and update \f[I]oidp\f[] if necessary. On error, they return \-1 and set \f[I]errno\f[] appropriately. .PP On success, \f[B]pmemobj_strdup\f[]() and \f[B]pmemobj_wcsdup\f[]() return 0. If \f[I]oidp\f[] is not NULL, the \f[I]PMEMoid\f[] of the duplicated string object is stored in \f[I]oidp\f[]. If \f[I]s\f[] is NULL, they return \-1, set \f[I]errno\f[] to \f[B]EINVAL\f[], and leave \f[I]oidp\f[] untouched. On other errors, they return \-1 and set \f[I]errno\f[] appropriately. .PP The \f[B]pmemobj_alloc_usable_size\f[]() function returns the number of usable bytes in the object represented by \f[I]oid\f[]. If \f[I]oid\f[] is \f[B]OID_NULL\f[], it returns 0. .PP On success, \f[B]pmemobj_defrag\f[]() returns 0. If defragmentation was unsuccessful or only partially successful (i.e.\ if it was aborted halfway through due to lack of resources), \-1 is returned. .SH SEE ALSO .PP \f[B]free\f[](3), \f[B]POBJ_FOREACH\f[](3), \f[B]realloc\f[](3), \f[B]strdup\f[](3), \f[B]wcsdup\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pobj_foreach_safe.30000664000000000000000000000002414123364546017622 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/tx_xadd_field.30000664000000000000000000000003314123364546017001 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_move_element_tail.30000664000000000000000000000002514123364546021741 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/libpmemobj.7.md0000664000000000000000000002247614123364546016745 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEMOBJ, 7) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2020, Intel Corporation) [comment]: <> (libpmemobj.7 -- man page for libpmemobj) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[MANAGING LIBRARY BEHAVIOR](#managing-library-behavior-1)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also)
# NAME # **libpmemobj** - persistent memory transactional object store # SYNOPSIS # ```c #include cc _WINUX(,-std=gnu99) ... -lpmemobj -lpmem ``` _UNICODE() ##### Library API versioning: ##### ```c _UWFUNC(pmemobj_check_version, =q= unsigned major_required, unsigned minor_required=e=) ``` ##### Managing library behavior: ##### ```c void pmemobj_set_funcs( void *(*malloc_func)(size_t size), void (*free_func)(void *ptr), void *(*realloc_func)(void *ptr, size_t size), char *(*strdup_func)(const char *s)); ``` ##### Error handling: ##### ```c _UWFUNC(pmemobj_errormsg, void) ``` ##### Other library functions: ##### A description of other **libpmemobj** functions can be found on the following manual pages: + control and statistics: **pmemobj_ctl_get**(3) + create, open, close and validate: **pmemobj_open**(3) + low-level memory manipulation: **pmemobj_memcpy_persist**(3) + locking: **pmemobj_mutex_zero**(3) + persistent object identifier: **OID_IS_NULL**(3) + type-safety: **TOID_DECLARE**(3) + layout declaration: **POBJ_LAYOUT_BEGIN**(3) + non-transactional atomic allocations: **pmemobj_alloc**(3) + root object management: **pmemobj_root**(3) + object containers: **pmemobj_first**(3) + non-transactional persistent atomic circular doubly-linked list: **pmemobj_list_insert**(3), **POBJ_LIST_HEAD**(3) + transactional object manipulation: **pmemobj_tx_begin**(3), **pmemobj_tx_add_range**(3), **pmemobj_tx_alloc**(3) + delayed atomicity actions: **pmemobj_action**(3) (EXPERIMENTAL) # DESCRIPTION # **libpmemobj** provides a transactional object store in *persistent memory* (pmem) for applications that require transactions and persistent memory management using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of *non-volatile memory DIMMs* (NVDIMMs) provide this type of byte addressable access to storage. A *persistent memory aware file system* is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in load/store, non-paged access to pmem. **libpmemobj** builds on this type of memory mapped file using the low-level pmem support provided by **libpmem**(7), handling the transactional updates, flushing changes to persistence, and managing recovery for the application. _WINUX(,=q=**libpmemobj** requires the **-std=gnu99** compilation flag to build properly.=e=) **libpmemobj** is one of a collection of persistent memory libraries available. The others are: + **libpmemblk**(7), providing pmem-resident arrays of fixed-sized blocks with atomic updates. + **libpmemlog**(7), providing a pmem-resident log file. + **libpmem**(7), low-level persistent memory support. Under normal usage, **libpmemobj** will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under **DEBUGGING AND ERROR HANDLING**, below. # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The _UW(pmemobj_check_version) function is used to see if the installed **libpmemobj** supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile-time version information, supplied by defines in **\**, like this: ```c reason = _U(pmemobj_check_version)(PMEMOBJ_MAJOR_VERSION, PMEMOBJ_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. On success, _UW(pmemobj_check_version) returns NULL. Otherwise, the return value is a static string describing the reason the version check failed. The string returned by _UW(pmemobj_check_version) must not be modified or freed. # MANAGING LIBRARY BEHAVIOR # The **pmemobj_set_funcs**() function allows an application to override memory allocation calls used internally by **libpmemobj**. Passing in NULL for any of the handlers will cause the **libpmemobj** default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4-8 kilobytes for each memory pool in use. By default, **libpmemobj** supports up to 1024 parallel transactions/allocations. For debugging purposes it is possible to decrease this value by setting the **PMEMOBJ_NLANES** environment variable to the desired limit. # DEBUGGING AND ERROR HANDLING # If an error is detected during the call to a **libpmemobj** function, the application may retrieve an error message describing the reason for the failure from _UW(pmemobj_errormsg). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmemobj** function indicated an error, or if *errno* was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. Two versions of **libpmemobj** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmemobj** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **libpmemobj**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEMOBJ_LOG_LEVEL** The value of **PMEMOBJ_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEMOBJ_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmemobj_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmemobj** developers. Unless **PMEMOBJ_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMOBJ_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEMOBJ_LOG_FILE** is not set, logging output is written to *stderr*. See also **libpmem**(7) to get information about other environment variables affecting **libpmemobj** behavior. # EXAMPLE # See for examples using the **libpmemobj** API. # ACKNOWLEDGEMENTS # **libpmemobj** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **OID_IS_NULL**(3), **pmemobj_alloc**(3), **pmemobj_ctl_exec**(3), **pmemobj_ctl_get**(3), **pmemobj_ctl_set**(3), **pmemobj_first**(3), **pmemobj_list_insert**(3), **pmemobj_memcpy_persist**(3), **pmemobj_mutex_zero**(3), **pmemobj_open**(3), **pmemobj_root**(3), **pmemobj_tx_add_range**(3), **pmemobj_tx_alloc**(3), **pmemobj_tx_begin**(3), **POBJ_LAYOUT_BEGIN**(3), **POBJ_LIST_HEAD**(3), **strerror**(3), **TOID_DECLARE**(3), **libpmem**(7), **libpmemblk**(7), **libpmemlog**(7) and **** pmdk-1.11.1/doc/libpmemobj/tx_zalloc.30000664000000000000000000000002714123364546016205 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_publish.30000664000000000000000000000002514123364546017363 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/tx_add_field_direct.30000664000000000000000000000003314123364546020143 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_open.30000664000000000000000000002013214123364732016654 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_OPEN" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2021, Intel Corporation .SH NAME .PP \f[B]pmemobj_open\f[](), \f[B]pmemobj_create\f[](), \f[B]pmemobj_close\f[](), \f[B]pmemobj_check\f[]() \f[B]pmemobj_set_user_data\f[](), \f[B]pmemobj_get_user_data\f[]() \- create, open, close and validate persistent memory transactional object store .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMobjpool\ *pmemobj_open(const\ char\ *path,\ const\ char\ *layout); PMEMobjpool\ *pmemobj_create(const\ char\ *path,\ const\ char\ *layout, \ \ \ \ size_t\ poolsize,\ mode_t\ mode); void\ pmemobj_close(PMEMobjpool\ *pop); int\ pmemobj_check(const\ char\ *path,\ const\ char\ *layout); void\ pmemobj_set_user_data(PMEMobjpool\ *pop,\ void\ *data); void\ *pmemobj_get_user_data(PMEMobjpool\ *pop); \f[] .fi .SH DESCRIPTION .PP To use the pmem\-resident transactional object store provided by \f[B]libpmemobj\f[](7), a \f[I]memory pool\f[] must first be created with the \f[B]pmemobj_create\f[]() function described below. Existing pools may be opened with the \f[B]pmemobj_open\f[]() function. .PP As of \f[B]libpmemobj\f[] \f[B]1.11\f[], these functions are thread\-safe; be careful if you have to use earlier versions of the library. .PP Once created, the memory pool is represented by an opaque handle, of type \f[I]PMEMobjpool*\f[], which is passed to most of the other \f[B]libpmemobj\f[](7) functions. Internally, \f[B]libpmemobj\f[](7) will use either \f[B]pmem_persist\f[](3) or \f[B]msync\f[](2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the \f[B]pmem_is_pmem\f[](3) function in \f[B]libpmem\f[](7) for more information). There is no need for applications to flush changes directly when using the object memory API provided by \f[B]libpmemobj\f[](7). .PP The \f[B]pmemobj_create\f[]() function creates a transactional object store with the given total \f[I]poolsize\f[]. \f[I]path\f[] specifies the name of the memory pool file to be created. \f[I]layout\f[] specifies the application's layout type in the form of a string. The layout name is not interpreted by \f[B]libpmemobj\f[](7), but may be used as a check when \f[B]pmemobj_open\f[]() is called. The layout name, including the terminating null byte (`\\0'), cannot be longer than \f[B]PMEMOBJ_MAX_LAYOUT\f[] as defined in \f[B]\f[]. A NULL \f[I]layout\f[] is equivalent to using an empty string as a layout name. \f[I]mode\f[] specifies the permissions to use when creating the file, as described by \f[B]creat\f[](2). The memory pool file is fully allocated to the size \f[I]poolsize\f[] using \f[B]posix_fallocate\f[](3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling \f[B]pmemobj_create\f[](), and then specifying \f[I]poolsize\f[] as zero. In this case \f[B]pmemobj_create\f[]() will take the pool size from the size of the existing file and will verify that the file appears to be empty by searching for any non\-zero data in the pool header at the beginning of the file. The minimum net pool size allowed by the library for a local transactional object store is defined in \f[B]\f[] as \f[B]PMEMOBJ_MIN_POOL\f[]. For remote replicas the minimum file size is defined in \f[B]\f[] as \f[B]RPMEM_MIN_PART\f[]. .PP Depending on the configuration of the system, the available non\-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemobj memory pool could be limited by the capacity of a single memory device. \f[B]libpmemobj\f[](7) allows building persistent memory resident object store spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a \f[I]pool set\f[] may be stored on a different memory device or pmem\-aware filesystem. .PP Creation of all the parts of the pool set can be done with \f[B]pmemobj_create\f[](); however, the recommended method for creating pool sets is with the \f[B]pmempool\f[](1) utility. .PP When creating a pool set consisting of multiple files, the \f[I]path\f[] argument passed to \f[B]pmemobj_create\f[]() must point to the special \f[I]set\f[] file that defines the pool layout and the location of all the parts of the pool set. The \f[I]poolsize\f[] argument must be 0. The meaning of the \f[I]layout\f[] and \f[I]mode\f[] arguments does not change, except that the same \f[I]mode\f[] is used for creation of all the parts of the pool set. .PP The \f[I]set\f[] file is a plain text file, the structure of which is described in \f[B]poolset\f[](5). .PP The \f[B]pmemobj_open\f[]() function opens an existing object store memory pool. Similar to \f[B]pmemobj_create\f[](), \f[I]path\f[] must identify either an existing obj memory pool file, or the \f[I]set\f[] file used to create a pool set. If \f[I]layout\f[] is non\-NULL, it is compared to the layout name provided to \f[B]pmemobj_create\f[]() when the pool was first created. This can be used to verify that the layout of the pool matches what was expected. The application must have permission to open the file and memory map it with read/write permissions. .PP Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in \f[B]pmempool\-feature\f[](1). .PP The \f[B]pmemobj_close\f[]() function closes the memory pool indicated by \f[I]pop\f[] and deletes the memory pool handle. The object store itself lives on in the file that contains it and may be re\-opened at a later time using \f[B]pmemobj_open\f[]() as described above. .PP The \f[B]pmemobj_check\f[]() function performs a consistency check of the file indicated by \f[I]path\f[]. \f[B]pmemobj_check\f[]() opens the given \f[I]path\f[] read\-only so it never makes any changes to the file. This function is not supported on Device DAX. .PP The \f[B]pmemobj_set_user_data\f[]() function associates custom volatile state, represented by pointer \f[I]data\f[], with the given pool \f[I]pop\f[]. This state can later be retrieved using \f[B]pmemobj_get_user_data\f[]() function. This state does not survive pool close. If \f[B]pmemobj_set_user_data\f[]() was not called for a given pool, \f[B]pmemobj_get_user_data\f[]() will return NULL. .SH RETURN VALUE .PP The \f[B]pmemobj_create\f[]() function returns a memory pool handle to be used with most of the functions in \f[B]libpmemobj\f[](7). On error it returns NULL and sets \f[I]errno\f[] appropriately. .PP The \f[B]pmemobj_open\f[]() function returns a memory pool handle to be used with most of the functions in \f[B]libpmemobj\f[](7). If an error prevents the pool from being opened, or if the given \f[I]layout\f[] does not match the pool's layout, \f[B]pmemobj_open\f[]() returns NULL and sets \f[I]errno\f[] appropriately. .PP The \f[B]pmemobj_close\f[]() function returns no value. .PP The \f[B]pmemobj_check\f[]() function returns 1 if the memory pool is found to be consistent. Any inconsistencies found will cause \f[B]pmemobj_check\f[]() to return 0, in which case the use of the file with \f[B]libpmemobj\f[](7) will result in undefined behavior. The debug version of \f[B]libpmemobj\f[](7) will provide additional details on inconsistencies when \f[B]PMEMOBJ_LOG_LEVEL\f[] is at least 1, as described in the \f[B]DEBUGGING AND ERROR HANDLING\f[] section in \f[B]libpmemobj\f[](7). \f[B]pmemobj_check\f[]() returns \-1 and sets \f[I]errno\f[] if it cannot perform the consistency check due to other errors. .SH CAVEATS .PP Not all file systems support \f[B]posix_fallocate\f[](3). \f[B]pmemobj_create\f[]() will fail if the underlying file system does not support \f[B]posix_fallocate\f[](3). .SH SEE ALSO .PP \f[B]creat\f[](2), \f[B]msync\f[](2), \f[B]pmem_is_pmem\f[](3), \f[B]pmem_persist\f[](3), \f[B]posix_fallocate\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_log_snapshots_max_size.30000664000000000000000000000002714123364546023214 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_move_element_before.30000664000000000000000000000002514123364546022252 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/tx_alloc.30000664000000000000000000000002714123364546016013 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/tx_add_direct.30000664000000000000000000000003314123364546017000 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_memcpy.30000664000000000000000000000003514123364546017210 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_direct.30000664000000000000000000000002214123364546017164 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_set_failure_behavior.30000664000000000000000000000002714123364546022613 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/tx_add_field.30000664000000000000000000000003314123364546016611 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/oid_instanceof.30000664000000000000000000000002314123364546017166 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_stage.30000664000000000000000000000002714123364546017535 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_begin.30000664000000000000000000006410614123364733017524 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_TX_BEGIN" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2020, Intel Corporation .SH NAME .PP \f[B]pmemobj_tx_stage\f[](), .PP \f[B]pmemobj_tx_begin\f[](), \f[B]pmemobj_tx_lock\f[](), \f[B]pmemobj_tx_xlock\f[](), \f[B]pmemobj_tx_abort\f[](), \f[B]pmemobj_tx_commit\f[](), \f[B]pmemobj_tx_end\f[](), \f[B]pmemobj_tx_errno\f[](), \f[B]pmemobj_tx_process\f[](), .PP \f[B]TX_BEGIN_PARAM\f[](), \f[B]TX_BEGIN_CB\f[](), \f[B]TX_BEGIN\f[](), \f[B]TX_ONABORT\f[], \f[B]TX_ONCOMMIT\f[], \f[B]TX_FINALLY\f[], \f[B]TX_END\f[], .PP \f[B]pmemobj_tx_log_append_buffer\f[](), \f[B]pmemobj_tx_xlog_append_buffer\f[](), \f[B]pmemobj_tx_log_auto_alloc\f[](), \f[B]pmemobj_tx_log_snapshots_max_size\f[](), \f[B]pmemobj_tx_log_intents_max_size\f[](), .PP \f[B]pmemobj_tx_set_user_data\f[](), \f[B]pmemobj_tx_get_user_data\f[](), .PP \f[B]pmemobj_tx_set_failure_behavior\f[](), \f[B]pmemobj_tx_get_failure_behavior\f[]() \- transactional object manipulation .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ pobj_tx_stage\ pmemobj_tx_stage(void); int\ pmemobj_tx_begin(PMEMobjpool\ *pop,\ jmp_buf\ *env,\ enum\ pobj_tx_param,\ ...); int\ pmemobj_tx_lock(enum\ tx_lock\ lock_type,\ void\ *lockp); int\ pmemobj_tx_xlock(enum\ tx_lock\ lock_type,\ void\ *lockp,\ uint64_t\ flags); void\ pmemobj_tx_abort(int\ errnum); void\ pmemobj_tx_commit(void); int\ pmemobj_tx_end(void); int\ pmemobj_tx_errno(void); void\ pmemobj_tx_process(void); TX_BEGIN_PARAM(PMEMobjpool\ *pop,\ ...) TX_BEGIN_CB(PMEMobjpool\ *pop,\ cb,\ arg,\ ...) TX_BEGIN(PMEMobjpool\ *pop) TX_ONABORT TX_ONCOMMIT TX_FINALLY TX_END int\ pmemobj_tx_log_append_buffer(enum\ pobj_log_type\ type,\ void\ *addr,\ size_t\ size); int\ pmemobj_tx_xlog_append_buffer(enum\ pobj_log_type\ type,\ void\ *addr,\ size_t\ size,\ uint64_t\ flags); int\ pmemobj_tx_log_auto_alloc(enum\ pobj_log_type\ type,\ int\ on_off); size_t\ pmemobj_tx_log_snapshots_max_size(size_t\ *sizes,\ size_t\ nsizes); size_t\ pmemobj_tx_log_intents_max_size(size_t\ nintents); void\ pmemobj_tx_set_user_data(void\ *data); void\ *pmemobj_tx_get_user_data(void); void\ pmemobj_tx_set_failure_behavior(enum\ pobj_tx_failure_behavior\ behavior); enum\ pobj_tx_failure_behavior\ pmemobj_tx_get_failure_behavior(void); \f[] .fi .SH DESCRIPTION .PP The non\-transactional functions and macros described in \f[B]pmemobj_alloc\f[](3), \f[B]pmemobj_list_insert\f[](3) and \f[B]POBJ_LIST_HEAD\f[](3) only guarantee the atomicity of a single operation on an object. In case of more complex changes involving multiple operations on an object, or allocation and modification of multiple objects, data consistency and fail\-safety may be provided only by using \f[I]atomic transactions\f[]. .PP A transaction is defined as series of operations on persistent memory objects that either all occur, or nothing occurs. In particular, if the execution of a transaction is interrupted by a power failure or a system crash, it is guaranteed that after system restart, all the changes made as a part of the uncompleted transaction will be rolled back, restoring the consistent state of the memory pool from the moment when the transaction was started. .PP Note that transactions do not provide atomicity with respect to other threads. All the modifications performed within the transactions are immediately visible to other threads. Therefore it is the responsibility of the application to implement a proper thread synchronization mechanism. .PP Each thread may have only one transaction open at a time, but that transaction may be nested. Nested transactions are flattened. Committing the nested transaction does not commit the outer transaction; however, errors in the nested transaction are propagated up to the outermost level, resulting in the interruption of the entire transaction. .PP Each transaction is visible only for the thread that started it. No other threads can add operations, commit or abort the transaction initiated by another thread. Multiple threads may have transactions open on a given memory pool at the same time. .PP Please see the \f[B]CAVEATS\f[] section below for known limitations of the transactional API. .PP The \f[B]pmemobj_tx_stage\f[]() function returns the current \f[I]transaction stage\f[] for a thread. Stages are changed only by the \f[B]pmemobj_tx_*\f[]() functions. Transaction stages are defined as follows: .IP \[bu] 2 \f[B]TX_STAGE_NONE\f[] \- no open transaction in this thread .IP \[bu] 2 \f[B]TX_STAGE_WORK\f[] \- transaction in progress .IP \[bu] 2 \f[B]TX_STAGE_ONCOMMIT\f[] \- successfully committed .IP \[bu] 2 \f[B]TX_STAGE_ONABORT\f[] \- starting the transaction failed or transaction aborted .IP \[bu] 2 \f[B]TX_STAGE_FINALLY\f[] \- ready for clean up .PP The \f[B]pmemobj_tx_begin\f[]() function starts a new transaction in the current thread. If called within an open transaction, it starts a nested transaction. The caller may use the \f[I]env\f[] argument to provide a pointer to a calling environment to be restored in case of transaction abort. This information must be provided by the caller using the \f[B]setjmp\f[](3) macro. .PP A new transaction may be started only if the current stage is \f[B]TX_STAGE_NONE\f[] or \f[B]TX_STAGE_WORK\f[]. If successful, the \f[I]transaction stage\f[] changes to \f[B]TX_STAGE_WORK\f[]. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[]. .PP Optionally, a list of parameters for the transaction may be provided. Each parameter consists of a type followed by a type\-specific number of values. Currently there are 4 types: .IP \[bu] 2 \f[B]TX_PARAM_NONE\f[], used as a termination marker. No following value. .IP \[bu] 2 \f[B]TX_PARAM_MUTEX\f[], followed by one value, a pmem\-resident PMEMmutex .IP \[bu] 2 \f[B]TX_PARAM_RWLOCK\f[], followed by one value, a pmem\-resident PMEMrwlock .IP \[bu] 2 \f[B]TX_PARAM_CB\f[], followed by two values: a callback function of type \f[I]pmemobj_tx_callback\f[], and a void pointer .PP Using \f[B]TX_PARAM_MUTEX\f[] or \f[B]TX_PARAM_RWLOCK\f[] causes the specified lock to be acquired at the beginning of the transaction. \f[B]TX_PARAM_RWLOCK\f[] acquires the lock for writing. It is guaranteed that \f[B]pmemobj_tx_begin\f[]() will acquire all locks prior to successful completion, and they will be held by the current thread until the outermost transaction is finished. Locks are taken in order from left to right. To avoid deadlocks, the user is responsible for proper lock ordering. .PP \f[B]TX_PARAM_CB\f[] registers the specified callback function to be executed at each transaction stage. For \f[B]TX_STAGE_WORK\f[], the callback is executed prior to commit. For all other stages, the callback is executed as the first operation after a stage change. It will also be called after each transaction; in this case the \f[I]stage\f[] parameter will be set to \f[B]TX_STAGE_NONE\f[]. \f[I]pmemobj_tx_callback\f[] must be compatible with: .IP .nf \f[C] void\ func(PMEMobjpool\ *pop,\ enum\ pobj_tx_stage\ stage,\ void\ *arg) \f[] .fi .PP \f[I]pop\f[] is a pool identifier used in \f[B]pmemobj_tx_begin\f[](), \f[I]stage\f[] is a current transaction stage and \f[I]arg\f[] is the second parameter of \f[B]TX_PARAM_CB\f[]. Without considering transaction nesting, this mechanism can be considered an alternative method for executing code between stages (instead of \f[B]TX_ONCOMMIT\f[], \f[B]TX_ONABORT\f[], etc). However, there are 2 significant differences when nested transactions are used: .IP \[bu] 2 The registered function is executed only in the outermost transaction, even if registered in an inner transaction. .IP \[bu] 2 There can be only one callback in the entire transaction, that is, the callback cannot be changed in an inner transaction. .PP Note that \f[B]TX_PARAM_CB\f[] does not replace the \f[B]TX_ONCOMMIT\f[], \f[B]TX_ONABORT\f[], etc. macros. They can be used together: the callback will be executed \f[I]before\f[] a \f[B]TX_ONCOMMIT\f[], \f[B]TX_ONABORT\f[], etc. section. .PP \f[B]TX_PARAM_CB\f[] can be used when the code dealing with transaction stage changes is shared between multiple users or when it must be executed only in the outer transaction. For example it can be very useful when the application must synchronize persistent and transient state. .PP The \f[B]pmemobj_tx_lock\f[]() function acquires the lock \f[I]lockp\f[] of type \f[I]lock_type\f[] and adds it to the current transaction. \f[I]lock_type\f[] may be \f[B]TX_LOCK_MUTEX\f[] or \f[B]TX_LOCK_RWLOCK\f[]; \f[I]lockp\f[] must be of type \f[I]PMEMmutex\f[] or \f[I]PMEMrwlock\f[], respectively. If \f[I]lock_type\f[] is \f[B]TX_LOCK_RWLOCK\f[] the lock is acquired for writing. If the lock is not successfully acquired, the function returns an error number. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xlock\f[]() function behaves exactly the same as \f[B]pmemobj_tx_lock\f[]() when \f[I]flags\f[] equals \f[B]POBJ_XLOCK_NO_ABORT\f[]. When \f[I]flags\f[] equals 0 and if the lock is not successfully acquired,the transaction is aborted. \f[I]flags\f[] is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XLOCK_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP \f[B]pmemobj_tx_abort\f[]() aborts the current transaction and causes a transition to \f[B]TX_STAGE_ONABORT\f[]. If \f[I]errnum\f[] is equal to 0, the transaction error code is set to \f[B]ECANCELED\f[]; otherwise, it is set to \f[I]errnum\f[]. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_commit\f[]() function commits the current open transaction and causes a transition to \f[B]TX_STAGE_ONCOMMIT\f[]. If called in the context of the outermost transaction, all the changes may be considered as durably written upon successful completion. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_end\f[]() function performs a cleanup of the current transaction. If called in the context of the outermost transaction, it releases all the locks acquired by \f[B]pmemobj_tx_begin\f[]() for outer and nested transactions. If called in the context of a nested transaction, it returns to the context of the outer transaction in \f[B]TX_STAGE_WORK\f[], without releasing any locks. The \f[B]pmemobj_tx_end\f[]() function can be called during \f[B]TX_STAGE_NONE\f[] if transitioned to this stage using \f[B]pmemobj_tx_process\f[](). If not already in \f[B]TX_STAGE_NONE\f[], it causes the transition to \f[B]TX_STAGE_NONE\f[]. \f[B]pmemobj_tx_end\f[] must always be called for each \f[B]pmemobj_tx_begin\f[](), even if starting the transaction failed. This function must \f[I]not\f[] be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_errno\f[]() function returns the error code of the last transaction. .PP The \f[B]pmemobj_tx_process\f[]() function performs the actions associated with the current stage of the transaction, and makes the transition to the next stage. It must be called in a transaction. The current stage must always be obtained by a call to \f[B]pmemobj_tx_stage\f[](). \f[B]pmemobj_tx_process\f[]() performs the following transitions in the transaction stage flow: .IP \[bu] 2 \f[B]TX_STAGE_WORK\f[] \-> \f[B]TX_STAGE_ONCOMMIT\f[] .IP \[bu] 2 \f[B]TX_STAGE_ONABORT\f[] \-> \f[B]TX_STAGE_FINALLY\f[] .IP \[bu] 2 \f[B]TX_STAGE_ONCOMMIT\f[] \-> \f[B]TX_STAGE_FINALLY\f[] .IP \[bu] 2 \f[B]TX_STAGE_FINALLY\f[] \-> \f[B]TX_STAGE_NONE\f[] .IP \[bu] 2 \f[B]TX_STAGE_NONE\f[] \-> \f[B]TX_STAGE_NONE\f[] .PP \f[B]pmemobj_tx_process\f[]() must not be called after calling \f[B]pmemobj_tx_end\f[]() for the outermost transaction. .PP In addition to the above API, \f[B]libpmemobj\f[](7) offers a more intuitive method of building transactions using the set of macros described below. When using these macros, the complete transaction flow looks like this: .IP .nf \f[C] TX_BEGIN(Pop)\ { \ \ \ \ /*\ the\ actual\ transaction\ code\ goes\ here...\ */ }\ TX_ONCOMMIT\ { \ \ \ \ /* \ \ \ \ \ *\ optional\ \-\ executed\ only\ if\ the\ above\ block \ \ \ \ \ *\ successfully\ completes \ \ \ \ \ */ }\ TX_ONABORT\ { \ \ \ \ /* \ \ \ \ \ *\ optional\ \-\ executed\ only\ if\ starting\ the\ transaction\ fails, \ \ \ \ \ *\ or\ if\ transaction\ is\ aborted\ by\ an\ error\ or\ a\ call\ to \ \ \ \ \ *\ pmemobj_tx_abort() \ \ \ \ \ */ }\ TX_FINALLY\ { \ \ \ \ /* \ \ \ \ \ *\ optional\ \-\ if\ exists,\ it\ is\ executed\ after \ \ \ \ \ *\ TX_ONCOMMIT\ or\ TX_ONABORT\ block \ \ \ \ \ */ }\ TX_END\ /*\ mandatory\ */ \f[] .fi .IP .nf \f[C] TX_BEGIN_PARAM(PMEMobjpool\ *pop,\ ...) TX_BEGIN_CB(PMEMobjpool\ *pop,\ cb,\ arg,\ ...) TX_BEGIN(PMEMobjpool\ *pop) \f[] .fi .PP The \f[B]TX_BEGIN_PARAM\f[](), \f[B]TX_BEGIN_CB\f[]() and \f[B]TX_BEGIN\f[]() macros start a new transaction in the same way as \f[B]pmemobj_tx_begin\f[](), except that instead of the environment buffer provided by a caller, they set up the local \f[I]jmp_buf\f[] buffer and use it to catch the transaction abort. The \f[B]TX_BEGIN\f[]() macro starts a transaction without any options. \f[B]TX_BEGIN_PARAM\f[] may be used when there is a need to acquire locks prior to starting a transaction (such as for a multi\-threaded program) or set up a transaction stage callback. \f[B]TX_BEGIN_CB\f[] is just a wrapper around \f[B]TX_BEGIN_PARAM\f[] that validates the callback signature. (For compatibility there is also a \f[B]TX_BEGIN_LOCK\f[] macro, which is an alias for \f[B]TX_BEGIN_PARAM\f[]). Each of these macros must be followed by a block of code with all the operations that are to be performed atomically. .PP The \f[B]TX_ONABORT\f[] macro starts a block of code that will be executed only if starting the transaction fails due to an error in \f[B]pmemobj_tx_begin\f[](), or if the transaction is aborted. This block is optional, but in practice it should not be omitted. If it is desirable to crash the application when a transaction aborts and there is no \f[B]TX_ONABORT\f[] section, the application can define the \f[B]POBJ_TX_CRASH_ON_NO_ONABORT\f[] macro before inclusion of \f[B]\f[]. This provides a default \f[B]TX_ONABORT\f[] section which just calls \f[B]abort\f[](3). .PP The \f[B]TX_ONCOMMIT\f[] macro starts a block of code that will be executed only if the transaction is successfully committed, which means that the execution of code in the \f[B]TX_BEGIN\f[]() block has not been interrupted by an error or by a call to \f[B]pmemobj_tx_abort\f[](). This block is optional. .PP The \f[B]TX_FINALLY\f[] macro starts a block of code that will be executed regardless of whether the transaction is committed or aborted. This block is optional. .PP The \f[B]TX_END\f[] macro cleans up and closes the transaction started by the \f[B]TX_BEGIN\f[]() / \f[B]TX_BEGIN_PARAM\f[]() / \f[B]TX_BEGIN_CB\f[]() macros. It is mandatory to terminate each transaction with this macro. If the transaction was aborted, \f[I]errno\f[] is set appropriately. .SS TRANSACTION LOG TUNING .PP From libpmemobj implementation perspective there are two types of operations in a transaction: .IP \[bu] 2 \f[B]snapshots\f[], where action must be persisted immediately, .IP \[bu] 2 \f[B]intents\f[], where action can be persisted at the transaction commit phase .PP \f[B]pmemobj_tx_add_range\f[](3) and all its variants belong to the \f[B]snapshots\f[] group. .PP \f[B]pmemobj_tx_alloc\f[](3) (with its variants), \f[B]pmemobj_tx_free\f[](3), \f[B]pmemobj_tx_realloc\f[](3) (with its variants) and \f[B]pmemobj_tx_publish\f[](3) belong to the \f[B]intents\f[] group. Even though \f[B]pmemobj_tx_alloc\f[]() allocates memory immediately, it modifies only the runtime state and postpones persistent memory modifications to the commit phase. \f[B]pmemobj_tx_free\f[](3) cannot free the object immediately, because of possible transaction rollback, so it postpones both the action and persistent memory modifications to the commit phase. \f[B]pmemobj_tx_realloc\f[](3) is just a combination of those two. \f[B]pmemobj_tx_publish\f[](3) postpones reservations and deferred frees to the commit phase. .PP Those two types of operations (snapshots and intents) require that libpmemobj builds a persistent log of operations. Intent log (also known as a \[lq]redo log\[rq]) is applied on commit and snapshot log (also known as an \[lq]undo log\[rq]) is applied on abort. .PP When libpmemobj transaction starts, it's not possible to predict how much persistent memory space will be needed for those logs. This means that libpmemobj must internally allocate this space whenever it's needed. This has two downsides: .IP \[bu] 2 when transaction snapshots a lot of memory or does a lot of allocations, libpmemobj may need to do many internal allocations, which must be freed when transaction ends, adding time overhead when big transactions are frequent, .IP \[bu] 2 transactions can start to fail due to not enough space for logs \- this can be especially problematic for transactions that want to \f[B]deallocate\f[] objects, as those might also fail .PP To solve both of these problems libpmemobj exposes the following functions: .IP \[bu] 2 \f[B]pmemobj_tx_log_append_buffer\f[](), .IP \[bu] 2 \f[B]pmemobj_tx_xlog_append_buffer\f[](), .IP \[bu] 2 \f[B]pmemobj_tx_log_auto_alloc\f[]() .PP \f[B]pmemobj_tx_log_append_buffer\f[]() appends a given range of memory [\f[I]addr\f[], \f[I]addr\f[] + \f[I]size\f[]) to the log \f[I]type\f[] of the current transaction. \f[I]type\f[] can be one of the two values (with meanings described above): .IP \[bu] 2 \f[B]TX_LOG_TYPE_SNAPSHOT\f[], .IP \[bu] 2 \f[B]TX_LOG_TYPE_INTENT\f[] .PP The range of memory \f[B]must\f[] belong to the same pool the transaction is on and \f[B]must not\f[] be used by more than one thread at the same time. The latter condition can be verified with tx.debug.verify_user_buffers ctl (see \f[B]pmemobj_ctl_get\f[](3)). .PP The \f[B]pmemobj_tx_xlog_append_buffer\f[]() function behaves exactly the same as \f[B]pmemobj_tx_log_append_buffer\f[]() when \f[I]flags\f[] equals zero. \f[I]flags\f[] is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XLOG_APPEND_BUFFER_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP \f[B]pmemobj_tx_log_snapshots_max_size\f[] calculates the \f[B]maximum\f[] size of a buffer which will be able to hold \f[I]nsizes\f[] snapshots, each of size \f[I]sizes[i]\f[]. Application should not expect this function to return the same value between restarts. In future versions of libpmemobj this function can return smaller (because of better accuracy or space optimizations) or higher (because of higher alignment required for better performance) value. This function is independent of transaction stage and can be called both inside and outside of transaction. If the returned value S is greater than \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[], the buffer should be split into N chunks of size \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[], where N is equal to (S / \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[]) (rounded down) and the last chunk of size (S \- (N * \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[])). .PP \f[B]pmemobj_tx_log_intents_max_size\f[] calculates the \f[B]maximum\f[] size of a buffer which will be able to hold \f[I]nintents\f[] intents. Just like with \f[B]pmemobj_tx_log_snapshots_max_size\f[], application should not expect this function to return the same value between restarts, for the same reasons. This function is independent of transaction stage and can be called both inside and outside of transaction. .PP \f[B]pmemobj_tx_log_auto_alloc\f[]() disables (\f[I]on_off\f[] set to 0) or enables (\f[I]on_off\f[] set to 1) automatic allocation of internal logs of given \f[I]type\f[]. It can be used to verify that the buffer set with \f[B]pmemobj_tx_log_append_buffer\f[]() is big enough to hold the log, without reaching out\-of\-space scenario. .PP The \f[B]pmemobj_tx_set_user_data\f[]() function associates custom volatile state, represented by pointer \f[I]data\f[], with the current transaction. This state can later be retrieved using \f[B]pmemobj_tx_get_user_data\f[]() function. If \f[B]pmemobj_tx_set_user_data\f[]() was not called for a current transaction, \f[B]pmemobj_tx_get_user_data\f[]() will return NULL. These functions must be called during \f[B]TX_STAGE_WORK\f[] or \f[B]TX_STAGE_ONABORT\f[] or \f[B]TX_STAGE_ONCOMMIT\f[] or \f[B]TX_STAGE_FINALLY\f[]. .PP \f[B]pmemobj_tx_set_failure_behavior\f[]() specifies what should happen in case of an error within the transaction. It only affects functions which take a NO_ABORT flag. If \f[B]pmemobj_tx_set_failure_behavior\f[]() is called with POBJ_TX_FAILURE_RETURN a NO_ABORT flag is implicitly passed to all functions which accept this flag. If called with POBJ_TX_FAILURE_ABORT then all functions abort the transaction (unless NO_ABORT flag is passed explicitly). This setting is inherited by inner transactions. It does not affect any of the outer transactions. Aborting on failure is the default behavior. \f[B]pmemobj_tx_get_failure_behavior\f[]() returns failure behavior for the current transaction. Both \f[B]pmemobj_tx_set_failure_behavior\f[]() and \f[B]pmemobj_tx_get_failure_behavior\f[]() must be called during \f[B]TX_STAGE_WORK\f[]. .SH RETURN VALUE .PP The \f[B]pmemobj_tx_stage\f[]() function returns the stage of the current transaction stage for a thread. .PP On success, \f[B]pmemobj_tx_begin\f[]() returns 0. Otherwise, an error number is returned. .PP The \f[B]pmemobj_tx_begin\f[]() and \f[B]pmemobj_tx_lock\f[]() functions return zero if \f[I]lockp\f[] is successfully added to the transaction. Otherwise, an error number is returned. .PP The \f[B]pmemobj_tx_xlock\f[]() function return zero if \f[I]lockp\f[] is successfully added to the transaction. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XLOCK_NO_ABORT\f[], the transaction is aborted. .PP The \f[B]pmemobj_tx_abort\f[]() and \f[B]pmemobj_tx_commit\f[]() functions return no value. .PP The \f[B]pmemobj_tx_end\f[]() function returns 0 if the transaction was successful. Otherwise it returns the error code set by \f[B]pmemobj_tx_abort\f[](). Note that \f[B]pmemobj_tx_abort\f[]() can be called internally by the library. .PP The \f[B]pmemobj_tx_errno\f[]() function returns the error code of the last transaction. .PP The \f[B]pmemobj_tx_process\f[]() function returns no value. .PP On success, \f[B]pmemobj_tx_log_append_buffer\f[]() returns 0. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]errno\f[] is set appropriately and transaction is aborted. .PP On success, \f[B]pmemobj_tx_xlog_append_buffer\f[]() returns 0. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XLOG_NO_ABORT\f[], the transaction is aborted. .PP On success, \f[B]pmemobj_tx_log_auto_alloc\f[]() returns 0. Otherwise, the transaction is aborted and an error number is returned. .PP On success, \f[B]pmemobj_tx_log_snapshots_max_size\f[]() returns size of the buffer. On failure it returns \f[I]SIZE_MAX\f[] and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]pmemobj_tx_log_intents_max_size\f[]() returns size of the buffer. On failure it returns \f[I]SIZE_MAX\f[] and sets \f[I]errno\f[] appropriately. .SH CAVEATS .PP Transaction flow control is governed by the \f[B]setjmp\f[](3) and \f[B]longjmp\f[](3) macros, and they are used in both the macro and function flavors of the API. The transaction will longjmp on transaction abort. This has one major drawback, which is described in the ISO C standard subsection 7.13.2.1. It says that \f[B]the values of objects of automatic storage duration that are local to the function containing the setjmp invocation that do not have volatile\-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.\f[] .PP The following example illustrates the issue described above. .IP .nf \f[C] int\ *bad_example_1\ =\ (int\ *)0xBAADF00D; int\ *bad_example_2\ =\ (int\ *)0xBAADF00D; int\ *bad_example_3\ =\ (int\ *)0xBAADF00D; int\ *\ volatile\ good_example\ =\ (int\ *)0xBAADF00D; TX_BEGIN(pop)\ { \ \ \ \ bad_example_1\ =\ malloc(sizeof(int)); \ \ \ \ bad_example_2\ =\ malloc(sizeof(int)); \ \ \ \ bad_example_3\ =\ malloc(sizeof(int)); \ \ \ \ good_example\ =\ malloc(sizeof(int)); \ \ \ \ /*\ manual\ or\ library\ abort\ called\ here\ */ \ \ \ \ pmemobj_tx_abort(EINVAL); }\ TX_ONCOMMIT\ { \ \ \ \ /* \ \ \ \ \ *\ This\ section\ is\ longjmp\-safe \ \ \ \ \ */ }\ TX_ONABORT\ { \ \ \ \ /* \ \ \ \ \ *\ This\ section\ is\ not\ longjmp\-safe \ \ \ \ \ */ \ \ \ \ free(good_example);\ /*\ OK\ */ \ \ \ \ free(bad_example_1);\ /*\ undefined\ behavior\ */ }\ TX_FINALLY\ { \ \ \ \ /* \ \ \ \ \ *\ This\ section\ is\ not\ longjmp\-safe\ on\ transaction\ abort\ only \ \ \ \ \ */ \ \ \ \ free(bad_example_2);\ /*\ undefined\ behavior\ */ }\ TX_END free(bad_example_3);\ /*\ undefined\ behavior\ */ \f[] .fi .PP Objects which are not volatile\-qualified, are of automatic storage duration and have been changed between the invocations of \f[B]setjmp\f[](3) and \f[B]longjmp\f[](3) (that also means within the work section of the transaction after \f[B]TX_BEGIN\f[]()) should not be used after a transaction abort, or should be used with utmost care. This also includes code after the \f[B]TX_END\f[] macro. .PP \f[B]libpmemobj\f[](7) is not cancellation\-safe. The pool will never be corrupted because of a canceled thread, but other threads may stall waiting on locks taken by that thread. If the application wants to use \f[B]pthread_cancel\f[](3), it must disable cancellation before calling any \f[B]libpmemobj\f[](7) APIs (see \f[B]pthread_setcancelstate\f[](3) with \f[B]PTHREAD_CANCEL_DISABLE\f[]), and re\-enable it afterwards. Deferring cancellation (\f[B]pthread_setcanceltype\f[](3) with \f[B]PTHREAD_CANCEL_DEFERRED\f[]) is not safe enough, because \f[B]libpmemobj\f[](7) internally may call functions that are specified as cancellation points in POSIX. .PP \f[B]libpmemobj\f[](7) relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .SH SEE ALSO .PP \f[B]dlclose\f[](3), \f[B]longjmp\f[](3), \f[B]pmemobj_tx_add_range\f[](3), \f[B]pmemobj_tx_alloc\f[](3), \f[B]pthread_setcancelstate\f[](3), \f[B]pthread_setcanceltype\f[](3), \f[B]setjmp\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_wb.30000664000000000000000000000003514123364546017471 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/tx_begin_param.30000664000000000000000000000002714123364546017165 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_alloc.3.md0000664000000000000000000003440414123364546017416 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_ALLOC, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2017-2020, Intel Corporation) [comment]: <> (pmemobj_alloc.3 -- man page for non-transactional atomic allocations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_alloc**(), **pmemobj_xalloc**(), **pmemobj_zalloc**(), **pmemobj_realloc**(), **pmemobj_zrealloc**(), **pmemobj_strdup**(), **pmemobj_wcsdup**(), **pmemobj_alloc_usable_size**(), **pmemobj_defrag**(), **POBJ_NEW**(), **POBJ_ALLOC**(), **POBJ_ZNEW**(), **POBJ_ZALLOC**(), **POBJ_REALLOC**(), **POBJ_ZREALLOC**(), **POBJ_FREE**() - non-transactional atomic allocations # SYNOPSIS # ```c #include typedef int (*pmemobj_constr)(**PMEMobjpool *pop, void *ptr, void *arg); int pmemobj_alloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, uint64_t type_num, pmemobj_constr constructor, void *arg); int pmemobj_xalloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, uint64_t type_num, uint64_t flags, pmemobj_constr constructor, void *arg); (EXPERIMENTAL) int pmemobj_zalloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, uint64_t type_num); void pmemobj_free(PMEMoid *oidp); int pmemobj_realloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, uint64_t type_num); int pmemobj_zrealloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, uint64_t type_num); int pmemobj_strdup(PMEMobjpool *pop, PMEMoid *oidp, const char *s, uint64_t type_num); int pmemobj_wcsdup(PMEMobjpool *pop, PMEMoid *oidp, const wchar_t *s, uint64_t type_num); size_t pmemobj_alloc_usable_size(PMEMoid oid); int pmemobj_defrag(PMEMobjpool *pop, PMEMoid **oidv, size_t oidcnt, struct pobj_defrag_result *result); POBJ_NEW(PMEMobjpool *pop, TOID *oidp, TYPE, pmemobj_constr constructor, void *arg) POBJ_ALLOC(PMEMobjpool *pop, TOID *oidp, TYPE, size_t size, pmemobj_constr constructor, void *arg) POBJ_ZNEW(PMEMobjpool *pop, TOID *oidp, TYPE) POBJ_ZALLOC(PMEMobjpool *pop, TOID *oidp, TYPE, size_t size) POBJ_REALLOC(PMEMobjpool *pop, TOID *oidp, TYPE, size_t size) POBJ_ZREALLOC(PMEMobjpool *pop, TOID *oidp, TYPE, size_t size) POBJ_FREE(TOID *oidp) ``` # DESCRIPTION # Functions described in this document provide the mechanism to allocate, resize and free objects from the persistent memory pool in a thread-safe and fail-safe manner. All the routines are atomic with respect to other threads and any power-fail interruptions. If any of these operations is torn by program failure or system crash, on recovery they are guaranteed to be entirely completed or discarded, leaving the persistent memory heap and internal object containers in a consistent state. All these functions should be used outside transactions. If executed within an open transaction they are considered durable immediately after completion. Changes made with these functions will not be rolled back if the transaction is aborted or interrupted. They have no information about other changes made by transactional API, so if the same data is modified in a single transaction using transactional and then non-transactional API, transaction abort will likely corrupt the data. The allocations are always aligned to a cache-line boundary. The *pmemobj_constr* type represents a constructor for atomic allocation from the persistent memory heap associated with memory pool *pop*. *ptr* is a pointer to the allocated memory area and *arg* is a user-defined argument passed to the constructor. The **pmemobj_alloc**() function allocates a new object from the persistent memory heap associated with memory pool *pop*. The *PMEMoid* of the allocated object is stored in *oidp*. If *oidp* is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with the type number *type_num*, as described in **POBJ_FOREACH**(3). If *oidp* points to a memory location from the **pmemobj** heap, *oidp* is modified atomically. Before returning, **pmemobj_alloc**() calls the *constructor* function, passing the pool handle *pop*, the pointer to the newly allocated object in *ptr*, and the *arg* argument. It is guaranteed that the allocated object is either properly initialized, or if the allocation is interrupted before the constructor completes, the memory space reserved for the object is reclaimed. *size* can be any non-zero value; however, due to internal padding and object metadata, the actual size of the allocation will differ from the requested size by at least 64 bytes. For this reason, making allocations of a size less than 64 bytes is extremely inefficient and discouraged. The allocated object is added to the internal container associated with *type_num*. **pmemobj_xalloc**() is equivalent to **pmemobj_alloc**(), but with an additional *flags* argument that is a bitmask of the following values: + **POBJ_XALLOC_ZERO** - zero the allocated object (equivalent of **pmemobj_zalloc**()) + **POBJ_CLASS_ID(class_id)** - allocate an object from the allocation class *class_id*. The class id cannot be 0. + **POBJ_ARENA_ID(arena_id)** - allocate an object from the arena specified by *arena_id*. The arena must exist, otherwise, the behavior is undefined. If *arena_id* is equal 0, then arena assigned to the current thread will be used. The **pmemobj_zalloc**() function allocates a new zeroed object from the persistent memory heap associated with memory pool *pop*. The *PMEMoid* of the allocated object is stored in *oidp*. If *oidp* is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with the type number *type_num*, as described in **POBJ_FOREACH**(3). If *oidp* points to a memory location from the **pmemobj** heap, *oidp* is modified atomically. *size* can be any non-zero value; however, due to internal padding and object metadata, the actual size of the allocation will differ from the requested one by at least 64 bytes. For this reason, making allocations of a size less than 64 bytes is extremely inefficient and discouraged. The allocated object is added to the internal container associated with *type_num*. The **pmemobj_free**() function frees the memory space represented by *oidp*, which must have been allocated by a previous call to **pmemobj_alloc**(), **pmemobj_xalloc**(), **pmemobj_zalloc**(), **pmemobj_realloc**(), or **pmemobj_zrealloc**(). **pmemobj_free**() provides the same semantics as **free**(3), but instead of operating on the process heap supplied by the system, it operates on the persistent memory heap. If *oidp* is **OID_NULL**, no operation is performed. If *oidp* is NULL or if it points to the root object's *OID*, the behavior of **pmemobj_free**() is undefined. *oidp* is set to **OID_NULL** after the memory is freed. If *oidp* points to a memory location from the **pmemobj** heap, *oidp* is modified atomically. The **pmemobj_realloc**() function changes the size of the object represented by *oidp* to *size* bytes. **pmemobj_realloc**() provides similar semantics to **realloc**(3), but operates on the persistent memory heap associated with memory pool *pop*. The resized object is also added or moved to the internal container associated with type number *type_num*. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will *not* be initialized. If *oidp* is *OID_NULL*, then the call is equivalent to *pmemobj_alloc(pop, size, type_num)*. If *size* is equal to zero, and *oidp* is not **OID_NULL**, then the call is equivalent to *pmemobj_free(oid)*. Unless *oidp* is **OID_NULL**, it must have been allocated by an earlier call to **pmemobj_alloc**(), **pmemobj_xalloc**(), **pmemobj_zalloc**(), **pmemobj_realloc**(), or **pmemobj_zrealloc**(). Note that the object handle value may change as a result of reallocation. If the object was moved, the memory space represented by *oid* is reclaimed. If *oidp* points to a memory location from the **pmemobj** heap, *oidp* is modified atomically. If *oidp* is NULL or if it points to the root object's *OID*, the behavior of **pmemobj_realloc**() is undefined. **pmemobj_zrealloc**() is equivalent to **pmemobj_realloc**(), except that if the new size is larger than the old size, the added memory will be zeroed. The **pmemobj_strdup**() function stores a handle to a new object in *oidp* which is a duplicate of the string *s*. **pmemobj_strdup**() provides the same semantics as **strdup**(3), but operates on the persistent memory heap associated with memory pool *pop*. If *oidp* is NULL, then the newly allocated object may be accessed only by iterating objects in the object container associated with type number *type_num*, as described in **POBJ_FOREACH**(3). If *oidp* points to a memory location from the **pmemobj** heap, *oidp* is modified atomically. The allocated string object is also added to the internal container associated with type number *type_num*. Memory for the new string is obtained with **pmemobj_alloc**(), on the given memory pool, and can be freed with **pmemobj_free**() on the same memory pool. **pmemobj_wcsdup**() is equivalent to **pmemobj_strdup**(), but operates on a wide character string (wchar_t) rather than a standard character string. The **pmemobj_alloc_usable_size**() function provides the same semantics as **malloc_usable_size**(3), but instead of the process heap supplied by the system, it operates on the persistent memory heap. The **POBJ_NEW**() macro is a wrapper around the **pmemobj_alloc**() function. Instead of taking a pointer to *PMEMoid*, it takes a pointer to the typed *OID* of type name *TYPE*, and passes the size and type number from the typed *OID* to **pmemobj_alloc**(). The **POBJ_ALLOC**() macro is equivalent to **POBJ_NEW**, except that instead of using the size of the typed *OID*, passes *size* to **pmemobj_alloc**(). The **POBJ_ZNEW**() macro is a wrapper around the **pmemobj_zalloc**() function. Instead of taking a pointer to *PMEMoid*, it takes a pointer to the typed *OID* of type name *TYPE*, and passes the size and type number from the typed *OID* to **pmemobj_zalloc**(). The **POBJ_ZALLOC**() macro is equivalent to **POBJ_ZNEW**, except that instead of using the size of the typed *OID*, passes *size* to **pmemobj_zalloc**(). The **POBJ_REALLOC**() macro is a wrapper around the **pmemobj_realloc**() function. Instead of taking a pointer to *PMEMoid*, it takes a pointer to the typed *OID* of type name *TYPE*, and passes the type number from the typed *OID* to **pmemobj_realloc**(). The **POBJ_ZREALLOC**() macro is a wrapper around the **pmemobj_zrealloc**() function. Instead of taking a pointer to *PMEMoid*, it takes a pointer to the typed *OID* of type name *TYPE*, and passes the type number from the typed *OID* to **pmemobj_zrealloc**(). The **POBJ_FREE**() macro is a wrapper around the **pmemobj_free**() function which takes a pointer to the typed *OID* instead of to *PMEMoid*. The **pmemobj_defrag**() function performs defragmentation on the objects provided through the array of pointers to PMEMoids *oidv* with size *oidcnt*. If an object from the provided array is selected to be moved to a new location in the heap, it is reallocated and all provided pointers to that object are atomically updated. To maintain data structure consistency, applications should always provide all pointers for an object to **pmemobj_defrag** method. This ensures that, even in the presence of failures, all pointers to the object will either point to the old or a new location. All objects and pointers to objects should belong to the pool *pop* or, in case of pointers, can also reside in volatile memory. Defragmentation across pools is not supported. Objects in the array that are *OID_NULL* are skipped over and no operation is performed on them. All other objects must have been allocated by an earlier call to **pmemobj_alloc**(), **pmemobj_xalloc**(), **pmemobj_zalloc**(), **pmemobj_realloc**(), **pmemobj_zrealloc**(), **pmemobj_strdup**() or **pmemobj_wcsdup**(). The *result* variable is an instance of *struct pobj_defrag_result* and, if not NULL, can be used to read *total*, the number of objects found that were processed, and *relocated*, the number of objects that were relocated during defragmentation. These variables are always initialized and can be non-zero, even if the return value of **pmemobj_defrag**() indicated a failure. This is because the failure might have occurred after some objects were already processed. # RETURN VALUE # On success, **pmemobj_alloc**() and **pmemobj_xalloc** return 0. If *oidp* is not NULL, the *PMEMoid* of the newly allocated object is stored in *oidp*. If the allocation fails, -1 is returned and *errno* is set appropriately. If the constructor returns a non-zero value, the allocation is canceled, -1 is returned, and *errno* is set to **ECANCELED**. If *size* equals 0, or the *flags* for **pmemobj_xalloc** are invalid, -1 is returned, *errno* is set to **EINVAL**, and *oidp* is left untouched. On success, **pmemobj_zalloc**() returns 0. If *oidp* is not NULL, the *PMEMoid* of the newly allocated object is stored in *oidp*. If the allocation fails, it returns -1 and sets *errno* appropriately. If *size* equals 0, it returns -1, sets *errno* to **EINVAL**, and leaves *oidp* untouched. The **pmemobj_free**() function returns no value. On success, **pmemobj_realloc**() and **pmemobj_zrealloc**() return 0 and update *oidp* if necessary. On error, they return -1 and set *errno* appropriately. On success, **pmemobj_strdup**() and **pmemobj_wcsdup**() return 0. If *oidp* is not NULL, the *PMEMoid* of the duplicated string object is stored in *oidp*. If *s* is NULL, they return -1, set *errno* to **EINVAL**, and leave *oidp* untouched. On other errors, they return -1 and set *errno* appropriately. The **pmemobj_alloc_usable_size**() function returns the number of usable bytes in the object represented by *oid*. If *oid* is **OID_NULL**, it returns 0. On success, **pmemobj_defrag**() returns 0. If defragmentation was unsuccessful or only partially successful (i.e. if it was aborted halfway through due to lack of resources), -1 is returned. # SEE ALSO # **free**(3), **POBJ_FOREACH**(3), **realloc**(3), **strdup**(3), **wcsdup**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pobj_list_last.30000664000000000000000000000002514123364546017214 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_xflush.30000664000000000000000000000003514123364546017227 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_new_after.30000664000000000000000000000002514123364546021607 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xfree.30000664000000000000000000000002714123364546017543 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_cond_timedwait.30000664000000000000000000000003114123364546020704 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_timedwrlock.30000664000000000000000000000003114123364546021617 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_next.30000664000000000000000000000002514123364546017227 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_cond_wait.30000664000000000000000000000003114123364546017661 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_begin.30000664000000000000000000000630414123364733017703 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "POBJ_LAYOUT_BEGIN" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]POBJ_LAYOUT_BEGIN\f[](), \f[B]POBJ_LAYOUT_TOID\f[](), \f[B]POBJ_LAYOUT_ROOT\f[](), \f[B]POBJ_LAYOUT_NAME\f[](), \f[B]POBJ_LAYOUT_END\f[](), \f[B]POBJ_LAYOUT_TYPES_NUM\f[]() \- persistent memory transactional object store layout .SH SYNOPSIS .IP .nf \f[C] #include\ POBJ_LAYOUT_BEGIN(layout) POBJ_LAYOUT_TOID(layout,\ TYPE) POBJ_LAYOUT_ROOT(layout,\ ROOT_TYPE) POBJ_LAYOUT_NAME(layout) POBJ_LAYOUT_END(layout) POBJ_LAYOUT_TYPES_NUM(layout) \f[] .fi .SH DESCRIPTION .PP \f[B]libpmemobj\f[](7) defines a set of macros for convenient declaration of a pool's layout. The layout declaration consists of declarations of a number of used types. The declared types will be assigned consecutive type numbers. Declared types may be used in conjunction with type safety macros (see \f[B]TOID_DECLARE\f[](3)). Once created, the layout declaration must not be changed unless any new types are added at the end of the existing layout declaration. Modifying any existing declaration may lead to changes in the type numbers of declared types, which in consequence may cause data corruption. .PP The \f[B]POBJ_LAYOUT_BEGIN\f[]() macro indicates a begin of declaration of layout. The \f[I]LAYOUT\f[] argument is a name of layout. This argument must be passed to all macros related to the declaration of layout. .PP The \f[B]POBJ_LAYOUT_TOID\f[]() macro declares a typed \f[I]OID\f[] for type passed as \f[I]TYPE\f[] argument inside the declaration of layout. All types declared using this macro are assigned with consecutive type numbers. This macro must be used between the \f[B]POBJ_LAYOUT_BEGIN\f[]() and \f[B]POBJ_LAYOUT_END\f[]() macros, with the same name passed as \f[I]LAYOUT\f[] argument. .PP The \f[B]POBJ_LAYOUT_ROOT\f[]() macro declares a typed \f[I]OID\f[] for type passed as \f[I]ROOT_TYPE\f[] argument inside the declaration of layout. The typed \f[I]OID\f[] will be assigned with type number for root object \f[B]POBJ_ROOT_TYPE_NUM\f[]. .PP The \f[B]POBJ_LAYOUT_END\f[]() macro ends the declaration of layout. .PP The \f[B]POBJ_LAYOUT_NAME\f[]() macro returns the name of layout as a null\-terminated string. .PP The \f[B]POBJ_LAYOUT_TYPES_NUM\f[]() macro returns number of types declared using the \f[B]POBJ_LAYOUT_TOID\f[]() macro within the layout declaration. .SH EXAMPLE .PP This is an example of layout declaration: .IP .nf \f[C] POBJ_LAYOUT_BEGIN(mylayout); POBJ_LAYOUT_ROOT(mylayout,\ struct\ root); POBJ_LAYOUT_TOID(mylayout,\ struct\ node); POBJ_LAYOUT_TOID(mylayout,\ struct\ foo); POBJ_LAYOUT_END(mylayout); struct\ root { \ \ \ \ TOID(struct\ node)\ node; }; struct\ node { \ \ \ \ TOID(struct\ node)\ next; \ \ \ \ TOID(struct\ foo)\ foo; }; \f[] .fi .PP The name of layout and the number of declared types can be retrieved using the following code: .IP .nf \f[C] const\ char\ *layout_name\ =\ POBJ_LAYOUT_NAME(mylayout); int\ num_of_types\ =\ POBJ_LAYOUT_TYPES_NUM(mylayout); \f[] .fi .SH SEE ALSO .PP \f[B]TOID_DECLARE\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/tx_memset.30000664000000000000000000000003314123364546016210 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/oid_equals.30000664000000000000000000000002214123364546016326 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/toid_typeof.30000664000000000000000000000002314123364546016527 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_end.30000664000000000000000000000003014123364546017355 0ustar rootroot.so pobj_layout_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_toid.30000664000000000000000000000003014123364546017546 0ustar rootroot.so pobj_layout_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_persist.30000664000000000000000000000003514123364546017407 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_remove_free.30000664000000000000000000000002514123364546020547 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_check.30000664000000000000000000000002314123364546016770 0ustar rootroot.so pmemobj_open.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_wcsdup.30000664000000000000000000000002714123364546017737 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/tx_set.30000664000000000000000000000003314123364546015511 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/toid_declare_root.30000664000000000000000000000002314123364546017663 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/tx_znew.30000664000000000000000000000002714123364546015704 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_pool_by_oid.30000664000000000000000000000002214123364546020210 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/pobj_alloc.30000664000000000000000000000002414123364546016307 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xpublish.30000664000000000000000000000002514123364546020266 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_wcsdup.30000664000000000000000000000002414123364546017221 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_free.30000664000000000000000000000002414123364546016635 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_unlock.30000664000000000000000000000003114123364546020566 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_action.30000664000000000000000000002000514123364731017166 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_ACTION" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2019, Intel Corporation .SH NAME .PP \f[B]pmemobj_reserve\f[](), \f[B]pmemobj_xreserve\f[](), \f[B]pmemobj_defer_free\f[](), \f[B]pmemobj_set_value\f[](), \f[B]pmemobj_publish\f[](), \f[B]pmemobj_tx_publish\f[](), \f[B]pmemobj_tx_xpublish\f[](), \f[B]pmemobj_cancel\f[](), \f[B]POBJ_RESERVE_NEW\f[](), \f[B]POBJ_RESERVE_ALLOC\f[](), \f[B]POBJ_XRESERVE_NEW\f[](),\f[B]POBJ_XRESERVE_ALLOC\f[]() \- Delayed atomicity actions (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMoid\ pmemobj_reserve(PMEMobjpool\ *pop,\ struct\ pobj_action\ *act, \ \ \ \ size_t\ size,\ uint64_t\ type_num);\ (EXPERIMENTAL) PMEMoid\ pmemobj_xreserve(PMEMobjpool\ *pop,\ struct\ pobj_action\ *act, \ \ \ \ size_t\ size,\ uint64_t\ type_num,\ uint64_t\ flags);\ (EXPERIMENTAL) void\ pmemobj_defer_free(PMEMobjpool\ *pop,\ PMEMoid\ oid,\ struct\ pobj_action\ *act); void\ pmemobj_set_value(PMEMobjpool\ *pop,\ struct\ pobj_action\ *act, \ \ \ \ uint64_t\ *ptr,\ uint64_t\ value);\ (EXPERIMENTAL) int\ pmemobj_publish(PMEMobjpool\ *pop,\ struct\ pobj_action\ *actv, \ \ \ \ size_t\ actvcnt);\ (EXPERIMENTAL) int\ pmemobj_tx_publish(struct\ pobj_action\ *actv,\ size_t\ actvcnt);\ (EXPERIMENTAL) int\ pmemobj_tx_xpublish(struct\ pobj_action\ *actv,\ size_t\ actvcnt,\ uint64_t\ flags);\ (EXPERIMENTAL) void\ pmemobj_cancel(PMEMobjpool\ *pop,\ struct\ pobj_action\ *actv, \ \ \ \ size_t\ actvcnt);\ (EXPERIMENTAL) POBJ_RESERVE_NEW(pop,\ t,\ act)\ (EXPERIMENTAL) POBJ_RESERVE_ALLOC(pop,\ t,\ size,\ act)\ (EXPERIMENTAL) POBJ_XRESERVE_NEW(pop,\ t,\ act,\ flags)\ (EXPERIMENTAL) POBJ_XRESERVE_ALLOC(pop,\ t,\ size,\ act,\ flags)\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP All of the functions described so far have an immediate effect on the persistent state of the pool, and as such, the cost of maintaining fail\-safety is paid outright and, most importantly, in the calling thread. This behavior makes implementing algorithms involving relaxed consistency guarantees difficult, if not outright impossible. .PP The following set of functions introduce a mechanism that allows one to delay the persistent publication of a set of prepared actions to an arbitrary moment in time of the execution of a program. .PP The publication is fail\-safe atomic in the scope of the entire collection of actions. If a program exits without publishing the actions, or the actions are canceled, any resources reserved by those actions are released and placed back in the pool. .PP A single action is represented by a single \f[C]struct\ pobj_action\f[]. Functions that create actions take that structure by pointer, whereas functions that publish actions take array of actions and the size of the array. The actions can be created, and published, from different threads. When creating actions, the \f[I]act\f[] argument must be non\-NULL and point to a \f[C]struct\ pobj_action\f[], the structure will be populated by the function and must not be modified or deallocated until after publishing. .PP The \f[B]pmemobj_reserve\f[]() functions performs a transient reservation of an object. Behaves similarly to \f[B]pmemobj_alloc\f[](3), but performs no modification to the persistent state. The object returned by this function can be freely modified without worrying about fail\-safe atomicity until the object has been published. Any modifications of the object must be manually persisted, just like in the case of the atomic API. .PP \f[B]pmemobj_xreserve\f[]() is equivalent to \f[B]pmemobj_reserve\f[](), but with an additional \f[I]flags\f[] argument that is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XALLOC_ZERO\f[] \- zero the allocated object (and persist it) .IP \[bu] 2 \f[B]POBJ_CLASS_ID(class_id)\f[] \- allocate an object from the allocation class \f[I]class_id\f[]. The class id cannot be 0. .IP \[bu] 2 \f[B]POBJ_ARENA_ID(arena_id)\f[] \- allocate an object from the arena specified by \f[I]arena_id\f[]. The arena must exist, otherwise, the behavior is undefined. If \f[I]arena_id\f[] is equal 0, then arena assigned to the current thread will be used. .PP \f[B]pmemobj_defer_free\f[]() function creates a deferred free action, meaning that the provided object will be freed when the action is published. Calling this function with a NULL OID is invalid and causes undefined behavior. .PP The \f[B]pmemobj_set_value\f[] function prepares an action that, once published, will modify the memory location pointed to by \f[I]ptr\f[] to \f[I]value\f[]. .PP The \f[B]pmemobj_publish\f[] function publishes the provided set of actions. The publication is fail\-safe atomic. Once done, the persistent state will reflect the changes contained in the actions. .PP The \f[B]pmemobj_tx_publish\f[] function moves the provided actions to the scope of the transaction in which it is called. Only object reservations are supported in transactional publish. Once done, the reserved objects will follow normal transactional semantics. Can only be called during \f[I]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xpublish\f[]() function behaves exactly the same as \f[B]pmemobj_tx_publish\f[]() when \f[I]flags\f[] equals zero. \f[I]flags\f[] is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XPUBLISH_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP The \f[B]pmemobj_cancel\f[] function releases any resources held by the provided set of actions and invalidates all actions. .PP The \f[B]POBJ_RESERVE_NEW\f[] macro is a typed variant of \f[B]pmemobj_reserve\f[]. The size of the reservation is determined from the provided type \f[I]t\f[]. .PP The \f[B]POBJ_RESERVE_ALLOC\f[] macro is a typed variant of \f[B]pmemobj_reserve\f[]. The \f[I]size\f[] of the reservation is user\-provided. .PP The \f[B]POBJ_XRESERVE_NEW\f[] and the \f[B]POBJ_XRESERVE_ALLOC\f[] macros are equivalent to \f[B]POBJ_RESERVE_NEW\f[] and the \f[B]POBJ_RESERVE_ALLOC\f[], but with an additional \f[I]flags\f[] argument defined for \f[B]pmemobj_xreserve\f[](). .SH EXAMPLES .PP The following code shows atomic append of two objects into a singly linked list. .IP .nf \f[C] struct\ list_node\ { \ \ \ \ int\ value; \ \ \ \ PMEMoid\ next; }; /*\ statically\ allocate\ the\ array\ of\ actions\ */ struct\ pobj_action\ actv[4]; /*\ reserve,\ populate\ and\ persist\ the\ first\ object\ */ PMEMoid\ tail\ =\ pmemobj_reserve(pop,\ &actv[0],\ sizeof(struct\ list_node),\ 0); if\ (TOID_IS_NULL(tail)) \ \ \ \ return\ \-1; D_RW(tail)\->value\ =\ 1; D_RW(tail)\->next\ =\ OID_NULL; pmemobj_persist(pop,\ D_RW(tail),\ sizeof(struct\ list_node)); /*\ reserve,\ populate\ and\ persist\ the\ second\ object\ */ PMEMoid\ head\ =\ pmemobj_reserve(pop,\ &actv[1],\ sizeof(struct\ list_node),\ 0); if\ (TOID_IS_NULL(head)) \ \ \ \ return\ \-1; D_RW(head)\->value\ =\ 2; D_RW(head)\->next\ =\ tail; pmemobj_persist(pop,\ D_RW(head),\ sizeof(struct\ list_node)); /*\ create\ actions\ to\ set\ the\ PMEMoid\ to\ the\ new\ values\ */ pmemobj_set_value(pop,\ &actv[2],\ &D_RO(root)\->head.pool_uuid_lo,\ head.pool_uuid_lo); pmemobj_set_value(pop,\ &actv[3],\ &D_RO(root)\->head.off,\ head.off); /*\ atomically\ publish\ the\ above\ actions\ */ pmemobj_publish(pop,\ actv,\ 4); \f[] .fi .SH RETURN VALUE .PP On success, \f[B]pmemobj_reserve\f[]() functions return a handle to the newly reserved object. Otherwise an \f[I]OID_NULL\f[] is returned. .PP On success, \f[B]pmemobj_tx_publish\f[]() returns 0. Otherwise, the transaction is aborted, the stage is changed to \f[I]TX_STAGE_ONABORT\f[] and \f[I]errno\f[] is set appropriately. .PP On success, \f[B]pmemobj_tx_xpublish\f[]() returns 0. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XPUBLISH_NO_ABORT\f[], the transaction is aborted. .PP On success, \f[B]pmemobj_publish\f[]() returns 0. Otherwise, returns \-1 and \f[I]errno\f[] is set appropriately. .SH SEE ALSO .PP \f[B]pmemobj_alloc\f[](3), \f[B]pmemobj_tx_alloc\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_end.30000664000000000000000000000002714123364546017200 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_drain.30000664000000000000000000000003514123364546017013 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/tx_onabort.30000664000000000000000000000002714123364546016365 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_log_intents_max_size.30000664000000000000000000000002714123364546022656 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xlock.30000664000000000000000000000002714123364546017552 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_get_user_data.30000664000000000000000000000002314123364546020521 0ustar rootroot.so pmemobj_open.3 pmdk-1.11.1/doc/libpmemobj/tx_new.30000664000000000000000000000002714123364546015512 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_empty.30000664000000000000000000000002514123364546017407 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/toid_valid.30000664000000000000000000000002314123364546016320 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_errormsg.30000664000000000000000000000002614123364546017556 0ustar rootroot.so man7/libpmemobj.7 pmdk-1.11.1/doc/libpmemobj/pmemobj_memset.30000664000000000000000000000003514123364546017210 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_trywrlock.30000664000000000000000000000003114123364546021333 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_new_before.30000664000000000000000000000002514123364546021750 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_log_auto_alloc.30000664000000000000000000000002714123364546021415 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_zero.3.md0000664000000000000000000002304114123364546020520 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_MUTEX_ZERO, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemobj_mutex_zero.3 -- man page for locking functions from libpmemobj library) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_mutex_zero**(), **pmemobj_mutex_lock**(), **pmemobj_mutex_timedlock**(), **pmemobj_mutex_trylock**(), **pmemobj_mutex_unlock**(), **pmemobj_rwlock_zero**(), **pmemobj_rwlock_rdlock**(), **pmemobj_rwlock_wrlock**(), **pmemobj_rwlock_timedrdlock**(), **pmemobj_rwlock_timedwrlock**(), **pmemobj_rwlock_tryrdlock**(), **pmemobj_rwlock_trywrlock**(), **pmemobj_rwlock_unlock**(), **pmemobj_cond_zero**(), **pmemobj_cond_broadcast**(), **pmemobj_cond_signal**(), **pmemobj_cond_timedwait**(), **pmemobj_cond_wait**() - pmemobj synchronization primitives # SYNOPSIS # ```c #include void pmemobj_mutex_zero(PMEMobjpool *pop, PMEMmutex *mutexp); int pmemobj_mutex_lock(PMEMobjpool *pop, PMEMmutex *mutexp); int pmemobj_mutex_timedlock(PMEMobjpool *pop, PMEMmutex *restrict mutexp, const struct timespec *restrict abs_timeout); int pmemobj_mutex_trylock(PMEMobjpool *pop, PMEMmutex *mutexp); int pmemobj_mutex_unlock(PMEMobjpool *pop, PMEMmutex *mutexp); void pmemobj_rwlock_zero(PMEMobjpool *pop, PMEMrwlock *rwlockp); int pmemobj_rwlock_rdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp); int pmemobj_rwlock_wrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp); int pmemobj_rwlock_timedrdlock(PMEMobjpool *pop, PMEMrwlock *restrict rwlockp, const struct timespec *restrict abs_timeout); int pmemobj_rwlock_timedwrlock(PMEMobjpool *pop, PMEMrwlock *restrict rwlockp, const struct timespec *restrict abs_timeout); int pmemobj_rwlock_tryrdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp); int pmemobj_rwlock_trywrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp); int pmemobj_rwlock_unlock(PMEMobjpool *pop, PMEMrwlock *rwlockp); void pmemobj_cond_zero(PMEMobjpool *pop, PMEMcond *condp); int pmemobj_cond_broadcast(PMEMobjpool *pop, PMEMcond *condp); int pmemobj_cond_signal(PMEMobjpool *pop, PMEMcond *condp); int pmemobj_cond_timedwait(PMEMobjpool *pop, PMEMcond *restrict condp, PMEMmutex *restrict mutexp, const struct timespec *restrict abs_timeout); int pmemobj_cond_wait(PMEMobjpool *pop, PMEMcond *restrict condp, PMEMmutex *restrict mutexp); ``` # DESCRIPTION # **libpmemobj**(7) provides several types of synchronization primitives designed to be used with persistent memory. The pmem-aware lock implementation is based on the standard POSIX Threads Library, as described in **pthread_mutex_init**(3), **pthread_rwlock_init**(3) and **pthread_cond_init**(3). Pmem-aware locks provide semantics similar to standard **pthread** locks, except that they are embedded in pmem-resident objects and are considered initialized by zeroing them. Therefore, locks allocated with **pmemobj_zalloc**(3) or **pmemobj_tx_zalloc**(3) do not require another initialization step. For performance reasons, they are also padded up to 64 bytes (cache line size). On FreeBSD, since all **pthread** locks are dynamically allocated, while the lock object is still padded up to 64 bytes for consistency with Linux, only the pointer to the lock is embedded in the pmem-resident object. **libpmemobj**(7) transparently manages freeing of the locks when the pool is closed. The fundamental property of pmem-aware locks is their automatic reinitialization every time the persistent object store pool is opened. Thus, all the pmem-aware locks may be considered initialized (unlocked) immediately after the pool is opened, regardless of their state at the time the pool was closed for the last time. Pmem-aware mutexes, read/write locks and condition variables must be declared with the *PMEMmutex*, *PMEMrwlock*, or *PMEMcond* type, respectively. The **pmemobj_mutex_zero**() function explicitly initializes the pmem-aware mutex *mutexp* by zeroing it. Initialization is not necessary if the object containing the mutex has been allocated using **pmemobj_zalloc**(3) or **pmemobj_tx_zalloc**(3). The **pmemobj_mutex_lock**() function locks the pmem-aware mutex *mutexp*. If the mutex is already locked, the calling thread will block until the mutex becomes available. If this is the first use of the mutex since the opening of the pool *pop*, the mutex is automatically reinitialized and then locked. **pmemobj_mutex_timedlock**() performs the same action as **pmemobj_mutex_lock**(), but will not wait beyond *abs_timeout* to obtain the lock before returning. The **pmemobj_mutex_trylock**() function locks pmem-aware mutex *mutexp*. If the mutex is already locked, **pthread_mutex_trylock**() will not block waiting for the mutex, but will return an error. If this is the first use of the mutex since the opening of the pool *pop*, the mutex is automatically reinitialized and then locked. The **pmemobj_mutex_unlock**() function unlocks the pmem-aware mutex *mutexp*. Undefined behavior follows if a thread tries to unlock a mutex that has not been locked by it, or if a thread tries to release a mutex that is already unlocked or has not been initialized. The **pmemobj_rwlock_zero**() function is used to explicitly initialize the pmem-aware read/write lock *rwlockp* by zeroing it. Initialization is not necessary if the object containing the lock has been allocated using **pmemobj_zalloc**(3) or **pmemobj_tx_zalloc**(3). The **pmemobj_rwlock_rdlock**() function acquires a read lock on *rwlockp*, provided that the lock is not presently held for writing and no writer threads are presently blocked on the lock. If the read lock cannot be acquired immediately, the calling thread blocks until it can acquire the lock. If this is the first use of the lock since the opening of the pool *pop*, the lock is automatically reinitialized and then acquired. **pmemobj_rwlock_timedrdlock**() performs the same action as **pmemobj_rwlock_rdlock**(), but will not wait beyond *abs_timeout* to obtain the lock before returning. A thread may hold multiple concurrent read locks. If so, **pmemobj_rwlock_unlock**() must be called once for each lock obtained. The results of acquiring a read lock while the calling thread holds a write lock are undefined. The **pmemobj_rwlock_wrlock**() function blocks until a write lock can be acquired against read/write lock *rwlockp*. If this is the first use of the lock since the opening of the pool *pop*, the lock is automatically reinitialized and then acquired. **pmemobj_rwlock_timedwrlock**() performs the same action, but will not wait beyond *abs_timeout* to obtain the lock before returning. The **pmemobj_rwlock_tryrdlock**() function performs the same action as **pmemobj_rwlock_rdlock**(), but does not block if the lock cannot be immediately obtained. The results are undefined if the calling thread already holds the lock at the time the call is made. The **pmemobj_rwlock_trywrlock**() function performs the same action as **pmemobj_rwlock_wrlock**(), but does not block if the lock cannot be immediately obtained. The results are undefined if the calling thread already holds the lock at the time the call is made. The **pmemobj_rwlock_unlock**() function is used to release the read/write lock previously obtained by **pmemobj_rwlock_rdlock**(), **pmemobj_rwlock_wrlock**(), **pthread_rwlock_tryrdlock**(), or **pmemobj_rwlock_trywrlock**(). The **pmemobj_cond_zero**() function explicitly initializes the pmem-aware condition variable *condp* by zeroing it. Initialization is not necessary if the object containing the condition variable has been allocated using **pmemobj_zalloc**(3) or **pmemobj_tx_zalloc**(3). The difference between **pmemobj_cond_broadcast**() and **pmemobj_cond_signal**() is that the former unblocks all threads waiting for the condition variable, whereas the latter blocks only one waiting thread. If no threads are waiting on *condp*, neither function has any effect. If more than one thread is blocked on a condition variable, the used scheduling policy determines the order in which threads are unblocked. The same mutex used for waiting must be held while calling either function. Although neither function strictly enforces this requirement, undefined behavior may follow if the mutex is not held. The **pmemobj_cond_timedwait**() and **pmemobj_cond_wait**() functions block on a condition variable. They must be called with mutex *mutexp* locked by the calling thread, or undefined behavior results. These functions atomically release mutex *mutexp* and cause the calling thread to block on the condition variable *condp*; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to **pmemobj_cond_broadcast**() or **pmemobj_cond_signal**() in that thread will behave as if it were issued after the about-to-block thread has blocked. Upon successful return, the mutex will be locked and owned by the calling thread. # RETURN VALUE # The **pmemobj_mutex_zero**(), **pmemobj_rwlock_zero**() and **pmemobj_cond_zero**() functions return no value. Other locking functions return 0 on success. Otherwise, an error number will be returned to indicate the error. # SEE ALSO # **pmemobj_tx_zalloc**(3), **pmemobj_zalloc**(3), **pthread_cond_init**(3), **pthread_mutex_init**(3), **pthread_rwlock_init**(3), **libpmem**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pobj_root.30000664000000000000000000000002314123364546016177 0ustar rootroot.so pmemobj_root.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_types_num.30000664000000000000000000000003014123364546020632 0ustar rootroot.so pobj_layout_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_zrealloc.30000664000000000000000000000002414123364546017030 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_trylock.30000664000000000000000000000003114123364546020623 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/tx_xadd_direct.30000664000000000000000000000003314123364546017170 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/toid_type_num_of.30000664000000000000000000000002314123364546017545 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/direct_ro.30000664000000000000000000000002314123364546016154 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_action.3.md0000664000000000000000000001704614123364546017604 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_ACTION, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2019, Intel Corporation) [comment]: <> (pmemobj_action.3 -- Delayed atomicity actions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[EXAMPLES](#examples)
[SEE ALSO](#see-also)
# NAME # **pmemobj_reserve**(), **pmemobj_xreserve**(), **pmemobj_defer_free**(), **pmemobj_set_value**(), **pmemobj_publish**(), **pmemobj_tx_publish**(), **pmemobj_tx_xpublish**(), **pmemobj_cancel**(), **POBJ_RESERVE_NEW**(), **POBJ_RESERVE_ALLOC**(), **POBJ_XRESERVE_NEW**(),**POBJ_XRESERVE_ALLOC**() - Delayed atomicity actions (EXPERIMENTAL) # SYNOPSIS # ```c #include PMEMoid pmemobj_reserve(PMEMobjpool *pop, struct pobj_action *act, size_t size, uint64_t type_num); (EXPERIMENTAL) PMEMoid pmemobj_xreserve(PMEMobjpool *pop, struct pobj_action *act, size_t size, uint64_t type_num, uint64_t flags); (EXPERIMENTAL) void pmemobj_defer_free(PMEMobjpool *pop, PMEMoid oid, struct pobj_action *act); void pmemobj_set_value(PMEMobjpool *pop, struct pobj_action *act, uint64_t *ptr, uint64_t value); (EXPERIMENTAL) int pmemobj_publish(PMEMobjpool *pop, struct pobj_action *actv, size_t actvcnt); (EXPERIMENTAL) int pmemobj_tx_publish(struct pobj_action *actv, size_t actvcnt); (EXPERIMENTAL) int pmemobj_tx_xpublish(struct pobj_action *actv, size_t actvcnt, uint64_t flags); (EXPERIMENTAL) void pmemobj_cancel(PMEMobjpool *pop, struct pobj_action *actv, size_t actvcnt); (EXPERIMENTAL) POBJ_RESERVE_NEW(pop, t, act) (EXPERIMENTAL) POBJ_RESERVE_ALLOC(pop, t, size, act) (EXPERIMENTAL) POBJ_XRESERVE_NEW(pop, t, act, flags) (EXPERIMENTAL) POBJ_XRESERVE_ALLOC(pop, t, size, act, flags) (EXPERIMENTAL) ``` # DESCRIPTION # All of the functions described so far have an immediate effect on the persistent state of the pool, and as such, the cost of maintaining fail-safety is paid outright and, most importantly, in the calling thread. This behavior makes implementing algorithms involving relaxed consistency guarantees difficult, if not outright impossible. The following set of functions introduce a mechanism that allows one to delay the persistent publication of a set of prepared actions to an arbitrary moment in time of the execution of a program. The publication is fail-safe atomic in the scope of the entire collection of actions. If a program exits without publishing the actions, or the actions are canceled, any resources reserved by those actions are released and placed back in the pool. A single action is represented by a single `struct pobj_action`. Functions that create actions take that structure by pointer, whereas functions that publish actions take array of actions and the size of the array. The actions can be created, and published, from different threads. When creating actions, the *act* argument must be non-NULL and point to a `struct pobj_action`, the structure will be populated by the function and must not be modified or deallocated until after publishing. The **pmemobj_reserve**() functions performs a transient reservation of an object. Behaves similarly to **pmemobj_alloc**(3), but performs no modification to the persistent state. The object returned by this function can be freely modified without worrying about fail-safe atomicity until the object has been published. Any modifications of the object must be manually persisted, just like in the case of the atomic API. **pmemobj_xreserve**() is equivalent to **pmemobj_reserve**(), but with an additional *flags* argument that is a bitmask of the following values: + **POBJ_XALLOC_ZERO** - zero the allocated object (and persist it) + **POBJ_CLASS_ID(class_id)** - allocate an object from the allocation class *class_id*. The class id cannot be 0. + **POBJ_ARENA_ID(arena_id)** - allocate an object from the arena specified by *arena_id*. The arena must exist, otherwise, the behavior is undefined. If *arena_id* is equal 0, then arena assigned to the current thread will be used. **pmemobj_defer_free**() function creates a deferred free action, meaning that the provided object will be freed when the action is published. Calling this function with a NULL OID is invalid and causes undefined behavior. The **pmemobj_set_value** function prepares an action that, once published, will modify the memory location pointed to by *ptr* to *value*. The **pmemobj_publish** function publishes the provided set of actions. The publication is fail-safe atomic. Once done, the persistent state will reflect the changes contained in the actions. The **pmemobj_tx_publish** function moves the provided actions to the scope of the transaction in which it is called. Only object reservations are supported in transactional publish. Once done, the reserved objects will follow normal transactional semantics. Can only be called during *TX_STAGE_WORK*. The **pmemobj_tx_xpublish**() function behaves exactly the same as **pmemobj_tx_publish**() when *flags* equals zero. *flags* is a bitmask of the following values: + **POBJ_XPUBLISH_NO_ABORT** - if the function does not end successfully, do not abort the transaction. The **pmemobj_cancel** function releases any resources held by the provided set of actions and invalidates all actions. The **POBJ_RESERVE_NEW** macro is a typed variant of **pmemobj_reserve**. The size of the reservation is determined from the provided type *t*. The **POBJ_RESERVE_ALLOC** macro is a typed variant of **pmemobj_reserve**. The *size* of the reservation is user-provided. The **POBJ_XRESERVE_NEW** and the **POBJ_XRESERVE_ALLOC** macros are equivalent to **POBJ_RESERVE_NEW** and the **POBJ_RESERVE_ALLOC**, but with an additional *flags* argument defined for **pmemobj_xreserve**(). # EXAMPLES # The following code shows atomic append of two objects into a singly linked list. ```c struct list_node { int value; PMEMoid next; }; /* statically allocate the array of actions */ struct pobj_action actv[4]; /* reserve, populate and persist the first object */ PMEMoid tail = pmemobj_reserve(pop, &actv[0], sizeof(struct list_node), 0); if (TOID_IS_NULL(tail)) return -1; D_RW(tail)->value = 1; D_RW(tail)->next = OID_NULL; pmemobj_persist(pop, D_RW(tail), sizeof(struct list_node)); /* reserve, populate and persist the second object */ PMEMoid head = pmemobj_reserve(pop, &actv[1], sizeof(struct list_node), 0); if (TOID_IS_NULL(head)) return -1; D_RW(head)->value = 2; D_RW(head)->next = tail; pmemobj_persist(pop, D_RW(head), sizeof(struct list_node)); /* create actions to set the PMEMoid to the new values */ pmemobj_set_value(pop, &actv[2], &D_RO(root)->head.pool_uuid_lo, head.pool_uuid_lo); pmemobj_set_value(pop, &actv[3], &D_RO(root)->head.off, head.off); /* atomically publish the above actions */ pmemobj_publish(pop, actv, 4); ``` # RETURN VALUE # On success, **pmemobj_reserve**() functions return a handle to the newly reserved object. Otherwise an *OID_NULL* is returned. On success, **pmemobj_tx_publish**() returns 0. Otherwise, the transaction is aborted, the stage is changed to *TX_STAGE_ONABORT* and *errno* is set appropriately. On success, **pmemobj_tx_xpublish**() returns 0. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XPUBLISH_NO_ABORT**, the transaction is aborted. On success, **pmemobj_publish**() returns 0. Otherwise, returns -1 and *errno* is set appropriately. # SEE ALSO # **pmemobj_alloc**(3), **pmemobj_tx_alloc**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/toid_declare.3.md0000664000000000000000000000720314123364546017226 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(TOID_DECLARE, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (toid_declare.3 -- man page for obj type safety mechanism) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[SEE ALSO](#see-also)
# NAME # **TOID_DECLARE**(), **TOID_DECLARE_ROOT**(), **TOID**(), **TOID_TYPE_NUM**(), **TOID_TYPE_NUM_OF**(), **TOID_VALID**(), **OID_INSTANCEOF**(), **TOID_ASSIGN**(), **TOID_IS_NULL**(), **TOID_EQUALS**(), **TOID_TYPEOF**(), **TOID_OFFSETOF**(), **DIRECT_RW**(), **D_RW**(), **DIRECT_RO**(), **D_RO**() - libpmemobj type safety mechanism # SYNOPSIS # ```c #include TOID_DECLARE(TYPE, uint64_t type_num) TOID_DECLARE_ROOT(ROOT_TYPE) TOID(TYPE) TOID_TYPE_NUM(TYPE) TOID_TYPE_NUM_OF(TOID oid) TOID_VALID(TOID oid) OID_INSTANCEOF(PMEMoid oid, TYPE) TOID_ASSIGN(TOID o, VALUE) TOID_IS_NULL(TOID o) TOID_EQUALS(TOID lhs, TOID rhs) TOID_TYPEOF(TOID o) TOID_OFFSETOF(TOID o, FILED) DIRECT_RW(TOID oid) D_RW(TOID oid) DIRECT_RO(TOID oid) D_RO(TOID oid) ``` # DESCRIPTION # Operating on untyped object handles, as well as on direct untyped object pointers (*void\**), may be confusing and error-prone. To facilitate type safety, **libpmemobj**(7) defines a set of macros that provide static type enforcement, catching potential errors at compile time. For example, a compile-time error is generated when an attempt is made to assign a handle to an object of one type to the object handle variable of another type of object. The **TOID_DECLARE**() macro declares a typed *OID* of user-defined type *TYPE* and type number *type_num*. The **TOID_DECLARE_ROOT**() macro declares a typed *OID* of user-defined type *ROOT_TYPE* and root object type number **POBJ_ROOT_TYPE_NUM**. The **TOID**() macro declares a handle to an object of type *TYPE*, where *TYPE* is the name of a user-defined structure. The typed *OID* must be declared first using the **TOID_DECLARE**(), **TOID_DECLARE_ROOT**(), **POBJ_LAYOUT_TOID**(3) or **POBJ_LAYOUT_ROOT**(3) macros. The **TOID_TYPE_NUM**() macro returns the type number of the type specified by *TYPE*. The **TOID_TYPE_NUM_OF**() macro returns the type number of the object specified by *oid*. The type number is read from the typed *OID*. The **TOID_VALID**() macro validates whether the type number stored in the object's metadata is equal to the type number read from the typed *OID*. The **OID_INSTANCEOF**() macro checks whether the *oid* is of type *TYPE*. The **TOID_ASSIGN**() macro assigns the object handle *VALUE* to typed *OID* *o*. The **TOID_IS_NULL**() macro evaluates to true if the object handle represented by *o* is **OID_NULL**. The **TOID_EQUALS**() macro evaluates to true if both the *lhs* and *rhs* object handles reference the same persistent object. The **TOID_TYPEOF**() macro returns the type of the object handle represented by typed *OID* *o*. The **TOID_OFFSETOF**() macro returns the offset of the *FIELD* member from the start of the object represented by *o*. The **DIRECT_RW**() macro and its shortened form **D_RW**() return a typed write pointer (*TYPE\**) to an object represented by *oid*. If *oid* is **OID_NULL**, the macro evaluates to NULL. The **DIRECT_RO**() macro and its shortened form **D_RO**() return a typed read-only (const) pointer (*TYPE\**) to an object represented by *oid*. If *oid* is **OID_NULL**, the macro evaluates to NULL. # SEE ALSO # **OID_IS_NULL**(3), **POBJ_LAYOUT_ROOT**(3), **POBJ_LAYOUT_TOID**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_log_append_buffer.30000664000000000000000000000002714123364546022073 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_reserve_alloc.30000664000000000000000000000002514123364546020043 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_zalloc.30000664000000000000000000000002414123364546017200 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_type_num.30000664000000000000000000000002214123364546017552 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/toid.30000664000000000000000000000002314123364546015141 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_ctl_get.30000664000000000000000000004261014123364731017340 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_CTL_GET" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2021, Intel Corporation .SH NAME .PP \f[B]pmemobj_ctl_get\f[](), \f[B]pmemobj_ctl_set\f[](), \f[B]pmemobj_ctl_exec\f[]() \- Query and modify libpmemobj internal behavior (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemobj_ctl_get(PMEMobjpool\ *pop,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemobj_ctl_set(PMEMobjpool\ *pop,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemobj_ctl_exec(PMEMobjpool\ *pop,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemobj_ctl_get\f[](), \f[B]pmemobj_ctl_set\f[]() and \f[B]pmemobj_ctl_exec\f[]() functions provide a uniform interface for querying and modifying the internal behavior of \f[B]libpmemobj\f[](7) through the control (CTL) namespace. .PP The \f[I]name\f[] argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra \f[I]arg\f[] is required. Those two parameters together create a CTL query. The functions and the entry points are thread\-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either \f[I]name\f[] or \f[I]arg\f[] is invalid, \-1 is returned. .PP If the provided ctl query is valid, the CTL functions will always return 0 on success and \-1 on failure, unless otherwise specified in the entry point description. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH CTL NAMESPACE .PP prefault.at_create | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemobj_create\f[]() function. .PP prefault.at_open | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemobj_open\f[]() function. .PP sds.at_create | rw | global | int | int | \- | boolean .PP If set, force\-enables or force\-disables SDS feature during pool creation. Affects only the \f[B]pmemobj_create\f[]() function. See \f[B]pmempool_feature_query\f[](3) for information about SDS (SHUTDOWN_STATE) feature. .PP copy_on_write.at_open | rw | global | int | int | \- | boolean .PP If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. .PP tx.debug.skip_expensive_checks | rw | \- | int | int | \- | boolean .PP Turns off some expensive checks performed by the transaction module in \[lq]debug\[rq] builds. Ignored in \[lq]release\[rq] builds. .PP tx.debug.verify_user_buffers | rw | \- | int | int | \- | boolean .PP Enables verification of user buffers provided by \f[B]pmemobj_tx_log_append_buffer\f[](3) API. For now the only verified aspect is whether the same buffer is used simultaneously in 2 or more transactions or more than once in the same transaction. This value should not be modified at runtime if any transaction for the current pool is in progress. .PP tx.cache.size | rw | \- | long long | long long | \- | integer .PP Size in bytes of the transaction snapshot cache. In a larger cache the frequency of persistent allocations is lower, but with higher fixed cost. .PP This should be set to roughly the sum of sizes of the snapshotted regions in an average transaction in the pool. .PP This entry point is not thread safe and should not be modified if there are any transactions currently running. .PP This value must be a in a range between 0 and \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[], otherwise this entry point will fail. .PP tx.cache.threshold | rw | \- | long long | long long | \- | integer .PP This entry point is deprecated. All snapshots, regardless of the size, use the transactional cache. .PP tx.post_commit.queue_depth | rw | \- | int | int | \- | integer .PP This entry point is deprecated. .PP tx.post_commit.worker | r\- | \- | void * | \- | \- | \- .PP This entry point is deprecated. .PP tx.post_commit.stop | r\- | \- | void * | \- | \- | \- .PP This entry point is deprecated. .PP heap.narenas.automatic | r\- | \- | unsigned | \- | \- | \- .PP Reads the number of arenas used in automatic scheduling of memory operations for threads. By default, this value is equal to the number of available processors. An arena is a memory management structure which enables concurrency by taking exclusive ownership of parts of the heap and allowing associated threads to allocate without contention. .PP heap.narenas.total | r\- | \- | unsigned | \- | \- | \- .PP Reads the number of all created arenas. It includes automatic arenas created by default and arenas created using heap.arena.create CTL. .PP heap.narenas.max | rw\- | \- | unsigned | unsigned | \- | \- .PP Reads or writes the maximum number of arenas that can be created. This entry point is not thread\-safe with regards to heap operations (allocations, frees, reallocs). .PP heap.arena.[arena_id].size | r\- | \- | uint64_t | \- | \- | \- .PP Reads the total amount of memory in bytes which is currently exclusively owned by the arena. Large differences in this value between arenas might indicate an uneven scheduling of memory resources. The arena id cannot be 0. .PP heap.thread.arena_id | rw\- | \- | unsigned | unsigned | \- | \- .PP Reads the index of the arena assigned to the current thread or assigns arena with specific id to the current thread. The arena id cannot be 0. .PP heap.arena.create | \[en]x | \- | \- | \- | unsigned | \- .PP Creates and initializes one new arena in the heap. This entry point reads an id of the new created arena. .PP Newly created arenas by this CTL are inactive, which means that the arena will not be used in the automatic scheduling of memory requests. To activate the new arena, use heap.arena.[arena_id].automatic CTL. .PP Arena created using this CTL can be used for allocation by explicitly specifying the \f[I]arena_id\f[] for \f[B]POBJ_ARENA_ID(id)\f[] flag in \f[B]pmemobj_tx_xalloc\f[]()/\f[B]pmemobj_xalloc\f[]()/\f[B]pmemobj_xreserve()\f[] functions. .PP By default, the number of arenas is limited to 1024. .PP heap.arena.[arena_id].automatic | rw\- | \- | boolean | boolean | \- | \- .PP Reads or modifies the state of the arena. If set, the arena is used in automatic scheduling of memory operations for threads. This should be set to false if the application wants to manually manage allocator scalability through explicitly assigning arenas to threads by using heap.thread.arena_id. The arena id cannot be 0 and at least one automatic arena must exist. .PP heap.arenas_assignment_type | rw | global | \f[C]enum\ pobj_arenas_assignment_type\f[] | \f[C]enum\ pobj_arenas_assignment_type\f[] | \- | string .PP Reads or modifies the behavior of arenas assignment for threads. By default, each thread is assigned its own arena from the pool of automatic arenas (described earlier). This consumes one TLS key from the OS for every open pool. Applications that wish to avoid this behavior can instead rely on one global arena assignment per pool. This might limits scalability if not using arenas explicitly. .PP The argument for this CTL is an enum with the following types: .IP \[bu] 2 \f[B]POBJ_ARENAS_ASSIGNMENT_THREAD_KEY\f[], string value: \f[C]thread\f[]. Default, threads use individually assigned arenas. .IP \[bu] 2 \f[B]POBJ_ARENAS_ASSIGNMENT_GLOBAL\f[], string value: \f[C]global\f[]. Threads use one global arena. .PP Changing this value has no impact on already open pools. It should typically be set at the beginning of the application, before any pools are opened or created. .PP heap.alloc_class.[class_id].desc | rw | \- | \f[C]struct\ pobj_alloc_class_desc\f[] | \f[C]struct\ pobj_alloc_class_desc\f[] | \- | integer, integer, integer, string .PP Describes an allocation class. Allows one to create or view the internal data structures of the allocator. .PP Creating custom allocation classes can be beneficial for both raw allocation throughput, scalability and, most importantly, fragmentation. By carefully constructing allocation classes that match the application workload, one can entirely eliminate external and internal fragmentation. For example, it is possible to easily construct a slab\-like allocation mechanism for any data structure. .PP The \f[C][class_id]\f[] is an index field. Only values between 0\-254 are valid. If setting an allocation class, but the \f[C]class_id\f[] is already taken, the function will return \-1. The values between 0\-127 are reserved for the default allocation classes of the library and can be used only for reading. .PP The recommended method for retrieving information about all allocation classes is to call this entry point for all class ids between 0 and 254 and discard those results for which the function returns an error. .PP This entry point takes a complex argument. .IP .nf \f[C] struct\ pobj_alloc_class_desc\ { \ \ \ \ size_t\ unit_size; \ \ \ \ size_t\ alignment; \ \ \ \ unsigned\ units_per_block; \ \ \ \ enum\ pobj_header_type\ header_type; \ \ \ \ unsigned\ class_id; }; \f[] .fi .PP The first field, \f[C]unit_size\f[], is an 8\-byte unsigned integer that defines the allocation class size. While theoretically limited only by \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[], for most workloads this value should be between 8 bytes and 2 megabytes. .PP The \f[C]alignment\f[] field specifies the user data alignment of objects allocated using the class. If set, must be a power of two and an even divisor of unit size. Alignment is limited to maximum of 2 megabytes. All objects have default alignment of 64 bytes, but the user data alignment is affected by the size of the chosen header. .PP The \f[C]units_per_block\f[] field defines how many units a single block of memory contains. This value will be adjusted to match the internal size of the block (256 kilobytes or a multiple thereof). For example, given a class with a \f[C]unit_size\f[] of 512 bytes and a \f[C]units_per_block\f[] of 1000, a single block of memory for that class will have 512 kilobytes. This is relevant because the bigger the block size, the less frequently blocks need to be fetched, resulting in lower contention on global heap state. If the CTL call is being done at runtime, the \f[C]units_per_block\f[] variable of the provided alloc class structure is modified to match the actual value. .PP The \f[C]header_type\f[] field defines the header of objects from the allocation class. There are three types: .IP \[bu] 2 \f[B]POBJ_HEADER_LEGACY\f[], string value: \f[C]legacy\f[]. Used for allocation classes prior to version 1.3 of the library. Not recommended for use. Incurs a 64 byte metadata overhead for every object. Fully supports all features. .IP \[bu] 2 \f[B]POBJ_HEADER_COMPACT\f[], string value: \f[C]compact\f[]. Used as default for all predefined allocation classes. Incurs a 16 byte metadata overhead for every object. Fully supports all features. .IP \[bu] 2 \f[B]POBJ_HEADER_NONE\f[], string value: \f[C]none\f[]. Header type that incurs no metadata overhead beyond a single bitmap entry. Can be used for very small allocation classes or when objects must be adjacent to each other. This header type does not support type numbers (type number is always .RS 2 .IP "0)" 3 or allocations that span more than one unit. .RE .PP The \f[C]class_id\f[] field is an optional, runtime\-only variable that allows the user to retrieve the identifier of the class. This will be equivalent to the provided \f[C][class_id]\f[]. This field cannot be set from a config file. .PP The allocation classes are a runtime state of the library and must be created after every open. It is highly recommended to use the configuration file to store the classes. .PP This structure is declared in the \f[C]libpmemobj/ctl.h\f[] header file. Please refer to this file for an in\-depth explanation of the allocation classes and relevant algorithms. .PP Allocation classes constructed in this way can be leveraged by explicitly specifying the class using \f[B]POBJ_CLASS_ID(id)\f[] flag in \f[B]pmemobj_tx_xalloc\f[]()/\f[B]pmemobj_xalloc\f[]() functions. .PP Example of a valid alloc class query string: .IP .nf \f[C] heap.alloc_class.128.desc=500,0,1000,compact \f[] .fi .PP This query, if executed, will create an allocation class with an id of 128 that has a unit size of 500 bytes, has at least 1000 units per block and uses a compact header. .PP For reading, function returns 0 if successful, if the allocation class does not exist it sets the errno to \f[B]ENOENT\f[] and returns \-1; .PP This entry point can fail if any of the parameters of the allocation class is invalid or if exactly the same class already exists. .PP heap.alloc_class.new.desc | \-w | \- | \- | \f[C]struct\ pobj_alloc_class_desc\f[] | \- | integer, integer, integer, string .PP Same as \f[C]heap.alloc_class.[class_id].desc\f[], but instead of requiring the user to provide the class_id, it automatically creates the allocation class with the first available identifier. .PP This should be used when it's impossible to guarantee unique allocation class naming in the application (e.g.\ when writing a library that uses libpmemobj). .PP The required class identifier will be stored in the \f[C]class_id\f[] field of the \f[C]struct\ pobj_alloc_class_desc\f[]. .PP stats.enabled | rw | \- | enum pobj_stats_enabled | enum pobj_stats_enabled | \- | string .PP Enables or disables runtime collection of statistics. There are two types of statistics: persistent and transient ones. Persistent statistics survive pool restarts, whereas transient ones don't. Statistics are not recalculated after enabling; any operations that occur between disabling and re\-enabling will not be reflected in subsequent values. .PP Only transient statistics are enabled by default. Enabling persistent statistics may have non\-trivial performance impact. .PP stats.heap.curr_allocated | r\- | \- | uint64_t | \- | \- | \- .PP Reads the number of bytes currently allocated in the heap. If statistics were disabled at any time in the lifetime of the heap, this value may be inaccurate. .PP This is a persistent statistic. .PP stats.heap.run_allocated | r\- | \- | uint64_t | \- | \- | \- .PP Reads the number of bytes currently allocated using run\-based allocation classes, i.e., huge allocations are not accounted for in this statistic. This is useful for comparison against stats.heap.run_active to estimate the ratio between active and allocated memory. .PP This is a transient statistic and is rebuilt every time the pool is opened. .PP stats.heap.run_active | r\- | \- | uint64_t | \- | \- | \- .PP Reads the number of bytes currently occupied by all run memory blocks, including both allocated and free space, i.e., this is all the all space that's not occupied by huge allocations. .PP This value is a sum of all allocated and free run memory. In systems where memory is efficiently used, \f[C]run_active\f[] should closely track \f[C]run_allocated\f[], and the amount of active, but free, memory should be minimal. .PP A large relative difference between active memory and allocated memory is indicative of heap fragmentation. This information can be used to make a decision to call \f[B]pmemobj_defrag()\f[](3) if the fragmentation looks to be high. .PP However, for small heaps \f[C]run_active\f[] might be disproportionately higher than \f[C]run_allocated\f[] because the allocator typically activates a significantly larger amount of memory than is required to satisfy a single request in the anticipation of future needs. For example, the first allocation of 100 bytes in a heap will trigger activation of 256 kilobytes of space. .PP This is a transient statistic and is rebuilt lazily every time the pool is opened. .PP heap.size.granularity | rw\- | \- | uint64_t | uint64_t | \- | long long .PP Reads or modifies the granularity with which the heap grows when OOM. Valid only if the poolset has been defined with directories. .PP A granularity of 0 specifies that the pool will not grow automatically. .PP This entry point can fail if the granularity value is non\-zero and smaller than \f[I]PMEMOBJ_MIN_PART\f[]. .PP heap.size.extend | \[en]x | \- | \- | \- | uint64_t | \- .PP Extends the heap by the given size. Must be larger than \f[I]PMEMOBJ_MIN_PART\f[]. .PP This entry point can fail if the pool does not support extend functionality or if there's not enough space left on the device. .PP debug.heap.alloc_pattern | rw | \- | int | int | \- | \- .PP Single byte pattern that is used to fill new uninitialized memory allocation. If the value is negative, no pattern is written. This is intended for debugging, and is disabled by default. .SH CTL EXTERNAL CONFIGURATION .PP In addition to direct function call, each write entry point can also be set using two alternative methods. .PP The first method is to load a configuration directly from the \f[B]PMEMOBJ_CONF\f[] environment variable. .PP The second method of loading an external configuration is to set the \f[B]PMEMOBJ_CONF_FILE\f[] environment variable to point to a file that contains a sequence of ctl queries. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH SEE ALSO .PP \f[B]libpmemobj\f[](7), \f[B]pmem_ctl\f[](5) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pobj_list_first.30000664000000000000000000000002514123364546017400 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pobj_first.30000664000000000000000000000002414123364546016344 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_cancel.30000664000000000000000000000002514123364546017142 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_root.30000664000000000000000000000003014123364546017572 0ustar rootroot.so pobj_layout_begin.3 pmdk-1.11.1/doc/libpmemobj/tx_xfree.30000664000000000000000000000002714123364546016032 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_head.30000664000000000000000000002635114123364733017162 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "POBJ_LIST_HEAD" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]POBJ_LIST_HEAD\f[](), \f[B]POBJ_LIST_ENTRY\f[](), \f[B]POBJ_LIST_FIRST\f[](), \f[B]POBJ_LIST_LAST\f[](), \f[B]POBJ_LIST_EMPTY\f[](), \f[B]POBJ_LIST_NEXT\f[](), \f[B]POBJ_LIST_PREV\f[](), .PP \f[B]POBJ_LIST_FOREACH\f[](), \f[B]POBJ_LIST_FOREACH_REVERSE\f[](), .PP \f[B]POBJ_LIST_INSERT_HEAD\f[](), \f[B]POBJ_LIST_INSERT_TAIL\f[](), \f[B]POBJ_LIST_INSERT_AFTER\f[](), \f[B]POBJ_LIST_INSERT_BEFORE\f[](), \f[B]POBJ_LIST_INSERT_NEW_HEAD\f[](), \f[B]POBJ_LIST_INSERT_NEW_TAIL\f[](), \f[B]POBJ_LIST_INSERT_NEW_AFTER\f[](), \f[B]POBJ_LIST_INSERT_NEW_BEFORE\f[](), .PP \f[B]POBJ_LIST_REMOVE\f[](), \f[B]POBJ_LIST_REMOVE_FREE\f[](), .PP \f[B]POBJ_LIST_MOVE_ELEMENT_HEAD\f[](), \f[B]POBJ_LIST_MOVE_ELEMENT_TAIL\f[](), \f[B]POBJ_LIST_MOVE_ELEMENT_AFTER\f[](), \f[B]POBJ_LIST_MOVE_ELEMENT_BEFORE\f[]() \- type\-safe non\-transactional persistent atomic lists .SH SYNOPSIS .IP .nf \f[C] #include\ POBJ_LIST_HEAD(HEADNAME,\ TYPE) POBJ_LIST_ENTRY(TYPE) POBJ_LIST_FIRST(POBJ_LIST_HEAD\ *head) POBJ_LIST_LAST(POBJ_LIST_HEAD\ *head,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_EMPTY(POBJ_LIST_HEAD\ *head) POBJ_LIST_NEXT(TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_PREV(TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_FOREACH(TOID\ var,\ POBJ_LIST_HEAD\ *head,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_FOREACH_REVERSE(TOID\ var,\ POBJ_LIST_HEAD\ *head,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_INSERT_HEAD(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_INSERT_TAIL(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_INSERT_AFTER(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ listelm,\ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_INSERT_BEFORE(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ listelm,\ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_INSERT_NEW_HEAD(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_ENTRY\ FIELD,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg) POBJ_LIST_INSERT_NEW_TAIL(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_ENTRY\ FIELD,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg) POBJ_LIST_INSERT_NEW_AFTER(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ listelm,\ POBJ_LIST_ENTRY\ FIELD,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg) POBJ_LIST_INSERT_NEW_BEFORE(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ listelm,\ POBJ_LIST_ENTRY\ FIELD,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg) POBJ_LIST_REMOVE(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_REMOVE_FREE(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD) POBJ_LIST_MOVE_ELEMENT_HEAD(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_HEAD\ *head_new,\ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD, \ \ \ \ POBJ_LIST_ENTRY\ field_new) POBJ_LIST_MOVE_ELEMENT_TAIL(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_HEAD\ *head_new,\ TOID\ elm,\ POBJ_LIST_ENTRY\ FIELD, \ \ \ \ POBJ_LIST_ENTRY\ field_new) POBJ_LIST_MOVE_ELEMENT_AFTER(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_HEAD\ *head_new,\ TOID\ listelm,\ TOID\ elm, \ \ \ \ POBJ_LIST_ENTRY\ FIELD,\ POBJ_LIST_ENTRY\ field_new) POBJ_LIST_MOVE_ELEMENT_BEFORE(PMEMobjpool\ *pop,\ POBJ_LIST_HEAD\ *head, \ \ \ \ POBJ_LIST_HEAD\ *head_new,\ TOID\ listelm,\ TOID\ elm, \ \ \ \ POBJ_LIST_ENTRY\ FIELD,\ POBJ_LIST_ENTRY\ field_new) \f[] .fi .SH DESCRIPTION .PP The following macros define and operate on a type\-safe persistent atomic circular doubly linked list data structure that consist of a set of persistent objects of a well\-known type. Unlike the functions described in the previous section, these macros provide type enforcement by requiring declaration of type of the objects stored in given list, and not allowing mixing objects of different types in a single list. .PP The functionality and semantics of those macros is similar to circular queues defined in \f[B]queue\f[](3). .PP The majority of the macros must specify the handle to the memory pool \f[I]pop\f[] and the name of the \f[I]field\f[] in the user\-defined structure, which must be of type \f[I]POBJ_LIST_ENTRY\f[] and is used to connect the elements in the list. .PP A list is headed by a structure defined by the \f[B]POBJ_LIST_HEAD\f[]() macro. This structure contains an object handle of the first element on the list. The elements are doubly linked so that an arbitrary element can be removed without a need to traverse the list. New elements can be added to the list before or after an existing element, at the head of the list, or at the end of the list. A list may be traversed in either direction. A \f[I]POBJ_LIST_HEAD\f[] structure is declared as follows: .IP .nf \f[C] #define\ POBJ_LIST_HEAD(HEADNAME,\ TYPE) struct\ HEADNAME { \ \ \ \ TOID(TYPE)\ pe_first; \ \ \ \ PMEMmutex\ lock; }; \f[] .fi .PP In the macro definitions, \f[I]TYPE\f[] is the name of a user\-defined structure, that must contain a field of type \f[I]POBJ_LIST_ENTRY\f[]. The argument \f[I]HEADNAME\f[] is the name of a user\-defined structure that must be declared using the macro \f[I]POBJ_LIST_HEAD\f[]. See the examples below for further explanation of how these macros are used. .PP The macro \f[I]POBJ_LIST_ENTRY\f[] declares a structure that connects the elements in the list. .IP .nf \f[C] #define\ POBJ_LIST_ENTRY(TYPE) struct { \ \ \ \ TOID(TYPE)\ pe_next; \ \ \ \ TOID(TYPE)\ pe_prev; }; \f[] .fi .PP The macro \f[B]POBJ_LIST_FIRST\f[]() returns the first element on the list referenced by \f[I]head\f[]. If the list is empty \f[B]OID_NULL\f[] is returned. .PP The macro \f[B]POBJ_LIST_LAST\f[]() returns the last element on the list referenced by \f[I]head\f[]. If the list is empty \f[B]OID_NULL\f[] is returned. .PP The macro \f[B]POBJ_LIST_EMPTY\f[]() evaluates to 1 if the list referenced by \f[I]head\f[] is empty. Otherwise, 0 is returned. .PP The macro \f[B]POBJ_LIST_NEXT\f[]() returns the element next to the element \f[I]elm\f[]. .PP The macro \f[B]POBJ_LIST_PREV\f[]() returns the element preceding the element \f[I]elm\f[]. .PP The macro \f[B]POBJ_LIST_FOREACH\f[]() traverses the list referenced by \f[I]head\f[] assigning a handle to each element in turn to \f[I]var\f[] variable. .PP The macro \f[B]POBJ_LIST_FOREACH_REVERSE\f[]() traverses the list referenced by \f[I]head\f[] in reverse order, assigning a handle to each element in turn to \f[I]var\f[] variable. The \f[I]field\f[] argument is the name of the field of type \f[I]POBJ_LIST_ENTRY\f[] in the element structure. .PP The macro \f[B]POBJ_LIST_INSERT_HEAD\f[]() inserts the element \f[I]elm\f[] at the head of the list referenced by \f[I]head\f[]. .PP The macro \f[B]POBJ_LIST_INSERT_TAIL\f[]() inserts the element \f[I]elm\f[] at the end of the list referenced by \f[I]head\f[]. .PP The macro \f[B]POBJ_LIST_INSERT_AFTER\f[]() inserts the element \f[I]elm\f[] into the list referenced by \f[I]head\f[] after the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[B]TOID_NULL\f[], the object is inserted at the end of the list. .PP The macro \f[B]POBJ_LIST_INSERT_BEFORE\f[]() inserts the element \f[I]elm\f[] into the list referenced by \f[I]head\f[] before the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[B]TOID_NULL\f[], the object is inserted at the head of the list. .PP The macro \f[B]POBJ_LIST_INSERT_NEW_HEAD\f[]() atomically allocates a new object of size \f[I]size\f[] and inserts it at the head of the list referenced by \f[I]head\f[]. The newly allocated object is also added to the internal object container associated with a type number which is retrieved from the typed \f[I]OID\f[] of the first element on list. .PP The macro \f[B]POBJ_LIST_INSERT_NEW_TAIL\f[]() atomically allocates a new object of size \f[I]size\f[] and inserts it at the tail of the list referenced by \f[I]head\f[]. The newly allocated object is also added to the internal object container associated with a type number which is retrieved from the typed \f[I]OID\f[] of the first element on list. .PP The macro \f[B]POBJ_LIST_INSERT_NEW_AFTER\f[]() atomically allocates a new object of size \f[I]size\f[] and inserts it into the list referenced by \f[I]head\f[] after the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[B]TOID_NULL\f[], the object is inserted at the end of the list. The newly allocated object is also added to the internal object container associated with with a type number which is retrieved from the typed \f[I]OID\f[] of the first element on list. .PP The macro \f[B]POBJ_LIST_INSERT_NEW_BEFORE\f[]() atomically allocates a new object of size \f[I]size\f[] and inserts it into the list referenced by \f[I]head\f[] before the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[B]TOID_NULL\f[], the object is inserted at the head of the list. The newly allocated object is also added to the internal object container associated with with a type number which is retrieved from the typed \f[I]OID\f[] of the first element on list. .PP The macro \f[B]POBJ_LIST_REMOVE\f[]() removes the element \f[I]elm\f[] from the list referenced by \f[I]head\f[]. .PP The macro \f[B]POBJ_LIST_REMOVE_FREE\f[]() removes the element \f[I]elm\f[] from the list referenced by \f[I]head\f[] and frees the memory space represented by this element. .PP The macro \f[B]POBJ_LIST_MOVE_ELEMENT_HEAD\f[]() moves the element \f[I]elm\f[] from the list referenced by \f[I]head\f[] to the head of the list \f[I]head_new\f[]. The \f[I]field\f[] and \f[I]field_new\f[] arguments are the names of the fields of type \f[I]POBJ_LIST_ENTRY\f[] in the element structure that are used to connect the elements in both lists. .PP The macro \f[B]POBJ_LIST_MOVE_ELEMENT_TAIL\f[]() moves the element \f[I]elm\f[] from the list referenced by \f[I]head\f[] to the end of the list \f[I]head_new\f[]. The \f[I]field\f[] and \f[I]field_new\f[] arguments are the names of the fields of type \f[I]POBJ_LIST_ENTRY\f[] in the element structure that are used to connect the elements in both lists. .PP The macro \f[B]POBJ_LIST_MOVE_ELEMENT_AFTER\f[]() atomically removes the element \f[I]elm\f[] from the list referenced by \f[I]head\f[] and inserts it into the list referenced by \f[I]head_new\f[] after the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[I]TOID_NULL\f[], the object is inserted at the end of the list. The \f[I]field\f[] and \f[I]field_new\f[] arguments are the names of the fields of type \f[I]POBJ_LIST_ENTRY\f[] in the element structure that are used to connect the elements in both lists. .PP The macro \f[B]POBJ_LIST_MOVE_ELEMENT_BEFORE\f[]() atomically removes the element \f[I]elm\f[] from the list referenced by \f[I]head\f[] and inserts it into the list referenced by \f[I]head_new\f[] before the element \f[I]listelm\f[]. If \f[I]listelm\f[] value is \f[B]TOID_NULL\f[], the object is inserted at the head of the list. The \f[I]field\f[] and \f[I]field_new\f[] arguments are the names of the fields of type \f[I]POBJ_LIST_ENTRY\f[] in the element structure that are used to connect the elements in both lists. .SH SEE ALSO .PP \f[B]queue\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pobj_list_foreach.30000664000000000000000000000002514123364546017660 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_wrlock.30000664000000000000000000000003114123364546020574 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_root.3.md0000664000000000000000000000761314123364546017311 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_ROOT, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemobj_root.3 -- man page for root object management) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_root**(), **pmemobj_root_construct**() **POBJ_ROOT**(), **pmemobj_root_size**() - root object management # SYNOPSIS # ```c #include PMEMoid pmemobj_root(PMEMobjpool *pop, size_t size); PMEMoid pmemobj_root_construct(PMEMobjpool *pop, size_t size, pmemobj_constr constructor, void *arg); POBJ_ROOT(PMEMobjpool *pop, TYPE) size_t pmemobj_root_size(PMEMobjpool *pop); ``` # DESCRIPTION # The root object of a persistent memory pool is an entry point for all other persistent objects allocated using the **libpmemobj** API. In other words, every object stored in the persistent memory pool has the root object at the end of its reference path. It may be assumed that for each persistent memory pool the root object always exists, and there is exactly one root object in each pool. The **pmemobj_root**() function creates or resizes the root object for the persistent memory pool *pop*. If this is the first call to **pmemobj_root**(), the requested *size* is greater than zero and the root object does not exist, it is implicitly allocated in a thread-safe manner, so the function may be called by more than one thread simultaneously (as long as all threads use the identical *size* value). The size of the root object is guaranteed to be not less than the requested *size*. If the requested size is larger than the current size, the root object is automatically resized. In such case, the old data is preserved and the extra space is zeroed. If the requested size is equal to or smaller than the current size, the root object remains unchanged. If the requested *size* is equal to zero, the root object is not allocated. **pmemobj_root_construct**() performs the same actions as **pmemobj_root**(), but instead of zeroing the newly allocated object a *constructor* function is called to initialize the object. The constructor is also called on reallocations. The **POBJ_ROOT**() macro works the same way as the **pmemobj_root**() function except it returns a typed *OID* value. The **pmemobj_root_size**() function returns the current size of the root object associated with the persistent memory pool *pop*. # RETURN VALUE # Upon success, **pmemobj_root**() returns a handle to the root object associated with the persistent memory pool *pop*. The same root object handle is returned in all the threads. If the requested object size is larger than the maximum allocation size supported for the pool, or if there is not enough free space in the pool to satisfy a reallocation request, **pmemobj_root**() returns **OID_NULL** and sets *errno* to ENOMEM. If the *size* was equal to zero and the root object has not been allocated, **pmemobj_root**() returns **OID_NULL** and sets *errno* to EINVAL. If the **pmemobj_root_construct**() constructor fails, the allocation is canceled, **pmemobj_root_construct**() returns *OID_NULL*, and *errno* is set to **ECANCELED**. **pmemobj_root_size**() can be used in the constructor to check whether this is the first call to the constructor. **POBJ_ROOT**() returns a typed *OID* of type *TYPE* instead of the *PMEMoid* returned by **pmemobj_root**(). The **pmemobj_root_size**() function returns the current size of the root object associated with the persistent memory pool *pop*. The returned size is the largest value requested by any of the earlier **pmemobj_root**() calls. If the root object has not been allocated yet, **pmemobj_root_size**() returns 0. # SEE ALSO # **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_reserve.30000664000000000000000000000002514123364546017370 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_xreserve.30000664000000000000000000000002514123364546017560 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_set_user_data.30000664000000000000000000000002714123364546021254 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/tx_finally.30000664000000000000000000000002714123364546016357 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_create.30000664000000000000000000000002314123364546017156 0ustar rootroot.so pmemobj_open.3 pmdk-1.11.1/doc/libpmemobj/pobj_xreserve_new.30000664000000000000000000000002514123364546017732 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_move_element_after.30000664000000000000000000000002514123364546022111 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xlog_append_buffer.30000664000000000000000000000002714123364546022263 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_alloc.30000664000000000000000000003251414123364733017530 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_TX_ALLOC" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2019, Intel Corporation .SH NAME .PP \f[B]pmemobj_tx_alloc\f[](), \f[B]pmemobj_tx_zalloc\f[](), \f[B]pmemobj_tx_xalloc\f[](), \f[B]pmemobj_tx_realloc\f[](), \f[B]pmemobj_tx_zrealloc\f[](), \f[B]pmemobj_tx_strdup\f[](), \f[B]pmemobj_tx_xstrdup\f[](), \f[B]pmemobj_tx_wcsdup\f[](), \f[B]pmemobj_tx_xwcsdup\f[](), \f[B]pmemobj_tx_free\f[](), \f[B]pmemobj_tx_xfree\f[]() .PP \f[B]TX_NEW\f[](), \f[B]TX_ALLOC\f[](), \f[B]TX_ZNEW\f[](), \f[B]TX_ZALLOC\f[](), \f[B]TX_XALLOC\f[](), \f[B]TX_REALLOC\f[](), \f[B]TX_ZREALLOC\f[](), \f[B]TX_STRDUP\f[](), \f[B]TX_XSTRDUP\f[](), \f[B]TX_WCSDUP\f[](), \f[B]TX_XWCSDUP\f[](), \f[B]TX_FREE\f[](), \f[B]TX_XFREE\f[]() \- transactional object manipulation .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMoid\ pmemobj_tx_alloc(size_t\ size,\ uint64_t\ type_num); PMEMoid\ pmemobj_tx_zalloc(size_t\ size,\ uint64_t\ type_num); PMEMoid\ pmemobj_tx_xalloc(size_t\ size,\ uint64_t\ type_num,\ uint64_t\ flags); PMEMoid\ pmemobj_tx_realloc(PMEMoid\ oid,\ size_t\ size,\ uint64_t\ type_num); PMEMoid\ pmemobj_tx_zrealloc(PMEMoid\ oid,\ size_t\ size,\ uint64_t\ type_num); PMEMoid\ pmemobj_tx_strdup(const\ char\ *s,\ uint64_t\ type_num); PMEMoid\ pmemobj_tx_wcsdup(const\ wchar_t\ *s,\ uint64_t\ type_num); int\ pmemobj_tx_free(PMEMoid\ oid); int\ pmemobj_tx_xfree(PMEMoid\ oid,\ uint64_t\ flags); TX_NEW(TYPE) TX_ALLOC(TYPE,\ size_t\ size) TX_ZNEW(TYPE) TX_ZALLOC(TYPE,\ size_t\ size) TX_XALLOC(TYPE,\ size_t\ size,\ uint64_t\ flags) TX_REALLOC(TOID\ o,\ size_t\ size) TX_ZREALLOC(TOID\ o,\ size_t\ size) TX_STRDUP(const\ char\ *s,\ uint64_t\ type_num) TX_WCSDUP(const\ wchar_t\ *s,\ uint64_t\ type_num) TX_FREE(TOID\ o) TX_XFREE(TOID\ o,\ uint64_t\ flags) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemobj_tx_alloc\f[]() function transactionally allocates a new object of given \f[I]size\f[] and \f[I]type_num\f[]. In contrast to the non\-transactional allocations, the objects are added to the internal object containers of given \f[I]type_num\f[] only after the transaction is committed, making the objects visible to the \f[B]POBJ_FOREACH_*\f[]() macros. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_zalloc\f[]() function transactionally allocates a new zeroed object of given \f[I]size\f[] and \f[I]type_num\f[]. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xalloc\f[]() function transactionally allocates a new object of given \f[I]size\f[] and \f[I]type_num\f[]. The \f[I]flags\f[] argument is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XALLOC_ZERO\f[] \- zero the allocated object (equivalent of pmemobj_tx_zalloc) .IP \[bu] 2 \f[B]POBJ_XALLOC_NO_FLUSH\f[] \- skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) .IP \[bu] 2 \f[B]POBJ_CLASS_ID(class_id)\f[] \- allocate an object from the allocation class with id equal to \f[I]class_id\f[] .IP \[bu] 2 \f[B]POBJ_ARENA_ID(arena_id)\f[] \- allocate an object from the arena specified by \f[I]arena_id\f[]. The arena must exist, otherwise, the behavior is undefined. If \f[I]arena_id\f[] is equal 0, then arena assigned to the current thread will be used. .IP \[bu] 2 \f[B]POBJ_XALLOC_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_realloc\f[]() function transactionally resizes an existing object to the given \f[I]size\f[] and changes its type to \f[I]type_num\f[]. If \f[I]oid\f[] is \f[B]OID_NULL\f[], then the call is equivalent to \f[I]pmemobj_tx_alloc(pop, size, type_num)\f[]. If \f[I]size\f[] is equal to zero and \f[I]oid\f[] is not \f[B]OID_NULL\f[], then the call is equivalent to \f[I]pmemobj_tx_free(oid)\f[]. If the new size is larger than the old size, the added memory will \f[I]not\f[] be initialized. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_zrealloc\f[]() function transactionally resizes an existing object to the given \f[I]size\f[] and changes its type to \f[I]type_num\f[]. If the new size is larger than the old size, the extended new space is zeroed. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_strdup\f[]() function transactionally allocates a new object containing a duplicate of the string \f[I]s\f[] and assigns it a type \f[I]type_num\f[]. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xstrdup\f[]() function behaves exactly the same as \f[B]pmemobj_tx_strdup\f[]() when \f[I]flags\f[] equals zero. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xalloc\f[] section. .PP The \f[B]pmemobj_tx_wcsdup\f[]() function transactionally allocates a new object containing a duplicate of the wide character string \f[I]s\f[] and assigns it a type \f[I]type_num\f[]. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xwcsdup\f[]() function behaves exactly the same as \f[B]pmemobj_tx_wcsdup\f[]() when \f[I]flags\f[] equals zero. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xalloc\f[] section. .PP The \f[B]pmemobj_tx_free\f[]() function transactionally frees an existing object referenced by \f[I]oid\f[]. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xfree\f[]() function behaves exactly the same as \f[B]pmemobj_tx_free\f[]() when \f[I]flags\f[] equals zero. \f[I]flags\f[] is a bitmask of the following value: .IP \[bu] 2 \f[B]POBJ_XFREE_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]TX_NEW\f[]() macro transactionally allocates a new object of given \f[I]TYPE\f[] and assigns it a type number read from the typed \f[I]OID\f[]. The allocation size is determined from the size of the user\-defined structure \f[I]TYPE\f[]. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_ALLOC\f[]() macro transactionally allocates a new object of given \f[I]TYPE\f[] and assigns it a type number read from the typed \f[I]OID\f[]. The allocation size is passed by \f[I]size\f[] parameter. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the stage is set to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_ZNEW\f[]() macro transactionally allocates a new zeroed object of given \f[I]TYPE\f[] and assigns it a type number read from the typed \f[I]OID\f[]. The allocation size is determined from the size of the user\-defined structure \f[I]TYPE\f[]. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, stage changes to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_ZALLOC\f[]() macro transactionally allocates a new zeroed object of given \f[I]TYPE\f[] and assigns it a type number read from the typed \f[I]OID\f[]. The allocation size is passed by \f[I]size\f[] argument. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_XALLOC\f[]() macro transactionally allocates a new object of given \f[I]TYPE\f[] and assigns it a type number read from the typed \f[I]OID\f[]. The allocation size is passed by \f[I]size\f[] argument. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xalloc\f[] section. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the \f[B]OID_NULL\f[] is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XALLOC_NO_ABORT\f[], the transaction is aborted. .PP The \f[B]TX_REALLOC\f[]() macro transactionally resizes an existing object referenced by a handle \f[I]o\f[] to the given \f[I]size\f[]. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the reallocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_ZREALLOC\f[]() macro transactionally resizes an existing object referenced by a handle \f[I]o\f[] to the given \f[I]size\f[]. If the new size is larger than the old size, the extended new space is zeroed. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the reallocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_STRDUP\f[]() macro transactionally allocates a new object containing a duplicate of the string \f[I]s\f[] and assigns it type \f[I]type_num\f[]. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_XSTRDUP\f[]() macro transactionally allocates a new object containing a duplicate of the string \f[I]s\f[] and assigns it type \f[I]type_num\f[]. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xalloc\f[] section. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the \f[B]OID_NULL\f[] is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XALLOC_NO_ABORT\f[], the transaction is aborted. .PP The \f[B]TX_WCSDUP\f[]() macro transactionally allocates a new object containing a duplicate of the wide character string \f[I]s\f[] and assigns it a type \f[I]type_num\f[]. If successful and called during \f[B]TX_STAGE_WORK\f[], it returns a handle to the newly allocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_XWCSDUP\f[]() macro transactionally allocates a new object containing a duplicate of the wide character string \f[I]s\f[] and assigns it a type \f[I]type_num\f[]. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xalloc\f[] section. If successful and called during \f[B]TX_STAGE_WORK\f[] it returns a handle to the newly allocated object. Otherwise, the \f[B]OID_NULL\f[] is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XALLOC_NO_ABORT\f[], the transaction is aborted. .PP The \f[B]TX_FREE\f[]() macro transactionally frees the memory space represented by an object handle \f[I]o\f[]. If \f[I]o\f[] is \f[B]OID_NULL\f[], no operation is performed. If successful and called during \f[B]TX_STAGE_WORK\f[], \f[B]TX_FREE\f[]() returns 0. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[] and \f[I]errno\f[] is set appropriately. .PP The \f[B]TX_XFREE\f[]() macro transactionally frees the memory space represented by an object handle \f[I]o\f[]. If \f[I]o\f[] is \f[B]OID_NULL\f[], no operation is performed. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xfree\f[] section. If successful and called during \f[B]TX_STAGE_WORK\f[], \f[B]TX_FREE\f[]() returns 0. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XFREE_NO_ABORT\f[], the transaction is aborted. .SH RETURN VALUE .PP On success, the \f[B]pmemobj_tx_alloc\f[](), \f[B]pmemobj_tx_zalloc\f[](), \f[B]pmemobj_tx_strdup\f[]() and \f[B]pmemobj_tx_wcsdup\f[]() functions return a handle to the newly allocated object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. If \f[I]size\f[] equals 0, \f[B]OID_NULL\f[] is returned and \f[I]errno\f[] is set appropriately. .PP On success, the \f[B]pmemobj_tx_xalloc\f[](), \f[B]pmemobj_tx_xstrdup\f[]() and \f[B]pmemobj_tx_xwcsdup\f[]() functions return a handle to the newly allocated object. Otherwise, the \f[B]OID_NULL\f[] is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XALLOC_NO_ABORT\f[], the transaction is aborted. .PP On success, \f[B]pmemobj_tx_realloc\f[]() and \f[B]pmemobj_tx_zrealloc\f[]() return a handle to the resized object. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]OID_NULL\f[] is returned, and \f[I]errno\f[] is set appropriately. Note that the object handle value may change as a result of reallocation. .PP On success, \f[B]pmemobj_tx_free\f[]() returns 0. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]errno\f[] is set appropriately and transaction is aborted .PP On success \f[B]pmemobj_tx_xfree\f[]() returns 0. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XFREE_NO_ABORT\f[], the transaction is aborted. .SH SEE ALSO .PP \f[B]pmemobj_tx_add_range\f[](3), \f[B]pmemobj_tx_begin\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pobj_list_head.3.md0000664000000000000000000002425014123364546017557 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(POBJ_LIST_HEAD, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pobj_list_head.3 -- man page for type-safe non-transactional persistent atomic lists) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[SEE ALSO](#see-also)
# NAME # **POBJ_LIST_HEAD**(), **POBJ_LIST_ENTRY**(), **POBJ_LIST_FIRST**(), **POBJ_LIST_LAST**(), **POBJ_LIST_EMPTY**(), **POBJ_LIST_NEXT**(), **POBJ_LIST_PREV**(), **POBJ_LIST_FOREACH**(), **POBJ_LIST_FOREACH_REVERSE**(), **POBJ_LIST_INSERT_HEAD**(), **POBJ_LIST_INSERT_TAIL**(), **POBJ_LIST_INSERT_AFTER**(), **POBJ_LIST_INSERT_BEFORE**(), **POBJ_LIST_INSERT_NEW_HEAD**(), **POBJ_LIST_INSERT_NEW_TAIL**(), **POBJ_LIST_INSERT_NEW_AFTER**(), **POBJ_LIST_INSERT_NEW_BEFORE**(), **POBJ_LIST_REMOVE**(), **POBJ_LIST_REMOVE_FREE**(), **POBJ_LIST_MOVE_ELEMENT_HEAD**(), **POBJ_LIST_MOVE_ELEMENT_TAIL**(), **POBJ_LIST_MOVE_ELEMENT_AFTER**(), **POBJ_LIST_MOVE_ELEMENT_BEFORE**() - type-safe non-transactional persistent atomic lists # SYNOPSIS # ```c #include POBJ_LIST_HEAD(HEADNAME, TYPE) POBJ_LIST_ENTRY(TYPE) POBJ_LIST_FIRST(POBJ_LIST_HEAD *head) POBJ_LIST_LAST(POBJ_LIST_HEAD *head, POBJ_LIST_ENTRY FIELD) POBJ_LIST_EMPTY(POBJ_LIST_HEAD *head) POBJ_LIST_NEXT(TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_PREV(TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_FOREACH(TOID var, POBJ_LIST_HEAD *head, POBJ_LIST_ENTRY FIELD) POBJ_LIST_FOREACH_REVERSE(TOID var, POBJ_LIST_HEAD *head, POBJ_LIST_ENTRY FIELD) POBJ_LIST_INSERT_HEAD(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_INSERT_TAIL(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_INSERT_AFTER(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID listelm, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_INSERT_BEFORE(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID listelm, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_INSERT_NEW_HEAD(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_ENTRY FIELD, size_t size, pmemobj_constr constructor, void *arg) POBJ_LIST_INSERT_NEW_TAIL(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_ENTRY FIELD, size_t size, pmemobj_constr constructor, void *arg) POBJ_LIST_INSERT_NEW_AFTER(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID listelm, POBJ_LIST_ENTRY FIELD, size_t size, pmemobj_constr constructor, void *arg) POBJ_LIST_INSERT_NEW_BEFORE(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID listelm, POBJ_LIST_ENTRY FIELD, size_t size, pmemobj_constr constructor, void *arg) POBJ_LIST_REMOVE(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_REMOVE_FREE(PMEMobjpool *pop, POBJ_LIST_HEAD *head, TOID elm, POBJ_LIST_ENTRY FIELD) POBJ_LIST_MOVE_ELEMENT_HEAD(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_HEAD *head_new, TOID elm, POBJ_LIST_ENTRY FIELD, POBJ_LIST_ENTRY field_new) POBJ_LIST_MOVE_ELEMENT_TAIL(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_HEAD *head_new, TOID elm, POBJ_LIST_ENTRY FIELD, POBJ_LIST_ENTRY field_new) POBJ_LIST_MOVE_ELEMENT_AFTER(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_HEAD *head_new, TOID listelm, TOID elm, POBJ_LIST_ENTRY FIELD, POBJ_LIST_ENTRY field_new) POBJ_LIST_MOVE_ELEMENT_BEFORE(PMEMobjpool *pop, POBJ_LIST_HEAD *head, POBJ_LIST_HEAD *head_new, TOID listelm, TOID elm, POBJ_LIST_ENTRY FIELD, POBJ_LIST_ENTRY field_new) ``` # DESCRIPTION # The following macros define and operate on a type-safe persistent atomic circular doubly linked list data structure that consist of a set of persistent objects of a well-known type. Unlike the functions described in the previous section, these macros provide type enforcement by requiring declaration of type of the objects stored in given list, and not allowing mixing objects of different types in a single list. The functionality and semantics of those macros is similar to circular queues defined in **queue**(3). The majority of the macros must specify the handle to the memory pool *pop* and the name of the *field* in the user-defined structure, which must be of type *POBJ_LIST_ENTRY* and is used to connect the elements in the list. A list is headed by a structure defined by the **POBJ_LIST_HEAD**() macro. This structure contains an object handle of the first element on the list. The elements are doubly linked so that an arbitrary element can be removed without a need to traverse the list. New elements can be added to the list before or after an existing element, at the head of the list, or at the end of the list. A list may be traversed in either direction. A *POBJ_LIST_HEAD* structure is declared as follows: ```c #define POBJ_LIST_HEAD(HEADNAME, TYPE) struct HEADNAME { TOID(TYPE) pe_first; PMEMmutex lock; }; ``` In the macro definitions, *TYPE* is the name of a user-defined structure, that must contain a field of type *POBJ_LIST_ENTRY*. The argument *HEADNAME* is the name of a user-defined structure that must be declared using the macro *POBJ_LIST_HEAD*. See the examples below for further explanation of how these macros are used. The macro *POBJ_LIST_ENTRY* declares a structure that connects the elements in the list. ```c #define POBJ_LIST_ENTRY(TYPE) struct { TOID(TYPE) pe_next; TOID(TYPE) pe_prev; }; ``` The macro **POBJ_LIST_FIRST**() returns the first element on the list referenced by *head*. If the list is empty **OID_NULL** is returned. The macro **POBJ_LIST_LAST**() returns the last element on the list referenced by *head*. If the list is empty **OID_NULL** is returned. The macro **POBJ_LIST_EMPTY**() evaluates to 1 if the list referenced by *head* is empty. Otherwise, 0 is returned. The macro **POBJ_LIST_NEXT**() returns the element next to the element *elm*. The macro **POBJ_LIST_PREV**() returns the element preceding the element *elm*. The macro **POBJ_LIST_FOREACH**() traverses the list referenced by *head* assigning a handle to each element in turn to *var* variable. The macro **POBJ_LIST_FOREACH_REVERSE**() traverses the list referenced by *head* in reverse order, assigning a handle to each element in turn to *var* variable. The *field* argument is the name of the field of type *POBJ_LIST_ENTRY* in the element structure. The macro **POBJ_LIST_INSERT_HEAD**() inserts the element *elm* at the head of the list referenced by *head*. The macro **POBJ_LIST_INSERT_TAIL**() inserts the element *elm* at the end of the list referenced by *head*. The macro **POBJ_LIST_INSERT_AFTER**() inserts the element *elm* into the list referenced by *head* after the element *listelm*. If *listelm* value is **TOID_NULL**, the object is inserted at the end of the list. The macro **POBJ_LIST_INSERT_BEFORE**() inserts the element *elm* into the list referenced by *head* before the element *listelm*. If *listelm* value is **TOID_NULL**, the object is inserted at the head of the list. The macro **POBJ_LIST_INSERT_NEW_HEAD**() atomically allocates a new object of size *size* and inserts it at the head of the list referenced by *head*. The newly allocated object is also added to the internal object container associated with a type number which is retrieved from the typed *OID* of the first element on list. The macro **POBJ_LIST_INSERT_NEW_TAIL**() atomically allocates a new object of size *size* and inserts it at the tail of the list referenced by *head*. The newly allocated object is also added to the internal object container associated with a type number which is retrieved from the typed *OID* of the first element on list. The macro **POBJ_LIST_INSERT_NEW_AFTER**() atomically allocates a new object of size *size* and inserts it into the list referenced by *head* after the element *listelm*. If *listelm* value is **TOID_NULL**, the object is inserted at the end of the list. The newly allocated object is also added to the internal object container associated with with a type number which is retrieved from the typed *OID* of the first element on list. The macro **POBJ_LIST_INSERT_NEW_BEFORE**() atomically allocates a new object of size *size* and inserts it into the list referenced by *head* before the element *listelm*. If *listelm* value is **TOID_NULL**, the object is inserted at the head of the list. The newly allocated object is also added to the internal object container associated with with a type number which is retrieved from the typed *OID* of the first element on list. The macro **POBJ_LIST_REMOVE**() removes the element *elm* from the list referenced by *head*. The macro **POBJ_LIST_REMOVE_FREE**() removes the element *elm* from the list referenced by *head* and frees the memory space represented by this element. The macro **POBJ_LIST_MOVE_ELEMENT_HEAD**() moves the element *elm* from the list referenced by *head* to the head of the list *head_new*. The *field* and *field_new* arguments are the names of the fields of type *POBJ_LIST_ENTRY* in the element structure that are used to connect the elements in both lists. The macro **POBJ_LIST_MOVE_ELEMENT_TAIL**() moves the element *elm* from the list referenced by *head* to the end of the list *head_new*. The *field* and *field_new* arguments are the names of the fields of type *POBJ_LIST_ENTRY* in the element structure that are used to connect the elements in both lists. The macro **POBJ_LIST_MOVE_ELEMENT_AFTER**() atomically removes the element *elm* from the list referenced by *head* and inserts it into the list referenced by *head_new* after the element *listelm*. If *listelm* value is *TOID_NULL*, the object is inserted at the end of the list. The *field* and *field_new* arguments are the names of the fields of type *POBJ_LIST_ENTRY* in the element structure that are used to connect the elements in both lists. The macro **POBJ_LIST_MOVE_ELEMENT_BEFORE**() atomically removes the element *elm* from the list referenced by *head* and inserts it into the list referenced by *head_new* before the element *listelm*. If *listelm* value is **TOID_NULL**, the object is inserted at the head of the list. The *field* and *field_new* arguments are the names of the fields of type *POBJ_LIST_ENTRY* in the element structure that are used to connect the elements in both lists. # SEE ALSO # **queue**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_after.30000664000000000000000000000002514123364546020736 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/tx_xadd.30000664000000000000000000000003314123364546015636 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_nodrain.30000664000000000000000000000003514123364546020513 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xwcsdup.30000664000000000000000000000002714123364546020127 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_reserve_new.30000664000000000000000000000002514123364546017542 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pobj_foreach_safe_type.30000664000000000000000000000002414123364546020663 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_errno.30000664000000000000000000000002714123364546017557 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_head.30000664000000000000000000000002514123364546020536 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_temporal.30000664000000000000000000000003514123364546020704 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_timedrdlock.30000664000000000000000000000003114123364546021574 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/toid_offsetof.30000664000000000000000000000002314123364546017034 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_mutex_timedlock.30000664000000000000000000000003114123364546021107 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pobj_free.30000664000000000000000000000002414123364546016136 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_remove.30000664000000000000000000000002514123364546017546 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xstrdup.30000664000000000000000000000002714123364546020143 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_add_range.3.md0000664000000000000000000002000114123364546020727 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_TX_ADD_RANGE, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2019, Intel Corporation) [comment]: <> (pmemobj_tx_add_range.3 -- man page for transactional object manipulation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_tx_add_range**(), **pmemobj_tx_add_range_direct**(), **pmemobj_tx_xadd_range**(), **pmemobj_tx_xadd_range_direct**() **TX_ADD**(), **TX_ADD_FIELD**(), **TX_ADD_DIRECT**(), **TX_ADD_FIELD_DIRECT**(), **TX_XADD**(), **TX_XADD_FIELD**(), **TX_XADD_DIRECT**(), **TX_XADD_FIELD_DIRECT**(), **TX_SET**(), **TX_SET_DIRECT**(), **TX_MEMCPY**(), **TX_MEMSET**() - transactional object manipulation # SYNOPSIS # ```c #include int pmemobj_tx_add_range(PMEMoid oid, uint64_t off, size_t size); int pmemobj_tx_add_range_direct(const void *ptr, size_t size); int pmemobj_tx_xadd_range(PMEMoid oid, uint64_t off, size_t size, uint64_t flags); int pmemobj_tx_xadd_range_direct(const void *ptr, size_t size, uint64_t flags); TX_ADD(TOID o) TX_ADD_FIELD(TOID o, FIELD) TX_ADD_DIRECT(TYPE *p) TX_ADD_FIELD_DIRECT(TYPE *p, FIELD) TX_XADD(TOID o, uint64_t flags) TX_XADD_FIELD(TOID o, FIELD, uint64_t flags) TX_XADD_DIRECT(TYPE *p, uint64_t flags) TX_XADD_FIELD_DIRECT(TYPE *p, FIELD, uint64_t flags) TX_SET(TOID o, FIELD, VALUE) TX_SET_DIRECT(TYPE *p, FIELD, VALUE) TX_MEMCPY(void *dest, const void *src, size_t num) TX_MEMSET(void *dest, int c, size_t num) ``` # DESCRIPTION # **pmemobj_tx_add_range**() takes a "snapshot" of the memory block of given *size*, located at given offset *off* in the object specified by *oid*, and saves it to the undo log. The application is then free to directly modify the object in that memory range. In case of a failure or abort, all the changes within this range will be rolled back. The supplied block of memory has to be within the pool registered in the transaction. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xadd_range**() function behaves exactly the same as **pmemobj_tx_add_range**() when *flags* equals zero. *flags* is a bitmask of the following values: + **POBJ_XADD_NO_FLUSH** - skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) + **POBJ_XADD_NO_SNAPSHOT** - added range will not be "snapshotted", i.e. any changes made within it during the transaction will not be rolled backed after abort + **POBJ_XADD_ASSUME_INITIALIZED** - added range is assumed to be initialized. If this flag is not specified, passing uninitialized memory will result in an error when run under Valgrind memcheck. + **POBJ_XADD_NO_ABORT** - if the function does not end successfully, do not abort the transaction. **pmemobj_tx_add_range_direct**() behaves the same as **pmemobj_tx_add_range**() with the exception that it operates on virtual memory addresses and not persistent memory objects. It takes a "snapshot" of a persistent memory block of given *size*, located at the given address *ptr* in the virtual memory space and saves it to the undo log. The application is then free to directly modify the object in that memory range. In case of a failure or abort, all the changes within this range will be rolled back. The supplied block of memory has to be within the pool registered in the transaction. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xadd_range_direct**() function behaves exactly the same as **pmemobj_tx_add_range_direct**() when *flags* equals zero. *flags* is a bitmask of the following values: + **POBJ_XADD_NO_FLUSH** - skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) + **POBJ_XADD_NO_SNAPSHOT** - added range will not be "snapshotted", i.e. any changes made within it during the transaction will not be rolled backed after abort + **POBJ_XADD_ASSUME_INITIALIZED** - added range is assumed to be initialized. If this flag is not specified, passing uninitialized memory will result in an error when run under Valgrind memcheck. + **POBJ_XADD_NO_ABORT** - if the function does not end successfully, do not abort the transaction. Similarly to the macros controlling the transaction flow, **libpmemobj** defines a set of macros that simplify the transactional operations on persistent objects. Note that those macros operate on typed object handles, thus eliminating the need to specify the size of the object, or the size and offset of the field in the user-defined structure that is to be modified. The **TX_ADD_FIELD**() macro saves the current value of given *FIELD* of the object referenced by a handle *o* in the undo log. The application is then free to directly modify the specified *FIELD*. In case of a failure or abort, the saved value will be restored. The **TX_XADD_FIELD**() macro works exactly like **TX_ADD_FIELD** when *flags* equals 0. The *flags* argument is a bitmask of values described in **pmemobj_tx_xadd_range**, above. The **TX_ADD**() macro takes a "snapshot" of the entire object referenced by object handle *o* and saves it in the undo log. The object size is determined from its *TYPE*. The application is then free to directly modify the object. In case of a failure or abort, all the changes within the object will be rolled back. The **TX_XADD**() macro works exactly like **TX_ADD** when *flags* equals 0. The *flags* argument is a bitmask of values as described in **pmemobj_tx_xadd_range**, above. The **TX_ADD_FIELD_DIRECT**() macro saves the current value of the given *FIELD* of the object referenced by (direct) pointer *p* in the undo log. The application is then free to directly modify the specified *FIELD*. In case of a failure or abort, the saved value will be restored. The **TX_XADD_FIELD_DIRECT**() macro works exactly like **TX_ADD_FIELD_DIRECT** when *flags* equals 0. The *flags* argument is a bitmask of values as described in **pmemobj_tx_xadd_range_direct**, above. The **TX_ADD_DIRECT**() macro takes a "snapshot" of the entire object referenced by (direct) pointer *p* and saves it in the undo log. The object size is determined from its *TYPE*. The application is then free to directly modify the object. In case of a failure or abort, all the changes within the object will be rolled back. The **TX_XADD_DIRECT**() macro works exactly like **TX_ADD_DIRECT** when *flags* equals 0. The *flags* argument is a bitmask of values as described in **pmemobj_tx_xadd_range_direct**, above. The **TX_SET**() macro saves the current value of the given *FIELD* of the object referenced by handle *o* in the undo log, and then sets its new *VALUE*. In case of a failure or abort, the saved value will be restored. The **TX_SET_DIRECT**() macro saves in the undo log the current value of given *FIELD* of the object referenced by (direct) pointer *p*, and then set its new *VALUE*. In case of a failure or abort, the saved value will be restored. The **TX_MEMCPY**() macro saves in the undo log the current content of *dest* buffer and then overwrites the first *num* bytes of its memory area with the data copied from the buffer pointed by *src*. In case of a failure or abort, the saved value will be restored. The **TX_MEMSET**() macro saves the current content of the *dest* buffer in the undo log and then fills the first *num* bytes of its memory area with the constant byte *c*. In case of a failure or abort, the saved value will be restored. # RETURN VALUE # On success, **pmemobj_tx_add_range**() and **pmemobj_tx_add_range_direct**() return 0. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **errno** is set appropriately and transaction is aborted. On success, **pmemobj_tx_xadd_range**() and **pmemobj_tx_xadd_range_direct**() returns 0. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XADD_NO_ABORT**, the transaction is aborted. # SEE ALSO # **pmemobj_tx_alloc**(3), **pmemobj_tx_begin**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_set_user_data.30000664000000000000000000000002314123364546020535 0ustar rootroot.so pmemobj_open.3 pmdk-1.11.1/doc/libpmemobj/toid_equals.30000664000000000000000000000002314123364546016513 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_move_element_head.30000664000000000000000000000002514123364546021711 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_set_value.30000664000000000000000000000002514123364546017704 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_flush.30000664000000000000000000000003514123364546017037 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/.gitignore0000664000000000000000000000046114123364546016114 0ustar rootrootlibpmemobj.7 oid_is_null.3 pmemobj_action.3 pmemobj_alloc.3 pmemobj_ctl_get.3 pmemobj_first.3 pmemobj_list_insert.3 pmemobj_memcpy_persist.3 pmemobj_mutex_zero.3 pmemobj_open.3 pmemobj_root.3 pmemobj_tx_add_range.3 pmemobj_tx_alloc.3 pmemobj_tx_begin.3 pobj_layout_begin.3 pobj_list_head.3 toid_declare.3 pmdk-1.11.1/doc/libpmemobj/tx_wcsdup.30000664000000000000000000000002714123364546016226 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_alloc_usable_size.30000664000000000000000000000002414123364546021373 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_xreserve_alloc.30000664000000000000000000000002514123364546020233 0ustar rootroot.so pmemobj_action.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_alloc.3.md0000664000000000000000000003011014123364546020117 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_TX_ALLOC, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2019, Intel Corporation) [comment]: <> (pmemobj_tx_alloc.3 -- man page for transactional object manipulation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_tx_alloc**(), **pmemobj_tx_zalloc**(), **pmemobj_tx_xalloc**(), **pmemobj_tx_realloc**(), **pmemobj_tx_zrealloc**(), **pmemobj_tx_strdup**(), **pmemobj_tx_xstrdup**(), **pmemobj_tx_wcsdup**(), **pmemobj_tx_xwcsdup**(), **pmemobj_tx_free**(), **pmemobj_tx_xfree**() **TX_NEW**(), **TX_ALLOC**(), **TX_ZNEW**(), **TX_ZALLOC**(), **TX_XALLOC**(), **TX_REALLOC**(), **TX_ZREALLOC**(), **TX_STRDUP**(), **TX_XSTRDUP**(), **TX_WCSDUP**(), **TX_XWCSDUP**(), **TX_FREE**(), **TX_XFREE**() - transactional object manipulation # SYNOPSIS # ```c #include PMEMoid pmemobj_tx_alloc(size_t size, uint64_t type_num); PMEMoid pmemobj_tx_zalloc(size_t size, uint64_t type_num); PMEMoid pmemobj_tx_xalloc(size_t size, uint64_t type_num, uint64_t flags); PMEMoid pmemobj_tx_realloc(PMEMoid oid, size_t size, uint64_t type_num); PMEMoid pmemobj_tx_zrealloc(PMEMoid oid, size_t size, uint64_t type_num); PMEMoid pmemobj_tx_strdup(const char *s, uint64_t type_num); PMEMoid pmemobj_tx_wcsdup(const wchar_t *s, uint64_t type_num); int pmemobj_tx_free(PMEMoid oid); int pmemobj_tx_xfree(PMEMoid oid, uint64_t flags); TX_NEW(TYPE) TX_ALLOC(TYPE, size_t size) TX_ZNEW(TYPE) TX_ZALLOC(TYPE, size_t size) TX_XALLOC(TYPE, size_t size, uint64_t flags) TX_REALLOC(TOID o, size_t size) TX_ZREALLOC(TOID o, size_t size) TX_STRDUP(const char *s, uint64_t type_num) TX_WCSDUP(const wchar_t *s, uint64_t type_num) TX_FREE(TOID o) TX_XFREE(TOID o, uint64_t flags) ``` # DESCRIPTION # The **pmemobj_tx_alloc**() function transactionally allocates a new object of given *size* and *type_num*. In contrast to the non-transactional allocations, the objects are added to the internal object containers of given *type_num* only after the transaction is committed, making the objects visible to the **POBJ_FOREACH_\***() macros. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_zalloc**() function transactionally allocates a new zeroed object of given *size* and *type_num*. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xalloc**() function transactionally allocates a new object of given *size* and *type_num*. The *flags* argument is a bitmask of the following values: + **POBJ_XALLOC_ZERO** - zero the allocated object (equivalent of pmemobj_tx_zalloc) + **POBJ_XALLOC_NO_FLUSH** - skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) + **POBJ_CLASS_ID(class_id)** - allocate an object from the allocation class with id equal to *class_id* + **POBJ_ARENA_ID(arena_id)** - allocate an object from the arena specified by *arena_id*. The arena must exist, otherwise, the behavior is undefined. If *arena_id* is equal 0, then arena assigned to the current thread will be used. + **POBJ_XALLOC_NO_ABORT** - if the function does not end successfully, do not abort the transaction. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_realloc**() function transactionally resizes an existing object to the given *size* and changes its type to *type_num*. If *oid* is **OID_NULL**, then the call is equivalent to *pmemobj_tx_alloc(pop, size, type_num)*. If *size* is equal to zero and *oid* is not **OID_NULL**, then the call is equivalent to *pmemobj_tx_free(oid)*. If the new size is larger than the old size, the added memory will *not* be initialized. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_zrealloc**() function transactionally resizes an existing object to the given *size* and changes its type to *type_num*. If the new size is larger than the old size, the extended new space is zeroed. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_strdup**() function transactionally allocates a new object containing a duplicate of the string *s* and assigns it a type *type_num*. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xstrdup**() function behaves exactly the same as **pmemobj_tx_strdup**() when *flags* equals zero. The *flags* argument is a bitmask of values described in **pmemobj_tx_xalloc** section. The **pmemobj_tx_wcsdup**() function transactionally allocates a new object containing a duplicate of the wide character string *s* and assigns it a type *type_num*. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xwcsdup**() function behaves exactly the same as **pmemobj_tx_wcsdup**() when *flags* equals zero. The *flags* argument is a bitmask of values described in **pmemobj_tx_xalloc** section. The **pmemobj_tx_free**() function transactionally frees an existing object referenced by *oid*. This function must be called during **TX_STAGE_WORK**. The **pmemobj_tx_xfree**() function behaves exactly the same as **pmemobj_tx_free**() when *flags* equals zero. *flags* is a bitmask of the following value: + **POBJ_XFREE_NO_ABORT** - if the function does not end successfully, do not abort the transaction. This function must be called during **TX_STAGE_WORK**. The **TX_NEW**() macro transactionally allocates a new object of given *TYPE* and assigns it a type number read from the typed *OID*. The allocation size is determined from the size of the user-defined structure *TYPE*. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_ALLOC**() macro transactionally allocates a new object of given *TYPE* and assigns it a type number read from the typed *OID*. The allocation size is passed by *size* parameter. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the stage is set to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_ZNEW**() macro transactionally allocates a new zeroed object of given *TYPE* and assigns it a type number read from the typed *OID*. The allocation size is determined from the size of the user-defined structure *TYPE*. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, stage changes to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_ZALLOC**() macro transactionally allocates a new zeroed object of given *TYPE* and assigns it a type number read from the typed *OID*. The allocation size is passed by *size* argument. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_XALLOC**() macro transactionally allocates a new object of given *TYPE* and assigns it a type number read from the typed *OID*. The allocation size is passed by *size* argument. The *flags* argument is a bitmask of values described in **pmemobj_tx_xalloc** section. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the **OID_NULL** is returned, **errno** is set and when flags do not contain **POBJ_XALLOC_NO_ABORT**, the transaction is aborted. The **TX_REALLOC**() macro transactionally resizes an existing object referenced by a handle *o* to the given *size*. If successful and called during **TX_STAGE_WORK** it returns a handle to the reallocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_ZREALLOC**() macro transactionally resizes an existing object referenced by a handle *o* to the given *size*. If the new size is larger than the old size, the extended new space is zeroed. If successful and called during **TX_STAGE_WORK** it returns a handle to the reallocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_STRDUP**() macro transactionally allocates a new object containing a duplicate of the string *s* and assigns it type *type_num*. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_XSTRDUP**() macro transactionally allocates a new object containing a duplicate of the string *s* and assigns it type *type_num*. The *flags* argument is a bitmask of values described in **pmemobj_tx_xalloc** section. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the **OID_NULL** is returned, **errno** is set and when flags do not contain **POBJ_XALLOC_NO_ABORT**, the transaction is aborted. The **TX_WCSDUP**() macro transactionally allocates a new object containing a duplicate of the wide character string *s* and assigns it a type *type_num*. If successful and called during **TX_STAGE_WORK**, it returns a handle to the newly allocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. The **TX_XWCSDUP**() macro transactionally allocates a new object containing a duplicate of the wide character string *s* and assigns it a type *type_num*. The *flags* argument is a bitmask of values described in **pmemobj_tx_xalloc** section. If successful and called during **TX_STAGE_WORK** it returns a handle to the newly allocated object. Otherwise, the **OID_NULL** is returned, **errno** is set and when flags do not contain **POBJ_XALLOC_NO_ABORT**, the transaction is aborted. The **TX_FREE**() macro transactionally frees the memory space represented by an object handle *o*. If *o* is **OID_NULL**, no operation is performed. If successful and called during **TX_STAGE_WORK**, **TX_FREE**() returns 0. Otherwise, the stage is changed to **TX_STAGE_ONABORT** and *errno* is set appropriately. The **TX_XFREE**() macro transactionally frees the memory space represented by an object handle *o*. If *o* is **OID_NULL**, no operation is performed. The *flags* argument is a bitmask of values described in **pmemobj_tx_xfree** section. If successful and called during **TX_STAGE_WORK**, **TX_FREE**() returns 0. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XFREE_NO_ABORT**, the transaction is aborted. # RETURN VALUE # On success, the **pmemobj_tx_alloc**(), **pmemobj_tx_zalloc**(), **pmemobj_tx_strdup**() and **pmemobj_tx_wcsdup**() functions return a handle to the newly allocated object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. If *size* equals 0, **OID_NULL** is returned and *errno* is set appropriately. On success, the **pmemobj_tx_xalloc**(), **pmemobj_tx_xstrdup**() and **pmemobj_tx_xwcsdup**() functions return a handle to the newly allocated object. Otherwise, the **OID_NULL** is returned, **errno** is set and when flags do not contain **POBJ_XALLOC_NO_ABORT**, the transaction is aborted. On success, **pmemobj_tx_realloc**() and **pmemobj_tx_zrealloc**() return a handle to the resized object. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **OID_NULL** is returned, and *errno* is set appropriately. Note that the object handle value may change as a result of reallocation. On success, **pmemobj_tx_free**() returns 0. Otherwise, the stage is changed to **TX_STAGE_ONABORT**, **errno** is set appropriately and transaction is aborted On success **pmemobj_tx_xfree**() returns 0. Otherwise, the error number is returned, **errno** is set and when flags do not contain **POBJ_XFREE_NO_ABORT**, the transaction is aborted. # SEE ALSO # **pmemobj_tx_add_range**(3), **pmemobj_tx_begin**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_first.3.md0000664000000000000000000000704214123364546017451 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_FIRST, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemobj_first.3 -- man page for pmemobj container operations) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[SEE ALSO](#see-also)
# NAME # **pmemobj_first**(), **pmemobj_next**(), **POBJ_FIRST**(), **POBJ_FIRST_TYPE_NUM**(), **POBJ_NEXT**(), **POBJ_NEXT_TYPE_NUM**(), **POBJ_FOREACH**(), **POBJ_FOREACH_SAFE**(), **POBJ_FOREACH_TYPE**(), **POBJ_FOREACH_SAFE_TYPE**() - pmemobj container operations # SYNOPSIS # ```c #include PMEMoid pmemobj_first(PMEMobjpool *pop); PMEMoid pmemobj_next(PMEMoid oid); POBJ_FIRST(PMEMobjpool *pop, TYPE) POBJ_FIRST_TYPE_NUM(PMEMobjpool *pop, uint64_t type_num) POBJ_NEXT(TOID oid) POBJ_NEXT_TYPE_NUM(PMEMoid oid) POBJ_FOREACH(PMEMobjpool *pop, PMEMoid varoid) POBJ_FOREACH_SAFE(PMEMobjpool *pop, PMEMoid varoid, PMEMoid nvaroid) POBJ_FOREACH_TYPE(PMEMobjpool *pop, TOID var) POBJ_FOREACH_SAFE_TYPE(PMEMobjpool *pop, TOID var, TOID nvar) ``` # DESCRIPTION # The **libpmemobj**(7) container operations provide a mechanism that allows iteration through the internal object collection, either looking for a specific object, or performing a specific operation on each object of a given type. Software should not make any assumptions about the order of the objects in the internal object containers. The **pmemobj_first**() function returns the first object from the pool. The **POBJ_FIRST**() macro returns the first object from the pool of the type specified by *TYPE*. The **POBJ_FIRST_TYPE_NUM**() macro returns the first object from the pool of the type specified by *type_num*. The **pmemobj_next**() function returns the next object from the pool. The **POBJ_NEXT**() macro returns the next object of the same type as the object referenced by *oid*. The **POBJ_NEXT_TYPE_NUM**() macro returns the next object of the same type number as the object referenced by *oid*. The following four macros provide a more convenient way to iterate through the internal collections, performing a specific operation on each object. The **POBJ_FOREACH**() macro performs a specific operation on each allocated object stored in the persistent memory pool *pop*. It traverses the internal collection of all the objects, assigning a handle to each element in turn to *varoid*. The **POBJ_FOREACH_TYPE**() macro performs a specific operation on each allocated object stored in the persistent memory pool *pop* that has the same type as *var*. It traverses the internal collection of all the objects of the specified type, assigning a handle to each element in turn to *var*. The macros **POBJ_FOREACH_SAFE**() and **POBJ_FOREACH_SAFE_TYPE**() work in a similar fashion as **POBJ_FOREACH**() and **POBJ_FOREACH_TYPE**(), except that prior to performing the operation on the object, they preserve a handle to the next object in the collection by assigning it to *nvaroid* or *nvar*, respectively. This allows safe deletion of selected objects while iterating through the collection. # RETURN VALUE # **pmemobj_first**() returns the first object from the pool, or, if the pool is empty, **OID_NULL**. **pmemobj_next**() returns the next object from the pool. If the object referenced by *oid* is the last object in the collection, or if *oid* is *OID_NULL*, **pmemobj_next**() returns **OID_NULL**. # SEE ALSO # **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_wc.30000664000000000000000000000003514123364546017472 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_memset_persist.30000664000000000000000000000003514123364546020761 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_strdup.30000664000000000000000000000002414123364546017235 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_open.3.md0000664000000000000000000001776014123364546017273 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_OPEN, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2021, Intel Corporation) [comment]: <> (pmemobj_open.3 -- man page for most commonly used functions from libpmemobj library) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # _UW(pmemobj_open), _UW(pmemobj_create), **pmemobj_close**(), _UW(pmemobj_check) **pmemobj_set_user_data**(), **pmemobj_get_user_data**() - create, open, close and validate persistent memory transactional object store # SYNOPSIS # ```c #include _UWFUNCR1(PMEMobjpool, *pmemobj_open, *path, const char *layout) _UWFUNCR1(PMEMobjpool, *pmemobj_create, *path, =q=const char *layout, size_t poolsize, mode_t mode=e=) void pmemobj_close(PMEMobjpool *pop); _UWFUNCR1(int, pmemobj_check, *path, const char *layout) void pmemobj_set_user_data(PMEMobjpool *pop, void *data); void *pmemobj_get_user_data(PMEMobjpool *pop); ``` _UNICODE() # DESCRIPTION # To use the pmem-resident transactional object store provided by **libpmemobj**(7), a *memory pool* must first be created with the _UW(pmemobj_create) function described below. Existing pools may be opened with the _UW(pmemobj_open) function. As of **libpmemobj** **1.11**, these functions are thread-safe; be careful if you have to use earlier versions of the library. Once created, the memory pool is represented by an opaque handle, of type *PMEMobjpool\**, which is passed to most of the other **libpmemobj**(7) functions. Internally, **libpmemobj**(7) will use either **pmem_persist**(3) or **msync**(2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the **pmem_is_pmem**(3) function in **libpmem**(7) for more information). There is no need for applications to flush changes directly when using the object memory API provided by **libpmemobj**(7). The _UW(pmemobj_create) function creates a transactional object store with the given total *poolsize*. *path* specifies the name of the memory pool file to be created. *layout* specifies the application's layout type in the form of a string. The layout name is not interpreted by **libpmemobj**(7), but may be used as a check when _UW(pmemobj_open) is called. The layout name, including the terminating null byte ('\0'), cannot be longer than **PMEMOBJ_MAX_LAYOUT** as defined in **\**. A NULL *layout* is equivalent to using an empty string as a layout name. *mode* specifies the permissions to use when creating the file, as described by **creat**(2). The memory pool file is fully allocated to the size *poolsize* using **posix_fallocate**(3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling _UW(pmemobj_create), and then specifying *poolsize* as zero. In this case _UW(pmemobj_create) will take the pool size from the size of the existing file and will verify that the file appears to be empty by searching for any non-zero data in the pool header at the beginning of the file. The minimum net pool size allowed by the library for a local transactional object store is defined in **\** as **PMEMOBJ_MIN_POOL**. _WINUX(,=q=For remote replicas the minimum file size is defined in **\** as **RPMEM_MIN_PART**.=e=) Depending on the configuration of the system, the available non-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemobj memory pool could be limited by the capacity of a single memory device. **libpmemobj**(7) allows building persistent memory resident object store spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a *pool set* may be stored on a different memory device or pmem-aware filesystem. Creation of all the parts of the pool set can be done with _UW(pmemobj_create); however, the recommended method for creating pool sets is with the **pmempool**(1) utility. When creating a pool set consisting of multiple files, the *path* argument passed to _UW(pmemobj_create) must point to the special *set* file that defines the pool layout and the location of all the parts of the pool set. The *poolsize* argument must be 0. The meaning of the *layout* and *mode* arguments does not change, except that the same *mode* is used for creation of all the parts of the pool set. The *set* file is a plain text file, the structure of which is described in **poolset**(5). The _UW(pmemobj_open) function opens an existing object store memory pool. Similar to _UW(pmemobj_create), *path* must identify either an existing obj memory pool file, or the *set* file used to create a pool set. If *layout* is non-NULL, it is compared to the layout name provided to _UW(pmemobj_create) when the pool was first created. This can be used to verify that the layout of the pool matches what was expected. The application must have permission to open the file and memory map it with read/write permissions. Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in **pmempool-feature**(1). The **pmemobj_close**() function closes the memory pool indicated by *pop* and deletes the memory pool handle. The object store itself lives on in the file that contains it and may be re-opened at a later time using _UW(pmemobj_open) as described above. The _UW(pmemobj_check) function performs a consistency check of the file indicated by *path*. _UW(pmemobj_check) opens the given *path* read-only so it never makes any changes to the file. This function is not supported on Device DAX. The **pmemobj_set_user_data**() function associates custom volatile state, represented by pointer *data*, with the given pool *pop*. This state can later be retrieved using **pmemobj_get_user_data**() function. This state does not survive pool close. If **pmemobj_set_user_data**() was not called for a given pool, **pmemobj_get_user_data**() will return NULL. # RETURN VALUE # The _UW(pmemobj_create) function returns a memory pool handle to be used with most of the functions in **libpmemobj**(7). On error it returns NULL and sets *errno* appropriately. The _UW(pmemobj_open) function returns a memory pool handle to be used with most of the functions in **libpmemobj**(7). If an error prevents the pool from being opened, or if the given *layout* does not match the pool's layout, _UW(pmemobj_open) returns NULL and sets *errno* appropriately. The **pmemobj_close**() function returns no value. The _UW(pmemobj_check) function returns 1 if the memory pool is found to be consistent. Any inconsistencies found will cause _UW(pmemobj_check) to return 0, in which case the use of the file with **libpmemobj**(7) will result in undefined behavior. The debug version of **libpmemobj**(7) will provide additional details on inconsistencies when **PMEMOBJ_LOG_LEVEL** is at least 1, as described in the **DEBUGGING AND ERROR HANDLING** section in **libpmemobj**(7). _UW(pmemobj_check) returns -1 and sets *errno* if it cannot perform the consistency check due to other errors. # CAVEATS # Not all file systems support **posix_fallocate**(3). _UW(pmemobj_create) will fail if the underlying file system does not support **posix_fallocate**(3). _WINUX(=q= On Windows if _UW(pmemobj_create) is called on an existing file with FILE_ATTRIBUTE_SPARSE_FILE and FILE_ATTRIBUTE_COMPRESSED set, they will be removed, to physically allocate space for the pool. This is a workaround for _chsize() performance issues. =e=) # SEE ALSO # **creat**(2), **msync**(2), **pmem_is_pmem**(3), **pmem_persist**(3), **posix_fallocate**(3), **libpmem**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_cond_zero.30000664000000000000000000000003114123364546017674 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_get_failure_behavior.30000664000000000000000000000002714123364546022577 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_zalloc.30000664000000000000000000000002414123364546016501 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_volatile.30000664000000000000000000000002214123364546017531 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_cond_signal.30000664000000000000000000000003114123364546020172 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_check_version.30000664000000000000000000000002614123364546020540 0ustar rootroot.so man7/libpmemobj.7 pmdk-1.11.1/doc/libpmemobj/pmemobj_list_remove.30000664000000000000000000000003214123364546020243 0ustar rootroot.so pmemobj_list_insert.3 pmdk-1.11.1/doc/libpmemobj/pobj_next.30000664000000000000000000000002414123364546016173 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_strdup.30000664000000000000000000000002714123364546017753 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_new.30000664000000000000000000000002414123364546016006 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_znew.30000664000000000000000000000002414123364546016200 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xadd_range.30000664000000000000000000000003314123364546020523 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_noflush.30000664000000000000000000000003514123364546020537 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/tx_xadd_field_direct.30000664000000000000000000000003314123364546020333 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/toid_assign.30000664000000000000000000000002314123364546016505 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_oid.30000664000000000000000000000002214123364546016465 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_insert_new_tail.30000664000000000000000000000002514123364546021437 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_f_mem_nontemporal.30000664000000000000000000000003514123364546021417 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_zero.30000664000000000000000000000003114123364546020252 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xalloc.30000664000000000000000000000002714123364546017714 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/tx_realloc.30000664000000000000000000000002714123364546016342 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_abort.30000664000000000000000000000002714123364546017541 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_root_construct.30000664000000000000000000000002314123364546021002 0ustar rootroot.so pmemobj_root.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_name.30000664000000000000000000000003014123364546017527 0ustar rootroot.so pobj_layout_begin.3 pmdk-1.11.1/doc/libpmemobj/pobj_foreach_type.30000664000000000000000000000002414123364546017665 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/tx_set_direct.30000664000000000000000000000003314123364546017043 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pobj_list_entry.30000664000000000000000000000002514123364546017412 0ustar rootroot.so pobj_list_head.3 pmdk-1.11.1/doc/libpmemobj/tx_memcpy.30000664000000000000000000000003314123364546016210 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_first.30000664000000000000000000000723314123364732017051 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_FIRST" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemobj_first\f[](), \f[B]pmemobj_next\f[](), \f[B]POBJ_FIRST\f[](), \f[B]POBJ_FIRST_TYPE_NUM\f[](), \f[B]POBJ_NEXT\f[](), \f[B]POBJ_NEXT_TYPE_NUM\f[](), \f[B]POBJ_FOREACH\f[](), \f[B]POBJ_FOREACH_SAFE\f[](), \f[B]POBJ_FOREACH_TYPE\f[](), \f[B]POBJ_FOREACH_SAFE_TYPE\f[]() \- pmemobj container operations .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMoid\ pmemobj_first(PMEMobjpool\ *pop); PMEMoid\ pmemobj_next(PMEMoid\ oid); POBJ_FIRST(PMEMobjpool\ *pop,\ TYPE) POBJ_FIRST_TYPE_NUM(PMEMobjpool\ *pop,\ uint64_t\ type_num) POBJ_NEXT(TOID\ oid) POBJ_NEXT_TYPE_NUM(PMEMoid\ oid) POBJ_FOREACH(PMEMobjpool\ *pop,\ PMEMoid\ varoid) POBJ_FOREACH_SAFE(PMEMobjpool\ *pop,\ PMEMoid\ varoid,\ PMEMoid\ nvaroid) POBJ_FOREACH_TYPE(PMEMobjpool\ *pop,\ TOID\ var) POBJ_FOREACH_SAFE_TYPE(PMEMobjpool\ *pop,\ TOID\ var,\ TOID\ nvar) \f[] .fi .SH DESCRIPTION .PP The \f[B]libpmemobj\f[](7) container operations provide a mechanism that allows iteration through the internal object collection, either looking for a specific object, or performing a specific operation on each object of a given type. Software should not make any assumptions about the order of the objects in the internal object containers. .PP The \f[B]pmemobj_first\f[]() function returns the first object from the pool. .PP The \f[B]POBJ_FIRST\f[]() macro returns the first object from the pool of the type specified by \f[I]TYPE\f[]. .PP The \f[B]POBJ_FIRST_TYPE_NUM\f[]() macro returns the first object from the pool of the type specified by \f[I]type_num\f[]. .PP The \f[B]pmemobj_next\f[]() function returns the next object from the pool. .PP The \f[B]POBJ_NEXT\f[]() macro returns the next object of the same type as the object referenced by \f[I]oid\f[]. .PP The \f[B]POBJ_NEXT_TYPE_NUM\f[]() macro returns the next object of the same type number as the object referenced by \f[I]oid\f[]. .PP The following four macros provide a more convenient way to iterate through the internal collections, performing a specific operation on each object. .PP The \f[B]POBJ_FOREACH\f[]() macro performs a specific operation on each allocated object stored in the persistent memory pool \f[I]pop\f[]. It traverses the internal collection of all the objects, assigning a handle to each element in turn to \f[I]varoid\f[]. .PP The \f[B]POBJ_FOREACH_TYPE\f[]() macro performs a specific operation on each allocated object stored in the persistent memory pool \f[I]pop\f[] that has the same type as \f[I]var\f[]. It traverses the internal collection of all the objects of the specified type, assigning a handle to each element in turn to \f[I]var\f[]. .PP The macros \f[B]POBJ_FOREACH_SAFE\f[]() and \f[B]POBJ_FOREACH_SAFE_TYPE\f[]() work in a similar fashion as \f[B]POBJ_FOREACH\f[]() and \f[B]POBJ_FOREACH_TYPE\f[](), except that prior to performing the operation on the object, they preserve a handle to the next object in the collection by assigning it to \f[I]nvaroid\f[] or \f[I]nvar\f[], respectively. This allows safe deletion of selected objects while iterating through the collection. .SH RETURN VALUE .PP \f[B]pmemobj_first\f[]() returns the first object from the pool, or, if the pool is empty, \f[B]OID_NULL\f[]. .PP \f[B]pmemobj_next\f[]() returns the next object from the pool. If the object referenced by \f[I]oid\f[] is the last object in the collection, or if \f[I]oid\f[] is \f[I]OID_NULL\f[], \f[B]pmemobj_next\f[]() returns \f[B]OID_NULL\f[]. .SH SEE ALSO .PP \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/tx_end.30000664000000000000000000000002714123364546015467 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/tx_zrealloc.30000664000000000000000000000002714123364546016534 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_ctl_exec.30000664000000000000000000000002614123364546017504 0ustar rootroot.so pmemobj_ctl_get.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_list_insert.3.md0000664000000000000000000001661714123364546020671 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_LIST_INSERT, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemobj_list_insert.3 -- man page for non-transactional persistent atomic lists) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemobj_list_insert**(), **pmemobj_list_insert_new**(), **pmemobj_list_move**(), **pmemobj_list_remove**() - non-transactional persistent atomic lists functions # SYNOPSIS # ```c #include int pmemobj_list_insert(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid dest, int before, PMEMoid oid); PMEMoid pmemobj_list_insert_new(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid dest, int before, size_t size, uint64_t type_num, pmemobj_constr constructor, void arg); int pmemobj_list_move(PMEMobjpool *pop, size_t pe_old_offset, void *head_old, size_t pe_new_offset, void *head_new, PMEMoid dest, int before, PMEMoid oid); int pmemobj_list_remove(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid oid, int free); ``` # DESCRIPTION # In addition to the container operations on internal object collections described in **pmemobj_first**(3), **libpmemobj**(7) provides a mechanism for organizing persistent objects in user-defined, persistent, atomic, circular, doubly-linked lists. All the routines and macros operating on the persistent lists provide atomicity with respect to any power-fail interruptions. If any of those operations is torn by program failure or system crash, on recovery they are guaranteed to be entirely completed or discarded, leaving the lists, persistent memory heap and internal object containers in a consistent state. The persistent atomic circular doubly linked lists support the following functionality: + Insertion of an object at the head of the list, or at the end of the list. + Insertion of an object before or after any element in the list. + Atomic allocation and insertion of a new object at the head of the list, or at the end of the list. + Atomic allocation and insertion of a new object before or after any element in the list. + Atomic moving of an element from one list to the specific location on another list. + Removal of any object in the list. + Atomic removal and freeing of any object in the list. + Forward or backward traversal through the list. A list is headed by a *list_head* structure containing the object handle of the first element on the list. The elements are doubly linked so that an arbitrary element can be removed without the need to traverse the list. New elements can be added to the list before or after an existing element, at the head of the list, or at the tail of the list. A list may be traversed in either direction. The user-defined structure of each element must contain a field of type *list_entry* that holds the object handles to the previous and next element on the list. Both the *list_head* and the *list_entry* structures are declared in **\**. The functions below are intended to be used outside transactions - transactional variants are described in manpages to functions mentioned at **TRANSACTIONAL OBJECT MANIPULATION** in **libpmemobj**(7). Note that operations performed using this non-transactional API are independent from their transactional counterparts. If any non-transactional allocations or list manipulations are performed within an open transaction, the changes will not be rolled back if such a transaction is aborted or interrupted. The list insertion and move functions use a common set of arguments to define where an object will be inserted into the list. *dest* identifies the element before or after which the object will be inserted, or, if *dest* is **OID_NULL**, indicates that the object should be inserted at the head or tail of the list. *before* determines where the object will be inserted: + **POBJ_LIST_DEST_BEFORE** - insert the element before the existing element *dest* + **POBJ_LIST_DEST_AFTER** - insert the element after the existing element *dest* + **POBJ_LIST_DEST_HEAD** - when *dest* is **OID_NULL**, insert the element at the head of the list + **POBJ_LIST_DEST_TAIL** - when *dest* is **OID_NULL**, insert the element at the tail of the list >NOTE: Earlier versions of **libpmemobj**(7) do not define **POBJ_LIST_DEST_BEFORE** and **POBJ_LIST_DEST_AFTER**. Use 1 for before, and 0 for after. The **pmemobj_list_insert**() function inserts the element represented by object handle *oid* into the list referenced by *head*, at the location specified by *dest* and *before* as described above. *pe_offset* specifies the offset of the structure that connects the elements in the list. All the handles *head*, *dest* and *oid* must point to objects allocated from memory pool *pop*. *head* and *oid* cannot be **OID_NULL**. The **pmemobj_list_insert_new**() function atomically allocates a new object of given *size* and type *type_num* and inserts it into the list referenced by *head* at the location specified by *dest* and *before* as described above. *pe_offset* specifies the offset of the structure that connects the elements in the list. The handles *head* and *dest* must point to objects allocated from memory pool *pop*. Before returning, **pmemobj_list_insert_new**() calls the *constructor* function, passing the pool handle *pop*, the pointer to the newly allocated object *ptr*, and the *arg* argument. It is guaranteed that the allocated object is either properly initialized or, if the allocation is interrupted before the constructor completes, the memory space reserved for the object is reclaimed. *head* cannot be **OID_NULL**. The allocated object is also added to the internal container associated with *type_num*, as described in **POBJ_FOREACH**(3). The **pmemobj_list_move**() function moves the object represented by object handle *oid* from the list referenced by *head_old* to the list referenced by *head_new*, inserting it at the location specified by *dest* and *before* as described above. *pe_old_offset* and *pe_new_offset* specify the offsets of the structures that connect the elements in the old and new lists, respectively. All the handles *head_old*, *head_new*, *dest* and *oid* must point to objects allocated from memory pool *pop*. *head_old*, *head_new* and *oid* cannot be **OID_NULL**. The **pmemobj_list_remove**() function removes the object represented by object handle *oid* from the list referenced by *head*. If *free* is set, it also removes the object from the internal object container and frees the associated memory space. *pe_offset* specifies the offset of the structure that connects the elements in the list. Both *head* and *oid* must point to objects allocated from memory pool *pop* and cannot be **OID_NULL**. # RETURN VALUE # On success, **pmemobj_list_insert**(), **pmemobj_list_remove**() and **pmemobj_list_move**() return 0. On error, they return -1 and set *errno* appropriately. On success, **pmemobj_list_insert_new**() returns a handle to the newly allocated object. If the constructor returns a non-zero value, the allocation is canceled, -1 is returned, and *errno* is set to **ECANCELED**. On other errors, **OID_NULL** is returned and *errno* is set appropriately. # SEE ALSO # **pmemobj_first**(3), **POBJ_FOREACH**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/tx_xstrdup.30000664000000000000000000000002714123364546016432 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_rwlock_tryrdlock.30000664000000000000000000000003114123364546021310 0ustar rootroot.so pmemobj_mutex_zero.3 pmdk-1.11.1/doc/libpmemobj/pobj_layout_begin.3.md0000664000000000000000000000624714123364546020312 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(POBJ_LAYOUT_BEGIN, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pobj_layout_begin.3 -- man page for declaration of pool's layout) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[EXAMPLE](#example)
[SEE ALSO](#see-also)
# NAME # **POBJ_LAYOUT_BEGIN**(), **POBJ_LAYOUT_TOID**(), **POBJ_LAYOUT_ROOT**(), **POBJ_LAYOUT_NAME**(), **POBJ_LAYOUT_END**(), **POBJ_LAYOUT_TYPES_NUM**() - persistent memory transactional object store layout # SYNOPSIS # ```c #include POBJ_LAYOUT_BEGIN(layout) POBJ_LAYOUT_TOID(layout, TYPE) POBJ_LAYOUT_ROOT(layout, ROOT_TYPE) POBJ_LAYOUT_NAME(layout) POBJ_LAYOUT_END(layout) POBJ_LAYOUT_TYPES_NUM(layout) ``` # DESCRIPTION # **libpmemobj**(7) defines a set of macros for convenient declaration of a pool's layout. The layout declaration consists of declarations of a number of used types. The declared types will be assigned consecutive type numbers. Declared types may be used in conjunction with type safety macros (see **TOID_DECLARE**(3)). Once created, the layout declaration must not be changed unless any new types are added at the end of the existing layout declaration. Modifying any existing declaration may lead to changes in the type numbers of declared types, which in consequence may cause data corruption. The **POBJ_LAYOUT_BEGIN**() macro indicates a begin of declaration of layout. The *LAYOUT* argument is a name of layout. This argument must be passed to all macros related to the declaration of layout. The **POBJ_LAYOUT_TOID**() macro declares a typed *OID* for type passed as *TYPE* argument inside the declaration of layout. All types declared using this macro are assigned with consecutive type numbers. This macro must be used between the **POBJ_LAYOUT_BEGIN**() and **POBJ_LAYOUT_END**() macros, with the same name passed as *LAYOUT* argument. The **POBJ_LAYOUT_ROOT**() macro declares a typed *OID* for type passed as *ROOT_TYPE* argument inside the declaration of layout. The typed *OID* will be assigned with type number for root object **POBJ_ROOT_TYPE_NUM**. The **POBJ_LAYOUT_END**() macro ends the declaration of layout. The **POBJ_LAYOUT_NAME**() macro returns the name of layout as a null-terminated string. The **POBJ_LAYOUT_TYPES_NUM**() macro returns number of types declared using the **POBJ_LAYOUT_TOID**() macro within the layout declaration. # EXAMPLE # This is an example of layout declaration: ```c POBJ_LAYOUT_BEGIN(mylayout); POBJ_LAYOUT_ROOT(mylayout, struct root); POBJ_LAYOUT_TOID(mylayout, struct node); POBJ_LAYOUT_TOID(mylayout, struct foo); POBJ_LAYOUT_END(mylayout); struct root { TOID(struct node) node; }; struct node { TOID(struct node) next; TOID(struct foo) foo; }; ``` The name of layout and the number of declared types can be retrieved using the following code: ```c const char *layout_name = POBJ_LAYOUT_NAME(mylayout); int num_of_types = POBJ_LAYOUT_TYPES_NUM(mylayout); ``` # SEE ALSO # **TOID_DECLARE**(3), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_ctl_get.3.md0000664000000000000000000004132114123364546017741 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_CTL_GET, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause [comment]: <> (Copyright 2017-2021, Intel Corporation) [comment]: <> (pmemobj_ctl_get.3 -- man page for libpmemobj CTL) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[CTL NAMESPACE](#ctl-namespace)
[CTL EXTERNAL CONFIGURATION](#ctl-external-configuration)
[SEE ALSO](#see-also)
# NAME # _UW(pmemobj_ctl_get), _UW(pmemobj_ctl_set), _UW(pmemobj_ctl_exec) - Query and modify libpmemobj internal behavior (EXPERIMENTAL) # SYNOPSIS # ```c #include _UWFUNCR2(int, pmemobj_ctl_get, PMEMobjpool *pop, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemobj_ctl_set, PMEMobjpool *pop, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemobj_ctl_exec, PMEMobjpool *pop, *name, void *arg, =q= (EXPERIMENTAL)=e=) ``` _UNICODE() # DESCRIPTION # The _UW(pmemobj_ctl_get), _UW(pmemobj_ctl_set) and _UW(pmemobj_ctl_exec) functions provide a uniform interface for querying and modifying the internal behavior of **libpmemobj**(7) through the control (CTL) namespace. The *name* argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra *arg* is required. Those two parameters together create a CTL query. The functions and the entry points are thread-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either *name* or *arg* is invalid, -1 is returned. If the provided ctl query is valid, the CTL functions will always return 0 on success and -1 on failure, unless otherwise specified in the entry point description. See more in **pmem_ctl**(5) man page. # CTL NAMESPACE # prefault.at_create | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemobj_create) function. prefault.at_open | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemobj_open) function. sds.at_create | rw | global | int | int | - | boolean If set, force-enables or force-disables SDS feature during pool creation. Affects only the _UW(pmemobj_create) function. See **pmempool_feature_query**(3) for information about SDS (SHUTDOWN_STATE) feature. copy_on_write.at_open | rw | global | int | int | - | boolean If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. tx.debug.skip_expensive_checks | rw | - | int | int | - | boolean Turns off some expensive checks performed by the transaction module in "debug" builds. Ignored in "release" builds. tx.debug.verify_user_buffers | rw | - | int | int | - | boolean Enables verification of user buffers provided by **pmemobj_tx_log_append_buffer**(3) API. For now the only verified aspect is whether the same buffer is used simultaneously in 2 or more transactions or more than once in the same transaction. This value should not be modified at runtime if any transaction for the current pool is in progress. tx.cache.size | rw | - | long long | long long | - | integer Size in bytes of the transaction snapshot cache. In a larger cache the frequency of persistent allocations is lower, but with higher fixed cost. This should be set to roughly the sum of sizes of the snapshotted regions in an average transaction in the pool. This entry point is not thread safe and should not be modified if there are any transactions currently running. This value must be a in a range between 0 and **PMEMOBJ_MAX_ALLOC_SIZE**, otherwise this entry point will fail. tx.cache.threshold | rw | - | long long | long long | - | integer This entry point is deprecated. All snapshots, regardless of the size, use the transactional cache. tx.post_commit.queue_depth | rw | - | int | int | - | integer This entry point is deprecated. tx.post_commit.worker | r- | - | void * | - | - | - This entry point is deprecated. tx.post_commit.stop | r- | - | void * | - | - | - This entry point is deprecated. heap.narenas.automatic | r- | - | unsigned | - | - | - Reads the number of arenas used in automatic scheduling of memory operations for threads. By default, this value is equal to the number of available processors. An arena is a memory management structure which enables concurrency by taking exclusive ownership of parts of the heap and allowing associated threads to allocate without contention. heap.narenas.total | r- | - | unsigned | - | - | - Reads the number of all created arenas. It includes automatic arenas created by default and arenas created using heap.arena.create CTL. heap.narenas.max | rw- | - | unsigned | unsigned | - | - Reads or writes the maximum number of arenas that can be created. This entry point is not thread-safe with regards to heap operations (allocations, frees, reallocs). heap.arena.[arena_id].size | r- | - | uint64_t | - | - | - Reads the total amount of memory in bytes which is currently exclusively owned by the arena. Large differences in this value between arenas might indicate an uneven scheduling of memory resources. The arena id cannot be 0. heap.thread.arena_id | rw- | - | unsigned | unsigned | - | - Reads the index of the arena assigned to the current thread or assigns arena with specific id to the current thread. The arena id cannot be 0. heap.arena.create | --x | - | - | - | unsigned | - Creates and initializes one new arena in the heap. This entry point reads an id of the new created arena. Newly created arenas by this CTL are inactive, which means that the arena will not be used in the automatic scheduling of memory requests. To activate the new arena, use heap.arena.[arena_id].automatic CTL. Arena created using this CTL can be used for allocation by explicitly specifying the *arena_id* for **POBJ_ARENA_ID(id)** flag in **pmemobj_tx_xalloc**()/**pmemobj_xalloc**()/**pmemobj_xreserve()** functions. By default, the number of arenas is limited to 1024. heap.arena.[arena_id].automatic | rw- | - | boolean | boolean | - | - Reads or modifies the state of the arena. If set, the arena is used in automatic scheduling of memory operations for threads. This should be set to false if the application wants to manually manage allocator scalability through explicitly assigning arenas to threads by using heap.thread.arena_id. The arena id cannot be 0 and at least one automatic arena must exist. heap.arenas_assignment_type | rw | global | `enum pobj_arenas_assignment_type` | `enum pobj_arenas_assignment_type` | - | string Reads or modifies the behavior of arenas assignment for threads. By default, each thread is assigned its own arena from the pool of automatic arenas (described earlier). This consumes one TLS key from the OS for every open pool. Applications that wish to avoid this behavior can instead rely on one global arena assignment per pool. This might limits scalability if not using arenas explicitly. The argument for this CTL is an enum with the following types: - **POBJ_ARENAS_ASSIGNMENT_THREAD_KEY**, string value: `thread`. Default, threads use individually assigned arenas. - **POBJ_ARENAS_ASSIGNMENT_GLOBAL**, string value: `global`. Threads use one global arena. Changing this value has no impact on already open pools. It should typically be set at the beginning of the application, before any pools are opened or created. heap.alloc_class.[class_id].desc | rw | - | `struct pobj_alloc_class_desc` | `struct pobj_alloc_class_desc` | - | integer, integer, integer, string Describes an allocation class. Allows one to create or view the internal data structures of the allocator. Creating custom allocation classes can be beneficial for both raw allocation throughput, scalability and, most importantly, fragmentation. By carefully constructing allocation classes that match the application workload, one can entirely eliminate external and internal fragmentation. For example, it is possible to easily construct a slab-like allocation mechanism for any data structure. The `[class_id]` is an index field. Only values between 0-254 are valid. If setting an allocation class, but the `class_id` is already taken, the function will return -1. The values between 0-127 are reserved for the default allocation classes of the library and can be used only for reading. The recommended method for retrieving information about all allocation classes is to call this entry point for all class ids between 0 and 254 and discard those results for which the function returns an error. This entry point takes a complex argument. ``` struct pobj_alloc_class_desc { size_t unit_size; size_t alignment; unsigned units_per_block; enum pobj_header_type header_type; unsigned class_id; }; ``` The first field, `unit_size`, is an 8-byte unsigned integer that defines the allocation class size. While theoretically limited only by **PMEMOBJ_MAX_ALLOC_SIZE**, for most workloads this value should be between 8 bytes and 2 megabytes. The `alignment` field specifies the user data alignment of objects allocated using the class. If set, must be a power of two and an even divisor of unit size. Alignment is limited to maximum of 2 megabytes. All objects have default alignment of 64 bytes, but the user data alignment is affected by the size of the chosen header. The `units_per_block` field defines how many units a single block of memory contains. This value will be adjusted to match the internal size of the block (256 kilobytes or a multiple thereof). For example, given a class with a `unit_size` of 512 bytes and a `units_per_block` of 1000, a single block of memory for that class will have 512 kilobytes. This is relevant because the bigger the block size, the less frequently blocks need to be fetched, resulting in lower contention on global heap state. If the CTL call is being done at runtime, the `units_per_block` variable of the provided alloc class structure is modified to match the actual value. The `header_type` field defines the header of objects from the allocation class. There are three types: - **POBJ_HEADER_LEGACY**, string value: `legacy`. Used for allocation classes prior to version 1.3 of the library. Not recommended for use. Incurs a 64 byte metadata overhead for every object. Fully supports all features. - **POBJ_HEADER_COMPACT**, string value: `compact`. Used as default for all predefined allocation classes. Incurs a 16 byte metadata overhead for every object. Fully supports all features. - **POBJ_HEADER_NONE**, string value: `none`. Header type that incurs no metadata overhead beyond a single bitmap entry. Can be used for very small allocation classes or when objects must be adjacent to each other. This header type does not support type numbers (type number is always 0) or allocations that span more than one unit. The `class_id` field is an optional, runtime-only variable that allows the user to retrieve the identifier of the class. This will be equivalent to the provided `[class_id]`. This field cannot be set from a config file. The allocation classes are a runtime state of the library and must be created after every open. It is highly recommended to use the configuration file to store the classes. This structure is declared in the `libpmemobj/ctl.h` header file. Please refer to this file for an in-depth explanation of the allocation classes and relevant algorithms. Allocation classes constructed in this way can be leveraged by explicitly specifying the class using **POBJ_CLASS_ID(id)** flag in **pmemobj_tx_xalloc**()/**pmemobj_xalloc**() functions. Example of a valid alloc class query string: ``` heap.alloc_class.128.desc=500,0,1000,compact ``` This query, if executed, will create an allocation class with an id of 128 that has a unit size of 500 bytes, has at least 1000 units per block and uses a compact header. For reading, function returns 0 if successful, if the allocation class does not exist it sets the errno to **ENOENT** and returns -1; This entry point can fail if any of the parameters of the allocation class is invalid or if exactly the same class already exists. heap.alloc_class.new.desc | -w | - | - | `struct pobj_alloc_class_desc` | - | integer, integer, integer, string Same as `heap.alloc_class.[class_id].desc`, but instead of requiring the user to provide the class_id, it automatically creates the allocation class with the first available identifier. This should be used when it's impossible to guarantee unique allocation class naming in the application (e.g. when writing a library that uses libpmemobj). The required class identifier will be stored in the `class_id` field of the `struct pobj_alloc_class_desc`. stats.enabled | rw | - | enum pobj_stats_enabled | enum pobj_stats_enabled | - | string Enables or disables runtime collection of statistics. There are two types of statistics: persistent and transient ones. Persistent statistics survive pool restarts, whereas transient ones don't. Statistics are not recalculated after enabling; any operations that occur between disabling and re-enabling will not be reflected in subsequent values. Only transient statistics are enabled by default. Enabling persistent statistics may have non-trivial performance impact. stats.heap.curr_allocated | r- | - | uint64_t | - | - | - Reads the number of bytes currently allocated in the heap. If statistics were disabled at any time in the lifetime of the heap, this value may be inaccurate. This is a persistent statistic. stats.heap.run_allocated | r- | - | uint64_t | - | - | - Reads the number of bytes currently allocated using run-based allocation classes, i.e., huge allocations are not accounted for in this statistic. This is useful for comparison against stats.heap.run_active to estimate the ratio between active and allocated memory. This is a transient statistic and is rebuilt every time the pool is opened. stats.heap.run_active | r- | - | uint64_t | - | - | - Reads the number of bytes currently occupied by all run memory blocks, including both allocated and free space, i.e., this is all the all space that's not occupied by huge allocations. This value is a sum of all allocated and free run memory. In systems where memory is efficiently used, `run_active` should closely track `run_allocated`, and the amount of active, but free, memory should be minimal. A large relative difference between active memory and allocated memory is indicative of heap fragmentation. This information can be used to make a decision to call **pmemobj_defrag()**(3) if the fragmentation looks to be high. However, for small heaps `run_active` might be disproportionately higher than `run_allocated` because the allocator typically activates a significantly larger amount of memory than is required to satisfy a single request in the anticipation of future needs. For example, the first allocation of 100 bytes in a heap will trigger activation of 256 kilobytes of space. This is a transient statistic and is rebuilt lazily every time the pool is opened. heap.size.granularity | rw- | - | uint64_t | uint64_t | - | long long Reads or modifies the granularity with which the heap grows when OOM. Valid only if the poolset has been defined with directories. A granularity of 0 specifies that the pool will not grow automatically. This entry point can fail if the granularity value is non-zero and smaller than *PMEMOBJ_MIN_PART*. heap.size.extend | --x | - | - | - | uint64_t | - Extends the heap by the given size. Must be larger than *PMEMOBJ_MIN_PART*. This entry point can fail if the pool does not support extend functionality or if there's not enough space left on the device. debug.heap.alloc_pattern | rw | - | int | int | - | - Single byte pattern that is used to fill new uninitialized memory allocation. If the value is negative, no pattern is written. This is intended for debugging, and is disabled by default. # CTL EXTERNAL CONFIGURATION # In addition to direct function call, each write entry point can also be set using two alternative methods. The first method is to load a configuration directly from the **PMEMOBJ_CONF** environment variable. The second method of loading an external configuration is to set the **PMEMOBJ_CONF_FILE** environment variable to point to a file that contains a sequence of ctl queries. See more in **pmem_ctl**(5) man page. # SEE ALSO # **libpmemobj**(7), **pmem_ctl**(5) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_memcpy_persist.30000664000000000000000000001605114123364732020763 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_MEMCPY_PERSIST" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemobj_persist\f[](), \f[B]pmemobj_xpersist\f[](), \f[B]pmemobj_flush\f[](), \f[B]pmemobj_xflush\f[](), \f[B]pmemobj_drain\f[](), \f[B]pmemobj_memcpy\f[](), \f[B]pmemobj_memmove\f[](), \f[B]pmemobj_memset\f[](), \f[B]pmemobj_memcpy_persist\f[](), \f[B]pmemobj_memset_persist\f[]() \- low\-level memory manipulation functions .SH SYNOPSIS .IP .nf \f[C] #include\ void\ pmemobj_persist(PMEMobjpool\ *pop,\ const\ void\ *addr, \ \ \ \ size_t\ len); void\ pmemobj_flush(PMEMobjpool\ *pop,\ const\ void\ *addr, \ \ \ \ size_t\ len); void\ pmemobj_drain(PMEMobjpool\ *pop); int\ pmemobj_xpersist(PMEMobjpool\ *pop,\ const\ void\ *addr, \ \ \ \ size_t\ len,\ unsigned\ flags); int\ pmemobj_xflush(PMEMobjpool\ *pop,\ const\ void\ *addr, \ \ \ \ size_t\ len,\ unsigned\ flags); void\ *pmemobj_memcpy(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ const\ void\ *src,\ size_t\ len,\ unsigned\ flags); void\ *pmemobj_memmove(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ const\ void\ *src,\ size_t\ len,\ unsigned\ flags); void\ *pmemobj_memset(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ int\ c,\ size_t\ len,\ unsigned\ flags); void\ *pmemobj_memcpy_persist(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ const\ void\ *src,\ size_t\ len); void\ *pmemobj_memset_persist(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ int\ c,\ size_t\ len); \f[] .fi .SH DESCRIPTION .PP The \f[B]libpmemobj\f[]\-specific low\-level memory manipulation functions described here leverage the knowledge of the additional configuration options available for \f[B]libpmemobj\f[](7) pools, such as replication. They also take advantage of the type of storage behind the pool and use appropriate flush/drain functions. It is advised to use these functions in conjunction with \f[B]libpmemobj\f[](7) objects rather than using low\-level memory manipulation functions from \f[B]libpmem\f[]. .PP \f[B]pmemobj_persist\f[]() forces any changes in the range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) to be stored durably in persistent memory. Internally this may call either \f[B]pmem_msync\f[](3) or \f[B]pmem_persist\f[](3). There are no alignment restrictions on the range described by \f[I]addr\f[] and \f[I]len\f[], but \f[B]pmemobj_persist\f[]() may expand the range as necessary to meet platform alignment requirements. .RS .PP WARNING: Like \f[B]msync\f[](2), there is nothing atomic or transactional about this call. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until \f[B]pmemobj_persist\f[]() is called to become persistent \- they can become persistent at any time before \f[B]pmemobj_persist\f[]() is called. .RE .PP The \f[B]pmemobj_flush\f[]() and \f[B]pmemobj_drain\f[]() functions provide partial versions of the \f[B]pmemobj_persist\f[]() function described above. These functions allow advanced programs to create their own variations of \f[B]pmemobj_persist\f[](). For example, a program that needs to flush several discontiguous ranges can call \f[B]pmemobj_flush\f[]() for each range and then follow up by calling \f[B]pmemobj_drain\f[]() once. For more information on partial flushing operations, see \f[B]pmem_flush\f[](3). .PP \f[B]pmemobj_xpersist\f[]() is a version of \f[B]pmemobj_persist\f[]() function with additional \f[I]flags\f[] argument. It supports only the \f[B]PMEMOBJ_F_RELAXED\f[] flag. This flag indicates that memory transfer operation does not require 8\-byte atomicity guarantees. .PP \f[B]pmemobj_xflush\f[]() is a version of \f[B]pmemobj_flush\f[]() function with additional \f[I]flags\f[] argument. It supports only the \f[B]PMEMOBJ_F_RELAXED\f[] flag. .PP The \f[B]pmemobj_memmove\f[](), \f[B]pmemobj_memcpy\f[]() and \f[B]pmemobj_memset\f[]() functions provide the same memory copying as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3), and \f[B]memset\f[](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEMOBJ_MEM_NOFLUSH\f[] flag was used). Valid flags for those functions: .IP \[bu] 2 \f[B]PMEMOBJ_F_RELAXED\f[] \- This flag indicates that memory transfer operation does not require 8\-byte atomicity guarantees. .IP \[bu] 2 \f[B]PMEMOBJ_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEMOBJ_F_MEM_NODRAIN\f[]. Using this flag only makes sense when it's followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEMOBJ_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEMOBJ_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEMOBJ_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_WB\f[]. On x86_64 this is an alias for \f[B]PMEMOBJ_F_MEM_NONTEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEMOBJ_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEMOBJ_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEMOBJ_F_MEM_TEMPORAL\f[]. .PP \f[B]pmemobj_memcpy_persist\f[]() is an alias for \f[B]pmemobj_memcpy\f[]() with flags equal to 0. .PP \f[B]pmemobj_memset_persist\f[]() is an alias for \f[B]pmemobj_memset\f[]() with flags equal to 0. .SH RETURN VALUE .PP \f[B]pmemobj_memmove\f[](), \f[B]pmemobj_memcpy\f[](), \f[B]pmemobj_memset\f[](), \f[B]pmemobj_memcpy_persist\f[]() and \f[B]pmemobj_memset_persist\f[]() return destination buffer. .PP \f[B]pmemobj_persist\f[](), \f[B]pmemobj_flush\f[]() and \f[B]pmemobj_drain\f[]() do not return any value. .PP \f[B]pmemobj_xpersist\f[]() and \f[B]pmemobj_xflush\f[]() returns non\-zero value and sets errno to EINVAL only if not supported flags has been provided. .SH EXAMPLES .PP The following code is functionally equivalent to \f[B]pmemobj_memcpy_persist\f[](): .IP .nf \f[C] void\ * pmemobj_memcpy_persist(PMEMobjpool\ *pop,\ void\ *dest, \ \ \ \ const\ void\ *src,\ size_t\ len) { \ \ \ \ void\ *retval\ =\ memcpy(dest,\ src,\ len); \ \ \ \ pmemobj_persist(pop,\ dest,\ len); \ \ \ \ return\ retval; } \f[] .fi .PP \f[B]pmemobj_persist\f[]() can be thought of as this: .IP .nf \f[C] void pmemobj_persist(PMEMobjpool\ *pop,\ const\ void\ *addr,\ size_t\ len) { \ \ \ \ /*\ flush\ the\ processor\ caches\ */ \ \ \ \ pmemobj_flush(pop,\ addr,\ len); \ \ \ \ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ \ \ \ \ pmemobj_drain(pop); } \f[] .fi .SH SEE ALSO .PP \f[B]memcpy\f[](3), \f[B]memset\f[](3), \f[B]pmem_msync\f[](3), \f[B]pmem_persist\f[](3), \f[B]libpmem\f[](7) \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_free.30000664000000000000000000000002714123364546017353 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_process.30000664000000000000000000000002714123364546020110 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/libpmemobj.70000664000000000000000000002354414123364725016342 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEMOBJ" "7" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2020, Intel Corporation .SH NAME .PP \f[B]libpmemobj\f[] \- persistent memory transactional object store .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ \-std=gnu99\ ...\ \-lpmemobj\ \-lpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *pmemobj_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Managing library behavior: .IP .nf \f[C] void\ pmemobj_set_funcs( \ \ \ \ void\ *(*malloc_func)(size_t\ size), \ \ \ \ void\ (*free_func)(void\ *ptr), \ \ \ \ void\ *(*realloc_func)(void\ *ptr,\ size_t\ size), \ \ \ \ char\ *(*strdup_func)(const\ char\ *s)); \f[] .fi .SS Error handling: .IP .nf \f[C] const\ char\ *pmemobj_errormsg(void); \f[] .fi .SS Other library functions: .PP A description of other \f[B]libpmemobj\f[] functions can be found on the following manual pages: .IP \[bu] 2 control and statistics: \f[B]pmemobj_ctl_get\f[](3) .IP \[bu] 2 create, open, close and validate: \f[B]pmemobj_open\f[](3) .IP \[bu] 2 low\-level memory manipulation: \f[B]pmemobj_memcpy_persist\f[](3) .IP \[bu] 2 locking: \f[B]pmemobj_mutex_zero\f[](3) .IP \[bu] 2 persistent object identifier: \f[B]OID_IS_NULL\f[](3) .IP \[bu] 2 type\-safety: \f[B]TOID_DECLARE\f[](3) .IP \[bu] 2 layout declaration: \f[B]POBJ_LAYOUT_BEGIN\f[](3) .IP \[bu] 2 non\-transactional atomic allocations: \f[B]pmemobj_alloc\f[](3) .IP \[bu] 2 root object management: \f[B]pmemobj_root\f[](3) .IP \[bu] 2 object containers: \f[B]pmemobj_first\f[](3) .IP \[bu] 2 non\-transactional persistent atomic circular doubly\-linked list: \f[B]pmemobj_list_insert\f[](3), \f[B]POBJ_LIST_HEAD\f[](3) .IP \[bu] 2 transactional object manipulation: \f[B]pmemobj_tx_begin\f[](3), \f[B]pmemobj_tx_add_range\f[](3), \f[B]pmemobj_tx_alloc\f[](3) .IP \[bu] 2 delayed atomicity actions: \f[B]pmemobj_action\f[](3) (EXPERIMENTAL) .SH DESCRIPTION .PP \f[B]libpmemobj\f[] provides a transactional object store in \f[I]persistent memory\f[] (pmem) for applications that require transactions and persistent memory management using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of \f[I]non\-volatile memory DIMMs\f[] (NVDIMMs) provide this type of byte addressable access to storage. A \f[I]persistent memory aware file system\f[] is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in load/store, non\-paged access to pmem. \f[B]libpmemobj\f[] builds on this type of memory mapped file using the low\-level pmem support provided by \f[B]libpmem\f[](7), handling the transactional updates, flushing changes to persistence, and managing recovery for the application. .PP \f[B]libpmemobj\f[] requires the \f[B]\-std=gnu99\f[] compilation flag to build properly. .PP \f[B]libpmemobj\f[] is one of a collection of persistent memory libraries available. The others are: .IP \[bu] 2 \f[B]libpmemblk\f[](7), providing pmem\-resident arrays of fixed\-sized blocks with atomic updates. .IP \[bu] 2 \f[B]libpmemlog\f[](7), providing a pmem\-resident log file. .IP \[bu] 2 \f[B]libpmem\f[](7), low\-level persistent memory support. .PP Under normal usage, \f[B]libpmemobj\f[] will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under \f[B]DEBUGGING AND ERROR HANDLING\f[], below. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]pmemobj_check_version\f[]() function is used to see if the installed \f[B]libpmemobj\f[] supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile\-time version information, supplied by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ pmemobj_check_version(PMEMOBJ_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEMOBJ_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP On success, \f[B]pmemobj_check_version\f[]() returns NULL. Otherwise, the return value is a static string describing the reason the version check failed. The string returned by \f[B]pmemobj_check_version\f[]() must not be modified or freed. .SH MANAGING LIBRARY BEHAVIOR .PP The \f[B]pmemobj_set_funcs\f[]() function allows an application to override memory allocation calls used internally by \f[B]libpmemobj\f[]. Passing in NULL for any of the handlers will cause the \f[B]libpmemobj\f[] default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4\-8 kilobytes for each memory pool in use. .PP By default, \f[B]libpmemobj\f[] supports up to 1024 parallel transactions/allocations. For debugging purposes it is possible to decrease this value by setting the \f[B]PMEMOBJ_NLANES\f[] environment variable to the desired limit. .SH DEBUGGING AND ERROR HANDLING .PP If an error is detected during the call to a \f[B]libpmemobj\f[] function, the application may retrieve an error message describing the reason for the failure from \f[B]pmemobj_errormsg\f[](). This function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmemobj\f[] function indicated an error, or if \f[I]errno\f[] was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. .PP Two versions of \f[B]libpmemobj\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmemobj\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]libpmemobj\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEMOBJ_LOG_LEVEL\f[] .PP The value of \f[B]PMEMOBJ_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEMOBJ_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmemobj_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmemobj\f[] developers. .PP Unless \f[B]PMEMOBJ_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMOBJ_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEMOBJ_LOG_FILE\f[] is not set, logging output is written to \f[I]stderr\f[]. .PP See also \f[B]libpmem\f[](7) to get information about other environment variables affecting \f[B]libpmemobj\f[] behavior. .SH EXAMPLE .PP See for examples using the \f[B]libpmemobj\f[] API. .SH ACKNOWLEDGEMENTS .PP \f[B]libpmemobj\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]OID_IS_NULL\f[](3), \f[B]pmemobj_alloc\f[](3), \f[B]pmemobj_ctl_exec\f[](3), \f[B]pmemobj_ctl_get\f[](3), \f[B]pmemobj_ctl_set\f[](3), \f[B]pmemobj_first\f[](3), \f[B]pmemobj_list_insert\f[](3), \f[B]pmemobj_memcpy_persist\f[](3), \f[B]pmemobj_mutex_zero\f[](3), \f[B]pmemobj_open\f[](3), \f[B]pmemobj_root\f[](3), \f[B]pmemobj_tx_add_range\f[](3), \f[B]pmemobj_tx_alloc\f[](3), \f[B]pmemobj_tx_begin\f[](3), \f[B]POBJ_LAYOUT_BEGIN\f[](3), \f[B]POBJ_LIST_HEAD\f[](3), \f[B]strerror\f[](3), \f[B]TOID_DECLARE\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemblk\f[](7), \f[B]libpmemlog\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/oid_is_null.30000664000000000000000000001666014123364731016514 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "OID_IS_NULL" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]OID_IS_NULL\f[](), \f[B]OID_EQUALS\f[](), \f[B]pmemobj_direct\f[](), \f[B]pmemobj_oid\f[](), \f[B]pmemobj_type_num\f[](), \f[B]pmemobj_pool_by_oid\f[](), \f[B]pmemobj_pool_by_ptr\f[]() \- functions that allow mapping operations between object addresses, object handles, oids or type numbers .SH SYNOPSIS .IP .nf \f[C] #include\ OID_IS_NULL(PMEMoid\ oid) OID_EQUALS(PMEMoid\ lhs,\ PMEMoid\ rhs) void\ *pmemobj_direct(PMEMoid\ oid); PMEMoid\ pmemobj_oid(const\ void\ *addr); uint64_t\ pmemobj_type_num(PMEMoid\ oid); PMEMobjpool\ *pmemobj_pool_by_oid(PMEMoid\ oid); PMEMobjpool\ *pmemobj_pool_by_ptr(const\ void\ *addr); void\ *pmemobj_volatile(PMEMobjpool\ *pop,\ struct\ pmemvlt\ *vlt, \ \ \ \ size_t\ size,\ void\ *ptr, \ \ \ \ int\ (*constr)(void\ *ptr,\ void\ *arg),\ void\ *arg);\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP Each object stored in a persistent memory pool is represented by an object handle of type \f[I]PMEMoid\f[]. In practice, such a handle is a unique Object IDentifier (\f[I]OID\f[]) of global scope, which means that two objects from different pools will never have the same \f[I]OID\f[]. The special \f[B]OID_NULL\f[] macro defines a NULL\-like handle that does not represent any object. The size of a single object is limited by \f[B]PMEMOBJ_MAX_ALLOC_SIZE\f[]. Thus an allocation with a requested size greater than this value will fail. .PP An \f[I]OID\f[] cannot be used as a direct pointer to an object. Each time the program attempts to read or write object data, it must obtain the current memory address of the object by converting its \f[I]OID\f[] into a pointer. .PP In contrast to the memory address, the \f[I]OID\f[] value for given object does not change during the life of an object (except for \f[I]realloc\f[]), and remains valid after closing and reopening the pool. For this reason, if an object contains a reference to another persistent object, for example, to build some kind of a linked data structure, the reference must be an \f[I]OID\f[] and not a memory address. .PP \f[B]pmemobj_direct\f[]() returns a pointer to the \f[I]PMEMoid\f[] object with handle \f[I]oid\f[]. .PP \f[B]pmemobj_oid\f[]() returns a \f[I]PMEMoid\f[] handle to the object pointed to by \f[I]addr\f[]. .PP \f[B]pmemobj_type_num\f[]() returns the type number of the \f[I]PMEMoid\f[] object with handle \f[I]oid\f[]. .PP \f[B]pmemobj_pool_by_oid\f[]() returns a \f[I]PMEMobjpool\f[]* handle to the pool containing the \f[I]PMEMoid\f[] object with handle \f[I]oid\f[]. .PP \f[B]pmemobj_pool_by_ptr\f[]() returns a \f[I]PMEMobjpool\f[]* handle to the pool containing the address \f[I]addr\f[]. .PP At the time of allocation (or reallocation), each object may be assigned a number representing its type. Such a \f[I]type number\f[] may be used to arrange the persistent objects based on their actual user\-defined structure type, thus facilitating implementation of a simple run\-time type safety mechanism. This also allows iterating through all the objects of a given type that are stored in the persistent memory pool. See \f[B]pmemobj_first\f[](3) for more information. .PP The \f[B]OID_IS_NULL\f[]() macro checks if \f[I]PMEMoid\f[] represents a NULL object. .PP The \f[B]OID_EQUALS\f[]() macro compares two \f[I]PMEMoid\f[] objects. .PP For special cases where volatile (transient) variables need to be stored on persistent memory, there's a mechanism composed of \f[I]struct pmemvlt\f[] type and \f[B]pmemobj_volatile()\f[] function. To use it, the \f[I]struct pmemvlt\f[] needs to be placed in the neighborhood of transient data region. The \f[I]PMEMvlt\f[] macro can be used to construct such a region. The \f[I]struct pmemvlt\f[] must be zeroed prior to use. This can be easily done in object constructor or in a transaction directly after an allocation. When the \f[B]pmemobj_volatile()\f[] function is called on a \f[I]struct pmemvlt\f[], it will return the pointer to the data and it will ensure that the provided constructor function is called exactly once in the current instance of the pmemobj pool. The constructor is called with the \f[I]ptr\f[] pointer to the data, and this function will return the same pointer if the constructor returns \f[I]0\f[], otherwise NULL is returned. The \f[I]size\f[] argument must accurately describe the total size of the volatile memory region that will be accessed. Calling \f[B]pmemobj_volatile()\f[] on the same region with different sizes is undefined behavior. For this mechanism to be effective, all accesses to transient variables must go through it, otherwise there's a risk of the constructor not being called on the first load. Maintaining transient state on persistent memory is challenging due to difficulties with dynamic resources acquisition and subsequent resource release. For example, one needs to consider what happens with volatile state of an object which is being freed inside of a transaction, especially with regards to the possibility of an abort. It's generally recommended to entirely separate the persistent and transient states, and when it's not possible, to only store types which do not require lifecycle management (i.e., primitive types) inside of volatile regions. .SH RETURN VALUE .PP The \f[B]pmemobj_direct\f[]() function returns a pointer to the object represented by \f[I]oid\f[]. If \f[I]oid\f[] is \f[B]OID_NULL\f[], \f[B]pmemobj_direct\f[]() returns NULL. .PP The \f[B]pmemobj_oid\f[]() function returns a \f[I]PMEMoid\f[] handle to the object pointed to by \f[I]addr\f[]. If \f[I]addr\f[] is not from within a pmemobj pool, \f[B]OID_NULL\f[] is returned. If \f[I]addr\f[] is not the start of an object (does not point to the beginning of a valid allocation), the resulting \f[I]PMEMoid\f[] can be safely used only with: .IP \[bu] 2 \f[B]pmemobj_pool_by_oid\f[]() .IP \[bu] 2 \f[B]pmemobj_direct\f[]() .IP \[bu] 2 \f[B]pmemobj_tx_add_range\f[](3) .PP The \f[B]pmemobj_type_num\f[]() function returns the type number of the object represented by \f[I]oid\f[]. .PP The \f[B]pmemobj_pool_by_oid\f[]() function returns a handle to the pool that contains the object represented by \f[I]oid\f[]. If the pool is not open or \f[I]oid\f[] is \f[B]OID_NULL\f[], \f[B]pmemobj_pool_by_oid\f[]() returns NULL. .PP The \f[B]pmemobj_pool_by_ptr\f[]() function returns a handle to the pool that contains the address, or NULL if the address does not belong to any open pool. .SH NOTES .PP For performance reasons, on Linux and FreeBSD the \f[B]pmemobj_direct\f[]() function is inlined by default. To use the non\-inlined variant of \f[B]pmemobj_direct\f[](), define \f[B]PMEMOBJ_DIRECT_NON_INLINE\f[] prior to the \f[I]#include\f[] of \f[B]\f[], either with \f[I]#define\f[] or with the \f[I]\-D\f[] option to the compiler. .SH EXAMPLES .PP The following code shows how to store transient variables on persistent memory. .IP .nf \f[C] struct\ my_data\ { \ \ \ \ PMEMvlt(uint64_t)\ foo; \ \ \ \ uint64_t\ bar; }; int my_data_constructor(void\ *ptr,\ void\ *arg) { \ \ \ \ uint64_t\ *foo\ =\ ptr; \ \ \ \ *foo\ =\ 0; \ \ \ \ return\ 0; } PMEMobjpool\ *pop\ =\ ...; struct\ my_data\ *data\ =\ D_RW(...); uint64_t\ *foo\ =\ pmemobj_volatile(pop,\ &data\->foo.vlt,\ &data\->foo.value, \ \ \ \ my_data_constructor,\ NULL); assert(*foo\ ==\ 0); \f[] .fi .SH SEE ALSO .PP \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_lock.30000664000000000000000000000002714123364546017362 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_root_size.30000664000000000000000000000002314123364546017730 0ustar rootroot.so pmemobj_root.3 pmdk-1.11.1/doc/libpmemobj/d_rw.30000664000000000000000000000002314123364546015135 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_xadd_range_direct.30000664000000000000000000000003314123364546022055 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/d_ro.30000664000000000000000000000002314123364546015125 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pobj_foreach.30000664000000000000000000000002414123364546016624 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/tx_xalloc.30000664000000000000000000000002714123364546016203 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_memcpy_persist.3.md0000664000000000000000000001502314123364546021363 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMOBJ_MEMCPY_PERSIST, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemobj_memcpy_persist.3 -- man page for Low-level memory manipulation) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[EXAMPLES](#examples)
[SEE ALSO](#see-also)
# NAME # **pmemobj_persist**(), **pmemobj_xpersist**(), **pmemobj_flush**(), **pmemobj_xflush**(), **pmemobj_drain**(), **pmemobj_memcpy**(), **pmemobj_memmove**(), **pmemobj_memset**(), **pmemobj_memcpy_persist**(), **pmemobj_memset_persist**() - low-level memory manipulation functions # SYNOPSIS # ```c #include void pmemobj_persist(PMEMobjpool *pop, const void *addr, size_t len); void pmemobj_flush(PMEMobjpool *pop, const void *addr, size_t len); void pmemobj_drain(PMEMobjpool *pop); int pmemobj_xpersist(PMEMobjpool *pop, const void *addr, size_t len, unsigned flags); int pmemobj_xflush(PMEMobjpool *pop, const void *addr, size_t len, unsigned flags); void *pmemobj_memcpy(PMEMobjpool *pop, void *dest, const void *src, size_t len, unsigned flags); void *pmemobj_memmove(PMEMobjpool *pop, void *dest, const void *src, size_t len, unsigned flags); void *pmemobj_memset(PMEMobjpool *pop, void *dest, int c, size_t len, unsigned flags); void *pmemobj_memcpy_persist(PMEMobjpool *pop, void *dest, const void *src, size_t len); void *pmemobj_memset_persist(PMEMobjpool *pop, void *dest, int c, size_t len); ``` # DESCRIPTION # The **libpmemobj**-specific low-level memory manipulation functions described here leverage the knowledge of the additional configuration options available for **libpmemobj**(7) pools, such as replication. They also take advantage of the type of storage behind the pool and use appropriate flush/drain functions. It is advised to use these functions in conjunction with **libpmemobj**(7) objects rather than using low-level memory manipulation functions from **libpmem**. **pmemobj_persist**() forces any changes in the range \[*addr*, *addr*+*len*) to be stored durably in persistent memory. Internally this may call either **pmem_msync**(3) or **pmem_persist**(3). There are no alignment restrictions on the range described by *addr* and *len*, but **pmemobj_persist**() may expand the range as necessary to meet platform alignment requirements. >WARNING: Like **msync**(2), there is nothing atomic or transactional about this call. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until **pmemobj_persist**() is called to become persistent - they can become persistent at any time before **pmemobj_persist**() is called. The **pmemobj_flush**() and **pmemobj_drain**() functions provide partial versions of the **pmemobj_persist**() function described above. These functions allow advanced programs to create their own variations of **pmemobj_persist**(). For example, a program that needs to flush several discontiguous ranges can call **pmemobj_flush**() for each range and then follow up by calling **pmemobj_drain**() once. For more information on partial flushing operations, see **pmem_flush**(3). **pmemobj_xpersist**() is a version of **pmemobj_persist**() function with additional *flags* argument. It supports only the **PMEMOBJ_F_RELAXED** flag. This flag indicates that memory transfer operation does not require 8-byte atomicity guarantees. **pmemobj_xflush**() is a version of **pmemobj_flush**() function with additional *flags* argument. It supports only the **PMEMOBJ_F_RELAXED** flag. The **pmemobj_memmove**(), **pmemobj_memcpy**() and **pmemobj_memset**() functions provide the same memory copying as their namesakes **memmove**(3), **memcpy**(3), and **memset**(3), and ensure that the result has been flushed to persistence before returning (unless **PMEMOBJ_MEM_NOFLUSH** flag was used). Valid flags for those functions: + **PMEMOBJ_F_RELAXED** - This flag indicates that memory transfer operation does not require 8-byte atomicity guarantees. + **PMEMOBJ_F_MEM_NOFLUSH** - Don't flush anything. This implies **PMEMOBJ_F_MEM_NODRAIN**. Using this flag only makes sense when it's followed by any function that flushes data. The remaining flags say *how* the operation should be done, and are merely hints. + **PMEMOBJ_F_MEM_NONTEMPORAL** - Use non-temporal instructions. This flag is mutually exclusive with **PMEMOBJ_F_MEM_TEMPORAL**. On x86\_64 this flag is mutually exclusive with **PMEMOBJ_F_MEM_NOFLUSH**. + **PMEMOBJ_F_MEM_TEMPORAL** - Use temporal instructions. This flag is mutually exclusive with **PMEMOBJ_F_MEM_NONTEMPORAL**. + **PMEMOBJ_F_MEM_WC** - Use write combining mode. This flag is mutually exclusive with **PMEMOBJ_F_MEM_WB**. On x86\_64 this is an alias for **PMEMOBJ_F_MEM_NONTEMPORAL**. On x86\_64 this flag is mutually exclusive with **PMEMOBJ_F_MEM_NOFLUSH**. + **PMEMOBJ_F_MEM_WB** - Use write back mode. This flag is mutually exclusive with **PMEMOBJ_F_MEM_WC**. On x86\_64 this is an alias for **PMEMOBJ_F_MEM_TEMPORAL**. **pmemobj_memcpy_persist**() is an alias for **pmemobj_memcpy**() with flags equal to 0. **pmemobj_memset_persist**() is an alias for **pmemobj_memset**() with flags equal to 0. # RETURN VALUE # **pmemobj_memmove**(), **pmemobj_memcpy**(), **pmemobj_memset**(), **pmemobj_memcpy_persist**() and **pmemobj_memset_persist**() return destination buffer. **pmemobj_persist**(), **pmemobj_flush**() and **pmemobj_drain**() do not return any value. **pmemobj_xpersist**() and **pmemobj_xflush**() returns non-zero value and sets errno to EINVAL only if not supported flags has been provided. # EXAMPLES # The following code is functionally equivalent to **pmemobj_memcpy_persist**(): ```c void * pmemobj_memcpy_persist(PMEMobjpool *pop, void *dest, const void *src, size_t len) { void *retval = memcpy(dest, src, len); pmemobj_persist(pop, dest, len); return retval; } ``` **pmemobj_persist**() can be thought of as this: ```c void pmemobj_persist(PMEMobjpool *pop, const void *addr, size_t len) { /* flush the processor caches */ pmemobj_flush(pop, addr, len); /* wait for any pmem stores to drain from HW buffers */ pmemobj_drain(pop); } ``` # SEE ALSO # **memcpy**(3), **memset**(3), **pmem_msync**(3), **pmem_persist**(3), **libpmem**(7) **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_f_relaxed.30000664000000000000000000000003514123364546017647 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_commit.30000664000000000000000000000002714123364546017722 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_zrealloc.30000664000000000000000000000002714123364546020245 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/tx_oncommit.30000664000000000000000000000002714123364546016546 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_next.30000664000000000000000000000002414123364546016672 0ustar rootroot.so pmemobj_first.3 pmdk-1.11.1/doc/libpmemobj/toid_is_null.30000664000000000000000000000002314123364546016666 0ustar rootroot.so toid_declare.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_ctl_set.30000664000000000000000000000002614123364546017353 0ustar rootroot.so pmemobj_ctl_get.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_xalloc.30000664000000000000000000000002414123364546017176 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/oid_is_null.3.md0000664000000000000000000001601714123364546017113 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(OID_IS_NULL, 3) collection: libpmemobj header: PMDK date: pmemobj API version 2.3 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (oid_is_null.3 -- man page for persistent object identifier and functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
_WINUX(,[NOTES](#notes)
) [SEE ALSO](#see-also)
# NAME # **OID_IS_NULL**(), **OID_EQUALS**(), **pmemobj_direct**(), **pmemobj_oid**(), **pmemobj_type_num**(), **pmemobj_pool_by_oid**(), **pmemobj_pool_by_ptr**() - functions that allow mapping operations between object addresses, object handles, oids or type numbers # SYNOPSIS # ```c #include OID_IS_NULL(PMEMoid oid) OID_EQUALS(PMEMoid lhs, PMEMoid rhs) void *pmemobj_direct(PMEMoid oid); PMEMoid pmemobj_oid(const void *addr); uint64_t pmemobj_type_num(PMEMoid oid); PMEMobjpool *pmemobj_pool_by_oid(PMEMoid oid); PMEMobjpool *pmemobj_pool_by_ptr(const void *addr); void *pmemobj_volatile(PMEMobjpool *pop, struct pmemvlt *vlt, size_t size, void *ptr, int (*constr)(void *ptr, void *arg), void *arg); (EXPERIMENTAL) ``` # DESCRIPTION # Each object stored in a persistent memory pool is represented by an object handle of type *PMEMoid*. In practice, such a handle is a unique Object IDentifier (*OID*) of global scope, which means that two objects from different pools will never have the same *OID*. The special **OID_NULL** macro defines a NULL-like handle that does not represent any object. The size of a single object is limited by **PMEMOBJ_MAX_ALLOC_SIZE**. Thus an allocation with a requested size greater than this value will fail. An *OID* cannot be used as a direct pointer to an object. Each time the program attempts to read or write object data, it must obtain the current memory address of the object by converting its *OID* into a pointer. In contrast to the memory address, the *OID* value for given object does not change during the life of an object (except for *realloc*), and remains valid after closing and reopening the pool. For this reason, if an object contains a reference to another persistent object, for example, to build some kind of a linked data structure, the reference must be an *OID* and not a memory address. **pmemobj_direct**() returns a pointer to the *PMEMoid* object with handle *oid*. **pmemobj_oid**() returns a *PMEMoid* handle to the object pointed to by *addr*. **pmemobj_type_num**() returns the type number of the *PMEMoid* object with handle *oid*. **pmemobj_pool_by_oid**() returns a *PMEMobjpool*\* handle to the pool containing the *PMEMoid* object with handle *oid*. **pmemobj_pool_by_ptr**() returns a *PMEMobjpool*\* handle to the pool containing the address *addr*. At the time of allocation (or reallocation), each object may be assigned a number representing its type. Such a *type number* may be used to arrange the persistent objects based on their actual user-defined structure type, thus facilitating implementation of a simple run-time type safety mechanism. This also allows iterating through all the objects of a given type that are stored in the persistent memory pool. See **pmemobj_first**(3) for more information. The **OID_IS_NULL**() macro checks if *PMEMoid* represents a NULL object. The **OID_EQUALS**() macro compares two *PMEMoid* objects. For special cases where volatile (transient) variables need to be stored on persistent memory, there's a mechanism composed of *struct pmemvlt* type and **pmemobj_volatile()** function. To use it, the *struct pmemvlt* needs to be placed in the neighborhood of transient data region. The *PMEMvlt* macro can be used to construct such a region. The *struct pmemvlt* must be zeroed prior to use. This can be easily done in object constructor or in a transaction directly after an allocation. When the **pmemobj_volatile()** function is called on a *struct pmemvlt*, it will return the pointer to the data and it will ensure that the provided constructor function is called exactly once in the current instance of the pmemobj pool. The constructor is called with the *ptr* pointer to the data, and this function will return the same pointer if the constructor returns *0*, otherwise NULL is returned. The *size* argument must accurately describe the total size of the volatile memory region that will be accessed. Calling **pmemobj_volatile()** on the same region with different sizes is undefined behavior. For this mechanism to be effective, all accesses to transient variables must go through it, otherwise there's a risk of the constructor not being called on the first load. Maintaining transient state on persistent memory is challenging due to difficulties with dynamic resources acquisition and subsequent resource release. For example, one needs to consider what happens with volatile state of an object which is being freed inside of a transaction, especially with regards to the possibility of an abort. It's generally recommended to entirely separate the persistent and transient states, and when it's not possible, to only store types which do not require lifecycle management (i.e., primitive types) inside of volatile regions. # RETURN VALUE # The **pmemobj_direct**() function returns a pointer to the object represented by *oid*. If *oid* is **OID_NULL**, **pmemobj_direct**() returns NULL. The **pmemobj_oid**() function returns a *PMEMoid* handle to the object pointed to by *addr*. If *addr* is not from within a pmemobj pool, **OID_NULL** is returned. If *addr* is not the start of an object (does not point to the beginning of a valid allocation), the resulting *PMEMoid* can be safely used only with: + **pmemobj_pool_by_oid**() + **pmemobj_direct**() + **pmemobj_tx_add_range**(3) The **pmemobj_type_num**() function returns the type number of the object represented by *oid*. The **pmemobj_pool_by_oid**() function returns a handle to the pool that contains the object represented by *oid*. If the pool is not open or *oid* is **OID_NULL**, **pmemobj_pool_by_oid**() returns NULL. The **pmemobj_pool_by_ptr**() function returns a handle to the pool that contains the address, or NULL if the address does not belong to any open pool. _WINUX(,=q= # NOTES # For performance reasons, on Linux and FreeBSD the **pmemobj_direct**() function is inlined by default. To use the non-inlined variant of **pmemobj_direct**(), define **PMEMOBJ_DIRECT_NON_INLINE** prior to the *\#include* of **\**, either with *\#define* or with the *\-D* option to the compiler.=e=) # EXAMPLES # The following code shows how to store transient variables on persistent memory. ```c struct my_data { PMEMvlt(uint64_t) foo; uint64_t bar; }; int my_data_constructor(void *ptr, void *arg) { uint64_t *foo = ptr; *foo = 0; return 0; } PMEMobjpool *pop = ...; struct my_data *data = D_RW(...); uint64_t *foo = pmemobj_volatile(pop, &data->foo.vlt, &data->foo.value, my_data_constructor, NULL); assert(*foo == 0); ``` # SEE ALSO # **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemobj/pmemobj_pool_by_ptr.30000664000000000000000000000002214123364546020242 0ustar rootroot.so oid_is_null.3 pmdk-1.11.1/doc/libpmemobj/tx_begin_cb.30000664000000000000000000000002714123364546016451 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_realloc.30000664000000000000000000000002714123364546020053 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pobj_realloc.30000664000000000000000000000002414123364546016636 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/tx_free.30000664000000000000000000000002714123364546015642 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_list_insert_new.30000664000000000000000000000003214123364546021123 0ustar rootroot.so pmemobj_list_insert.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_add_range.30000664000000000000000000002115714123364733020343 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_TX_ADD_RANGE" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2019, Intel Corporation .SH NAME .PP \f[B]pmemobj_tx_add_range\f[](), \f[B]pmemobj_tx_add_range_direct\f[](), \f[B]pmemobj_tx_xadd_range\f[](), \f[B]pmemobj_tx_xadd_range_direct\f[]() .PP \f[B]TX_ADD\f[](), \f[B]TX_ADD_FIELD\f[](), \f[B]TX_ADD_DIRECT\f[](), \f[B]TX_ADD_FIELD_DIRECT\f[](), .PP \f[B]TX_XADD\f[](), \f[B]TX_XADD_FIELD\f[](), \f[B]TX_XADD_DIRECT\f[](), \f[B]TX_XADD_FIELD_DIRECT\f[](), .PP \f[B]TX_SET\f[](), \f[B]TX_SET_DIRECT\f[](), \f[B]TX_MEMCPY\f[](), \f[B]TX_MEMSET\f[]() \- transactional object manipulation .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemobj_tx_add_range(PMEMoid\ oid,\ uint64_t\ off,\ size_t\ size); int\ pmemobj_tx_add_range_direct(const\ void\ *ptr,\ size_t\ size); int\ pmemobj_tx_xadd_range(PMEMoid\ oid,\ uint64_t\ off,\ size_t\ size,\ uint64_t\ flags); int\ pmemobj_tx_xadd_range_direct(const\ void\ *ptr,\ size_t\ size,\ uint64_t\ flags); TX_ADD(TOID\ o) TX_ADD_FIELD(TOID\ o,\ FIELD) TX_ADD_DIRECT(TYPE\ *p) TX_ADD_FIELD_DIRECT(TYPE\ *p,\ FIELD) TX_XADD(TOID\ o,\ uint64_t\ flags) TX_XADD_FIELD(TOID\ o,\ FIELD,\ uint64_t\ flags) TX_XADD_DIRECT(TYPE\ *p,\ uint64_t\ flags) TX_XADD_FIELD_DIRECT(TYPE\ *p,\ FIELD,\ uint64_t\ flags) TX_SET(TOID\ o,\ FIELD,\ VALUE) TX_SET_DIRECT(TYPE\ *p,\ FIELD,\ VALUE) TX_MEMCPY(void\ *dest,\ const\ void\ *src,\ size_t\ num) TX_MEMSET(void\ *dest,\ int\ c,\ size_t\ num) \f[] .fi .SH DESCRIPTION .PP \f[B]pmemobj_tx_add_range\f[]() takes a \[lq]snapshot\[rq] of the memory block of given \f[I]size\f[], located at given offset \f[I]off\f[] in the object specified by \f[I]oid\f[], and saves it to the undo log. The application is then free to directly modify the object in that memory range. In case of a failure or abort, all the changes within this range will be rolled back. The supplied block of memory has to be within the pool registered in the transaction. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xadd_range\f[]() function behaves exactly the same as \f[B]pmemobj_tx_add_range\f[]() when \f[I]flags\f[] equals zero. \f[I]flags\f[] is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XADD_NO_FLUSH\f[] \- skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) .IP \[bu] 2 \f[B]POBJ_XADD_NO_SNAPSHOT\f[] \- added range will not be \[lq]snapshotted\[rq], i.e.\ any changes made within it during the transaction will not be rolled backed after abort .IP \[bu] 2 \f[B]POBJ_XADD_ASSUME_INITIALIZED\f[] \- added range is assumed to be initialized. If this flag is not specified, passing uninitialized memory will result in an error when run under Valgrind memcheck. .IP \[bu] 2 \f[B]POBJ_XADD_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP \f[B]pmemobj_tx_add_range_direct\f[]() behaves the same as \f[B]pmemobj_tx_add_range\f[]() with the exception that it operates on virtual memory addresses and not persistent memory objects. It takes a \[lq]snapshot\[rq] of a persistent memory block of given \f[I]size\f[], located at the given address \f[I]ptr\f[] in the virtual memory space and saves it to the undo log. The application is then free to directly modify the object in that memory range. In case of a failure or abort, all the changes within this range will be rolled back. The supplied block of memory has to be within the pool registered in the transaction. This function must be called during \f[B]TX_STAGE_WORK\f[]. .PP The \f[B]pmemobj_tx_xadd_range_direct\f[]() function behaves exactly the same as \f[B]pmemobj_tx_add_range_direct\f[]() when \f[I]flags\f[] equals zero. \f[I]flags\f[] is a bitmask of the following values: .IP \[bu] 2 \f[B]POBJ_XADD_NO_FLUSH\f[] \- skip flush on commit (when application deals with flushing or uses pmemobj_memcpy_persist) .IP \[bu] 2 \f[B]POBJ_XADD_NO_SNAPSHOT\f[] \- added range will not be \[lq]snapshotted\[rq], i.e.\ any changes made within it during the transaction will not be rolled backed after abort .IP \[bu] 2 \f[B]POBJ_XADD_ASSUME_INITIALIZED\f[] \- added range is assumed to be initialized. If this flag is not specified, passing uninitialized memory will result in an error when run under Valgrind memcheck. .IP \[bu] 2 \f[B]POBJ_XADD_NO_ABORT\f[] \- if the function does not end successfully, do not abort the transaction. .PP Similarly to the macros controlling the transaction flow, \f[B]libpmemobj\f[] defines a set of macros that simplify the transactional operations on persistent objects. Note that those macros operate on typed object handles, thus eliminating the need to specify the size of the object, or the size and offset of the field in the user\-defined structure that is to be modified. .PP The \f[B]TX_ADD_FIELD\f[]() macro saves the current value of given \f[I]FIELD\f[] of the object referenced by a handle \f[I]o\f[] in the undo log. The application is then free to directly modify the specified \f[I]FIELD\f[]. In case of a failure or abort, the saved value will be restored. .PP The \f[B]TX_XADD_FIELD\f[]() macro works exactly like \f[B]TX_ADD_FIELD\f[] when \f[I]flags\f[] equals 0. The \f[I]flags\f[] argument is a bitmask of values described in \f[B]pmemobj_tx_xadd_range\f[], above. .PP The \f[B]TX_ADD\f[]() macro takes a \[lq]snapshot\[rq] of the entire object referenced by object handle \f[I]o\f[] and saves it in the undo log. The object size is determined from its \f[I]TYPE\f[]. The application is then free to directly modify the object. In case of a failure or abort, all the changes within the object will be rolled back. .PP The \f[B]TX_XADD\f[]() macro works exactly like \f[B]TX_ADD\f[] when \f[I]flags\f[] equals 0. The \f[I]flags\f[] argument is a bitmask of values as described in \f[B]pmemobj_tx_xadd_range\f[], above. .PP The \f[B]TX_ADD_FIELD_DIRECT\f[]() macro saves the current value of the given \f[I]FIELD\f[] of the object referenced by (direct) pointer \f[I]p\f[] in the undo log. The application is then free to directly modify the specified \f[I]FIELD\f[]. In case of a failure or abort, the saved value will be restored. .PP The \f[B]TX_XADD_FIELD_DIRECT\f[]() macro works exactly like \f[B]TX_ADD_FIELD_DIRECT\f[] when \f[I]flags\f[] equals 0. The \f[I]flags\f[] argument is a bitmask of values as described in \f[B]pmemobj_tx_xadd_range_direct\f[], above. .PP The \f[B]TX_ADD_DIRECT\f[]() macro takes a \[lq]snapshot\[rq] of the entire object referenced by (direct) pointer \f[I]p\f[] and saves it in the undo log. The object size is determined from its \f[I]TYPE\f[]. The application is then free to directly modify the object. In case of a failure or abort, all the changes within the object will be rolled back. .PP The \f[B]TX_XADD_DIRECT\f[]() macro works exactly like \f[B]TX_ADD_DIRECT\f[] when \f[I]flags\f[] equals 0. The \f[I]flags\f[] argument is a bitmask of values as described in \f[B]pmemobj_tx_xadd_range_direct\f[], above. .PP The \f[B]TX_SET\f[]() macro saves the current value of the given \f[I]FIELD\f[] of the object referenced by handle \f[I]o\f[] in the undo log, and then sets its new \f[I]VALUE\f[]. In case of a failure or abort, the saved value will be restored. .PP The \f[B]TX_SET_DIRECT\f[]() macro saves in the undo log the current value of given \f[I]FIELD\f[] of the object referenced by (direct) pointer \f[I]p\f[], and then set its new \f[I]VALUE\f[]. In case of a failure or abort, the saved value will be restored. .PP The \f[B]TX_MEMCPY\f[]() macro saves in the undo log the current content of \f[I]dest\f[] buffer and then overwrites the first \f[I]num\f[] bytes of its memory area with the data copied from the buffer pointed by \f[I]src\f[]. In case of a failure or abort, the saved value will be restored. .PP The \f[B]TX_MEMSET\f[]() macro saves the current content of the \f[I]dest\f[] buffer in the undo log and then fills the first \f[I]num\f[] bytes of its memory area with the constant byte \f[I]c\f[]. In case of a failure or abort, the saved value will be restored. .SH RETURN VALUE .PP On success, \f[B]pmemobj_tx_add_range\f[]() and \f[B]pmemobj_tx_add_range_direct\f[]() return 0. Otherwise, the stage is changed to \f[B]TX_STAGE_ONABORT\f[], \f[B]errno\f[] is set appropriately and transaction is aborted. .PP On success, \f[B]pmemobj_tx_xadd_range\f[]() and \f[B]pmemobj_tx_xadd_range_direct\f[]() returns 0. Otherwise, the error number is returned, \f[B]errno\f[] is set and when flags do not contain \f[B]POBJ_XADD_NO_ABORT\f[], the transaction is aborted. .SH SEE ALSO .PP \f[B]pmemobj_tx_alloc\f[](3), \f[B]pmemobj_tx_begin\f[](3), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/tx_add.30000664000000000000000000000003314123364546015446 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_add_range_direct.30000664000000000000000000000003314123364546021665 0ustar rootroot.so pmemobj_tx_add_range.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_close.30000664000000000000000000000002314123364546017020 0ustar rootroot.so pmemobj_open.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_realloc.30000664000000000000000000000002414123364546017335 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_memmove.30000664000000000000000000000003514123364546017363 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_xpersist.30000664000000000000000000000003514123364546017577 0ustar rootroot.so pmemobj_memcpy_persist.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_tx_get_user_data.30000664000000000000000000000002714123364546021240 0ustar rootroot.so pmemobj_tx_begin.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_defrag.30000664000000000000000000000002414123364546017144 0ustar rootroot.so pmemobj_alloc.3 pmdk-1.11.1/doc/libpmemobj/pmemobj_root.30000664000000000000000000000775114123364732016712 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMOBJ_ROOT" "3" "2021-09-24" "PMDK - pmemobj API version 2.3" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemobj_root\f[](), \f[B]pmemobj_root_construct\f[]() \f[B]POBJ_ROOT\f[](), \f[B]pmemobj_root_size\f[]() \- root object management .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMoid\ pmemobj_root(PMEMobjpool\ *pop,\ size_t\ size); PMEMoid\ pmemobj_root_construct(PMEMobjpool\ *pop,\ size_t\ size, \ \ \ \ pmemobj_constr\ constructor,\ void\ *arg); POBJ_ROOT(PMEMobjpool\ *pop,\ TYPE) size_t\ pmemobj_root_size(PMEMobjpool\ *pop); \f[] .fi .SH DESCRIPTION .PP The root object of a persistent memory pool is an entry point for all other persistent objects allocated using the \f[B]libpmemobj\f[] API. In other words, every object stored in the persistent memory pool has the root object at the end of its reference path. It may be assumed that for each persistent memory pool the root object always exists, and there is exactly one root object in each pool. .PP The \f[B]pmemobj_root\f[]() function creates or resizes the root object for the persistent memory pool \f[I]pop\f[]. If this is the first call to \f[B]pmemobj_root\f[](), the requested \f[I]size\f[] is greater than zero and the root object does not exist, it is implicitly allocated in a thread\-safe manner, so the function may be called by more than one thread simultaneously (as long as all threads use the identical \f[I]size\f[] value). The size of the root object is guaranteed to be not less than the requested \f[I]size\f[]. If the requested size is larger than the current size, the root object is automatically resized. In such case, the old data is preserved and the extra space is zeroed. If the requested size is equal to or smaller than the current size, the root object remains unchanged. If the requested \f[I]size\f[] is equal to zero, the root object is not allocated. .PP \f[B]pmemobj_root_construct\f[]() performs the same actions as \f[B]pmemobj_root\f[](), but instead of zeroing the newly allocated object a \f[I]constructor\f[] function is called to initialize the object. The constructor is also called on reallocations. .PP The \f[B]POBJ_ROOT\f[]() macro works the same way as the \f[B]pmemobj_root\f[]() function except it returns a typed \f[I]OID\f[] value. .PP The \f[B]pmemobj_root_size\f[]() function returns the current size of the root object associated with the persistent memory pool \f[I]pop\f[]. .SH RETURN VALUE .PP Upon success, \f[B]pmemobj_root\f[]() returns a handle to the root object associated with the persistent memory pool \f[I]pop\f[]. The same root object handle is returned in all the threads. If the requested object size is larger than the maximum allocation size supported for the pool, or if there is not enough free space in the pool to satisfy a reallocation request, \f[B]pmemobj_root\f[]() returns \f[B]OID_NULL\f[] and sets \f[I]errno\f[] to ENOMEM. If the \f[I]size\f[] was equal to zero and the root object has not been allocated, \f[B]pmemobj_root\f[]() returns \f[B]OID_NULL\f[] and sets \f[I]errno\f[] to EINVAL. .PP If the \f[B]pmemobj_root_construct\f[]() constructor fails, the allocation is canceled, \f[B]pmemobj_root_construct\f[]() returns \f[I]OID_NULL\f[], and \f[I]errno\f[] is set to \f[B]ECANCELED\f[]. \f[B]pmemobj_root_size\f[]() can be used in the constructor to check whether this is the first call to the constructor. .PP \f[B]POBJ_ROOT\f[]() returns a typed \f[I]OID\f[] of type \f[I]TYPE\f[] instead of the \f[I]PMEMoid\f[] returned by \f[B]pmemobj_root\f[](). .PP The \f[B]pmemobj_root_size\f[]() function returns the current size of the root object associated with the persistent memory pool \f[I]pop\f[]. The returned size is the largest value requested by any of the earlier \f[B]pmemobj_root\f[]() calls. If the root object has not been allocated yet, \f[B]pmemobj_root_size\f[]() returns 0. .SH SEE ALSO .PP \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemobj/tx_strdup.30000664000000000000000000000002714123364546016242 0ustar rootroot.so pmemobj_tx_alloc.3 pmdk-1.11.1/doc/macros.man0000664000000000000000000001201414123364546013762 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # These macros are defined for the m4 preprocessor and are controlled by # the FREEBSD, WIN32 and WEB variables. These MUST be explicitly defined or # undefined on the m4 command line. # # This solution allows the maintenance of Windows, Linux and FreeBSD # documentation in the same file. # # The macros are: # # _BSDWX(FreeBSD,WinLinux): # Choose text based on FREEBSD. Both arguments are optional # (although the comma must be present if FreeBSD is omitted). # Bracket string with (=q=, =e=) if it contains commas. # _DEBUGLIBPATH() # Inserts pathnames for debug libraries depending on WIN32 and # FREEBSD. # _LDLIBPATH() # Inserts suggested pathnames for LD_LIBRARY_PATH depending on # WIN32 and FREEBSD. # _MP(man_page_name, section): # Include the man page section number if not building for WEB. # _UNICODE(): # Inserts a standard note regarding UNICODE support if WIN32. # _U(func_name): # Append "U" to func_name if WIN32. # _UW(func_name): # Emit **func_nameU**()/**func_nameW**() if WIN32. # _UWFUNC(func_name, args): # Define U and W prototypes of char/wchar_t *func_name if WIN32. # Bracket args string with (=q=, =e=) if it is a comma-separated # list. # _UWFUNCR(ret_type, func_name, char_arg): # Define U and W prototypes of ret_type func_name if WIN32. # Single char/wchar_t argument is char_arg. # _UWFUNCRUW(ret_type, func_name, args): # Define U and W prototypes of ret_type[U/W] func_name if WIN32. # Bracket args string with (=q=, =e=) if it is a comma-separated # list. # _UWFUNCR1(ret_type, func_name, char_arg, rest_of_args, comment): # Define U and W prototypes of ret_type func_name if WIN32. # First char/wchar_t argument is char_arg. Bracket rest_of_args # string with (=q=, =e=) if it is a comma-separated list. # Comment is added after prototype definition if present. # _UWFUNCR12(ret_type, func_name, char_arg1, char_arg2, rest_of_args, # comment): # Define U and W prototypes of ret_type func_name if WIN32. # Two char/wchar_t arguments are char_arg1-2. Bracket # rest_of_args string with (=q=, =e=) if it is a comma-separated # list. Comment is added after prototype definition if present. # _UWFUNCR1UW(ret_type, func_name, arg1_type, arg1, rest_of_args): # Define U and W prototypes of ret_type func_name, append [U/W] # to arg1_type arg1. Bracket rest_of_args string with (=q=, =e=) # if it is a comma-separated list. # _UWFUNCR20(ret_type, func_name, arg1, char_arg): # Define U and W prototypes of ret_type func_name if WIN32. # Second char/wchar_t argument is char_arg. # _UWFUNCR2(ret_type, func_name, arg1, char_arg, rest_of_args, comment): # Define U and W prototypes of ret_type func_name if WIN32. # Second char/wchar_t argument is char_arg. Bracket rest_of_args # string with (=q=, =e=) if it is a comma-separated list. # Comment is added after prototype definition if present. # _UWS(struct_name): # Emit *struct struct_nameU*/*struct struct_nameW* if WIN32. # _WINUX(Windows,UX): # Choose text based on WIN32. Both arguments are optional # (although the comma must be present if Windows is omitted). # Bracket string with (=q=, =e=) if it contains commas. changequote(=q=,=e=) changecom() define(_BSDWX, ifdef(=q=FREEBSD=e=,$1,$2)) define(_DEBUGLIBPATH, ifdef(=q=WIN32=e=,**/pmdk/src/x64/Debug**, ifdef(=q=FREEBSD=e=,**/usr/local/lib/pmdk_debug**, **/usr/lib/pmdk_debug**))) define(_LDLIBPATH, ifdef(=q=WIN32=e=,**/pmdk/src/x64/Debug**, ifdef(=q=FREEBSD=e=,**/usr/local/lib/pmdk_debug**, =q==q==q=**/usr/lib/pmdk_debug** or **/usr/lib64/pmdk_debug**, as appropriate=e==e==e=))) define(_MP, ifdef(=q=WEB=e=,$1,$1($2))) define(_UNICODE, ifdef(=q=WIN32=e=,=q==q= >NOTE: The PMDK API supports UNICODE. If the **PMDK_UTF8_API** macro is defined, basic API functions are expanded to the UTF-8 API with postfix *U*. Otherwise they are expanded to the UNICODE API with postfix *W*.=e==e=)) define(_U, ifdef(=q=WIN32=e=,$1U,$1)) define(_UW, ifdef(=q=WIN32=e=,**$1U**()/**$1W**(),**$1**())) define(_UWFUNC, ifdef(=q=WIN32=e=, const char *$1U($2); const wchar_t *$1W($2);, const char *$1($2);)) define(_UWFUNCR, ifdef(=q=WIN32=e=, $1 $2U(const char $3); $1 $2W(const wchar_t $3);, $1 $2(const char $3);)) define(_UWFUNCRUW, ifdef(=q=WIN32=e=, $1U $2U($3); $1W $2W($3);, $1 $2($3);)) define(_UWFUNCR1, ifdef(=q=WIN32=e=, $1 $2U(const char $3, $4);$5 $1 $2W(const wchar_t $3, $4);$5, $1 $2(const char $3, $4);$5)) define(_UWFUNCR12, ifdef(=q=WIN32=e=, $1 $2U(const char $3, const char $4, $5);$6 $1 $2W(const wchar_t $3, const wchar_t $4, $5);$6, $1 $2(const char $3, const char $4, $5);$6)) define(_UWFUNCR1UW, ifdef(=q=WIN32=e=, $1 $2U($3U $4, $5); $1 $2W($3W $4, $5);, $1 $2($3 $4, $5);)) define(_UWFUNCR20, ifdef(=q=WIN32=e=, $1 $2U($3, const char $4); $1 $2W($3, const wchar_t $4);, $1 $2($3, const char $4);)) define(_UWFUNCR2, ifdef(=q=WIN32=e=, $1 $2U($3, const char $4, $5);$6 $1 $2W($3, const wchar_t $4, $5);$6, $1 $2($3, const char $4, $5);$6)) define(_UWS, ifdef(=q=WIN32=e=,*struct $1U*/*struct $1W*,*struct $1*)) define(_WINUX, ifdef(=q=WIN32=e=,$1,$2)) pmdk-1.11.1/doc/pmem_ctl/0000775000000000000000000000000014123364726013603 5ustar rootrootpmdk-1.11.1/doc/pmem_ctl/pmem_ctl.50000664000000000000000000000776214123364726015505 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_CTL" "5" "2021-09-24" "PMDK - pmem_ctl API version 1.4" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018-2019, Intel Corporation .SH NAME .PP ctl \- interface for examination and modification of the library's internal state. .SH DESCRIPTION .PP The CTL namespace is organized in a tree structure. Starting from the root, each node can be either internal, containing other elements, or a leaf. Internal nodes themselves can only contain other nodes and cannot be entry points. There are two types of those nodes: \f[I]named\f[] and \f[I]indexed\f[]. Named nodes have string identifiers. Indexed nodes represent an abstract array index and have an associated string identifier. The index itself is provided by the user. A collection of indexes present on the path of an entry point is provided to the handler functions as name and index pairs. .PP Entry points are the leaves of the CTL namespace structure. Each entry point can read from the internal state, write to the internal state, exec a function or a combination of these operations. .PP The entry points are listed in the following format: .PP name | r(ead)w(rite)x(ecute) | global/\- | read argument type | write argument type | exec argument type | config argument type .PP A description of \f[B]pmem_ctl\f[] functions can be found on the following manual pages: \f[B]libpmemblk_ctl_get\f[](3), \f[B]libpmemlog_ctl_get\f[](3), \f[B]libpmemobj_ctl_get\f[](3) .SH CTL EXTERNAL CONFIGURATION .PP In addition to direct function call, each write entry point can also be set using two alternative methods. .PP The first method is to load a configuration directly from the \f[B]PMEMBLK_CONF\f[]/ \f[B]PMEMLOG_CONF\f[]/ \f[B]PMEMOBJ_CONF\f[] environment variable. A properly formatted ctl config string is a single\-line sequence of queries separated by `;': .IP .nf \f[C] query0;query1;...;queryN \f[] .fi .PP A single query is constructed from the name of the ctl write entry point and the argument, separated by `=': .IP .nf \f[C] entry_point=entry_point_argument \f[] .fi .PP The entry point argument type is defined by the entry point itself, but there are three predefined primitives: .IP .nf \f[C] *)\ integer:\ represented\ by\ a\ sequence\ of\ [0\-9]\ characters\ that\ form \ \ \ \ a\ single\ number. *)\ boolean:\ represented\ by\ a\ single\ character:\ y/n/Y/N/0/1,\ each \ \ \ \ corresponds\ to\ true\ or\ false.\ If\ the\ argument\ contains\ any \ \ \ \ trailing\ characters,\ they\ are\ ignored. *)\ string:\ a\ simple\ sequence\ of\ characters. \f[] .fi .PP There are also complex argument types that are formed from the primitives separated by a `,': .IP .nf \f[C] first_arg,second_arg \f[] .fi .PP In summary, a full configuration sequence looks like this: .IP .nf \f[C] (first_entry_point)=(arguments,\ ...);...;(last_entry_point)=(arguments,\ ...); \f[] .fi .PP As an example, to set both prefault at_open and at_create variables: .IP .nf \f[C] PMEMBLK_CONF="prefault.at_open=1;prefault.at_create=1" \f[] .fi .PP The second method of loading an external configuration is to set the \f[B]PMEMBLK_CONF_FILE\f[]/ \f[B]PMEMLOG_CONF_FILE\f[]/ \f[B]PMEMOBJ_CONF_FILE\f[] environment variable to point to a file that contains a sequence of ctl queries. The parsing rules are all the same, but the file can also contain white\-spaces and comments. .PP To create a comment, simply use `#' anywhere in a line and everything afterwards, until a new line, will be ignored. .PP An example configuration file: .IP .nf \f[C] ######################### #\ My\ pmemblk\ configuration ######################### # #\ Global\ settings: prefault.\ #\ modify\ the\ behavior\ of\ pre\-faulting \ \ \ \ at_open\ =\ 1;\ #\ prefault\ when\ the\ pool\ is\ opened prefault. \ \ \ \ at_create\ =\ 0;\ #\ but\ don\[aq]t\ prefault\ when\ it\[aq]s\ created #\ Per\-pool\ settings: #\ ... \f[] .fi .SH SEE ALSO .PP \f[B]libpmemblk_ctl_get\f[](3), \f[B]libpmemlog_ctl_get\f[](3), \f[B]libpmemobj_ctl_get\f[](3) and \f[B]\f[] pmdk-1.11.1/doc/pmem_ctl/pmem_ctl.5.md0000664000000000000000000000754414123364546016102 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEM_CTL, 5) collection: pmem_ctl header: PMDK date: pmem_ctl API version 1.4 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018-2019, Intel Corporation) [comment]: <> (pmem_ctl.5 -- man page for CTL) [NAME](#name)
[DESCRIPTION](#description)
[CTL EXTERNAL CONFIGURATION](#ctl-external-configuration)
[SEE ALSO](#see-also)
# NAME # ctl - interface for examination and modification of the library's internal state. # DESCRIPTION # The CTL namespace is organized in a tree structure. Starting from the root, each node can be either internal, containing other elements, or a leaf. Internal nodes themselves can only contain other nodes and cannot be entry points. There are two types of those nodes: *named* and *indexed*. Named nodes have string identifiers. Indexed nodes represent an abstract array index and have an associated string identifier. The index itself is provided by the user. A collection of indexes present on the path of an entry point is provided to the handler functions as name and index pairs. Entry points are the leaves of the CTL namespace structure. Each entry point can read from the internal state, write to the internal state, exec a function or a combination of these operations. The entry points are listed in the following format: name | r(ead)w(rite)x(ecute) | global/- | read argument type | write argument type | exec argument type | config argument type A description of **pmem_ctl** functions can be found on the following manual pages: **libpmemblk_ctl_get**(3), **libpmemlog_ctl_get**(3), **libpmemobj_ctl_get**(3) # CTL EXTERNAL CONFIGURATION # In addition to direct function call, each write entry point can also be set using two alternative methods. The first method is to load a configuration directly from the **PMEMBLK_CONF**/ **PMEMLOG_CONF**/ **PMEMOBJ_CONF** environment variable. A properly formatted ctl config string is a single-line sequence of queries separated by ';': ``` query0;query1;...;queryN ``` A single query is constructed from the name of the ctl write entry point and the argument, separated by '=': ``` entry_point=entry_point_argument ``` The entry point argument type is defined by the entry point itself, but there are three predefined primitives: *) integer: represented by a sequence of [0-9] characters that form a single number. *) boolean: represented by a single character: y/n/Y/N/0/1, each corresponds to true or false. If the argument contains any trailing characters, they are ignored. *) string: a simple sequence of characters. There are also complex argument types that are formed from the primitives separated by a ',': ``` first_arg,second_arg ``` In summary, a full configuration sequence looks like this: ``` (first_entry_point)=(arguments, ...);...;(last_entry_point)=(arguments, ...); ``` As an example, to set both prefault at_open and at_create variables: ``` PMEMBLK_CONF="prefault.at_open=1;prefault.at_create=1" ``` The second method of loading an external configuration is to set the **PMEMBLK_CONF_FILE**/ **PMEMLOG_CONF_FILE**/ **PMEMOBJ_CONF_FILE** environment variable to point to a file that contains a sequence of ctl queries. The parsing rules are all the same, but the file can also contain white-spaces and comments. To create a comment, simply use '#' anywhere in a line and everything afterwards, until a new line, will be ignored. An example configuration file: ``` ######################### # My pmemblk configuration ######################### # # Global settings: prefault. # modify the behavior of pre-faulting at_open = 1; # prefault when the pool is opened prefault. at_create = 0; # but don't prefault when it's created # Per-pool settings: # ... ``` # SEE ALSO # **libpmemblk_ctl_get**(3), **libpmemlog_ctl_get**(3), **libpmemobj_ctl_get**(3) and **** pmdk-1.11.1/doc/pmem_ctl/.gitignore0000664000000000000000000000001314123364546015565 0ustar rootrootpmem_ctl.5 pmdk-1.11.1/doc/libvmem/0000775000000000000000000000000014123364546013436 5ustar rootrootpmdk-1.11.1/doc/libvmem/README.md0000664000000000000000000000012614123364546014714 0ustar rootrootThis library has been moved to a [separate repository](https://github.com/pmem/vmem). pmdk-1.11.1/doc/libpmemblk/0000775000000000000000000000000014123364730014114 5ustar rootrootpmdk-1.11.1/doc/libpmemblk/pmemblk_create.30000664000000000000000000001641714123364727017171 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMBLK_CREATE" "3" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemblk_create\f[](), \f[B]pmemblk_open\f[](), \f[B]pmemblk_close\f[](), \f[B]pmemblk_check\f[]() \- create, open, close and validate block pool .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMblkpool\ *pmemblk_create(const\ char\ *path,\ size_t\ bsize, \ \ \ \ \ \ \ \ size_t\ poolsize,\ mode_t\ mode); PMEMblkpool\ *pmemblk_open(const\ char\ *path,\ size_t\ bsize); void\ pmemblk_close(PMEMblkpool\ *pbp); int\ pmemblk_check(const\ char\ *path,\ size_t\ bsize); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemblk_create\f[]() function creates a block memory pool with the given total \f[I]poolsize\f[], divided into as many elements of size \f[I]bsize\f[] as will fit in the pool. Since the transactional nature of a block memory pool requires some space overhead in the memory pool, the resulting number of available blocks is less than \f[I]poolsize\f[]/\f[I]bsize\f[], and is made available to the caller via the \f[B]pmemblk_nblock\f[](3) function. Given the specifics of the implementation, the number of available blocks for the user cannot be less than 256. This translates to at least 512 internal blocks. \f[I]path\f[] specifies the name of the memory pool file to be created. \f[I]mode\f[] specifies the permissions to use when creating the file, as described by \f[B]creat\f[](2). The memory pool file is fully allocated to the size \f[I]poolsize\f[] using \f[B]posix_fallocate\f[](3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling \f[B]pmemblk_create\f[](), and then specifying \f[I]poolsize\f[] as zero. In this case \f[B]pmemblk_create\f[]() will take the pool size from the size of the existing file, and will verify that the file appears to be empty by searching for any non\-zero data in the pool header at the beginning of the file. The net pool size of a pool file is equal to the file size. The minimum net pool size allowed by the library for a block pool is defined in \f[B]\f[] as \f[B]PMEMBLK_MIN_POOL\f[]. \f[I]bsize\f[] can be any non\-zero value; however, \f[B]libpmemblk\f[] will silently round up the given size to \f[B]PMEMBLK_MIN_BLK\f[], as defined in \f[B]\f[]. .PP Depending on the configuration of the system, the available non\-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemblk memory pool could be limited by the capacity of a single memory device. \f[B]libpmemblk\f[](7) allows building a persistent memory resident array spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a \f[I]pool set\f[] may be stored on a different memory device or pmem\-aware filesystem. .PP Creation of all the parts of the pool set can be done with \f[B]pmemblk_create\f[](); however, the recommended method for creating pool sets is by using the \f[B]pmempool\f[](1) utility. .PP When creating a pool set consisting of multiple files, the \f[I]path\f[] argument passed to \f[B]pmemblk_create\f[]() must point to the special \f[I]set\f[] file that defines the pool layout and the location of all the parts of the pool set. The \f[I]poolsize\f[] argument must be 0. The meaning of the \f[I]mode\f[] argument does not change, except that the same \f[I]mode\f[] is used for creation of all the parts of the pool set. .PP For more information on pool set format, see \f[B]poolset\f[](5). .PP The \f[B]pmemblk_open\f[]() function opens an existing block memory pool. As with \f[B]pmemblk_create\f[](), \f[I]path\f[] must identify either an existing block memory pool file, or the \f[I]set\f[] file used to create a pool set. The application must have permission to open the file and memory map the file or pool set with read/write permissions. If \f[I]bsize\f[] is non\-zero, \f[B]pmemblk_open\f[]() will verify that the given block size matches the block size used when the pool was created. Otherwise, \f[B]pmemblk_open\f[]() will open the pool without verifying the block size. The \f[I]bsize\f[] can be determined using the \f[B]pmemblk_bsize\f[](3) function. .PP Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in \f[B]pmempool\-feature\f[](1). .PP The \f[B]pmemblk_close\f[]() function closes the memory pool indicated by \f[I]pbp\f[] and deletes the memory pool handle. The block memory pool itself lives on in the file that contains it and may be re\-opened at a later time using \f[B]pmemblk_open\f[]() as described above. .PP The \f[B]pmemblk_check\f[]() function performs a consistency check of the file indicated by \f[I]path\f[], and returns 1 if the memory pool is found to be consistent. If the pool is found not to be consistent, further use of the file with \f[B]libpmemblk\f[] will result in undefined behavior. The debug version of \f[B]libpmemblk\f[] will provide additional details on inconsistencies when \f[B]PMEMBLK_LOG_LEVEL\f[] is at least 1, as described in the \f[B]DEBUGGING AND ERROR HANDLING\f[] section in \f[B]libpmemblk\f[](7). \f[B]pmemblk_check\f[]() opens the given \f[I]path\f[] read\-only so it never makes any changes to the file. This function is not supported on Device DAX. .SH RETURN VALUE .PP On success, \f[B]pmemblk_create\f[]() returns a \f[I]PMEMblkpool*\f[] handle to the block memory pool. On error, it returns NULL and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]pmemblk_open\f[]() returns a \f[I]PMEMblkpool*\f[] handle that can be used with most of the functions in \f[B]libpmemblk\f[](7). On error, it returns NULL and sets \f[I]errno\f[] appropriately. Possible errors include: .IP \[bu] 2 failure to open \f[I]path\f[] .IP \[bu] 2 \f[I]path\f[] specifies a \f[I]set\f[] file and any of the pool set files cannot be opened .IP \[bu] 2 \f[I]path\f[] specifies a \f[I]set\f[] file and the actual size of any file does not match the corresponding part size defined in the \f[I]set\f[] file .IP \[bu] 2 \f[I]bsize\f[] is non\-zero and does not match the block size given when the pool was created. \f[I]errno\f[] is set to \f[B]EINVAL\f[] in this case. .PP The \f[B]pmemblk_close\f[]() function returns no value. .PP \f[B]pmemblk_check\f[]() returns 1 if the memory pool is found to be consistent. If the check is successfully performed but the pool is found to be inconsistent, \f[B]pmemblk_check\f[]() returns 0. This includes the case where \f[I]bsize\f[] is non\-zero and does not match the block size given when the pool was created. If the consistency check cannot be performed, \f[B]pmemblk_check\f[]() returns \-1 and sets \f[I]errno\f[] appropriately. .SH CAVEATS .PP Not all file systems support \f[B]posix_fallocate\f[](3). \f[B]pmemblk_create\f[]() will fail if the underlying file system does not support \f[B]posix_fallocate\f[](3). .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]creat\f[](2), \f[B]pmemblk_nblock\f[](3), \f[B]posix_fallocate\f[](3), \f[B]poolset\f[](5), \f[B]libpmemblk\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/pmemblk_ctl_exec.30000664000000000000000000000002614123364546017500 0ustar rootroot.so pmemblk_ctl_get.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_read.30000664000000000000000000000266614123364730016634 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMBLK_READ" "3" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemblk_read\f[](), \f[B]pmemblk_write\f[]() \- read or write a block from a block memory pool .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemblk_read(PMEMblkpool\ *pbp,\ void\ *buf,\ long\ long\ blockno); int\ pmemblk_write(PMEMblkpool\ *pbp,\ const\ void\ *buf,\ long\ long\ blockno); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemblk_read\f[]() function reads the block with block number \f[I]blockno\f[] from memory pool \f[I]pbp\f[] into the buffer \f[I]buf\f[]. Reading a block that has never been written by \f[B]pmemblk_write\f[]() will return a block of zeroes. .PP The \f[B]pmemblk_write\f[]() function writes a block from \f[I]buf\f[] to block number \f[I]blockno\f[] in the memory pool \f[I]pbp\f[]. The write is atomic with respect to other reads and writes. In addition, the write cannot be torn by program failure or system crash; on recovery the block is guaranteed to contain either the old data or the new data, never a mixture of both. .SH RETURN VALUE .PP On success, the \f[B]pmemblk_read\f[]() and \f[B]pmemblk_write\f[]() functions return 0. On error, they return \-1 and set \f[I]errno\f[] appropriately. .SH SEE ALSO .PP \f[B]libpmemblk\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/pmemblk_check.30000664000000000000000000000002514123364546016766 0ustar rootroot.so pmemblk_create.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_read.3.md0000664000000000000000000000305214123364546017226 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMBLK_READ, 3) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemblk_read.3 -- man page for libpmemblk read and write functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemblk_read**(), **pmemblk_write**() - read or write a block from a block memory pool # SYNOPSIS # ```c #include int pmemblk_read(PMEMblkpool *pbp, void *buf, long long blockno); int pmemblk_write(PMEMblkpool *pbp, const void *buf, long long blockno); ``` # DESCRIPTION # The **pmemblk_read**() function reads the block with block number *blockno* from memory pool *pbp* into the buffer *buf*. Reading a block that has never been written by **pmemblk_write**() will return a block of zeroes. The **pmemblk_write**() function writes a block from *buf* to block number *blockno* in the memory pool *pbp*. The write is atomic with respect to other reads and writes. In addition, the write cannot be torn by program failure or system crash; on recovery the block is guaranteed to contain either the old data or the new data, never a mixture of both. # RETURN VALUE # On success, the **pmemblk_read**() and **pmemblk_write**() functions return 0. On error, they return -1 and set *errno* appropriately. # SEE ALSO # **libpmemblk**(7) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_bsize.3.md0000664000000000000000000000310614123364546017427 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMBLK_BSIZE, 3) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemblk_bsize.3 -- man page for functions that check number of available blocks or usable space in block memory pool) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemblk_bsize**(), **pmemblk_nblock**() - check number of available blocks or usable space in block memory pool # SYNOPSIS # ```c #include size_t pmemblk_bsize(PMEMblkpool *pbp); size_t pmemblk_nblock(PMEMblkpool *pbp); ``` # DESCRIPTION # The **pmemblk_bsize**() function returns the block size of the specified block memory pool, that is, the value which was passed as *bsize* to _UW(pmemblk_create). *pbp* must be a block memory pool handle as returned by **pmemblk_open**(3) or **pmemblk_create**(3). The **pmemblk_nblock**() function returns the usable space in the block memory pool. *pbp* must be a block memory pool handle as returned by **pmemblk_open**(3) or **pmemblk_create**(3). # RETURN VALUE # The **pmemblk_bsize**() function returns the block size of the specified block memory pool. The **pmemblk_nblock**() function returns the usable space in the block memory pool, expressed as the number of blocks available. # SEE ALSO # **pmemblk_create**(3), **pmemblk_open**(3), **libpmemblk**(7) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_ctl_get.30000664000000000000000000000706414123364727017345 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMBLK_CTL_GET" "3" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018-2019, Intel Corporation .SH NAME .PP \f[B]pmemblk_ctl_get\f[](), \f[B]pmemblk_ctl_set\f[](), \f[B]pmemblk_ctl_exec\f[]() \- Query and modify libpmemblk internal behavior (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemblk_ctl_get(PMEMblkpool\ *pbp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemblk_ctl_set(PMEMblkpool\ *pbp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemblk_ctl_exec(PMEMblkpool\ *pbp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemblk_ctl_get\f[](), \f[B]pmemblk_ctl_set\f[]() and \f[B]pmemblk_ctl_exec\f[]() functions provide a uniform interface for querying and modifying the internal behavior of \f[B]libpmemblk\f[](7) through the control (CTL) namespace. .PP The \f[I]name\f[] argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra \f[I]arg\f[] is required. Those two parameters together create a CTL query. The functions and the entry points are thread\-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either \f[I]name\f[] or \f[I]arg\f[] is invalid, \-1 is returned. .PP If the provided ctl query is valid, the CTL functions will always return 0 on success and \-1 on failure, unless otherwise specified in the entry point description. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH CTL NAMESPACE .PP prefault.at_create | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemblk_create\f[]() function. .PP Always returns 0. .PP prefault.at_open | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemblk_open\f[]() function. .PP Always returns 0. .PP sds.at_create | rw | global | int | int | \- | boolean .PP If set, force\-enables or force\-disables SDS feature during pool creation. Affects only the \f[B]pmemblk_create\f[]() function. See \f[B]pmempool_feature_query\f[](3) for information about SDS (SHUTDOWN_STATE) feature. .PP Always returns 0. .PP copy_on_write.at_open | rw | global | int | int | \- | boolean .PP If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. .PP Always returns 0. .SH CTL EXTERNAL CONFIGURATION .PP In addition to direct function call, each write entry point can also be set using two alternative methods. .PP The first method is to load a configuration directly from the \f[B]PMEMBLK_CONF\f[] environment variable. .PP The second method of loading an external configuration is to set the \f[B]PMEMBLK_CONF_FILE\f[] environment variable to point to a file that contains a sequence of ctl queries. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH SEE ALSO .PP \f[B]libpmemblk\f[](7), \f[B]pmem_ctl\f[](5) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/pmemblk_check_version.30000664000000000000000000000002614123364546020534 0ustar rootroot.so man7/libpmemblk.7 pmdk-1.11.1/doc/libpmemblk/pmemblk_create.3.md0000664000000000000000000001623514123364546017565 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMBLK_CREATE, 3) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemblk_create.3 -- man page for libpmemblk create, open, close and validate functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # _UW(pmemblk_create), _UW(pmemblk_open), **pmemblk_close**(), _UW(pmemblk_check) - create, open, close and validate block pool # SYNOPSIS # ```c #include _UWFUNCR1(PMEMblkpool, *pmemblk_create, *path, =q=size_t bsize, size_t poolsize, mode_t mode=e=) _UWFUNCR1(PMEMblkpool, *pmemblk_open, *path, size_t bsize) void pmemblk_close(PMEMblkpool *pbp); _UWFUNCR1(int, pmemblk_check, *path, size_t bsize) ``` _UNICODE() # DESCRIPTION # The _UW(pmemblk_create) function creates a block memory pool with the given total *poolsize*, divided into as many elements of size *bsize* as will fit in the pool. Since the transactional nature of a block memory pool requires some space overhead in the memory pool, the resulting number of available blocks is less than *poolsize*/*bsize*, and is made available to the caller via the **pmemblk_nblock**(3) function. Given the specifics of the implementation, the number of available blocks for the user cannot be less than 256. This translates to at least 512 internal blocks. *path* specifies the name of the memory pool file to be created. *mode* specifies the permissions to use when creating the file, as described by **creat**(2). The memory pool file is fully allocated to the size *poolsize* using **posix_fallocate**(3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling _UW(pmemblk_create), and then specifying *poolsize* as zero. In this case _UW(pmemblk_create) will take the pool size from the size of the existing file, and will verify that the file appears to be empty by searching for any non-zero data in the pool header at the beginning of the file. The net pool size of a pool file is equal to the file size. The minimum net pool size allowed by the library for a block pool is defined in **\** as **PMEMBLK_MIN_POOL**. *bsize* can be any non-zero value; however, **libpmemblk** will silently round up the given size to **PMEMBLK_MIN_BLK**, as defined in **\**. Depending on the configuration of the system, the available non-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemblk memory pool could be limited by the capacity of a single memory device. **libpmemblk**(7) allows building a persistent memory resident array spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a *pool set* may be stored on a different memory device or pmem-aware filesystem. Creation of all the parts of the pool set can be done with _UW(pmemblk_create); however, the recommended method for creating pool sets is by using the **pmempool**(1) utility. When creating a pool set consisting of multiple files, the *path* argument passed to _UW(pmemblk_create) must point to the special *set* file that defines the pool layout and the location of all the parts of the pool set. The *poolsize* argument must be 0. The meaning of the *mode* argument does not change, except that the same *mode* is used for creation of all the parts of the pool set. For more information on pool set format, see **poolset**(5). The _UW(pmemblk_open) function opens an existing block memory pool. As with _UW(pmemblk_create), *path* must identify either an existing block memory pool file, or the *set* file used to create a pool set. The application must have permission to open the file and memory map the file or pool set with read/write permissions. If *bsize* is non-zero, _UW(pmemblk_open) will verify that the given block size matches the block size used when the pool was created. Otherwise, _UW(pmemblk_open) will open the pool without verifying the block size. The *bsize* can be determined using the **pmemblk_bsize**(3) function. Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in **pmempool-feature**(1). The **pmemblk_close**() function closes the memory pool indicated by *pbp* and deletes the memory pool handle. The block memory pool itself lives on in the file that contains it and may be re-opened at a later time using _UW(pmemblk_open) as described above. The _UW(pmemblk_check) function performs a consistency check of the file indicated by *path*, and returns 1 if the memory pool is found to be consistent. If the pool is found not to be consistent, further use of the file with **libpmemblk** will result in undefined behavior. The debug version of **libpmemblk** will provide additional details on inconsistencies when **PMEMBLK_LOG_LEVEL** is at least 1, as described in the **DEBUGGING AND ERROR HANDLING** section in **libpmemblk**(7). _UW(pmemblk_check) opens the given *path* read-only so it never makes any changes to the file. This function is not supported on Device DAX. # RETURN VALUE # On success, _UW(pmemblk_create) returns a *PMEMblkpool\** handle to the block memory pool. On error, it returns NULL and sets *errno* appropriately. On success, _UW(pmemblk_open) returns a *PMEMblkpool\** handle that can be used with most of the functions in **libpmemblk**(7). On error, it returns NULL and sets *errno* appropriately. Possible errors include: + failure to open *path* + *path* specifies a *set* file and any of the pool set files cannot be opened + *path* specifies a *set* file and the actual size of any file does not match the corresponding part size defined in the *set* file + *bsize* is non-zero and does not match the block size given when the pool was created. *errno* is set to **EINVAL** in this case. The **pmemblk_close**() function returns no value. _UW(pmemblk_check) returns 1 if the memory pool is found to be consistent. If the check is successfully performed but the pool is found to be inconsistent, _UW(pmemblk_check) returns 0. This includes the case where *bsize* is non-zero and does not match the block size given when the pool was created. If the consistency check cannot be performed, _UW(pmemblk_check) returns -1 and sets *errno* appropriately. # CAVEATS # Not all file systems support **posix_fallocate**(3). _UW(pmemblk_create) will fail if the underlying file system does not support **posix_fallocate**(3). _WINUX(=q= On Windows if _UW(pmemblk_create) is called on an existing file with FILE_ATTRIBUTE_SPARSE_FILE and FILE_ATTRIBUTE_COMPRESSED set, they will be removed, to physically allocate space for the pool. This is a workaround for _chsize() performance issues. =e=) # SEE ALSO # **pmempool**(1), **creat**(2), **pmemblk_nblock**(3), **posix_fallocate**(3), **poolset**(5), **libpmemblk**(7) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_set_error.30000664000000000000000000000002714123364546017717 0ustar rootroot.so pmemblk_set_zero.3 pmdk-1.11.1/doc/libpmemblk/libpmemblk.70000664000000000000000000002762014123364725016335 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEMBLK" "7" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]libpmemblk\f[] \- persistent memory resident array of blocks .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lpmemblk\ \-lpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *pmemblk_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Managing library behavior: .IP .nf \f[C] void\ pmemblk_set_funcs( \ \ \ \ void\ *(*malloc_func)(size_t\ size), \ \ \ \ void\ (*free_func)(void\ *ptr), \ \ \ \ void\ *(*realloc_func)(void\ *ptr,\ size_t\ size), \ \ \ \ char\ *(*strdup_func)(const\ char\ *s)); \f[] .fi .SS Error handling: .IP .nf \f[C] const\ char\ *pmemblk_errormsg(void); \f[] .fi .SS Other library functions: .PP A description of other \f[B]libpmemblk\f[] functions can be found on the following manual pages: .PP \f[B]pmemblk_bsize\f[](3), \f[B]pmemblk_create\f[](3), \f[B]pmemblk_ctl_exec\f[](3), \f[B]pmemblk_ctl_get\f[](3), \f[B]pmemblk_ctl_set\f[](3), \f[B]pmemblk_read\f[](3), \f[B]pmemblk_set_zero\f[](3), .SH DESCRIPTION .PP \f[B]libpmemblk\f[] provides an array of blocks in \f[I]persistent memory\f[] (pmem) such that updates to a single block are atomic. This library is intended for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of \f[I]non\-volatile memory DIMMs\f[] (NVDIMMs) provide this type of byte addressable access to storage. A \f[I]persistent memory aware file system\f[] is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non\-paged access to pmem. \f[B]libpmemblk\f[] builds on this type of memory mapped file. .PP This library is for applications that need a potentially large array of blocks, all the same size, where any given block is updated atomically (the update cannot be \f[I]torn\f[] by program interruption such as power failures). This library builds on the low\-level pmem support provided by \f[B]libpmem\f[](7), handling the transactional update of the blocks, flushing to persistence, and recovery for the application. \f[B]libpmemblk\f[] is one of a collection of persistent memory libraries available, the others are: .IP \[bu] 2 \f[B]libpmemobj\f[](7), a general use persistent memory API, providing memory allocation and transactional operations on variable\-sized objects. .IP \[bu] 2 \f[B]libpmemlog\f[](7), providing a pmem\-resident log file. .IP \[bu] 2 \f[B]libpmem\f[](7), low\-level persistent memory support. .PP Under normal usage, \f[B]libpmemblk\f[] will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under \f[B]DEBUGGING AND ERROR HANDLING\f[] below. .PP To use the atomic block arrays supplied by \f[B]libpmemblk\f[], a \f[I]memory pool\f[] is first created using the \f[B]pmemblk_create\f[]() function described in \f[B]pmemblk_create\f[](3). The other \f[B]libpmemblk\f[] functions operate on the resulting block memory pool using the opaque handle, of type \f[I]PMEMblkpool*\f[], that is returned by \f[B]pmemblk_create\f[]() or \f[B]pmemblk_open\f[](). Internally, \f[B]libpmemblk\f[] will use either \f[B]pmem_persist\f[](3) or \f[B]msync\f[](2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the \f[B]pmem_is_pmem\f[](3) function in \f[B]libpmem\f[](7) for more information). There is no need for applications to flush changes directly when using the block memory API provided by \f[B]libpmemblk\f[]. .SH CAVEATS .PP \f[B]libpmemblk\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]pmemblk_check_version\f[]() function is used to determine whether the installed \f[B]libpmemblk\f[] supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile\-time version information, supplied by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ pmemblk_check_version(PMEMBLK_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEMBLK_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP When the version check performed by \f[B]pmemblk_check_version\f[]() is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by \f[B]pmemblk_check_version\f[]() must not be modified or freed. .SH MANAGING LIBRARY BEHAVIOR .PP The \f[B]pmemblk_set_funcs\f[]() function allows an application to override memory allocation calls used internally by \f[B]libpmemblk\f[]. Passing in NULL for any of the handlers will cause the \f[B]libpmemblk\f[] default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4\-8 kilobytes for each memory pool in use. .SH DEBUGGING AND ERROR HANDLING .PP The \f[B]pmemblk_errormsg\f[]() function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code, as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmemblk\f[] function indicated an error, or if \f[I]errno\f[] was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. .PP Two versions of \f[B]libpmemblk\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmemblk\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. If an error is detected in a call to \f[B]libpmemblk\f[], the error message describing the failure may be retrieved with \f[B]pmemblk_errormsg\f[]() as described above. .PP A second version of \f[B]libpmemblk\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the \f[B]LD_LIBRARY_PATH\f[] environment variable to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEMBLK_LOG_LEVEL\f[] .PP The value of \f[B]PMEMBLK_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEMBLK_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmemblk_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmemblk\f[] developers. .PP Unless \f[B]PMEMBLK_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMBLK_LOG_FILE\f[] .PP Specifies the name of a file where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEMBLK_LOG_FILE\f[] is not set, the logging output is written to \f[I]stderr\f[]. .PP See also \f[B]libpmem\f[](7) for information on other environment variables that may affect \f[B]libpmemblk\f[] behavior. .SH EXAMPLE .PP The following example illustrates how the \f[B]libpmemblk\f[] API is used. .IP .nf \f[C] #include\ #include\ #include\ #include\ #include\ #include\ /*\ size\ of\ the\ pmemblk\ pool\ \-\-\ 1\ GB\ */ #define\ POOL_SIZE\ ((size_t)(1\ <<\ 30)) /*\ size\ of\ each\ element\ in\ the\ pmem\ pool\ */ #define\ ELEMENT_SIZE\ 1024 int main(int\ argc,\ char\ *argv[]) { \ \ \ \ const\ char\ path[]\ =\ "/pmem\-fs/myfile"; \ \ \ \ PMEMblkpool\ *pbp; \ \ \ \ size_t\ nelements; \ \ \ \ char\ buf[ELEMENT_SIZE]; \ \ \ \ /*\ create\ the\ pmemblk\ pool\ or\ open\ it\ if\ it\ already\ exists\ */ \ \ \ \ pbp\ =\ pmemblk_create(path,\ ELEMENT_SIZE,\ POOL_SIZE,\ 0666); \ \ \ \ if\ (pbp\ ==\ NULL) \ \ \ \ \ \ \ \ pbp\ =\ pmemblk_open(path,\ ELEMENT_SIZE); \ \ \ \ if\ (pbp\ ==\ NULL)\ { \ \ \ \ \ \ \ \ perror(path); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ how\ many\ elements\ fit\ into\ the\ file?\ */ \ \ \ \ nelements\ =\ pmemblk_nblock(pbp); \ \ \ \ printf("file\ holds\ %zu\ elements",\ nelements); \ \ \ \ /*\ store\ a\ block\ at\ index\ 5\ */ \ \ \ \ strcpy(buf,\ "hello,\ world"); \ \ \ \ if\ (pmemblk_write(pbp,\ buf,\ 5)\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("pmemblk_write"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ read\ the\ block\ at\ index\ 10\ (reads\ as\ zeros\ initially)\ */ \ \ \ \ if\ (pmemblk_read(pbp,\ buf,\ 10)\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("pmemblk_read"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ zero\ out\ the\ block\ at\ index\ 5\ */ \ \ \ \ if\ (pmemblk_set_zero(pbp,\ 5)\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("pmemblk_set_zero"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ ...\ */ \ \ \ \ pmemblk_close(pbp); } \f[] .fi .PP See for more examples using the \f[B]libpmemblk\f[] API. .SH BUGS .PP Unlike \f[B]libpmemobj\f[](7), data replication is not supported in \f[B]libpmemblk\f[]. Thus, specifying replica sections in pool set files is not allowed. .SH ACKNOWLEDGEMENTS .PP \f[B]libpmemblk\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]msync\f[](2), \f[B]dlclose\f[](3), \f[B]pmemblk_bsize\f[](3), \f[B]pmemblk_create\f[](3), \f[B]pmemblk_ctl_exec\f[](3), \f[B]pmemblk_ctl_get\f[](3), \f[B]pmemblk_ctl_set\f[](3), \f[B]pmemblk_read\f[](3), \f[B]pmemblk_set_zero\f[](3), \f[B]pmem_is_pmem\f[](3), \f[B]pmem_persist\f[](3), \f[B]strerror\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemlog\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/libpmemblk.7.md0000664000000000000000000002603614123364546016735 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEMBLK, 7) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (libpmemblk.7 -- man page for libpmemblk) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[MANAGING LIBRARY BEHAVIOR](#managing-library-behavior-1)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[BUGS](#bugs)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also)
# NAME # **libpmemblk** - persistent memory resident array of blocks # SYNOPSIS # ```c #include cc ... -lpmemblk -lpmem ``` _UNICODE() ##### Library API versioning: ##### ```c _UWFUNC(pmemblk_check_version, =q= unsigned major_required, unsigned minor_required=e=) ``` ##### Managing library behavior: ##### ```c void pmemblk_set_funcs( void *(*malloc_func)(size_t size), void (*free_func)(void *ptr), void *(*realloc_func)(void *ptr, size_t size), char *(*strdup_func)(const char *s)); ``` ##### Error handling: ##### ```c _UWFUNC(pmemblk_errormsg, void) ``` ##### Other library functions: ##### A description of other **libpmemblk** functions can be found on the following manual pages: **pmemblk_bsize**(3), **pmemblk_create**(3), **pmemblk_ctl_exec**(3), **pmemblk_ctl_get**(3), **pmemblk_ctl_set**(3), **pmemblk_read**(3), **pmemblk_set_zero**(3), # DESCRIPTION # **libpmemblk** provides an array of blocks in *persistent memory* (pmem) such that updates to a single block are atomic. This library is intended for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of *non-volatile memory DIMMs* (NVDIMMs) provide this type of byte addressable access to storage. A *persistent memory aware file system* is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non-paged access to pmem. **libpmemblk** builds on this type of memory mapped file. This library is for applications that need a potentially large array of blocks, all the same size, where any given block is updated atomically (the update cannot be *torn* by program interruption such as power failures). This library builds on the low-level pmem support provided by **libpmem**(7), handling the transactional update of the blocks, flushing to persistence, and recovery for the application. **libpmemblk** is one of a collection of persistent memory libraries available, the others are: + **libpmemobj**(7), a general use persistent memory API, providing memory allocation and transactional operations on variable-sized objects. + **libpmemlog**(7), providing a pmem-resident log file. + **libpmem**(7), low-level persistent memory support. Under normal usage, **libpmemblk** will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under **DEBUGGING AND ERROR HANDLING** below. To use the atomic block arrays supplied by **libpmemblk**, a *memory pool* is first created using the _UW(pmemblk_create) function described in **pmemblk_create**(3). The other **libpmemblk** functions operate on the resulting block memory pool using the opaque handle, of type *PMEMblkpool\**, that is returned by _UW(pmemblk_create) or _UW(pmemblk_open). Internally, **libpmemblk** will use either **pmem_persist**(3) or **msync**(2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the **pmem_is_pmem**(3) function in **libpmem**(7) for more information). There is no need for applications to flush changes directly when using the block memory API provided by **libpmemblk**. # CAVEATS # **libpmemblk** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The _UW(pmemblk_check_version) function is used to determine whether the installed **libpmemblk** supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile-time version information, supplied by defines in **\**, like this: ```c reason = _U(pmemblk_check_version)(PMEMBLK_MAJOR_VERSION, PMEMBLK_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. When the version check performed by _UW(pmemblk_check_version) is successful, the return value is NULL. Otherwise the return value is a static string describing the reason for failing the version check. The string returned by _UW(pmemblk_check_version) must not be modified or freed. # MANAGING LIBRARY BEHAVIOR # The **pmemblk_set_funcs**() function allows an application to override memory allocation calls used internally by **libpmemblk**. Passing in NULL for any of the handlers will cause the **libpmemblk** default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4-8 kilobytes for each memory pool in use. # DEBUGGING AND ERROR HANDLING # The _UW(pmemblk_errormsg) function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code, as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmemblk** function indicated an error, or if *errno* was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. Two versions of **libpmemblk** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmemblk** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. If an error is detected in a call to **libpmemblk**, the error message describing the failure may be retrieved with _UW(pmemblk_errormsg) as described above. A second version of **libpmemblk**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the **LD_LIBRARY_PATH** environment variable to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEMBLK_LOG_LEVEL** The value of **PMEMBLK_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEMBLK_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmemblk_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmemblk** developers. Unless **PMEMBLK_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMBLK_LOG_FILE** Specifies the name of a file where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEMBLK_LOG_FILE** is not set, the logging output is written to *stderr*. See also **libpmem**(7) for information on other environment variables that may affect **libpmemblk** behavior. # EXAMPLE # The following example illustrates how the **libpmemblk** API is used. ```c #include #include #include #include #include #include /* size of the pmemblk pool -- 1 GB */ #define POOL_SIZE ((size_t)(1 << 30)) /* size of each element in the pmem pool */ #define ELEMENT_SIZE 1024 int main(int argc, char *argv[]) { const char path[] = "/pmem-fs/myfile"; PMEMblkpool *pbp; size_t nelements; char buf[ELEMENT_SIZE]; /* create the pmemblk pool or open it if it already exists */ pbp = _U(pmemblk_create)(path, ELEMENT_SIZE, POOL_SIZE, 0666); if (pbp == NULL) pbp = _U(pmemblk_open)(path, ELEMENT_SIZE); if (pbp == NULL) { perror(path); exit(1); } /* how many elements fit into the file? */ nelements = pmemblk_nblock(pbp); printf("file holds %zu elements", nelements); /* store a block at index 5 */ strcpy(buf, "hello, world"); if (pmemblk_write(pbp, buf, 5) < 0) { perror("pmemblk_write"); exit(1); } /* read the block at index 10 (reads as zeros initially) */ if (pmemblk_read(pbp, buf, 10) < 0) { perror("pmemblk_read"); exit(1); } /* zero out the block at index 5 */ if (pmemblk_set_zero(pbp, 5) < 0) { perror("pmemblk_set_zero"); exit(1); } /* ... */ pmemblk_close(pbp); } ``` See for more examples using the **libpmemblk** API. # BUGS # Unlike **libpmemobj**(7), data replication is not supported in **libpmemblk**. Thus, specifying replica sections in pool set files is not allowed. # ACKNOWLEDGEMENTS # **libpmemblk** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **msync**(2), **dlclose**(3), **pmemblk_bsize**(3), **pmemblk_create**(3), **pmemblk_ctl_exec**(3), **pmemblk_ctl_get**(3), **pmemblk_ctl_set**(3), **pmemblk_read**(3), **pmemblk_set_zero**(3), **pmem_is_pmem**(3), **pmem_persist**(3), **strerror**(3), **libpmem**(7), **libpmemlog**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_errormsg.30000664000000000000000000000002614123364546017552 0ustar rootroot.so man7/libpmemblk.7 pmdk-1.11.1/doc/libpmemblk/pmemblk_ctl_get.3.md0000664000000000000000000000723314123364546017741 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMBLK_CTL_GET, 3) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018-2019, Intel Corporation) [comment]: <> (pmemblk_ctl_get.3 -- man page for libpmemblk CTL) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[CTL NAMESPACE](#ctl-namespace)
[CTL EXTERNAL CONFIGURATION](#ctl-external-configuration)
[SEE ALSO](#see-also)
# NAME # _UW(pmemblk_ctl_get), _UW(pmemblk_ctl_set), _UW(pmemblk_ctl_exec) - Query and modify libpmemblk internal behavior (EXPERIMENTAL) # SYNOPSIS # ```c #include _UWFUNCR2(int, pmemblk_ctl_get, PMEMblkpool *pbp, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemblk_ctl_set, PMEMblkpool *pbp, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemblk_ctl_exec, PMEMblkpool *pbp, *name, void *arg, =q= (EXPERIMENTAL)=e=) ``` _UNICODE() # DESCRIPTION # The _UW(pmemblk_ctl_get), _UW(pmemblk_ctl_set) and _UW(pmemblk_ctl_exec) functions provide a uniform interface for querying and modifying the internal behavior of **libpmemblk**(7) through the control (CTL) namespace. The *name* argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra *arg* is required. Those two parameters together create a CTL query. The functions and the entry points are thread-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either *name* or *arg* is invalid, -1 is returned. If the provided ctl query is valid, the CTL functions will always return 0 on success and -1 on failure, unless otherwise specified in the entry point description. See more in **pmem_ctl**(5) man page. # CTL NAMESPACE # prefault.at_create | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemblk_create) function. Always returns 0. prefault.at_open | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemblk_open) function. Always returns 0. sds.at_create | rw | global | int | int | - | boolean If set, force-enables or force-disables SDS feature during pool creation. Affects only the _UW(pmemblk_create) function. See **pmempool_feature_query**(3) for information about SDS (SHUTDOWN_STATE) feature. Always returns 0. copy_on_write.at_open | rw | global | int | int | - | boolean If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. Always returns 0. # CTL EXTERNAL CONFIGURATION # In addition to direct function call, each write entry point can also be set using two alternative methods. The first method is to load a configuration directly from the **PMEMBLK_CONF** environment variable. The second method of loading an external configuration is to set the **PMEMBLK_CONF_FILE** environment variable to point to a file that contains a sequence of ctl queries. See more in **pmem_ctl**(5) man page. # SEE ALSO # **libpmemblk**(7), **pmem_ctl**(5) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_ctl_set.30000664000000000000000000000002614123364546017347 0ustar rootroot.so pmemblk_ctl_get.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_set_funcs.30000664000000000000000000000002614123364546017703 0ustar rootroot.so man7/libpmemblk.7 pmdk-1.11.1/doc/libpmemblk/pmemblk_write.30000664000000000000000000000002314123364546017041 0ustar rootroot.so pmemblk_read.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_set_zero.30000664000000000000000000000260014123364730017537 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMBLK_SET_ZERO" "3" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemblk_set_zero\f[](), \f[B]pmemblk_set_error\f[]() \- block management functions .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemblk_set_zero(PMEMblkpool\ *pbp,\ long\ long\ blockno); int\ pmemblk_set_error(PMEMblkpool\ *pbp,\ long\ long\ blockno); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemblk_set_zero\f[]() function writes zeros to block number \f[I]blockno\f[] in persistent memory resident array of blocks \f[I]pbp\f[]. Using this function is faster than actually writing a block of zeros since \f[B]libpmemblk\f[](7) uses metadata to indicate the block should read back as zero. .PP The \f[B]pmemblk_set_error\f[]() function sets the error state for block number \f[I]blockno\f[] in persistent memory resident array of blocks \f[I]pbp\f[]. A block in the error state returns \f[I]errno\f[] \f[B]EIO\f[] when read. Writing the block clears the error state and returns the block to normal use. .SH RETURN VALUE .PP On success, \f[B]pmemblk_set_zero\f[]() and \f[B]pmemblk_set_error\f[]() return 0. On error, they return \-1 and set \f[I]errno\f[] appropriately. .SH SEE ALSO .PP \f[B]libpmemblk\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/.gitignore0000664000000000000000000000014214123364546016106 0ustar rootrootlibpmemblk.7 pmemblk_bsize.3 pmemblk_create.3 pmemblk_ctl_get.3 pmemblk_read.3 pmemblk_set_zero.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_nblock.30000664000000000000000000000002414123364546017160 0ustar rootroot.so pmemblk_bsize.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_bsize.30000664000000000000000000000263214123364727017034 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMBLK_BSIZE" "3" "2021-09-24" "PMDK - pmemblk API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemblk_bsize\f[](), \f[B]pmemblk_nblock\f[]() \- check number of available blocks or usable space in block memory pool .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ pmemblk_bsize(PMEMblkpool\ *pbp); size_t\ pmemblk_nblock(PMEMblkpool\ *pbp); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemblk_bsize\f[]() function returns the block size of the specified block memory pool, that is, the value which was passed as \f[I]bsize\f[] to \f[B]pmemblk_create\f[](). \f[I]pbp\f[] must be a block memory pool handle as returned by \f[B]pmemblk_open\f[](3) or \f[B]pmemblk_create\f[](3). .PP The \f[B]pmemblk_nblock\f[]() function returns the usable space in the block memory pool. \f[I]pbp\f[] must be a block memory pool handle as returned by \f[B]pmemblk_open\f[](3) or \f[B]pmemblk_create\f[](3). .SH RETURN VALUE .PP The \f[B]pmemblk_bsize\f[]() function returns the block size of the specified block memory pool. .PP The \f[B]pmemblk_nblock\f[]() function returns the usable space in the block memory pool, expressed as the number of blocks available. .SH SEE ALSO .PP \f[B]pmemblk_create\f[](3), \f[B]pmemblk_open\f[](3), \f[B]libpmemblk\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemblk/pmemblk_open.30000664000000000000000000000002514123364546016652 0ustar rootroot.so pmemblk_create.3 pmdk-1.11.1/doc/libpmemblk/pmemblk_set_zero.3.md0000664000000000000000000000276714123364546020161 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMBLK_SET_ZERO, 3) collection: libpmemblk header: PMDK date: pmemblk API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemblk_set_zero.3 -- man page for block management functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemblk_set_zero**(), **pmemblk_set_error**() - block management functions # SYNOPSIS # ```c #include int pmemblk_set_zero(PMEMblkpool *pbp, long long blockno); int pmemblk_set_error(PMEMblkpool *pbp, long long blockno); ``` # DESCRIPTION # The **pmemblk_set_zero**() function writes zeros to block number *blockno* in persistent memory resident array of blocks *pbp*. Using this function is faster than actually writing a block of zeros since **libpmemblk**(7) uses metadata to indicate the block should read back as zero. The **pmemblk_set_error**() function sets the error state for block number *blockno* in persistent memory resident array of blocks *pbp*. A block in the error state returns *errno* **EIO** when read. Writing the block clears the error state and returns the block to normal use. # RETURN VALUE # On success, **pmemblk_set_zero**() and **pmemblk_set_error**() return 0. On error, they return -1 and set *errno* appropriately. # SEE ALSO # **libpmemblk**(7) and **** pmdk-1.11.1/doc/libpmemblk/pmemblk_close.30000664000000000000000000000002514123364546017016 0ustar rootroot.so pmemblk_create.3 pmdk-1.11.1/doc/libpmemlog/0000775000000000000000000000000014123364731014126 5ustar rootrootpmdk-1.11.1/doc/libpmemlog/pmemlog_create.30000664000000000000000000001417214123364730017201 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMLOG_CREATE" "3" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemlog_create\f[](), \f[B]pmemlog_open\f[](), \f[B]pmemlog_close\f[](), \f[B]pmemlog_check\f[]() \- create, open, close and validate persistent memory resident log file .SH SYNOPSIS .IP .nf \f[C] #include\ PMEMlogpool\ *pmemlog_open(const\ char\ *path); PMEMlogpool\ *pmemlog_create(const\ char\ *path,\ size_t\ poolsize,\ mode_t\ mode); void\ pmemlog_close(PMEMlogpool\ *plp); int\ pmemlog_check(const\ char\ *path); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemlog_create\f[]() function creates a log memory pool with the given total \f[I]poolsize\f[]. Since the transactional nature of a log memory pool requires some space overhead in the memory pool, the resulting available log size is less than \f[I]poolsize\f[], and is made available to the caller via the \f[B]pmemlog_nbyte\f[](3) function. \f[I]path\f[] specifies the name of the memory pool file to be created. \f[I]mode\f[] specifies the permissions to use when creating the file as described by \f[B]creat\f[](2). The memory pool file is fully allocated to the size \f[I]poolsize\f[] using \f[B]posix_fallocate\f[](3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling \f[B]pmemlog_create\f[]() and then specifying \f[I]poolsize\f[] as zero. In this case \f[B]pmemlog_create\f[]() will take the pool size from the size of the existing file and will verify that the file appears to be empty by searching for any non\-zero data in the pool header at the beginning of the file. The net pool size of a pool file is equal to the file size. The minimum net pool size allowed by the library for a log pool is defined in \f[B]\f[] as \f[B]PMEMLOG_MIN_POOL\f[]. .PP Depending on the configuration of the system, the available non\-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemlog memory pool could be limited by the capacity of a single memory device. \f[B]libpmemlog\f[](7) allows building persistent memory resident logs spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a \f[I]pool set\f[] may be stored on a different memory device or pmem\-aware filesystem. .PP Creation of all the parts of the pool set can be done with \f[B]pmemlog_create\f[](); however, the recommended method for creating pool sets is with the \f[B]pmempool\f[](1) utility. .PP When creating a pool set consisting of multiple files, the \f[I]path\f[] argument passed to \f[B]pmemlog_create\f[]() must point to the special \f[I]set\f[] file that defines the pool layout and the location of all the parts of the pool set. The \f[I]poolsize\f[] argument must be 0. The meaning of the \f[I]mode\f[] argument does not change, except that the same \f[I]mode\f[] is used for creation of all the parts of the pool set. .PP The set file is a plain text file, the structure of which is described in \f[B]poolset\f[](5). .PP The \f[B]pmemlog_open\f[]() function opens an existing log memory pool. Similar to \f[B]pmemlog_create\f[](), \f[I]path\f[] must identify either an existing log memory pool file, or the \f[I]set\f[] file used to create a pool set. The application must have permission to open the file and memory map the file or pool set with read/write permissions. .PP Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in \f[B]pmempool\-feature\f[](1). .PP The \f[B]pmemlog_close\f[]() function closes the memory pool indicated by \f[I]plp\f[] and deletes the memory pool handle. The log memory pool itself lives on in the file that contains it and may be re\-opened at a later time using \f[B]pmemlog_open\f[]() as described above. .PP The \f[B]pmemlog_check\f[]() function performs a consistency check of the file indicated by \f[I]path\f[]. \f[B]pmemlog_check\f[]() opens the given \f[I]path\f[] read\-only so it never makes any changes to the file. This function is not supported on Device DAX. .SH RETURN VALUE .PP On success, \f[B]pmemlog_create\f[]() returns a \f[I]PMEMlogpool*\f[] handle to the memory pool that is used with most of the functions from \f[B]libpmemlog\f[](7). If an error prevents any of the pool set files from being created, it returns NULL and sets \f[I]errno\f[] appropriately. .PP On success, \f[B]pmemlog_open\f[]() returns a \f[I]PMEMlogpool*\f[] handle to the memory pool that is used with most of the functions from \f[B]libpmemlog\f[](7). If an error prevents the pool from being opened, or a pool set is being opened and the actual size of any file does not match the corresponding part size defined in the \f[I]set\f[] file, \f[B]pmemlog_open\f[]() returns NULL and sets \f[I]errno\f[] appropriately. .PP The \f[B]pmemlog_close\f[]() function returns no value. .PP The \f[B]pmemlog_check\f[]() function returns 1 if the persistent memory resident log file is found to be consistent. Any inconsistencies will cause \f[B]pmemlog_check\f[]() to return 0, in which case the use of the file with \f[B]libpmemlog\f[] will result in undefined behavior. The debug version of \f[B]libpmemlog\f[] will provide additional details on inconsistencies when \f[B]PMEMLOG_LOG_LEVEL\f[] is at least 1, as described in the \f[B]DEBUGGING AND ERROR HANDLING\f[] section in \f[B]libpmemlog\f[](7). \f[B]pmemlog_check\f[]() will return \-1 and set \f[I]errno\f[] if it cannot perform the consistency check due to other errors. .SH CAVEATS .PP Not all file systems support \f[B]posix_fallocate\f[](3). \f[B]pmemlog_create\f[]() will fail if the underlying file system does not support \f[B]posix_fallocate\f[](3). .SH SEE ALSO .PP \f[B]pmempool\f[](1), \f[B]creat\f[](2), \f[B]posix_fallocate\f[](3), \f[B]pmemlog_nbyte\f[](3), \f[B]poolset\f[](5), \f[B]libpmemlog\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_errormsg.30000664000000000000000000000002614123364546017574 0ustar rootroot.so man7/libpmemlog.7 pmdk-1.11.1/doc/libpmemlog/pmemlog_tell.30000664000000000000000000000467614123364731016707 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMLOG_TELL" "3" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemlog_tell\f[](), \f[B]pmemlog_rewind\f[](), \f[B]pmemlog_walk\f[]() \- checks current write point for the log or walks through the log .SH SYNOPSIS .IP .nf \f[C] #include\ long\ long\ pmemlog_tell(PMEMlogpool\ *plp); void\ pmemlog_rewind(PMEMlogpool\ *plp); void\ pmemlog_walk(PMEMlogpool\ *plp,\ size_t\ chunksize, \ \ \ \ int\ (*process_chunk)(const\ void\ *buf,\ size_t\ len,\ void\ *arg), \ \ \ \ void\ *arg); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemlog_tell\f[]() function returns the current write point for the log, expressed as a byte offset into the usable log space in the memory pool. This offset starts off as zero on a newly\-created log, and is incremented by each successful append operation. This function can be used to determine how much data is currently in the log. .PP The \f[B]pmemlog_rewind\f[]() function resets the current write point for the log to zero. After this call, the next append adds to the beginning of the log. .PP The \f[B]pmemlog_walk\f[]() function walks through the log \f[I]plp\f[], from beginning to end, calling the callback function \f[I]process_chunk\f[] for each \f[I]chunksize\f[] block of data found. The argument \f[I]arg\f[] is also passed to the callback to help avoid the need for global state. The \f[I]chunksize\f[] argument is useful for logs with fixed\-length records and may be specified as 0 to cause a single call to the callback with the entire log contents passed as the \f[I]buf\f[] argument. The \f[I]len\f[] argument tells the \f[I]process_chunk\f[] function how much data \f[I]buf\f[] is holding. The callback function should return 1 if \f[B]pmemlog_walk\f[]() should continue walking through the log, or 0 to terminate the walk. The callback function is called while holding \f[B]libpmemlog\f[](7) internal locks that make calls atomic, so the callback function must not try to append to the log itself or deadlock will occur. .SH RETURN VALUE .PP On success, \f[B]pmemlog_tell\f[]() returns the current write point for the log. On error, it returns \-1 and sets \f[I]errno\f[] appropriately. .PP The \f[B]pmemlog_rewind\f[]() and \f[B]pmemlog_walk\f[]() functions return no value. .SH SEE ALSO .PP \f[B]libpmemlog\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_tell.3.md0000664000000000000000000000500514123364546017275 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMLOG_TELL, 3) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemlog_tell.3 -- man page for pmemlog_tell, pmemlog_rewind and pmemlog_walk functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemlog_tell**(), **pmemlog_rewind**(), **pmemlog_walk**() - checks current write point for the log or walks through the log # SYNOPSIS # ```c #include long long pmemlog_tell(PMEMlogpool *plp); void pmemlog_rewind(PMEMlogpool *plp); void pmemlog_walk(PMEMlogpool *plp, size_t chunksize, int (*process_chunk)(const void *buf, size_t len, void *arg), void *arg); ``` # DESCRIPTION # The **pmemlog_tell**() function returns the current write point for the log, expressed as a byte offset into the usable log space in the memory pool. This offset starts off as zero on a newly-created log, and is incremented by each successful append operation. This function can be used to determine how much data is currently in the log. The **pmemlog_rewind**() function resets the current write point for the log to zero. After this call, the next append adds to the beginning of the log. The **pmemlog_walk**() function walks through the log *plp*, from beginning to end, calling the callback function *process_chunk* for each *chunksize* block of data found. The argument *arg* is also passed to the callback to help avoid the need for global state. The *chunksize* argument is useful for logs with fixed-length records and may be specified as 0 to cause a single call to the callback with the entire log contents passed as the *buf* argument. The *len* argument tells the *process_chunk* function how much data *buf* is holding. The callback function should return 1 if **pmemlog_walk**() should continue walking through the log, or 0 to terminate the walk. The callback function is called while holding **libpmemlog**(7) internal locks that make calls atomic, so the callback function must not try to append to the log itself or deadlock will occur. # RETURN VALUE # On success, **pmemlog_tell**() returns the current write point for the log. On error, it returns -1 and sets *errno* appropriately. The **pmemlog_rewind**() and **pmemlog_walk**() functions return no value. # SEE ALSO # **libpmemlog**(7) and **** pmdk-1.11.1/doc/libpmemlog/libpmemlog.7.md0000664000000000000000000002553614123364546016763 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(LIBPMEMLOG, 7) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2016-2018, Intel Corporation) [comment]: <> (libpmemlog.7 -- man page for libpmemlog) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[CAVEATS](#caveats)
[LIBRARY API VERSIONING](#library-api-versioning-1)
[MANAGING LIBRARY BEHAVIOR](#managing-library-behavior-1)
[DEBUGGING AND ERROR HANDLING](#debugging-and-error-handling)
[EXAMPLE](#example)
[BUGS](#bugs)
[ACKNOWLEDGEMENTS](#acknowledgements)
[SEE ALSO](#see-also) # NAME # **libpmemlog** - persistent memory resident log file # SYNOPSIS # ```c #include cc ... -lpmemlog -lpmem ``` _UNICODE() ##### Library API versioning: ##### ```c _UWFUNC(pmemlog_check_version, =q= unsigned major_required, unsigned minor_required=e=) ``` ##### Managing library behavior: ##### ```c void pmemlog_set_funcs( void *(*malloc_func)(size_t size), void (*free_func)(void *ptr), void *(*realloc_func)(void *ptr, size_t size), char *(*strdup_func)(const char *s)); ``` ##### Error handling: ##### ```c _UWFUNCR(int, pmemlog_check, *path) ``` ##### Other library functions: ##### A description of other **libpmemlog** functions can be found on the following manual pages: **pmemlog_append**(3), **pmemlog_create**(3), **pmemlog_ctl_exec**(3), **pmemlog_ctl_get**(3), **pmemlog_ctl_set**(3), **pmemlog_nbyte**(3), **pmemlog_tell**(3) # DESCRIPTION # **libpmemlog** provides a log file in *persistent memory* (pmem) such that additions to the log are appended atomically. This library is intended for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of *non-volatile memory DIMMs* (NVDIMMs) provide this type of byte addressable access to storage. A *persistent memory aware file system* is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non-paged access to pmem. **libpmemlog** builds on thistype of memory mapped file. This library is for applications that need a persistent log file updated atomically (the updates cannot be *torn* by program interruption such as power failures). This library builds on the low-level pmem support provided by **libpmem**(7), handling the transactional update of the log, flushing to persistence, and recovery for the application. **libpmemlog** is one of a collection of persistent memory libraries available. The others are: + **libpmemobj**(7), a general use persistent memory API, providing memory allocation and transactional operations on variable-sized objects. + **libpmemblk**(7), providing pmem-resident arrays of fixed-sized blocks with atomic updates. + **libpmem**(7), low-level persistent memory support. Under normal usage, **libpmemlog** will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under **DEBUGGING AND ERROR HANDLING** below. To use the pmem-resident log file provided by **libpmemlog**, a *memory pool* is first created. This is done with the **pmemlog_create**(3) function. The other functions mentioned above in SYNOPSIS section then operate on the resulting log memory pool. Once created, the memory pool is represented by an opaque handle, of type *PMEMlogpool\**, which is passed to most of the other functions from **libpmemlog**. Internally, **libpmemlog** will use either **pmem_persist**(3) or **msync**(2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the **pmem_is_pmem**(3) function in **libpmem**(7) for more information). There is no need for applications to flush changes directly when using the log memory API provided by **libpmemlog**. # CAVEATS # **libpmemlog** relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. **dlclose**(3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. # LIBRARY API VERSIONING # This section describes how the library API is versioned, allowing applications to work with an evolving API. The _UW(pmemlog_check_version) function is used to determine whether the installed **libpmemlog** supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile-time version information provided by defines in **\**, like this: ```c reason = _U(pmemlog_check_version)(PMEMLOG_MAJOR_VERSION, PMEMLOG_MINOR_VERSION); if (reason != NULL) { /* version check failed, reason string tells you why */ } ``` Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text *introduced in version x.y* in the section of this manual describing the feature. On success, _UW(pmemlog_check_version) returns NULL. Otherwise, the return value is a static string describing the reason the version check failed. The string returned by _UW(pmemlog_check_version) must not be modified or freed. # MANAGING LIBRARY BEHAVIOR # The **pmemlog_set_funcs**() function allows an application to override memory allocation calls used internally by **libpmemlog**. Passing in NULL for any of the handlers will cause the **libpmemlog** default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4-8 kilobytes for each memory pool in use. # DEBUGGING AND ERROR HANDLING # The _UW(pmemlog_errormsg) function returns a pointer to a static buffer containing the last error message logged for the current thread. If *errno* was set, the error message may include a description of the corresponding error code as returned by **strerror**(3). The error message buffer is thread-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a **libpmemlog** function indicated an error, or if *errno* was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. Two versions of **libpmemlog** are typically available on a development system. The normal version, accessed when a program is linked using the **-lpmemlog** option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run-time assertions. A second version of **libpmemlog**, accessed when a program uses the libraries under _DEBUGLIBPATH(), contains run-time assertions and trace points. The typical way to access the debug version is to set the environment variable **LD_LIBRARY_PATH** to _LDLIBPATH(). Debugging output is controlled using the following environment variables. These variables have no effect on the non-debug version of the library. + **PMEMLOG_LOG_LEVEL** The value of **PMEMLOG_LOG_LEVEL** enables trace points in the debug version of the library, as follows: + **0** - This is the default level when **PMEMLOG_LOG_LEVEL** is not set. No log messages are emitted at this level. + **1** - Additional details on any errors detected are logged, in addition to returning the *errno*-based errors as usual. The same information may be retrieved using _UW(pmemlog_errormsg). + **2** - A trace of basic operations is logged. + **3** - Enables a very verbose amount of function call tracing in the library. + **4** - Enables voluminous and fairly obscure tracing information that is likely only useful to the **libpmemlog** developers. Unless **PMEMLOG_LOG_FILE** is set, debugging output is written to *stderr*. + **PMEMLOG_LOG_FILE** Specifies the name of a file name where all logging information should be written. If the last character in the name is "-", the *PID* of the current process will be appended to the file name when the log file is created. If **PMEMLOG_LOG_FILE** is not set, logging output is written to *stderr*. See also **libpmem**(7) for information about other environment variables affecting **libpmemlog** behavior. # EXAMPLE # The following example illustrates how the **libpmemlog** API is used. ```c #include #include #include #include #include #include #include /* size of the pmemlog pool -- 1 GB */ #define POOL_SIZE ((size_t)(1 << 30)) /* * printit -- log processing callback for use with pmemlog_walk() */ int printit(const void *buf, size_t len, void *arg) { fwrite(buf, len, 1, stdout); return 0; } int main(int argc, char *argv[]) { const char path[] = "/pmem-fs/myfile"; PMEMlogpool *plp; size_t nbyte; char *str; /* create the pmemlog pool or open it if it already exists */ plp = _U(pmemlog_create)(path, POOL_SIZE, 0666); if (plp == NULL) plp = _U(pmemlog_open)(path); if (plp == NULL) { perror(path); exit(1); } /* how many bytes does the log hold? */ nbyte = pmemlog_nbyte(plp); printf("log holds %zu bytes", nbyte); /* append to the log... */ str = "This is the first string appended"; if (pmemlog_append(plp, str, strlen(str)) < 0) { perror("pmemlog_append"); exit(1); } str = "This is the second string appended"; if (pmemlog_append(plp, str, strlen(str)) < 0) { perror("pmemlog_append"); exit(1); } /* print the log contents */ printf("log contains:"); pmemlog_walk(plp, 0, printit, NULL); pmemlog_close(plp); } ``` See for more examples using the **libpmemlog** API. # BUGS # Unlike **libpmemobj**(7), data replication is not supported in **libpmemlog**. Thus, specifying replica sections in pool set files is not allowed. # ACKNOWLEDGEMENTS # **libpmemlog** builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: # SEE ALSO # **msync**(2), **pmemlog_append**(3), **pmemlog_create**(3), **pmemlog_ctl_exec**(3), **pmemlog_ctl_get**(3), **pmemlog_ctl_set**(3), **pmemlog_nbyte**(3), **pmemlog_tell**(3), **strerror**(3), **libpmem**(7), **libpmemblk**(7), **libpmemobj**(7) and **** pmdk-1.11.1/doc/libpmemlog/pmemlog_open.30000664000000000000000000000002514123364546016674 0ustar rootroot.so pmemlog_create.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_close.30000664000000000000000000000002514123364546017040 0ustar rootroot.so pmemlog_create.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_rewind.30000664000000000000000000000002314123364546017221 0ustar rootroot.so pmemlog_tell.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_create.3.md0000664000000000000000000001430614123364546017604 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMLOG_CREATE, 3) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemlog_create.3 -- man page for libpmemlog create, open, close and validate) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[CAVEATS](#caveats)
[SEE ALSO](#see-also)
# NAME # _UW(pmemlog_create), _UW(pmemlog_open), **pmemlog_close**(), _UW(pmemlog_check) - create, open, close and validate persistent memory resident log file # SYNOPSIS # ```c #include _UWFUNCR(PMEMlogpool, *pmemlog_open, *path) _UWFUNCR1(PMEMlogpool, *pmemlog_create, *path, =q=size_t poolsize, mode_t mode=e=) void pmemlog_close(PMEMlogpool *plp); _UWFUNCR(int, pmemlog_check, *path) ``` _UNICODE() # DESCRIPTION # The _UW(pmemlog_create) function creates a log memory pool with the given total *poolsize*. Since the transactional nature of a log memory pool requires some space overhead in the memory pool, the resulting available log size is less than *poolsize*, and is made available to the caller via the **pmemlog_nbyte**(3) function. *path* specifies the name of the memory pool file to be created. *mode* specifies the permissions to use when creating the file as described by **creat**(2). The memory pool file is fully allocated to the size *poolsize* using **posix_fallocate**(3). The caller may choose to take responsibility for creating the memory pool file by creating it before calling _UW(pmemlog_create) and then specifying *poolsize* as zero. In this case _UW(pmemlog_create) will take the pool size from the size of the existing file and will verify that the file appears to be empty by searching for any non-zero data in the pool header at the beginning of the file. The net pool size of a pool file is equal to the file size. The minimum net pool size allowed by the library for a log pool is defined in **\** as **PMEMLOG_MIN_POOL**. Depending on the configuration of the system, the available non-volatile memory space may be divided into multiple memory devices. In such case, the maximum size of the pmemlog memory pool could be limited by the capacity of a single memory device. **libpmemlog**(7) allows building persistent memory resident logs spanning multiple memory devices by creation of persistent memory pools consisting of multiple files, where each part of such a *pool set* may be stored on a different memory device or pmem-aware filesystem. Creation of all the parts of the pool set can be done with _UW(pmemlog_create); however, the recommended method for creating pool sets is with the **pmempool**(1) utility. When creating a pool set consisting of multiple files, the *path* argument passed to _UW(pmemlog_create) must point to the special *set* file that defines the pool layout and the location of all the parts of the pool set. The *poolsize* argument must be 0. The meaning of the *mode* argument does not change, except that the same *mode* is used for creation of all the parts of the pool set. The set file is a plain text file, the structure of which is described in **poolset**(5). The _UW(pmemlog_open) function opens an existing log memory pool. Similar to _UW(pmemlog_create), *path* must identify either an existing log memory pool file, or the *set* file used to create a pool set. The application must have permission to open the file and memory map the file or pool set with read/write permissions. Be aware that if the pool contains bad blocks inside, opening can be aborted by the SIGBUS signal, because currently the pool is not checked against bad blocks during opening. It can be turned on by setting the CHECK_BAD_BLOCKS compat feature. For details see description of this feature in **pmempool-feature**(1). The **pmemlog_close**() function closes the memory pool indicated by *plp* and deletes the memory pool handle. The log memory pool itself lives on in the file that contains it and may be re-opened at a later time using _UW(pmemlog_open) as described above. The _UW(pmemlog_check) function performs a consistency check of the file indicated by *path*. _UW(pmemlog_check) opens the given *path* read-only so it never makes any changes to the file. This function is not supported on Device DAX. # RETURN VALUE # On success, _UW(pmemlog_create) returns a *PMEMlogpool\** handle to the memory pool that is used with most of the functions from **libpmemlog**(7). If an error prevents any of the pool set files from being created, it returns NULL and sets *errno* appropriately. On success, _UW(pmemlog_open) returns a *PMEMlogpool\** handle to the memory pool that is used with most of the functions from **libpmemlog**(7). If an error prevents the pool from being opened, or a pool set is being opened and the actual size of any file does not match the corresponding part size defined in the *set* file, _UW(pmemlog_open) returns NULL and sets *errno* appropriately. The **pmemlog_close**() function returns no value. The _UW(pmemlog_check) function returns 1 if the persistent memory resident log file is found to be consistent. Any inconsistencies will cause _UW(pmemlog_check) to return 0, in which case the use of the file with **libpmemlog** will result in undefined behavior. The debug version of **libpmemlog** will provide additional details on inconsistencies when **PMEMLOG_LOG_LEVEL** is at least 1, as described in the **DEBUGGING AND ERROR HANDLING** section in **libpmemlog**(7). _UW(pmemlog_check) will return -1 and set *errno* if it cannot perform the consistency check due to other errors. # CAVEATS # Not all file systems support **posix_fallocate**(3). _UW(pmemlog_create) will fail if the underlying file system does not support **posix_fallocate**(3). _WINUX(=q= On Windows if _UW(pmemlog_create) is called on an existing file with FILE_ATTRIBUTE_SPARSE_FILE and FILE_ATTRIBUTE_COMPRESSED set, they will be removed, to physically allocate space for the pool. This is a workaround for _chsize() performance issues. =e=) # SEE ALSO # **pmempool**(1), **creat**(2), **posix_fallocate**(3), **pmemlog_nbyte**(3), **poolset**(5), **libpmemlog**(7) and **** pmdk-1.11.1/doc/libpmemlog/pmemlog_check.30000664000000000000000000000002514123364546017010 0ustar rootroot.so pmemlog_create.3 pmdk-1.11.1/doc/libpmemlog/libpmemlog.70000664000000000000000000002720514123364725016356 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "LIBPMEMLOG" "7" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2016-2018, Intel Corporation .SH NAME .PP \f[B]libpmemlog\f[] \- persistent memory resident log file .SH SYNOPSIS .IP .nf \f[C] #include\ cc\ ...\ \-lpmemlog\ \-lpmem \f[] .fi .SS Library API versioning: .IP .nf \f[C] const\ char\ *pmemlog_check_version( \ \ \ \ unsigned\ major_required, \ \ \ \ unsigned\ minor_required); \f[] .fi .SS Managing library behavior: .IP .nf \f[C] void\ pmemlog_set_funcs( \ \ \ \ void\ *(*malloc_func)(size_t\ size), \ \ \ \ void\ (*free_func)(void\ *ptr), \ \ \ \ void\ *(*realloc_func)(void\ *ptr,\ size_t\ size), \ \ \ \ char\ *(*strdup_func)(const\ char\ *s)); \f[] .fi .SS Error handling: .IP .nf \f[C] int\ pmemlog_check(const\ char\ *path); \f[] .fi .SS Other library functions: .PP A description of other \f[B]libpmemlog\f[] functions can be found on the following manual pages: .PP \f[B]pmemlog_append\f[](3), \f[B]pmemlog_create\f[](3), \f[B]pmemlog_ctl_exec\f[](3), \f[B]pmemlog_ctl_get\f[](3), \f[B]pmemlog_ctl_set\f[](3), \f[B]pmemlog_nbyte\f[](3), \f[B]pmemlog_tell\f[](3) .SH DESCRIPTION .PP \f[B]libpmemlog\f[] provides a log file in \f[I]persistent memory\f[] (pmem) such that additions to the log are appended atomically. This library is intended for applications using direct access storage (DAX), which is storage that supports load/store access without paging blocks from a block storage device. Some types of \f[I]non\-volatile memory DIMMs\f[] (NVDIMMs) provide this type of byte addressable access to storage. A \f[I]persistent memory aware file system\f[] is typically used to expose the direct access to applications. Memory mapping a file from this type of file system results in the load/store, non\-paged access to pmem. \f[B]libpmemlog\f[] builds on thistype of memory mapped file. .PP This library is for applications that need a persistent log file updated atomically (the updates cannot be \f[I]torn\f[] by program interruption such as power failures). This library builds on the low\-level pmem support provided by \f[B]libpmem\f[](7), handling the transactional update of the log, flushing to persistence, and recovery for the application. .PP \f[B]libpmemlog\f[] is one of a collection of persistent memory libraries available. The others are: .IP \[bu] 2 \f[B]libpmemobj\f[](7), a general use persistent memory API, providing memory allocation and transactional operations on variable\-sized objects. .IP \[bu] 2 \f[B]libpmemblk\f[](7), providing pmem\-resident arrays of fixed\-sized blocks with atomic updates. .IP \[bu] 2 \f[B]libpmem\f[](7), low\-level persistent memory support. .PP Under normal usage, \f[B]libpmemlog\f[] will never print messages or intentionally cause the process to exit. The only exception to this is the debugging information, when enabled, as described under \f[B]DEBUGGING AND ERROR HANDLING\f[] below. .PP To use the pmem\-resident log file provided by \f[B]libpmemlog\f[], a \f[I]memory pool\f[] is first created. This is done with the \f[B]pmemlog_create\f[](3) function. The other functions mentioned above in SYNOPSIS section then operate on the resulting log memory pool. .PP Once created, the memory pool is represented by an opaque handle, of type \f[I]PMEMlogpool*\f[], which is passed to most of the other functions from \f[B]libpmemlog\f[]. Internally, \f[B]libpmemlog\f[] will use either \f[B]pmem_persist\f[](3) or \f[B]msync\f[](2) when it needs to flush changes, depending on whether the memory pool appears to be persistent memory or a regular file (see the \f[B]pmem_is_pmem\f[](3) function in \f[B]libpmem\f[](7) for more information). There is no need for applications to flush changes directly when using the log memory API provided by \f[B]libpmemlog\f[]. .SH CAVEATS .PP \f[B]libpmemlog\f[] relies on the library destructor being called from the main thread. For this reason, all functions that might trigger destruction (e.g. \f[B]dlclose\f[](3)) should be called in the main thread. Otherwise some of the resources associated with that thread might not be cleaned up properly. .SH LIBRARY API VERSIONING .PP This section describes how the library API is versioned, allowing applications to work with an evolving API. .PP The \f[B]pmemlog_check_version\f[]() function is used to determine whether the installed \f[B]libpmemlog\f[] supports the version of the library API required by an application. The easiest way to do this is for the application to supply the compile\-time version information provided by defines in \f[B]\f[], like this: .IP .nf \f[C] reason\ =\ pmemlog_check_version(PMEMLOG_MAJOR_VERSION, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ PMEMLOG_MINOR_VERSION); if\ (reason\ !=\ NULL)\ { \ \ \ \ /*\ version\ check\ failed,\ reason\ string\ tells\ you\ why\ */ } \f[] .fi .PP Any mismatch in the major version number is considered a failure, but a library with a newer minor version number will pass this check since increasing minor versions imply backwards compatibility. .PP An application can also check specifically for the existence of an interface by checking for the version where that interface was introduced. These versions are documented in this man page as follows: unless otherwise specified, all interfaces described here are available in version 1.0 of the library. Interfaces added after version 1.0 will contain the text \f[I]introduced in version x.y\f[] in the section of this manual describing the feature. .PP On success, \f[B]pmemlog_check_version\f[]() returns NULL. Otherwise, the return value is a static string describing the reason the version check failed. The string returned by \f[B]pmemlog_check_version\f[]() must not be modified or freed. .SH MANAGING LIBRARY BEHAVIOR .PP The \f[B]pmemlog_set_funcs\f[]() function allows an application to override memory allocation calls used internally by \f[B]libpmemlog\f[]. Passing in NULL for any of the handlers will cause the \f[B]libpmemlog\f[] default function to be used. The library does not make heavy use of the system malloc functions, but it does allocate approximately 4\-8 kilobytes for each memory pool in use. .SH DEBUGGING AND ERROR HANDLING .PP The \f[B]pmemlog_errormsg\f[]() function returns a pointer to a static buffer containing the last error message logged for the current thread. If \f[I]errno\f[] was set, the error message may include a description of the corresponding error code as returned by \f[B]strerror\f[](3). The error message buffer is thread\-local; errors encountered in one thread do not affect its value in other threads. The buffer is never cleared by any library function; its content is significant only when the return value of the immediately preceding call to a \f[B]libpmemlog\f[] function indicated an error, or if \f[I]errno\f[] was set. The application must not modify or free the error message string, but it may be modified by subsequent calls to other library functions. .PP Two versions of \f[B]libpmemlog\f[] are typically available on a development system. The normal version, accessed when a program is linked using the \f[B]\-lpmemlog\f[] option, is optimized for performance. That version skips checks that impact performance and never logs any trace information or performs any run\-time assertions. .PP A second version of \f[B]libpmemlog\f[], accessed when a program uses the libraries under \f[B]/usr/lib/pmdk_debug\f[], contains run\-time assertions and trace points. The typical way to access the debug version is to set the environment variable \f[B]LD_LIBRARY_PATH\f[] to \f[B]/usr/lib/pmdk_debug\f[] or \f[B]/usr/lib64/pmdk_debug\f[], as appropriate. Debugging output is controlled using the following environment variables. These variables have no effect on the non\-debug version of the library. .IP \[bu] 2 \f[B]PMEMLOG_LOG_LEVEL\f[] .PP The value of \f[B]PMEMLOG_LOG_LEVEL\f[] enables trace points in the debug version of the library, as follows: .IP \[bu] 2 \f[B]0\f[] \- This is the default level when \f[B]PMEMLOG_LOG_LEVEL\f[] is not set. No log messages are emitted at this level. .IP \[bu] 2 \f[B]1\f[] \- Additional details on any errors detected are logged, in addition to returning the \f[I]errno\f[]\-based errors as usual. The same information may be retrieved using \f[B]pmemlog_errormsg\f[](). .IP \[bu] 2 \f[B]2\f[] \- A trace of basic operations is logged. .IP \[bu] 2 \f[B]3\f[] \- Enables a very verbose amount of function call tracing in the library. .IP \[bu] 2 \f[B]4\f[] \- Enables voluminous and fairly obscure tracing information that is likely only useful to the \f[B]libpmemlog\f[] developers. .PP Unless \f[B]PMEMLOG_LOG_FILE\f[] is set, debugging output is written to \f[I]stderr\f[]. .IP \[bu] 2 \f[B]PMEMLOG_LOG_FILE\f[] .PP Specifies the name of a file name where all logging information should be written. If the last character in the name is \[lq]\-\[rq], the \f[I]PID\f[] of the current process will be appended to the file name when the log file is created. If \f[B]PMEMLOG_LOG_FILE\f[] is not set, logging output is written to \f[I]stderr\f[]. .PP See also \f[B]libpmem\f[](7) for information about other environment variables affecting \f[B]libpmemlog\f[] behavior. .SH EXAMPLE .PP The following example illustrates how the \f[B]libpmemlog\f[] API is used. .IP .nf \f[C] #include\ #include\ #include\ #include\ #include\ #include\ #include\ /*\ size\ of\ the\ pmemlog\ pool\ \-\-\ 1\ GB\ */ #define\ POOL_SIZE\ ((size_t)(1\ <<\ 30)) /* \ *\ printit\ \-\-\ log\ processing\ callback\ for\ use\ with\ pmemlog_walk() \ */ int printit(const\ void\ *buf,\ size_t\ len,\ void\ *arg) { \ \ \ \ fwrite(buf,\ len,\ 1,\ stdout); \ \ \ \ return\ 0; } int main(int\ argc,\ char\ *argv[]) { \ \ \ \ const\ char\ path[]\ =\ "/pmem\-fs/myfile"; \ \ \ \ PMEMlogpool\ *plp; \ \ \ \ size_t\ nbyte; \ \ \ \ char\ *str; \ \ \ \ /*\ create\ the\ pmemlog\ pool\ or\ open\ it\ if\ it\ already\ exists\ */ \ \ \ \ plp\ =\ pmemlog_create(path,\ POOL_SIZE,\ 0666); \ \ \ \ if\ (plp\ ==\ NULL) \ \ \ \ \ \ \ \ plp\ =\ pmemlog_open(path); \ \ \ \ if\ (plp\ ==\ NULL)\ { \ \ \ \ \ \ \ \ perror(path); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ how\ many\ bytes\ does\ the\ log\ hold?\ */ \ \ \ \ nbyte\ =\ pmemlog_nbyte(plp); \ \ \ \ printf("log\ holds\ %zu\ bytes",\ nbyte); \ \ \ \ /*\ append\ to\ the\ log...\ */ \ \ \ \ str\ =\ "This\ is\ the\ first\ string\ appended"; \ \ \ \ if\ (pmemlog_append(plp,\ str,\ strlen(str))\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("pmemlog_append"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ str\ =\ "This\ is\ the\ second\ string\ appended"; \ \ \ \ if\ (pmemlog_append(plp,\ str,\ strlen(str))\ <\ 0)\ { \ \ \ \ \ \ \ \ perror("pmemlog_append"); \ \ \ \ \ \ \ \ exit(1); \ \ \ \ } \ \ \ \ /*\ print\ the\ log\ contents\ */ \ \ \ \ printf("log\ contains:"); \ \ \ \ pmemlog_walk(plp,\ 0,\ printit,\ NULL); \ \ \ \ pmemlog_close(plp); } \f[] .fi .PP See for more examples using the \f[B]libpmemlog\f[] API. .SH BUGS .PP Unlike \f[B]libpmemobj\f[](7), data replication is not supported in \f[B]libpmemlog\f[]. Thus, specifying replica sections in pool set files is not allowed. .SH ACKNOWLEDGEMENTS .PP \f[B]libpmemlog\f[] builds on the persistent memory programming model recommended by the SNIA NVM Programming Technical Work Group: .SH SEE ALSO .PP \f[B]msync\f[](2), \f[B]pmemlog_append\f[](3), \f[B]pmemlog_create\f[](3), \f[B]pmemlog_ctl_exec\f[](3), \f[B]pmemlog_ctl_get\f[](3), \f[B]pmemlog_ctl_set\f[](3), \f[B]pmemlog_nbyte\f[](3), \f[B]pmemlog_tell\f[](3), \f[B]strerror\f[](3), \f[B]libpmem\f[](7), \f[B]libpmemblk\f[](7), \f[B]libpmemobj\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_nbyte.3.md0000664000000000000000000000204714123364546017461 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMLOG_NBYTE, 3) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemlog_nbyte.3 -- man page for pmemlog_nbyte function) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[SEE ALSO](#see-also)
# NAME # **pmemlog_nbyte**() - checks the amount of usable space in the log pool. # SYNOPSIS # ```c #include size_t pmemlog_nbyte(PMEMlogpool *plp); ``` # DESCRIPTION # The **pmemlog_nbyte**() function checks the amount of usable space in the log *plp*. This function may be used on a log to determine how much usable space is available after **libpmemlog**(7) has added its metadata to the memory pool. # RETURN VALUE # The **pmemlog_nbyte**() function returns the amount of usable space in the log *plp*. # SEE ALSO # **libpmemlog**(7) and **** pmdk-1.11.1/doc/libpmemlog/pmemlog_nbyte.30000664000000000000000000000157414123364730017061 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMLOG_NBYTE" "3" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemlog_nbyte\f[]() \- checks the amount of usable space in the log pool. .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ pmemlog_nbyte(PMEMlogpool\ *plp); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemlog_nbyte\f[]() function checks the amount of usable space in the log \f[I]plp\f[]. This function may be used on a log to determine how much usable space is available after \f[B]libpmemlog\f[](7) has added its metadata to the memory pool. .SH RETURN VALUE .PP The \f[B]pmemlog_nbyte\f[]() function returns the amount of usable space in the log \f[I]plp\f[]. .SH SEE ALSO .PP \f[B]libpmemlog\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_appendv.30000664000000000000000000000002514123364546017370 0ustar rootroot.so pmemlog_append.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_append.30000664000000000000000000000376414123364730017212 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMLOG_APPEND" "3" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmemlog_append\f[](), \f[B]pmemlog_appendv\f[]() \- append bytes to the persistent memory resident log file .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemlog_append(PMEMlogpool\ *plp,\ const\ void\ *buf,\ size_t\ count); int\ pmemlog_appendv(PMEMlogpool\ *plp,\ const\ struct\ iovec\ *iov,\ int\ iovcnt); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemlog_append\f[]() function appends \f[I]count\f[] bytes from \f[I]buf\f[] to the current write offset in the log memory pool \f[I]plp\f[]. Calling this function is analogous to appending to a file. The append is atomic and cannot be torn by a program failure or system crash. .PP The \f[B]pmemlog_appendv\f[]() function appends to the log memory pool \f[I]plp\f[] from the scatter/gather list \f[I]iov\f[] in a manner similar to \f[B]writev\f[](2). The entire list of buffers is appended atomically, as if the buffers in \f[I]iov\f[] were concatenated in order. The append is atomic and cannot be torn by a program failure or system crash. .SH RETURN VALUE .PP On success, \f[B]pmemlog_append\f[]() and \f[B]pmemlog_appendv\f[]() return 0. On error, they return \-1 and set \f[I]errno\f[] appropriately. .SH ERRORS .PP \f[B]EINVAL\f[] The vector count \f[I]iovcnt\f[] is less than zero. .PP \f[B]ENOSPC\f[] There is no room for the data in the log file. .PP \f[B]EROFS\f[] The log file is open in read\-only mode. .SH NOTES .PP Since \f[B]libpmemlog\f[](7) is designed as a low\-latency code path, many of the checks routinely done by the operating system for \f[B]writev\f[](2) are not practical in the library's implementation of \f[B]pmemlog_appendv\f[](). No attempt is made to detect NULL or incorrect pointers, for example. .SH SEE ALSO .PP \f[B]writev\f[](2), \f[B]libpmemlog\f[](7) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_ctl_exec.30000664000000000000000000000002614123364546017522 0ustar rootroot.so pmemlog_ctl_get.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_ctl_get.3.md0000664000000000000000000000723314123364546017763 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMLOG_CTL_GET, 3) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2018-2019, Intel Corporation) [comment]: <> (pmemlog_ctl_get.3 -- man page for libpmemlog CTL) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[CTL NAMESPACE](#ctl-namespace)
[CTL EXTERNAL CONFIGURATION](#ctl-external-configuration)
[SEE ALSO](#see-also)
# NAME # _UW(pmemlog_ctl_get), _UW(pmemlog_ctl_set), _UW(pmemlog_ctl_exec) - Query and modify libpmemlog internal behavior (EXPERIMENTAL) # SYNOPSIS # ```c #include _UWFUNCR2(int, pmemlog_ctl_get, PMEMlogpool *plp, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemlog_ctl_set, PMEMlogpool *plp, *name, void *arg, =q= (EXPERIMENTAL)=e=) _UWFUNCR2(int, pmemlog_ctl_exec, PMEMlogpool *plp, *name, void *arg, =q= (EXPERIMENTAL)=e=) ``` _UNICODE() # DESCRIPTION # The _UW(pmemlog_ctl_get), _UW(pmemlog_ctl_set) and _UW(pmemlog_ctl_exec) functions provide a uniform interface for querying and modifying the internal behavior of **libpmemlog**(7) through the control (CTL) namespace. The *name* argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra *arg* is required. Those two parameters together create a CTL query. The functions and the entry points are thread-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either *name* or *arg* is invalid, -1 is returned. If the provided ctl query is valid, the CTL functions will always return 0 on success and -1 on failure, unless otherwise specified in the entry point description. See more in **pmem_ctl**(5) man page. # CTL NAMESPACE # prefault.at_create | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemlog_create) function. Always returns 0. prefault.at_open | rw | global | int | int | - | boolean If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the _UW(pmemlog_open) function. Always returns 0. sds.at_create | rw | global | int | int | - | boolean If set, force-enables or force-disables SDS feature during pool creation. Affects only the _UW(pmemlog_create) function. See **pmempool_feature_query**(3) for information about SDS (SHUTDOWN_STATE) feature. Always returns 0. copy_on_write.at_open | rw | global | int | int | - | boolean If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. Always returns 0. # CTL EXTERNAL CONFIGURATION # In addition to direct function call, each write entry point can also be set using two alternative methods. The first method is to load a configuration directly from the **PMEMLOG_CONF** environment variable. The second method of loading an external configuration is to set the **PMEMLOG_CONF_FILE** environment variable to point to a file that contains a sequence of ctl queries. See more in **pmem_ctl**(5) man page. # SEE ALSO # **libpmemlog**(7), **pmem_ctl**(5) and **** pmdk-1.11.1/doc/libpmemlog/.gitignore0000664000000000000000000000014014123364546016115 0ustar rootrootlibpmemlog.7 pmemlog_append.3 pmemlog_create.3 pmemlog_ctl_get.3 pmemlog_nbyte.3 pmemlog_tell.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_append.3.md0000664000000000000000000000412314123364546017604 0ustar rootroot--- layout: manual Content-Style: 'text/css' title: _MP(PMEMLOG_APPEND, 3) collection: libpmemlog header: PMDK date: pmemlog API version 1.1 ... [comment]: <> (SPDX-License-Identifier: BSD-3-Clause) [comment]: <> (Copyright 2017-2018, Intel Corporation) [comment]: <> (pmemlog_append.3 -- man page for pmemlog_append and pmemlog_appendv functions) [NAME](#name)
[SYNOPSIS](#synopsis)
[DESCRIPTION](#description)
[RETURN VALUE](#return-value)
[NOTES](#notes)
[SEE ALSO](#see-also)
# NAME # **pmemlog_append**(), **pmemlog_appendv**() - append bytes to the persistent memory resident log file # SYNOPSIS # ```c #include int pmemlog_append(PMEMlogpool *plp, const void *buf, size_t count); int pmemlog_appendv(PMEMlogpool *plp, const struct iovec *iov, int iovcnt); ``` # DESCRIPTION # The **pmemlog_append**() function appends *count* bytes from *buf* to the current write offset in the log memory pool *plp*. Calling this function is analogous to appending to a file. The append is atomic and cannot be torn by a program failure or system crash. The **pmemlog_appendv**() function appends to the log memory pool *plp* from the scatter/gather list *iov* in a manner similar to **writev**(2). The entire list of buffers is appended atomically, as if the buffers in *iov* were concatenated in order. The append is atomic and cannot be torn by a program failure or system crash. # RETURN VALUE # On success, **pmemlog_append**() and **pmemlog_appendv**() return 0. On error, they return -1 and set *errno* appropriately. # ERRORS # **EINVAL** The vector count *iovcnt* is less than zero. **ENOSPC** There is no room for the data in the log file. **EROFS** The log file is open in read-only mode. # NOTES # Since **libpmemlog**(7) is designed as a low-latency code path, many of the checks routinely done by the operating system for **writev**(2) are not practical in the library's implementation of **pmemlog_appendv**(). No attempt is made to detect NULL or incorrect pointers, for example. # SEE ALSO # **writev**(2), **libpmemlog**(7) and **** pmdk-1.11.1/doc/libpmemlog/pmemlog_set_funcs.30000664000000000000000000000002614123364546017725 0ustar rootroot.so man7/libpmemlog.7 pmdk-1.11.1/doc/libpmemlog/pmemlog_ctl_get.30000664000000000000000000000706414123364730017361 0ustar rootroot.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEMLOG_CTL_GET" "3" "2021-09-24" "PMDK - pmemlog API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2018-2019, Intel Corporation .SH NAME .PP \f[B]pmemlog_ctl_get\f[](), \f[B]pmemlog_ctl_set\f[](), \f[B]pmemlog_ctl_exec\f[]() \- Query and modify libpmemlog internal behavior (EXPERIMENTAL) .SH SYNOPSIS .IP .nf \f[C] #include\ int\ pmemlog_ctl_get(PMEMlogpool\ *plp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemlog_ctl_set(PMEMlogpool\ *plp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) int\ pmemlog_ctl_exec(PMEMlogpool\ *plp,\ const\ char\ *name,\ void\ *arg);\ (EXPERIMENTAL) \f[] .fi .SH DESCRIPTION .PP The \f[B]pmemlog_ctl_get\f[](), \f[B]pmemlog_ctl_set\f[]() and \f[B]pmemlog_ctl_exec\f[]() functions provide a uniform interface for querying and modifying the internal behavior of \f[B]libpmemlog\f[](7) through the control (CTL) namespace. .PP The \f[I]name\f[] argument specifies an entry point as defined in the CTL namespace specification. The entry point description specifies whether the extra \f[I]arg\f[] is required. Those two parameters together create a CTL query. The functions and the entry points are thread\-safe unless indicated otherwise below. If there are special conditions for calling an entry point, they are explicitly stated in its description. The functions propagate the return value of the entry point. If either \f[I]name\f[] or \f[I]arg\f[] is invalid, \-1 is returned. .PP If the provided ctl query is valid, the CTL functions will always return 0 on success and \-1 on failure, unless otherwise specified in the entry point description. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH CTL NAMESPACE .PP prefault.at_create | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is created, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemlog_create\f[]() function. .PP Always returns 0. .PP prefault.at_open | rw | global | int | int | \- | boolean .PP If set, every page of the pool will be touched and written to when the pool is opened, in order to trigger page allocation and minimize the performance impact of pagefaults. Affects only the \f[B]pmemlog_open\f[]() function. .PP Always returns 0. .PP sds.at_create | rw | global | int | int | \- | boolean .PP If set, force\-enables or force\-disables SDS feature during pool creation. Affects only the \f[B]pmemlog_create\f[]() function. See \f[B]pmempool_feature_query\f[](3) for information about SDS (SHUTDOWN_STATE) feature. .PP Always returns 0. .PP copy_on_write.at_open | rw | global | int | int | \- | boolean .PP If set, pool is mapped in such a way that modifications don't reach the underlying medium. From the user's perspective this means that when the pool is closed all changes are reverted. This feature is not supported for pools located on Device DAX. .PP Always returns 0. .SH CTL EXTERNAL CONFIGURATION .PP In addition to direct function call, each write entry point can also be set using two alternative methods. .PP The first method is to load a configuration directly from the \f[B]PMEMLOG_CONF\f[] environment variable. .PP The second method of loading an external configuration is to set the \f[B]PMEMLOG_CONF_FILE\f[] environment variable to point to a file that contains a sequence of ctl queries. .PP See more in \f[B]pmem_ctl\f[](5) man page. .SH SEE ALSO .PP \f[B]libpmemlog\f[](7), \f[B]pmem_ctl\f[](5) and \f[B]\f[] pmdk-1.11.1/doc/libpmemlog/pmemlog_walk.30000664000000000000000000000002314123364546016667 0ustar rootroot.so pmemlog_tell.3 pmdk-1.11.1/doc/libpmemlog/pmemlog_check_version.30000664000000000000000000000002614123364546020556 0ustar rootroot.so man7/libpmemlog.7 pmdk-1.11.1/doc/libpmemlog/pmemlog_ctl_set.30000664000000000000000000000002614123364546017371 0ustar rootroot.so pmemlog_ctl_get.3 pmdk-1.11.1/VERSION0000664000000000000000000000000714123364546012303 0ustar rootroot1.11.1 pmdk-1.11.1/.gitignore0000664000000000000000000000040314123364546013223 0ustar rootroot.* !.github !.gitignore !.gitattributes !.cirrus.yml !.clang-format !.travis.yml !.mailmap !.cstyleignore !.codecov.yml *~ *.swp *.o make.out core a.out nbproject/ /rpmbuild/ /dpkgbuild/ /rpm/ /dpkg/ /user.mk *.user ~* *.db *.htmp *.hpptmp *.aps tags *.link pmdk-1.11.1/.skip-doc0000664000000000000000000000000014123365127012732 0ustar rootrootpmdk-1.11.1/.gitattributes0000664000000000000000000000017114123364546014130 0ustar rootroot* text=auto eol=lf *.jpg binary *.png binary *.gif binary *.ico binary *.match text -whitespace GIT_VERSION export-subst pmdk-1.11.1/ChangeLog0000664000000000000000000011722414123364546013017 0ustar rootrootFri Sep 24 2020 Łukasz Plewa * Version 1.11.1 This release fixes a missing sfence in non-temporal version of memcpy function (https://github.com/pmem/pmdk/issues/5292), and fixes a number of smaller bugs. Detailed list of bug fixes: - doc: remove exprimental moniker from libpmem2(7) - common: fix missing sfence in non-temporal memcpy - common: fix a mismatch between prototype and body - common: the yearly spellchecker run - common: force no LTO for rpm build - common: fix mismatched function args - obj: rename vars clashing with those of a containing block - pmem2: don't force smaller alignment for fsdax mappings - pool: don't trample upon users of localtime() - rpmem: Fix RPMEM_RAW_BUFF_SIZE and LANE_ALIGN_SIZE for powerpc64le - rpmem: drop a redundant check Mon Sep 24 2021 Łukasz Plewa * Version 1.10.1 This release fixes a missing sfence in non-temporal version of memcpy function (https://github.com/pmem/pmdk/issues/5292), and fixes a number of smaller bugs. Detailed list of bug fixes: - common: add disable lto to cflags - doc: remove exprimental moniker from libpmem2(7) - common: fix missing sfence in non-temporal memcpy - common: fix a mismatch between prototype and body - common: the yearly spellchecker run - common: force no LTO for rpm build - common: fix mismatched function args - obj: rename vars clashing with those of a containing block - pmem2: don't force smaller alignment for fsdax mappings - pool: don't trample upon users of localtime() - rpmem: Fix RPMEM_RAW_BUFF_SIZE and LANE_ALIGN_SIZE for powerpc64le - rpmem: drop a redundant check Fri Sep 24 2021 Łukasz Plewa * Version 1.9.3 This release fixes a missing sfence in non-temporal version of memcpy function (https://github.com/pmem/pmdk/issues/5292), and fixes a number of smaller bugs. Detailed list of bug fixes: - common: add disable lto to cflags - common: fix missing sfence in non-temporal memcpy - common: fix mismatched function args - common: fix a mismatch between prototype and body - common: the yearly spellchecker run - common: force no LTO for rpm build - rpmem: Fix RPMEM_RAW_BUFF_SIZE and LANE_ALIGN_SIZE for powerpc64le Fri Jul 2 2021 Piotr Balcer * Version 1.11.0 This release: - Adds new APIs for libpmem2, most notably there are new functions to shrink and extend an existing reservation and a new iterator API for mappings contained within an existing reservation. There's also a new function to retrieve a numa node for a source. - Makes the pmemobj_open() and pmemobj_close() functions from libpmemobj thread-safe. It's now easier to correctly manage persistent memory pools in a parallel environment. - Introduces a new API in libpmemobj to globally change the method of assigning arenas to threads. The default is to rely on a OS per-thread key to store arena information. This release introduces an option to avoid the use of thread-local keys by simply using one global arena for all threads in a pool. Other changes and notable bug fixes: - pmem2: don't force smaller alignment for fsdax mappings - rpmem: various fixes for powerpc64le - doc: fix documentation of pmem_is_pmem() - common: fix various minor problems found by static analysis - pmem2: arm64: fix possible data loss on ARMv8.2+ (improper flushing) This release introduces no changes to the on-media layout and is fully compatible with the previous version of PMDK. Wed Oct 28 2020 Piotr Balcer * Version 1.10 This release introduces a new stable PMDK library, libpmem2, which is the next major release of libpmem. This library has an entirely new, but familiar, API that addresses many shortcomings of the previous version, while retaining all of its functionality. To learn more, see https://pmem.io/pmdk/libpmem2/ or libpmem2(7). The old library, libpmem, is still going to be maintained for the foreseeable future, but we'd like to encourage any new applications to leverage libpmem2. Wed Oct 28 2020 Piotr Balcer * Version 1.9.2 This release reverts an incorrect change in SDS handling "pool: disable SDS check if not supported", and introduces a proper fix for the issues that patch attempted to correct. Wed Sep 16 2020 Piotr Balcer * Version 1.9.1 Detailed list of bug fixes: - common: fix LIBFABRIC flags - common: Add runtime SDS check and disable - pool: disable SDS check if not supported - obj: fix failure atomicity bug in huge allocs - obj: add missing drain after ulog processing Fri Jul 3 2020 Piotr Balcer * Version 1.9 This release: - Switches the default instruction set for memcpy, memmove and memset implementations on x86 to AVX512, and introduces numerous performance improvements for those operations on AVX and SSE2 fallback paths. - Optimizes transactional allocations in libpmemobj by avoiding one extraneous cache miss and reducing the amount of work required to perform a reservation. - Introduces a new API in libpmemobj, pmemobj_tx_set_failure_behavior, that enables the application to control the behavior of aborting transactions. - Improves performance of pool creation on Windows by avoiding expensive physical page allocation during file allocation. - Stabilizes support for ppc64. Other changes: - pmem: mem[cpy|set] optimization when eADR is available - obj: detect msync failures in non-pmem variants of mem[cpy|move|set] Notable bug fixes: - core: fix Last_errormsg_get when NO_LIBPTHREAD is defined - pmem: read Unsafe Shutdown Count from region instead of interleave set - common: fix deep_flushes failing on platforms that don't need them - pmem: fix data cache flush on ppc64 - obj: fix run allocated recalculation Fri Jan 31 2020 Marcin Ślusarz * Version 1.8 This release: - Introduces new API in libpmemobj for user-assisted defragmentation (see pmemobj_defrag man page for details). - Introduces experimental support for PPC64LE architecture. - Introduces new flag in libpmemobj for opting-out of transaction aborts on failure (POBJ_TX_NO_ABORT), along with new variants of existing APIs that didn't accept flags (pmemobj_tx_xfree, pmemobj_tx_xpublish, pmemobj_tx_xlock, pmemobj_tx_xlog_append_buffer, pmemobj_tx_xstrdup, pmemobj_tx_xwcsdup). - Moves out libvmem and libvmmalloc to the new repository (https://github.com/pmem/vmem). Other changes: - obj: introduce new statistics useful for defrag - obj: introduce transient/persistent statistics enabling - obj: introduce pmemobj_tx_(set/get)_user_data funcs - obj: introduce pmemobj_(set/get)_user_data funcs - obj: disable workaround for offsetof() since VS 15.5 in public header - common: drop support for libndctl < 63 on Linux - pool: rename -N --no-exec to -d --dry-run Notable bug fixes: - obj: fix zone size calculations - obj: fix potential NULL-dereference in ulog_store - obj: fix unintended recursive locking during palloc - obj: fix lock release order in palloc publish - obj: fix transient redo log of more than 64 entries - obj: fix capacity ulog calculation - obj: fix check of unaligned capacity size - rpmem: add a missing case for GPSPM + FLUSH_STRICT - pmem: fix pmemcheck support on platforms with eADR - pool: fix possible memory leak - rpmem: fix possible memory leak in rpmemd_config_read - rpmem: fix possible memory leak in rpmemd_log_init - rpmem: fix possible use-after-free Mon Sep 30 2019 Marcin Ślusarz * Version 1.7 This release: - Introduces new APIs in libpmemobj for managing space used by transactions. (see pmemobj_tx_log_append_buffer man page for details) - Introduces new APIs in librpmem, splitting rpmem_persist into rpmem_flush and rpmem_drain, allowing applications to use the flush + drain model already known from libpmem. (libpmemobj does not use this feature yet) - Optimizes large libpmemobj transactions by significantly reducing the amount of memory modified at the commit phase. - Optimizes tracking of libpmemobj reservations. - Adds new flags for libpmemobj's pmemobj_tx_xadd_range[_direct] API: POBJ_XADD_NO_SNAPSHOT and POBJ_XADD_ASSUME_INITIALIZED, allowing applications to optimize how memory is tracked by the library. To support some of the above changes the libpmemobj on-media layout had to be changed, which means that old pools have to be converted using pmdk-convert >= 1.7. Other changes: - obj: fix merging of ranges when NOFLUSH flag is used (pmem/issues#1100) - rpmem: fix closing of ssh connection (pmem/issues#995, pmem/issues#1060) - obj: abort transaction on pmemobj_tx_publish failure Internal changes: - test: fault injection tests for pmemblk, pmemlog, and pmemobj - test: improved Python testing framework - test: support real pmem in bad blocks tests - common: allow not building examples and benchmarks Tue Aug 27 2019 Marcin Ślusarz * Version 1.6.1 This release fixes possible pool corruptions on Windows (see https://github.com/pmem/pmdk/pull/3728 for details), improves compatibility with newer Linux kernels with respect to Device DAX detection, fixes pmemobj space management for large pools, improves compatibility with newer toolchains, incorporates build fixes for FreeBSD and fixes a number of smaller bugs. Detailed list of bug fixes: - common: (win) fix possible pool file coruption (pmem/issues#972, pmem/issues#715, pmem/issues#603) - common: implement correct / robust device_dax_alignment (pmem/issues#1071) - obj: fix recycler not locating unused chunks - doc: update pmemobj_tx_lock documentation wrt behavior on fail - common: fix persistent domain detection (pmem/issues#1093) - common: vecq: fix a pointer-to-struct aliasing violation (crash on arm64) - common: fix minor issues related to ndctl linking - obj: drop recursion from pmemobj_next - common: fix bug in badblock file error handling - obj: fix handling of malloc failures - common: fix handling of malloc failures (ctl) - jemalloc: fix build with gcc 9 - obj: don't overwrite errno when palloc_heap_check_remote fails - doc: fix pmreorder emit log macro - rpmem: change order of rpmem init (pmem/issues#1043) - common: Fix build failure due to unused macro PAGE_SIZE - common: support older versions of pkg-config - tools: link with release variant of pmemcommon - common: add PMDK prefix to local copy of queue.h (pmem/issues#990) - rpmem: switch to using an open coded basename (FreeBSD) - common: posix_fallocate: guard against integer underflow in check (FreeBSD) - test: support Valgrind 3.15 - test: skip if fi_info is missing - test: (win) fix sparsefile error handling - test: fix libpmempool_feature tests that match logs - test: remove vmem_delete test (pmem/issues#1074) - test: adjust matchfiles in vmem_valgrind_region test (pmem/issues#1087) - test: remove old log files for windows (pmem/issues#1013) - test: remove invalid expect_normal_exit (pmem/issues#1092) - test: suppress ld leak (pmem/issues#1098) - test: Expose necessary symbols in libvmmalloc_dummy_funcs (FreeBSD) - test: fix tests failing because `tput` fails (FreeBSD) - test: avoid obj_critnib_mt taking very long on many-core machines - test: deal with libndctl's path without build system - test: overwrite old log in pmempool_create/TEST14.PS1 - test: fix match files in tests which use dax devices - test: fix match file in rpmem_addr_ext test - test: fix pmempool_check test Wed Aug 28 2019 Marcin Ślusarz * Version 1.5.2 This release fixes possible pool corruptions on Windows (see https://github.com/pmem/pmdk/pull/3728 for details), improves compatibility with newer Linux kernels with respect to Device DAX detection, fixes pmemobj space management for large pools, improves compatibility with newer toolchains and fixes a number of smaller bugs. Detailed list of bug fixes: - common: (win) fix possible pool file coruption (pmem/issues#972, pmem/issues#715, pmem/issues#603) - common: implement correct / robust device_dax_alignment (pmem/issues#1071) - obj: fix crash after large undo log recovery - obj: fix recycler not locating unused chunks - doc: update pmemobj_tx_lock documentation wrt behavior on fail - common: fix build of rpm packages on suse (pmem/issues#1023) - common: fix persistent domain detection (pmem/issues#1093) - common: vecq: fix a pointer-to-struct aliasing violation (crash on arm64) - rpmem: lock file prior to unlink (pmem/issues#833) - common: fix for pool_set error handling (pmem/issues#1036) - pmreorder: fix handling of store drain flush drain pattern - obj: fix possible memory leak in tx_add_lock - pool: free bad_block vector - common: fix bug in badblock file error handling - obj: fix handling of malloc failures - common: fix handling of malloc failures (ctl) - jemalloc: fix build with gcc 9 - obj: don't overwrite errno when palloc_heap_check_remote fails - doc: fix typos in pmreorder configuration - doc: fix pmreorder emit log macro - tools: link with release variant of pmemcommon - test: support Valgrind 3.15 - test: skip if fi_info is missing - test: split test obj_tx_lock into two test cases (pmem/issues#1027) - test: (win) fix sparsefile error handling - test: fix libpmempool_feature tests that match logs - test: remove vmem_delete test (pmem/issues#1074) - test: adjust matchfiles in vmem_valgrind_region test (pmem/issues#1087) - test: remove old log files for windows (pmem/issues#1013) - test: remove invalid expect_normal_exit (pmem/issues#1092) - test: suppress ld leak (pmem/issues#1098) - test: fix failing pmemdetect on Windows - test: fix match files in tests which use dax devices - test: fix pmempool_check test Fri Aug 30 2019 Marcin Ślusarz * Version 1.4.3 This release fixes possible pool corruptions on Windows (see https://github.com/pmem/pmdk/pull/3728 for details) and improves compatibility with newer Linux kernels with respect to Device DAX detection. Bug fixes: - common: (win) fix possible pool file coruption (pmem/issues#972, pmem/issues#715, pmem/issues#603) - common: implement correct / robust device_dax_alignment (pmem/issues#1071) - common: fix device dax detection - obj: fix pmemobj_check for pools with some sizes (pmem/issues#975) - obj: fix type numbers for pmemobj_list_insert_new - obj: fix pmemobj_tx_lock error handling - obj: fix possible memory leak in tx_add_lock - common: fix ctl_load_config during libpmemobj initialization (pmem/issues#917) - common: win: fix getopt returning "option is ambiguous" - common: fix persistent domain detection (pmem/issues#1093) - pool: do not copy same regions in update_uuids - test: split test obj_tx_lock into two test cases - test: remove checking errno in obj_tx_add_range_direct - test: remove invalid expect_normal_exit - test: fix int overflow in pmem_deep_persist test - test: fix pmempool_check test - test: (win) fix a few issues related to long paths Tue Aug 27 2019 Marcin Ślusarz * Version 1.3.3 Bug fixes: - pmem: fix clflush bit position - common: implement correct / robust device_dax_alignment - common: fix device dax detection - common: fix library dependencies (pmem/issues#767) - common: use rpm-config CFLAGS/LDFLAGS when building packages (pmem/issues#768) - test: fix vmmalloc_malloc_hooks (pmem/issues#773) - test: fix compilation with clang-5.0 (pmem/issues#783) - pool: fix set convert of v3 -> v4 - common: generate pkg-config files on make install (pmem/issues#610) - common: fix dependencies for Debian's dev packages - test: add missing include in unittest.h - common: (win) fix timed locks - common: provide src version in GitHub tarballs - common: fix free function in tls Tue Aug 27 2019 Marcin Ślusarz * Version 1.2.4 Bug fixes: - common: fix device dax detection (compatibility with newer kernels) Tue Mar 26 2019 Marcin Ślusarz * Version 1.6 This release: - Enables unsafe shutdown and bad block detection on Linux on systems with libndctl >= 63. It is expected that systems with libndctl >= 63 has necessary kernel support (Linux >= 4.20). However, due to bugs in libndctl = 63 and Linux = 4.20, it is recommended to use libndctl >= 64.1 and Linux >= 5.0.4. On systems with libndctl < 63, PMDK uses old superuser-only interfaces. Support for old or new interfaces is chosen at BUILD time. - Introduces arena control interface in pmemobj, allowing applications to tweak performance and scalability of heap operations. See pmemobj_ctl_get man page ("heap" namespace) for details. - Introduces copy_on_write mode, which allows testing applications using pmemobj with pmreorder. See pmemobj_ctl_get man page ("copy_on_write" namespace) for details. Other changes: - allocate file space when creating a pool on existing file (pmem/issues#167) - initial support for testing using fault injection - initial Python test framework - improve performance of pmemobj_pool_by_ptr Bug fixes: - common: work around tmpfs bug during pool creation (pmem/issues#1018) - pool: race-free pmempool create --max-size - obj: don't modify remote pools in pmemobj_check Tue Feb 19 2019 Marcin Ślusarz * Version 1.5.1 This release fixes minor bugs and improves compatibility with newer tool chains. Notable bug fixes: - common: make detection of device-dax instances more robust - obj: fix pmemobj_check for pools with some sizes - obj: don't use anon struct in an union (public header) - obj: fix pmemobj_tx_lock error handling - obj: don't use braces in an expression with clang (public header) - obj: suppress pmemcheck warnings for statistics - pmreorder: fix markers nontype issue Fri Oct 26 2018 Marcin Ślusarz * Version 1.5 This release has had two major focus areas - performance and RAS (Reliability, Availability and Serviceability). Beyond that, it introduces new APIs, new tools and many other improvements. As a side effect of performance optimizations, the libpmemobj on-media layout had to be changed, which means that old pools have to be converted using pmdk-convert. libpmemcto experiment has been finished and removed from the tree. For more details, please see https://pmem.io/2018/10/22/release-1-5.html. New features: - common: unsafe shutdown detection (SDS) - common: detection and repair of uncorrectable memory errors (bad blocks) - pool: new "feature" subcommand for enabling and disabling detection of unsafe shutdown and uncorrectable memory errors - common: auto flush detection on Windows (on Linux since 1.4) - pmreorder: new tool for verification of persistent memory algorithms - obj: new on media layout - pmem/obj: new flexible memcpy|memmove|memset API - obj: new flushing APIs: pmemobj_xpersist, pmemobj_xflush (PMEMOBJ_F_RELAXED) - rpmem: new flag RPMEM_PERSIST_RELAXED for rpmem_persist - obj: lazily initialized volatile variables (pmemobj_volatile) (EXPERIMENTAL) - obj: allocation classes with alignment - obj: new action APIs: pmemobj_defer_free, POBJ_XRESERVE_NEW, POBJ_XRESERVE_ALLOC - blk/log: new "ctl" API Optimizations: - obj: major performance improvements for AEP NVDIMMs - obj: better space utilization for small allocations - common: call msync only on one page for deep drain Other changes: - cto: removed - obj: remove actions limit - common: new dependency on libndctl on Linux - pmempool: "convert" subcommand is now a wrapper around pmdk-convert (please see https://github.com/pmem/pmdk-convert) - obj: C++ bindings have been moved to a new repository (please see https://github.com/pmem/libpmemobj-cpp) Bug fixes: - obj: fix type numbers for pmemobj_list_insert_new - pmem: fix inconsistency in pmem_is_pmem - common: fix windows mmap destruction - daxio: fix checking and adjusting length - common: fix long paths support on Windows Thu Aug 16 2018 Marcin Ślusarz * Version 1.4.2 This release fixes the way PMDK reports its version via pkg-config files. Bug fixes: - common: fix reported version - doc: use single "-" in NAME section (pmem/issues#914) Fri Jun 29 2018 Marcin Ślusarz * Version 1.4.1 In 1.4 development cycle, we created new daxio utility (command line tool for performing I/O on Device-DAX), but due to some complications we had to disable it just before the 1.4 release. In 1.4.1 we finally enable it. Daxio depends on ndctl v60.1. Bug fixes: - pmem: fix clflush bit position - obj: fix invalid OOMs when zones are fully packed - obj: don't register undo logs twice in memcheck - pool: fix bash completion script - pool: fix incorrect errno after transform - obj: fix clang-7 compilation - obj: test for msync failures in non-pmem path - doc: add missing field to alloc class entry point - common: (win) fix timed locks - common: provide src version in GitHub tarballs - common: fix free function in tls - common: fix double close - test: allow testing installed libraries - test: fix Valgrind vs stripped libraries issue - test: fix dependencies between tests and tools - test: fix races on make pcheck -jN - test: use libvmmalloc.so.1 - test: fix incorrect number of required dax devices - test: add suppression for leak in ld.so - test: fail if memcheck detects overlapping chunks - test: simplify time measurements in obj_sync - benchmark: check lseek() return value - examples: catch exceptions in map_cli Thu Mar 29 2018 Krzysztof Czurylo * Version 1.4 This is the first release of PMDK under a new name. The NVML project has been renamed to PMDK (Persistent Memory Development Kit). This is only the project/repo name change and it does not affect the names of the PMDK packages. See this blog article for more details on the reasons and impact of the name change: https://pmem.io/2017/12/11/NVML-is-now-PMDK.html New features: - common: support for concatenated Device-DAX devices with 2M/1G alignment - common: add support for MAP_SYNC flag - common: always enable Valgrind instrumentation (pmem/issues#292) - common: pool set options / headerless pools - pmem: add support for "deep flush" operation - rpmem: add rpmem_deep_persist - doc: split man pages and add per-function aliases (pmem/issues#385) Optimizations: - pmem: skip CPU cache flushing when eADR is available (no Windows support yet) - pmem: add AVX512F support in pmem_memcpy/memset (pmem/issues#656) Bug fixes: - common: fix library dependencies (pmem/issues#767, RHBZ #1539564) - common: use rpm-config CFLAGS/LDFLAGS when building packages (pmem/issues#768, RHBZ #1539564) - common: do not unload librpmem on close (pmem/issues#776) - common: fix NULL check in os_fopen (pmem/issues#813) - common: fix missing version in .pc files - obj: fix cancel of huge allocations (pmem/issues#726) - obj: fix error handling in pmemobj_open (pmem/issues#750) - obj: validate pe_offset in pmemobj_list_* APIs (pmem/issues#772) - obj: fix add_range with size == 0 (pmem/issues#781) - log: add check for negative iovcnt (pmem/issues#690) - rpmem: limit maximum number of lanes (pmem/issues#609) - rpmem: change order of memory registration (pmem/issues#655) - rpmem: fix removing remote pools (pmem/issues#721) - pool: fix error handling (pmem/issues#643) - pool: fix sync with switched parts (pmem/issues#730) - pool: fix sync with missing replica (pmem/issues#731) - pool: fix detection of Device DAX size (pmem/issues#805) - pool: fail pmempool_sync if there are no replicas (pmem/issues#816) - benchmark: fix calculating standard deviation (pmem/issues#318) - doc: clarify pmem_is_pmem behavior (pmem/issues#719) - doc: clarify pmemobj_root behavior (pmem/issues#733) Experimental features: - common: port PMDK to FreeBSD - common: add experimental support for aarch64 - obj: introduce allocation classes - obj: introduce two-phase heap ops (reserve/publish) (pmem/issues#380, pmem/issues#415) - obj: provide basic heap statistics (pmem/issues#676) - obj: implement run-time pool extending (pmem/issues#382) - cto: add close-to-open persistence library (pmem/issues#192) The following features are disabled by default, until ndctl v60.0 is available: - daxio: add utility to perform I/O on Device-DAX - RAS: unsafe shutdown detection/handling Wed Dec 20 2017 Krzysztof Czurylo * Version 1.3.1 Bug fixes: - rpmem: fix issues reported by Coverity - rpmem: fix read error handling - rpmem: add fip monitor (pmem/issues#597) - test: add rpmemd termination handling test - cpp: fix pop.persist function in obj_cpp_ptr - rpmem: return failure for a failed allocation - rpmem: fix potential memory leak - common: fix available rm options msg (pmem/issues#651) - pool: fix pmempool_get_max_size - obj: fix potential deadlock during realloc (pmem/issues#635, pmem/issues#636, pmem/issues#637) - obj: initialize TLS data - rpmem: fix cleanup if fork() failed (pmem/issues#634) - obj: fix bogus OOM after exhausting first zone Thu Jul 13 2017 Krzysztof Czurylo * Version 1.3 This release introduces some useful features and optimizations in libpmemobj. Most of them are experimental and controlled by the new pmemobj_ctl APIs. For details, please check the feature requests identified by the issue numbers listed next to the items below. Other important changes are related to performance tuning and stabilization of librpmem library, which is used by libpmemobj to get remote access to persistent memory and to provide basic data replication over RDMA. The librpmem is still considered experimental. NVML for Windows is feature complete (except for libvmmalloc). This release includes the support for Unicode, long paths and the NVML installer. New features: - common: add support for concatenated DAX Devices - common: add Unicode support on Windows - common: add long path support on Windows - common: add NVML installer for Windows - pmem: make pmem_is_pmem() true for Device DAX only - obj: add pmemobj_wcsdup()/pmemobj_tx_wcsdup() APIs - obj: export non-inlined pmemobj_direct() - obj: add PMEMOBJ_NLANES env variable - cpp: introduce the allocator - cpp: add wstring version of C++ entry points - vmem: add vmem_wcsdup() API entry - pool: add pmempool_rm() function (pmem/issues#307) - pool: add --force flag for create command (pmem/issues#529) - benchmark: add a minimal execution time option - benchmark: add thread affinity option - benchmark: print 99% and 99.9% percentiles - doc: separate Linux/Windows version of web-based man pages Optimizations: - obj: cache _pobj_cached_pool in pmemobj_direct() - obj: optimize thread utilization of buckets - obj: stop grabbing a lock when querying pool ptr - rpmem: use multiple endpoints Bug fixes: - common: fix issues reported by static code analyzers - pmem: fix mmap() implementation on Windows - pmem: fix mapping addr/length alignment on Windows - pmem: fix PMEM_MMAP_HINT implementation on Windows - pmem: fix pmem_is_pmem() on invalid memory ranges - pmem: fix wrong is_pmem returned by pmem_map_file() - pmem: fix mprotect() for private mappings on Windows - pmem: modify pmem_is_pmem() behavior for len==0 - obj: add failsafe to prevent allocs in constructor - cpp: fix swap implementation - cpp: fix sync primitives' constructors - cpp: fix wrong pointer type in the allocator - cpp: return persistent_ptr::swap to being public - pool: treat invalid answer as 'n' - pool: unify flags value for dry run - pool: transform for remote replicas - rpmem: persistency method detection - benchmark: fix time measurement Experimental features/optimizations: - obj: pmemobjctl - statistics and control submodule (pmem/issues#194, pmem/issues#211) - obj: zero-overhead allocations - customizable alloc header (pmem/issues#347) - obj: flexible run size index (pmem/issues#377) - obj: dynamic range cache (pmem/issues#378) - obj: asynchronous post-commit (pmem/issues#381) - obj: configurable object cache (pmem/issues#515) - obj: add cache size and threshold tx params - obj: add CTL var for suppressing expensive checks - rpmem: add rpmem_set_attr() API entry - rpmem: switch to libfabric v1.4.2 Thu May 18 2017 Krzysztof Czurylo * Version 1.2.3 Bug fixes: - test: extend timeout for selected tests - test: reduce number of operations in obj_tx_mt - test: define cfree() as free() in vmmalloc_calloc Other changes: - common: move Docker images to new repo Sat Apr 15 2017 Krzysztof Czurylo * Version 1.2.2 Bug fixes: - pmempool: fix mapping type in pool_params_parse - test: limit number of arenas in vmem_stats - test: do not run pool_lock test as root - common: fix pkg-config files - common: fix building packages for Debian Tue Feb 21 2017 Krzysztof Czurylo * Version 1.2.1 This NVML release changes the behavior of pmem_is_pmem() on Linux. The pmem_is_pmem() function will now return true only if the entire range is mapped directly from Device DAX (/dev/daxX.Y) without an intervening file system, and only if the corresponding file mapping was created with pmem_map_file(). See libpmem(7) for details. Bug fixes: - jemalloc: fix test compilation on Fedora 26 (rawhide) - test: fix cpp test compilation on Fedora 26 (rawhide) - common: use same queue.h on linux and windows - common: queue.h clang static analyzer fix - common: fix path handling in build-dpkg.sh - test: fix match files in pmempool_transform/TEST8 Fri Dec 30 2016 Krzysztof Czurylo * Version 1.2 - Windows Technical Preview #1 This is the first Technical Preview release of NVML for Windows. It is based on NVML 1.2 version, but not all the 1.2 features are ported to Windows. In particular, Device DAX and remote access to persistent memory (librpmem) are not supported by design. NOTE: This release has not gone through the full validation cycle, but only through some basic tests on Travis and AppVeyor. Thus, it cannot be assumed "Production quality" and should not be used in production environments. Besides several minor improvements and bug fixes, all the other changes since NVML 1.2 release were related to Windows support: - win: port libvmem (and jemalloc) - win: benchmarks Windows port - win: fix mapping files of unaligned length - win: clean up possible race condition in mmap_init() - win: enable QueryVirtualMemoryInformation() in pmem_is_pmem() - test: check open handles at START/DONE - test: port all the remaining unit tests (scope, pmem_map, obj_debug, util_poolset, pmempool_*) - win: add resource files for versioning Known issues and limitations of Windows version of NVML: - Unicode support is missing. The UTF/USC-encoded file paths or pool set files may not be handled correctly. - The libvmmalloc library is not ported yet. - The on-media format of pmem pools is not portable at the moment. The pmem pools created using Windows version of NVM libraries cannot be open on Linux and vice versa. - Despite the fact the current version of NVML would work with any recent version of Windows OS, to take full advantage of PMEM and NVML features and to benefit from the PMEM performance, the recommended platforms needs be equipped with the real NVDIMMs hardware and should support the native, Microsoft's implementation of DAX-enabled file system (i.e. Windows Server 2016 or later). In case of using NVML with older versions of Windows or with the custom implementation of PMEM/DAX drivers, the performance might not be satisfactory. Please, contact the provider of PMEM/DAX drivers for your platform to get the customized version of NVML in such case. Thu Dec 15 2016 Krzysztof Czurylo * Version 1.2 This NVML release causes a "flag day" for libpmemobj. The pmemobj pools built under NVML 1.1 are incompatible with pools built under NVML 1.2 and later. This is because an issue was discovered with the alignment of locks (pmem/issues#358) and, although rare, the issue potentially impacts program correctness, making the fix mandatory. The major version number of the pmemobj pool layout and the version of the libpmemobj API is changed to prevent the use of the potentially incorrect layout. Other key changes introduced in this release: - Add Device DAX support, providing that "optimized flush" mechanism defined in SNIA NVM Programming Model can safely be used, even if PMEM-aware file system supporting that model is not available, or if the user does not want to use the file system for some reason. - Add a package for libpmemobj C++ bindings. C++ API is no longer considered experimental. Web-based documentation for C++ API is available on https://pmem.io. - Add "sync" and "transform" commands to pmempool utility. The "sync" command allows one to recover missing or corrupted part(s) of a pool set from a healthy replica, while the "transform" command is a convenient way for modifying the structure of an existing pool set, i.e. by adding or removing replicas. - Add experimental support for remote access to persistent memory and basic remote data replication over RDMA (librpmem). Experimental support for remote replicas is also provided by libpmemobj library. New features: - common: add Device DAX support (pmem/issues#197) - obj: add C++ bindings package (libpmemobj++-devel) - obj: add TOID_OFFSETOF macro - pmempool: add "sync" and "transform" commands (pmem/issues#172, pmem/issues#196) Bug fixes: - obj: force alignment of pmem lock structures (pmem/issues#358) - blk: cast translation entry to uint64_t when calculating data offset - obj: fix Valgrind instrumentation of chunk headers and cancelled allocations - obj: set error message when user called pmemobj_tx_abort() - obj: fix status returned by pmemobj_list_insert() (pmem/issues#226) - obj: defer allocation of global structures Optimizations: - obj: fast path for pmemobj_pool_by_ptr() when inside a transaction - obj: simplify and optimize allocation class generation Experimental features: - rpmem: add support for remote access to persistent memory and basic remote data replication over RDMA - libpmempool: add pmempool_sync() and pmempool_transform() (pmem/issues#196) - obj: introduce pmemobj_oid() - obj: add pmemobj_tx_xalloc()/pmemobj_tx_xadd_range() APIs and the corresponding macros - obj: add transaction stage transition callbacks Thu Jun 23 2016 Krzysztof Czurylo * Version 1.1 This NVML release introduces a new version of libpmemobj pool layout. Internal undo log structure has been modified to improve performance of pmemobj transactions. Memory pools created with older versions of the libpmemobj library must be converted to the new format using "pmempool convert" command. See pmempool-convert(1) for details. A new "libpmempool" library is available, providing support for off-line pool management and diagnostics. Initially it provides only "check" and "repair" operations for log and blk memory pools, and for BTT devices. Other changes: - pmem: deprecate PCOMMIT - blk: match BTT Flog initialization with Linux NVDIMM BTT - pmem: defer pmem_is_pmem() initialization (pmem/issues#158) - obj: add TOID_TYPEOF macro Bug fixes: - doc: update description of valid file size units (pmem/issues#133) - pmempool: fix --version short option in man page (pmem/issues#135) - pmempool: print usage when running rm without arg (pmem/issues#136) - cpp: clarify polymorphism in persistent_ptr (pmem/issues#150) - obj: let the before flag be any non-zero value (pmem/issues#151) - obj: fix compare array pptr to nullptr (pmem/issues#152) - obj: cpp pool.get_root() fix (pmem/issues#156) - log/blk: set errno if replica section is specified (pmem/issues#161) - cpp: change exception message (pmem/issues#163) - doc: remove duplicated words in man page (pmem/issues#164) - common: always append EXTRA_CFLAGS after our CFLAGS Experimental features: - Implementation of C++ bindings for libpmempobj is complete. Web-based documentation for C++ API is available on https://pmem.io. Note that C++ API is still considered experimental. Do not use it in production environments. - Porting NVML to Windows is in progress. There are MS Visual Studio solution/projects available, allowing to compile libpmem, libpmemlog, libpmemblk and libpmemobj on Windows, but the libraries are not fully functional and most of the test are not enabled yet. Thu Apr 07 2016 Krzysztof Czurylo * Version 1.0 The API of six libraries (libpmem, libpmemblk, libpmemlog, libpmemobj, libvmem, libvmmalloc) is complete and stable. The on-media layout of persistent memory pools will be maintained from this point, and if changed it will be backward compatible. Man pages are all complete. This release has been validated to "Production quality". For the purpose of new features planned for next releases of NVML there have been some API modifications made: - pmem: pmem_map replaced with pmem_map_file - log/blk: 'off_t' substituted with 'long long' - obj: type numbers extended to 64-bit - obj: new entry points and macros added: pmemobj_tx_errno, pmemobj_tx_lock, pmemobj_mutex_timedlock, TX_ADD_DIRECT, TX_ADD_FIELD_DIRECT, TX_SET_DIRECT Other key changes since version 0.4 include: - common: updated/fixed installation scripts - common: eliminated dependency on libuuid - pmem: CPU features/ISA detection using CPUID - obj: improved error handling - obj: atomic allocation fails if constructor returns error - obj: multiple performance optimizations - obj: object store refactoring - obj: additional examples and benchmarks This release also introduces a prototype implementation of C++ bindings for libpmemobj. Note that C++ API is still experimental and should not be used in production environments. Fri Dec 04 2015 Krzysztof Czurylo * Version 0.4 This NVML version primarily focuses on improving code quality and reliability. In addition to a couple of bug fixes, the changes include: - benchmarks for libpmemobj, libpmemblk and libvmem - additional pmemobj tests and examples - pool mapping address randomization - added pmempool "rm" command - eliminated libpmem dependency on libpthread - enabled extra warnings - minor performance improvements Man pages are all complete. This release is considered "Beta quality" by the team, having been thoroughly validated, including significant performance analysis. The pmempool command does not yet support "check" and "repair" operations for pmemobj type pools. Sun Sep 13 2015 Andy Rudoff * Version 0.3 NVML is now feature complete, adding support for: - pool sets - pmemobj local replication (active/passive) - experimental valgrind support - pmempool support for all pool types Man pages are all complete. This release is considered "Alpha quality" by the team, having gone through significant validation but only some performance analysis at this point. Tue Jun 30 2015 Andy Rudoff * Version 0.2 NVML now consists of six libraries: - libpmem (basic flushing, etc) - libpmemblk, libpmemlog, libpmemobj (transactions) - libvmem, libvmmalloc (volatile use of pmem) The "pmempool" command is available for managing pmem files. Man pages for all the above are complete. The only things documented in man pages but not implemented are: - pmem sets (ability to spread a pool over a set of files) - replication (coming for libpmemobj) The pmempool command does not yet support pmemobj type pools. Thu Sep 11 2014 Andy Rudoff * Version 0.1 Initial development done in 0.1 builds pmdk-1.11.1/.travis.yml0000664000000000000000000000164014123364546013350 0ustar rootrootos: linux dist: bionic arch: - ppc64le - arm64-graviton2 language: c services: - docker env: global: - GITHUB_REPO=pmem/pmdk - DOCKER_REPO=ghcr.io/pmem/pmdk - OS=ubuntu - OS_VER=20.04 - MAKE_PKG=0 - PMDK_CC=gcc - PMDK_CXX=g++ - REMOTE_TESTS=1 - VALGRIND=1 - SRC_CHECKERS=0 - EXPERIMENTAL=n jobs: - FAULT_INJECTION=1 TEST_BUILD=debug PUSH_IMAGE=1 - OS=fedora OS_VER=31 PMDK_CC=clang PMDK_CXX=clang++ TEST_BUILD=nondebug PUSH_IMAGE=1 - MAKE_PKG=1 REMOTE_TESTS=0 VALGRIND=0 - MAKE_PKG=1 REMOTE_TESTS=0 VALGRIND=0 OS=fedora OS_VER=31 - COVERAGE=1 FAULT_INJECTION=1 TEST_BUILD=debug before_install: - echo $TRAVIS_COMMIT_RANGE - export HOST_WORKDIR=`pwd` - cd utils/docker - ./pull-or-rebuild-image.sh script: - ./build-CI.sh after_success: - source ./set-vars.sh - if [[ -f $CI_FILE_PUSH_IMAGE_TO_REPO ]]; then ./images/push-image.sh; fi pmdk-1.11.1/res/0000775000000000000000000000000014123364546012027 5ustar rootrootpmdk-1.11.1/res/PMDK.ico0000664000000000000000000014751314123364546013271 0ustar rootroot2V(L2 h@@ (B#PNG  IHDR\rf2\IDATx]|~:hFA*"{ァV(ZP-C, pb/XVVn͑KK%wݽ^'eX9m5 8]Ɲ'tDĠ9Cێ3 3,?jY`5Y0bĨ"r3nyڢWS[$gr]O(z"FYq&D g#ObD)&L".C  cy,7{2&Cмwc 8w[%Ú ̆q,%#Fqp9#A\7Amh>Gh&b|n V,.D=)wd `HՋʣUBjw!ch(t:o\.'_YVXn2q?cl \h_\qO }0@,!Φi#LpOj#&LN]kݼlFZ qdd#FQϓ"w=4Og @p ڿY_w~D̶VUpMXbq0u.C8 "`\L-bMMJ; 1+oC@LCک؈@ <䤏@0P @@ |(ad #SV0[ @xIl8"#f:F/fY k`#F/]#F7Gxg_BbĈ4Ձ`N {x@\`w 7n!03owp_&ϳ95`W@G@xXn? =:{=3@0P @@ |(a > ‡aj%S<@p> srLKp&Q#JV( E//!9 w`[ %1?|q17!] )`1gg`tAdל!* ."FcFR"l\j4 j?5tx Ĩ}s/61`_-0+V[ZmMԃ;E~|(g4fD菠9[͡ǻ`v'Ε{a <8:}]?~mL{\nґ$6/³ _H0;~xkM`PI={`@ Np@BwpB+"܃qW[;)| ,1]eoOAp @hj^ &GJV 0 0@H?4 L&񑐘B@#߅&=jr=(nF9!,zٶDm3GE&7fѝY[;dZDN;'}n%h*8y u3[UY&Rsu-!\mVv.w3_pòSTUکa=u V\_O!ǝ״w}=JUw`VEpr}!-5-sT`K*>pV_%i^qPY[= Z nBM~ ׁHer0̺[aﶣc!qRFI;ֵC{:9} pxlyOB" ވ~s/oxI䉠9 JPzaݯ˨\,> {4 ,?! bWj[QIq8la,hcvո/`I6jo>9]wT8uCr%!Awo pp< `6*u <}\=S|</9iT|ƿ:ΕCq>KD?h&o6#L-N Mׅ\yseKsFz\<;DGls\-@#83ZRV;ꁙ_OzOgz' {օߖ}ywo{Qq$ FhX\weNBz8 ]W'q4jw^1]za+["H \ Lz?)#jNv **hd%Sآ9C_7.Σ8Z_7rU=d Ty]4x>u04t}~y)W*|pE6Bu"Y_2Đƞ2$wŠдO}(V&{YϏ!%%Y}U.I1!RcK5)xOw {)[ttBւ>}Y=Ry\愁ow9}^ȯwR HjJJ"-j@GTO>rAptg3z2YG@¿9нMǓ և Q#'7Et^yeN @/C]lO A 0%;.@ /:F=oeއ{N"xdTN9_$/$'@ܟw}$x7Erڍ8_>^P9+E{a-t'qY`?3fG/+/9kR&ye䄮[CpYڄZjTۧT}Nm3r'I?@9@l݁3Aidd]ݐnIEAz)2)_&m /ZNuwRP~1HT48I-->Ng}b[8uA,'rcrj;r8ٛԖJ=O~ qG4>J ph "b*PrpMb;մX 35B1[`It65?(ٿ$J,]tߊRxxwC}rM)V rE\Voe!MYeU9kߡYpr@șh.TU`Bv^m9m 0rM(P0?lz{"ˆDۗP[kelT++Ǭ+]xS[`ifawU$7fClMv<^+^=hv5f:9iI+9שTbE,}$cQ/ X6nnWUGh=Cg)-:3:-w?Rlo?.g[p}4 ̽e! >.MZ$sSRػfm,oN= kguj,O:Y۩q~Q/)jr.wBqe,We?I9yGFu?u& .=ޣ.l7mڛ@ݰ rW_ UNFl`/cvÉ\ M=Lȣ ´c ȻU %-̯e> o cVI/.@::BVַֺ `I msvTen炩sԧ2N/;~F}m0:;|p[+/Q"4te9C;`O@lR0ehE1%։?۴,(ui'4@]sM.?0gV`WTy%wh"Eufޗ=H^NI&?kҿ.LX?*,7}XUy 5cA@iBw#K8]*v&N y\ C_wRa2C9Ls5v'%C?-D3;S=mlGu X#v HCJ䳻R[2{^%,\`cqS?= R#osj #Z  ~ )G\W{ӗ՗=۳ g> gL>Ӄm -):VP_>{ס˝jiUy| Id?ۋ۱ ;Dk 2!|PߍŎ~z9Jךi6F0ݯ '⴩aVd82J{V {j[-'rHϝ/ GX[r@`jn!4R [S3hY-sp|[Y?9 c>8i)i9Hݥ5wCMA(g ֞=s3>:%g~o\o1-&w/B{S}F -4۽&m{j[5@\րY]o uhÔПTw]99+IG~Sqw9;!՛Vї`o;1!/gJ9줬;Zc H(P+WQoO{cԚ~nhsqeևz1qjȱmGDE%q ެ92*K@j P+;hz t(Y> Lΐ A.Q])sAbbmCv??s(P+gE򵛡'QWeVRvGv!s?NvRNV@]Œo>@Z}ȋ<50sj rVXF*/E 7B֥!Z}6mUGqQg/6[Dz࣓T.xg |} @lcJK`AZ([|Lm;HtcN3P7pb_x{`}n>CJ; .h0r0 F&j8!Ŝa:*P]WHW]n`X{ >p}_G2H?ȇ aԟL_\>㋁Or\ÂmG媕* W~ 7">FZ8 :v&yvڰ0@{mwyݗɒIl Nglr0eЦ_Km+B?344y]qYPz'A5`n=Uhq*LlK+ IвpGrQzY:E7PFSx(uC[j_p: :O?TT356rxT'z.HHu^k`ewot:(-dUc" ik֣ DB/~I=bєr#~3ߞ7v^~҆ehG8~;Y/*([ UY| ](@xd(4@Uo^_y S=研Zc19 h/uorU_XDa /3)F-}8-?VKnub F,v-V.Be|گJ|  ɤ*Ϳʫb?&:,T) k4g?&d(^(5LuEFz k2b.^UU&m&yzN;֕_."GenвW3fj,~YОdg8ʃKrB]uΟ;su2G.Ol24@ %̑-ރ4#>:|4X yd%-<䀐? D={B _L17wHh;~P<@_W95) .9aP؀prEYh PN@t;560qEckاiUh< 7h1Fad Qs;-/-g]u0|#rxp\)'5eV`g 1orbкo bK\ r9roXc٫Mki+o.r }?фp׮xp-K7QAG q|Ԕ;5@q@LB&z2!̷fM>壦,=@9/wך)Ȩ+A[ PH PnHC &ͺ7ӆ@EO+} m?*xr)5eȃ/9gaLʑK83'u@^͠Y.{0r~;G* wP:0{t;>p&v3[=Gus+>&yF] i`A k֯b^^fEACrc]?*eN wkfݎüW`'OI '.m'P:y=9#0Toͅ O*oNCB*@Ϫ,# e*3E\yr2Or!yB/i$ػ_{\$'T= sRtBײ2. ݆wVL [U y=4 vM+pڲU+HF$(!rڂ%gDrfT4h^s?ڍk*%j@K-BdJR+4mЕopJf Y#VC|v__Jo/НJ`@+roTO|D% Y{>߯ikAv}P6qfQB;B@5NR+sþدqhIM,tO|u6@b#%)ڗ|dpΊKU}`rM!:@fݜs/ҽbEr l/^q]F ߫@>-^HbT: Z x%o;DEgt|`hH7[/FhrȎPX2\Iȓa uz^1"j 4ބ*_^Ne{AxMe@/⳿Ռ|p#D kPCo@2!ș;'|}e *$;Os^Q$/D\Euݧg C|tGuׅBM Cj,玮9W{%꼐zxm*H|t!ժIOȷyKE֥l`ҀB#UbΦU߂']qn?WiӼላ7C/ٟ;i*H|/wZ.yV4;0c\8[\XAZ|jgt[=lq(q7_BrbۢwSM>Ar;QY F^#uBέU5dg÷?j5Ø#f5I'a_qmzvxnuDX>:nO=?N 7e~JJ,m 凪u^WׄiLtF4eԯбy"!uo2Pz EzZ^=a^RI>53w+ )9C߿mkd (^(#z ~0kbuL EB Wgbw15cadПS^mKW`lg5 zcZY]6\NO#+3uX/Oy g!jlˌL|tT]\QZ7\J*ms!zbsWx4sӡBrzY3aYD@|xrԬ.zZ}f5ݷsU(\P1c\rs 7m\/S=Rȗh~;']ycB Otn!>qQZY'93H)B@nccA+u#W=UGpFJZPT"$x)\7[H|tt(WtH|/'>::C+ :$ !ˉ@BGAB`zE!@rп@!0d@{9~^Q o?P Y(^N|tt(WtH|/'>::C+ :$ !ˉ@cj^591 18w0:n} K/'  SWX_EB`zE!p}(U$&f$>]a`Z9muG[^Q\.LkiE#uN>ޤ,i})Cꏰ^o$>*VGVd {G :#+ kd]hmMOMG#x1I$ Aϱv@!-!@vѢGSfz'GOd60 #M(<ʉܳ6 hS5a!W"xB;U9&GQO]@Gv3DF{/]4f|>MO tm䩿g#.*_gw5r$g-:mca8Xf ksG Q:Oh$6#PXp1 1.o('RdvU;!T"2-xpHk7!6?Dcol@(Y/[ F9_sVIENDB`(D <I >G?G@K @M@IAQBSDUDYFXFPB[H]H[H]I_L[JH@JBKDLDNF\L]OUKPIVL`I`L` Me Qb PhTeShTiW`QaSeUaTfWmYgXjXlYo\o]p^S KS!LV%OW&P\&SY)R[+T\,U^/X_0Xg&[i!Zm"]n$^n)_a2Zf3^c5\d5\o%`q!`u!ar%au&cs,dx*fz.h}.kh5`i=cv4h{0k~2mv;j|s=tBuDxJyK{K}H}L~ZzX|^}\~``\PSVXZ_\]b`eghjm`jrtbfhkmlvz|fmosvy{~}£ĨƬȫijƵ˰ͱ̶ɺαͶʻϺ˼̽οеѺԻսbE3Dbssqqsoqs`aEE339ͯBDWboBߪX84<56<39Y9bDoVqqV:WPPs:V`as:V:<s:Vqsq:Vs:Vs:Vqts:V:̂43;q:VZZs;V_bs:Vs:VPVs: c\ Ys F%c xH#c# 4 xH%ee,,X xH#cwxH%e wN#S  m#  %  !# 7*S}0%v,M %!Jd%JgLv2%J}R%&GI/ %hiM$Jh1$ihf"$.lh h/nf$$z.   $          yI$       ?     $I F$       K      yŔ) @)     " @k||hK )K k j )  )  jU 'UQ j  >  j        >j         \ +         Uk         A K ȟ' T \ T u*  ( =ԅ  Tŭu*                                                                                                                                                                                                                                    CO^aprqooqq]`EE`??( @D <I >G?J @M@PBSDUEYFWGR E]H]JX HIANFWJZM`J`KbLaL` Ma MeRh SbPhVgVcUnZn[jYV$NY)R[*T^/Xh'[m(^a2Ze1\b4\d5\s#at ar&`q*bt(cu-eg;ah;au1gv9jz;moDhrIltKn}@qwNq|Uv3n:s=r?tDu@wEzJ|QT}^}OV_aeg`otejmvxz~nnwzx Ȭ̮̽г־/P"p0>M[iy1Qqұ/Pp  >1\Qzq/Pp!+6@IZ1pQq/ P6pLbx1Qq,/KPip1Qq/-P?pRcv1Qqϑܱ/Pp!&,>X1qQq(**+%kq;7VP92  ,  D  JY |m pw YQ@] NY 0bD?n b NY . 1^gSv RR 1!     iE oA  4/    :6 [}   _5  Fvj&         )+((( D <J ?F>M AQBTDXFXG\H]I^ MH@KCLDQFQG]NaLgWhVmZkYo\r_S KZ)Sm#]b4[d6]n0b{2j}0l|4llAfnChqGk{BosJmuMo~Bq|VwUx9r>v@rAvFzJyY|SitlrrvzäǩǷ̾ϼж  =1[Qyq/"P0p=LYgx1Qq&/@PZpt1Qq/&PAp[tϩ1Qq/P"p0>M[iy1Qqұ/Pp  >1\Qzq/Pp!+6@IZ1pQq/ P6pLbx1Qq,/KPip1Qq/-P?pRcv1Qqϑܱ/Pp!&,>X1qQq   3"&L6G2?%#I!<(BP O;HAE <)CQ NM=0:7RD**- M@MS D .87-  ,J/>1/4F9M'$5 (@ F<3E =D D dD D L @_ L\H_Ip]}`J`J`JTWFVESCOAK ?H >E ɫ`I`J`JdO`J`Jq]}`J`J`Jr_`J`J`J`J`J`J`J\HWEd"WD D H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H >H ?H ?5G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >G >F <3E /dev/null && echo y || echo n), y) export CLANG_FORMAT ?= clang-format-9 else export CLANG_FORMAT ?= clang-format endif endif ifeq ($(FLAKE8),) export FLAKE8 ?= flake8 endif GCOV_CFLAGS=-fprofile-arcs -ftest-coverage --coverage GCOV_LDFLAGS=-fprofile-arcs -ftest-coverage GCOV_LIBS=-lgcov LIBS += $(EXTRA_LIBS) ifeq ($(OS_KERNEL_NAME),) export OS_KERNEL_NAME := $(shell uname -s) endif osdep = $(1)_$(shell echo $(OS_KERNEL_NAME) | tr "[:upper:]" "[:lower:]")$(2) get_arch = $(shell $(CC) -dumpmachine | awk -F'[/-]' '{print $$1}') ifeq ($(ARCH),) export ARCH := $(call get_arch) endif ifeq ($(ARCH),amd64) override ARCH := x86_64 endif ifeq ($(ARCH),arm64) override ARCH := aarch64 endif ifneq ($(filter $(ARCH), powerpc64 powerpc64le ppc64 ppc64le ppc64el powerpc),) override ARCH := ppc64 endif ifeq ($(PKG_CONFIG_CHECKED),) ifeq ($(shell command -v $(PKG_CONFIG) && echo y || echo n), n) $(error $(PKG_CONFIG) not found) endif endif export PKG_CONFIG_CHECKED := y check_package = $(shell $(PKG_CONFIG) $(1) && echo y || echo n) check_flag = $(shell echo "int main(){return 0;}" |\ $(CC) $(CFLAGS) -Werror $(1) -x c -o /dev/null - 2>/dev/null && echo y || echo n) check_compiler = $(shell $(CC) --version | grep $(1) && echo y || echo n) check_Wconversion = $(shell echo "long random(void); char test(void); char test(void){char a = 0; char b = 'a'; char ret = random() == 1 ? a : b; return ret;}" |\ $(CC) -c $(CFLAGS) -Wconversion -x c -o /dev/null - 2>/dev/null && echo y || echo n) check_librt = $(shell echo "int main() { struct timespec t; return clock_gettime(CLOCK_MONOTONIC, &t); }" |\ $(CC) $(CFLAGS) -x c -include time.h -o /dev/null - 2>/dev/null && echo n || echo y) # XXX: required by clock_gettime(), if glibc version < 2.17 # The os_clock_gettime() function is now in OS abstraction layer, # linked to all the librariess, unit tests and benchmarks. ifeq ($(LIBRT_NEEDED),) export LIBRT_NEEDED := $(call check_librt) else export LIBRT_NEEDED endif ifeq ($(IS_ICC),) export IS_ICC := $(call check_compiler, icc) else export IS_ICC endif ifeq ($(WCONVERSION_AVAILABLE),) export WCONVERSION_AVAILABLE := $(call check_Wconversion) else export WCONVERSION_AVAILABLE endif ifeq ($(WUNREACHABLE_CODE_RETURN_AVAILABLE),) ifeq ($(IS_ICC), n) export WUNREACHABLE_CODE_RETURN_AVAILABLE := $(call check_flag, -Wunreachable-code-return) else export WUNREACHABLE_CODE_RETURN_AVAILABLE := n endif else export WUNREACHABLE_CODE_RETURN_AVAILABLE endif ifeq ($(WMISSING_VARIABLE_DECLARATIONS_AVAILABLE),) ifeq ($(IS_ICC), n) export WMISSING_VARIABLE_DECLARATIONS_AVAILABLE := $(call check_flag, -Wmissing-variable-declarations) else export WMISSING_VARIABLE_DECLARATIONS_AVAILABLE := n endif else export WMISSING_VARIABLE_DECLARATIONS_AVAILABLE endif ifeq ($(WFLOAT_EQUAL_AVAILABLE),) ifeq ($(IS_ICC), n) export WFLOAT_EQUAL_AVAILABLE := $(call check_flag, -Wfloat-equal) else export WFLOAT_EQUAL_AVAILABLE := n endif else export WFLOAT_EQUAL_AVAILABLE endif ifeq ($(WSWITCH_DEFAULT_AVAILABLE),) ifeq ($(IS_ICC), n) export WSWITCH_DEFAULT_AVAILABLE := $(call check_flag, -Wswitch-default) else export WSWITCH_DEFAULT_AVAILABLE := n endif else export WSWITCH_DEFAULT_AVAILABLE endif ifeq ($(WCAST_FUNCTION_TYPE_AVAILABLE),) ifeq ($(IS_ICC), n) export WCAST_FUNCTION_TYPE_AVAILABLE := $(call check_flag, -Wcast-function-type) else export WCAST_FUNCTION_TYPE_AVAILABLE := n endif else export WCAST_FUNCTION_TYPE_AVAILABLE endif ifeq ($(WSTRINGOP_TRUNCATION_AVAILABLE),) export WSTRINGOP_TRUNCATION_AVAILABLE := $(call check_flag, -Wstringop-truncation) else export WSTRINGOP_TRUNCATION_AVAILABLE endif ifeq ($(OG_AVAILABLE),) export OG_AVAILABLE := $(call check_flag, -Og) else export OG_AVAILABLE endif install_recursive = $(shell cd $(1) && find . -type f -exec install -m $(2) -D {} $(3)/{} \;) install_recursive_filter = $(shell cd $(1) && find . -type f -name "$(2)" -exec install -m $(3) -D {} $(4)/{} \;) define create-deps @cp $(objdir)/$*.d $(objdir)/.deps/$*.P; \ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ -e '/^$$/ d' -e 's/$$/ :/' < $(objdir)/$*.d >> $(objdir)/.deps/$*.P; \ $(RM) -f $(objdir)/$*.d endef check_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2))))) __check_defined = \ $(if $(value $1),, \ $(error Undefined $1$(if $2, ($2)))) export prefix = /usr/local export exec_prefix := $(prefix) export sysconfdir := $(prefix)/etc export datarootdir := $(prefix)/share export mandir := $(datarootdir)/man export docdir := $(datarootdir)/doc export man1dir := $(mandir)/man1 export man3dir := $(mandir)/man3 export man5dir := $(mandir)/man5 export man7dir := $(mandir)/man7 export cstyle_bin := $(CSTYLE) export clang_format_bin := $(CLANG_FORMAT) export flake8_bin := $(FLAKE8) ifneq ($(wildcard $(exec_prefix)/x86_64-linux-gnu),) LIB_PREFIX ?= x86_64-linux-gnu/lib endif ifneq ($(wildcard $(exec_prefix)/lib64),) LIB_PREFIX ?= lib64 endif LIB_PREFIX ?= lib all: cstyle-%: $(STYLE_CHECK) $* $(wildcard *.[ch]) $(wildcard *.[ch]pp) $(wildcard *.py) cstyle: cstyle-check format: cstyle-format ifeq ($(CSTYLEON),1) define check-cstyle @$(STYLE_CHECK) check $1 && if [ "$2" != "" ]; then mkdir -p `dirname $2` && touch $2; fi endef else ifeq ($(CSTYLEON),2) define check-cstyle @$(STYLE_CHECK) check $1 && if [ "$2" != "" ]; then mkdir -p `dirname $2` && touch $2; fi || true endef else define check-cstyle endef endif define check-os $(CHECK_OS) $(OS_BANNED) $(1) $(2) endef # XXX: to allow gcov tool to connect coverage with source code, we have to # use absolute path to source files ifeq ($(COVERAGE),1) define coverage-path `readlink -f $(1)` endef else define coverage-path $(1) endef endif define sub-target-foreach $(1)-$(2): $$(MAKE) -C $1 $2 ifeq ($(3),y) ifeq ($(custom_build),) $$(MAKE) -C $1 $2 DEBUG=1 endif endif endef define sub-target $(foreach f, $(1), $(eval $(call sub-target-foreach, $f,$(2),$(3)))) endef ifneq ($(wildcard $(prefix)/x86_64-linux-gnu),) INC_PREFIX ?= x86_64-linux-gnu/include endif INC_PREFIX ?= include test_build=$(addprefix "-b ", $(TEST_BUILD)) test_type=$(addprefix " -t ", $(TEST_TYPE)) test_fs=$(addprefix " -f ", $(TEST_FS)) test_time=$(addprefix " -o ", $(TEST_TIME)) test_memcheck=$(addprefix " -m ", $(MEMCHECK)) test_pmemcheck=$(addprefix " -p ", $(PMEMCHECK)) test_helgrind=$(addprefix " -e ", $(HELGRIND)) test_drd=$(addprefix " -d ", $(DRD)) test_providers=$(addprefix " -q ", $(TEST_PROVIDERS)) test_pmethods=$(addprefix " -r ", $(TEST_PMETHODS)) ifeq ($(CHECK_POOL),y) test_check_pool=" -c " endif RUNTEST_OPTIONS := "$(test_build)$(test_type)$(test_fs)$(test_time)" RUNTEST_OPTIONS += "$(test_memcheck)$(test_pmemcheck)$(test_helgrind)$(test_drd)" RUNTEST_OPTIONS += "$(test_providers)$(test_pmethods)$(test_check_pool)" export libdir := $(exec_prefix)/$(LIB_PREFIX) export includedir := $(prefix)/$(INC_PREFIX) export pkgconfigdir := $(libdir)/pkgconfig export bindir := $(exec_prefix)/bin export bashcompdir := $(sysconfdir)/bash_completion.d LIBFABRIC_MIN_VERSION := 1.4.2 # Keep in sync with requirements in src/test/unittest/unittest.sh and # utils/docker/images/install-libfabric.sh. ifeq ($(BUILD_RPMEM),) BUILD_RPMEM := $(call check_package, libfabric --atleast-version=$(LIBFABRIC_MIN_VERSION)) endif ifneq ($(BUILD_RPMEM),y) export BUILD_RPMEM_INFO := libfabric (version >= $(LIBFABRIC_MIN_VERSION)) is missing -- \ see src/librpmem/README for details else LIBFABRIC_CFLAGS := $(shell $(PKG_CONFIG) --cflags libfabric) LIBFABRIC_LD_LIBRARY_PATHS := $(shell $(PKG_CONFIG) --variable=libdir libfabric) LIBFABRIC_LIBS := $(shell $(PKG_CONFIG) --libs libfabric) LIBFABRIC_PATH := $(shell $(PKG_CONFIG) --variable=exec_prefix libfabric)/bin endif export BUILD_RPMEM export LIBFABRIC_CFLAGS export LIBFABRIC_LD_LIBRARY_PATHS export LIBFABRIC_LIBS export LIBFABRIC_PATH # unsafe shutdown count and badblock access without root (depends on kernel 4.20) NDCTL_MIN_VERSION := 63 sparse-c = $(shell for c in *.c; do sparse -Wsparse-all -Wno-declaration-after-statement $(CFLAGS) $(INCS) $$c || true; done) ifeq ($(USE_LIBUNWIND),) export USE_LIBUNWIND := $(call check_package, libunwind) ifeq ($(USE_LIBUNWIND),y) export LIBUNWIND_LIBS := $(shell $(PKG_CONFIG) --libs libunwind) endif else export USE_LIBUNWIND export LIBUNWIND_LIBS endif ifeq ($(OS_KERNEL_NAME),FreeBSD) GLIBC_CXXFLAGS=-D_GLIBCXX_USE_C99 UNIX98_CFLAGS= OS_INCS=-I$(TOP)/src/freebsd/include -I/usr/local/include OS_LIBS=-L/usr/local/lib LIBDL= LIBUTIL=-lutil LIBUUID=-luuid LIBNDCTL= OS_DIMM=none else GLIBC_CXXFLAGS= UNIX98_CFLAGS=-D__USE_UNIX98 OS_INCS= OS_LIBS= LIBDL=-ldl LIBUTIL= LIBUUID= NDCTL_ENABLE ?= y # Detect libndctl if not disabled. ifeq ($(NDCTL_ENABLE),y) ifeq ($(LIBNDCTL_LIBS),) HAS_NDCTL := $(call check_package, libndctl --atleast-version $(NDCTL_MIN_VERSION)) ifeq ($(HAS_NDCTL),y) OS_DIMM_CFLAG=-DNDCTL_ENABLED=1 else $(error Please install libndctl-dev/libndctl-devel >= $(NDCTL_MIN_VERSION)) endif HAS_DAXCTL := $(call check_package, libdaxctl --atleast-version $(NDCTL_MIN_VERSION)) ifeq ($(HAS_DAXCTL),n) $(error Please install libdaxctl-dev/libdaxctl-devel >= $(NDCTL_MIN_VERSION)) endif LIBNDCTL_PKG_CONFIG_DEPS := libndctl libdaxctl LIBNDCTL_PKG_CONFIG_DEPS_VAR := ,libndctl,libdaxctl LIBNDCTL_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(LIBNDCTL_PKG_CONFIG_DEPS)) LIBNDCTL_LD_LIBRARY_PATHS := $(shell $(PKG_CONFIG) --variable=libdir $(LIBNDCTL_PKG_CONFIG_DEPS) | sed "s/ /:/") LIBNDCTL_LIBS := $(shell $(PKG_CONFIG) --libs $(LIBNDCTL_PKG_CONFIG_DEPS)) endif OS_DIMM := ndctl else OS_DIMM := none endif export OS_DIMM export LIBNDCTL_PKG_CONFIG_DEPS export LIBNDCTL_PKG_CONFIG_DEPS_VAR export LIBNDCTL_CFLAGS export LIBNDCTL_LD_LIBRARY_PATHS export LIBNDCTL_LIBS export OS_DIMM_CFLAG endif pmdk-1.11.1/src/libpmempool/0000775000000000000000000000000014123364546014344 5ustar rootrootpmdk-1.11.1/src/libpmempool/pool.c0000664000000000000000000006024214123364546015465 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * pool.c -- pool processing functions */ #include #include #include #include #include #include #ifndef _WIN32 #include #ifdef __FreeBSD__ #include #define BLKGETSIZE64 DIOCGMEDIASIZE #else #include #endif #endif #include "libpmem.h" #include "libpmemlog.h" #include "libpmemblk.h" #include "libpmempool.h" #include "out.h" #include "pmempool.h" #include "pool.h" #include "lane.h" #include "obj.h" #include "btt.h" #include "file.h" #include "os.h" #include "set.h" #include "check_util.h" #include "util_pmem.h" #include "mmap.h" /* arbitrary size of a maximum file part being read / write at once */ #define RW_BUFFERING_SIZE (128 * 1024 * 1024) /* * pool_btt_lseek -- (internal) perform lseek in BTT file mode */ static inline os_off_t pool_btt_lseek(struct pool_data *pool, os_off_t offset, int whence) { os_off_t result; if ((result = os_lseek(pool->set_file->fd, offset, whence)) == -1) ERR("!lseek"); return result; } /* * pool_btt_read -- (internal) perform read in BTT file mode */ static inline ssize_t pool_btt_read(struct pool_data *pool, void *dst, size_t count) { size_t total = 0; ssize_t nread; while (count > total && (nread = util_read(pool->set_file->fd, dst, count - total))) { if (nread == -1) { ERR("!read"); return total ? (ssize_t)total : -1; } dst = (void *)((ssize_t)dst + nread); total += (size_t)nread; } return (ssize_t)total; } /* * pool_btt_write -- (internal) perform write in BTT file mode */ static inline ssize_t pool_btt_write(struct pool_data *pool, const void *src, size_t count) { ssize_t nwrite = 0; size_t total = 0; while (count > total && (nwrite = util_write(pool->set_file->fd, src, count - total))) { if (nwrite == -1) { ERR("!write"); return total ? (ssize_t)total : -1; } src = (void *)((ssize_t)src + nwrite); total += (size_t)nwrite; } return (ssize_t)total; } /* * pool_set_read_header -- (internal) read a header of a pool set */ static int pool_set_read_header(const char *fname, struct pool_hdr *hdr) { struct pool_set *set; int ret = 0; if (util_poolset_read(&set, fname)) { return -1; } /* open the first part set file to read the pool header values */ const struct pool_set_part *part = PART(REP(set, 0), 0); int fdp = util_file_open(part->path, NULL, 0, O_RDONLY); if (fdp < 0) { ERR("cannot open poolset part file"); ret = -1; goto err_pool_set; } /* read the pool header from first pool set file */ if (pread(fdp, hdr, sizeof(*hdr), 0) != sizeof(*hdr)) { ERR("cannot read pool header from poolset"); ret = -1; goto err_close_part; } err_close_part: os_close(fdp); err_pool_set: util_poolset_free(set); return ret; } /* * pool_set_map -- (internal) map poolset */ static int pool_set_map(const char *fname, struct pool_set **poolset, unsigned flags) { ASSERTeq(util_is_poolset_file(fname), 1); struct pool_hdr hdr; if (pool_set_read_header(fname, &hdr)) return -1; util_convert2h_hdr_nocheck(&hdr); /* parse pool type from first pool set file */ enum pool_type type = pool_hdr_get_type(&hdr); if (type == POOL_TYPE_UNKNOWN) { ERR("cannot determine pool type from poolset"); return -1; } /* * Open the poolset, the values passed to util_pool_open are read * from the first poolset file, these values are then compared with * the values from all headers of poolset files. */ struct pool_attr attr; util_pool_hdr2attr(&attr, &hdr); if (util_pool_open(poolset, fname, 0 /* minpartsize */, &attr, NULL, NULL, flags | POOL_OPEN_IGNORE_SDS | POOL_OPEN_IGNORE_BAD_BLOCKS)) { ERR("opening poolset failed"); return -1; } return 0; } /* * pool_params_from_header -- parse pool params from pool header */ void pool_params_from_header(struct pool_params *params, const struct pool_hdr *hdr) { memcpy(params->signature, hdr->signature, sizeof(params->signature)); memcpy(¶ms->features, &hdr->features, sizeof(params->features)); /* * Check if file is a part of pool set by comparing the UUID with the * next part UUID. If it is the same it means the pool consist of a * single file. */ int uuid_eq_next = uuidcmp(hdr->uuid, hdr->next_part_uuid); int uuid_eq_prev = uuidcmp(hdr->uuid, hdr->prev_part_uuid); params->is_part = !params->is_poolset && (uuid_eq_next || uuid_eq_prev); params->type = pool_hdr_get_type(hdr); } /* * pool_check_type_to_pool_type -- (internal) convert check pool type to * internal pool type value */ static enum pool_type pool_check_type_to_pool_type(enum pmempool_pool_type check_pool_type) { switch (check_pool_type) { case PMEMPOOL_POOL_TYPE_LOG: return POOL_TYPE_LOG; case PMEMPOOL_POOL_TYPE_BLK: return POOL_TYPE_BLK; case PMEMPOOL_POOL_TYPE_OBJ: return POOL_TYPE_OBJ; default: ERR("can not convert pmempool_pool_type %u to pool_type", check_pool_type); return POOL_TYPE_UNKNOWN; } } /* * pool_parse_params -- parse pool type, file size and block size */ static int pool_params_parse(const PMEMpoolcheck *ppc, struct pool_params *params, int check) { LOG(3, NULL); int is_btt = ppc->args.pool_type == PMEMPOOL_POOL_TYPE_BTT; params->type = POOL_TYPE_UNKNOWN; params->is_poolset = util_is_poolset_file(ppc->path) == 1; int fd = util_file_open(ppc->path, NULL, 0, O_RDONLY); if (fd < 0) return -1; int ret = 0; os_stat_t stat_buf; ret = os_fstat(fd, &stat_buf); if (ret) goto out_close; ASSERT(stat_buf.st_size >= 0); params->mode = stat_buf.st_mode; struct pool_set *set; void *addr; if (params->is_poolset) { /* * Need to close the poolset because it will be opened with * flock in the following instructions. */ os_close(fd); fd = -1; if (check) { if (pool_set_map(ppc->path, &set, 0)) return -1; } else { ret = util_poolset_create_set(&set, ppc->path, 0, 0, true); if (ret < 0) { LOG(2, "cannot open pool set -- '%s'", ppc->path); return -1; } if (set->remote) { ERR("poolsets with remote replicas are not " "supported"); return -1; } if (util_pool_open_nocheck(set, POOL_OPEN_IGNORE_BAD_BLOCKS)) return -1; } params->size = set->poolsize; addr = set->replica[0]->part[0].addr; /* * XXX mprotect for device dax with length not aligned to its * page granularity causes SIGBUS on the next page fault. * The length argument of this call should be changed to * set->poolsize once the kernel issue is solved. */ if (mprotect(addr, set->replica[0]->repsize, PROT_READ) < 0) { ERR("!mprotect"); goto out_unmap; } params->is_dev_dax = set->replica[0]->part[0].is_dev_dax; params->is_pmem = set->replica[0]->is_pmem; } else if (is_btt) { params->size = (size_t)stat_buf.st_size; #ifndef _WIN32 if (params->mode & S_IFBLK) if (ioctl(fd, BLKGETSIZE64, ¶ms->size)) { ERR("!ioctl"); goto out_close; } #endif addr = NULL; } else { enum file_type type = util_file_get_type(ppc->path); if (type < 0) { ret = -1; goto out_close; } ssize_t s = util_file_get_size(ppc->path); if (s < 0) { ret = -1; goto out_close; } params->size = (size_t)s; int map_sync; addr = util_map(fd, 0, params->size, MAP_SHARED, 1, 0, &map_sync); if (addr == NULL) { ret = -1; goto out_close; } params->is_dev_dax = type == TYPE_DEVDAX; params->is_pmem = params->is_dev_dax || map_sync || pmem_is_pmem(addr, params->size); } /* stop processing for BTT device */ if (is_btt) { params->type = POOL_TYPE_BTT; params->is_part = false; goto out_close; } struct pool_hdr hdr; memcpy(&hdr, addr, sizeof(hdr)); util_convert2h_hdr_nocheck(&hdr); pool_params_from_header(params, &hdr); if (ppc->args.pool_type != PMEMPOOL_POOL_TYPE_DETECT) { enum pool_type declared_type = pool_check_type_to_pool_type(ppc->args.pool_type); if ((params->type & ~declared_type) != 0) { ERR("declared pool type does not match"); errno = EINVAL; ret = 1; goto out_unmap; } } if (params->type == POOL_TYPE_BLK) { struct pmemblk pbp; memcpy(&pbp, addr, sizeof(pbp)); params->blk.bsize = le32toh(pbp.bsize); } else if (params->type == POOL_TYPE_OBJ) { struct pmemobjpool *pop = addr; memcpy(params->obj.layout, pop->layout, PMEMOBJ_MAX_LAYOUT); } out_unmap: if (params->is_poolset) { ASSERTeq(fd, -1); ASSERTne(addr, NULL); util_poolset_close(set, DO_NOT_DELETE_PARTS); } else if (!is_btt) { ASSERTne(fd, -1); ASSERTne(addr, NULL); munmap(addr, params->size); } out_close: if (fd != -1) os_close(fd); return ret; } /* * pool_set_file_open -- (internal) opens pool set file or regular file */ static struct pool_set_file * pool_set_file_open(const char *fname, struct pool_params *params, int rdonly) { LOG(3, NULL); struct pool_set_file *file = calloc(1, sizeof(*file)); if (!file) return NULL; file->fname = strdup(fname); if (!file->fname) goto err; const char *path = file->fname; if (params->type != POOL_TYPE_BTT) { int ret = util_poolset_create_set(&file->poolset, path, 0, 0, true); if (ret < 0) { LOG(2, "cannot open pool set -- '%s'", path); goto err_free_fname; } unsigned flags = (rdonly ? POOL_OPEN_COW : 0) | POOL_OPEN_IGNORE_BAD_BLOCKS; if (util_pool_open_nocheck(file->poolset, flags)) goto err_free_fname; file->size = file->poolset->poolsize; /* get modification time from the first part of first replica */ path = file->poolset->replica[0]->part[0].path; file->addr = file->poolset->replica[0]->part[0].addr; } else { int oflag = rdonly ? O_RDONLY : O_RDWR; file->fd = util_file_open(fname, NULL, 0, oflag); file->size = params->size; } os_stat_t buf; if (os_stat(path, &buf)) { ERR("%s", path); goto err_close_poolset; } file->mtime = buf.st_mtime; file->mode = buf.st_mode; return file; err_close_poolset: if (params->type != POOL_TYPE_BTT) util_poolset_close(file->poolset, DO_NOT_DELETE_PARTS); else if (file->fd != -1) os_close(file->fd); err_free_fname: free(file->fname); err: free(file); return NULL; } /* * pool_set_parse -- parse poolset file */ int pool_set_parse(struct pool_set **setp, const char *path) { LOG(3, "setp %p path %s", setp, path); int fd = os_open(path, O_RDONLY); int ret = 0; if (fd < 0) return 1; if (util_poolset_parse(setp, path, fd)) { ret = 1; goto err_close; } err_close: os_close(fd); return ret; } /* * pool_data_alloc -- allocate pool data and open set_file */ struct pool_data * pool_data_alloc(PMEMpoolcheck *ppc) { LOG(3, NULL); struct pool_data *pool = calloc(1, sizeof(*pool)); if (!pool) { ERR("!calloc"); return NULL; } PMDK_TAILQ_INIT(&pool->arenas); pool->uuid_op = UUID_NOP; if (pool_params_parse(ppc, &pool->params, 0)) goto error; int rdonly = CHECK_IS_NOT(ppc, REPAIR); int prv = CHECK_IS(ppc, DRY_RUN); if (prv && pool->params.is_dev_dax) { errno = ENOTSUP; ERR("!cannot perform a dry run on dax device"); goto error; } pool->set_file = pool_set_file_open(ppc->path, &pool->params, prv); if (pool->set_file == NULL) goto error; /* * XXX mprotect for device dax with length not aligned to its * page granularity causes SIGBUS on the next page fault. * The length argument of this call should be changed to * pool->set_file->poolsize once the kernel issue is solved. */ if (rdonly && mprotect(pool->set_file->addr, pool->set_file->poolset->replica[0]->repsize, PROT_READ) < 0) goto error; if (pool->params.type != POOL_TYPE_BTT) { if (pool_set_file_map_headers(pool->set_file, rdonly, prv)) goto error; } return pool; error: pool_data_free(pool); return NULL; } /* * pool_set_file_close -- (internal) closes pool set file or regular file */ static void pool_set_file_close(struct pool_set_file *file) { LOG(3, NULL); if (file->poolset) util_poolset_close(file->poolset, DO_NOT_DELETE_PARTS); else if (file->addr) { munmap(file->addr, file->size); os_close(file->fd); } else if (file->fd) os_close(file->fd); free(file->fname); free(file); } /* * pool_data_free -- close set_file and release pool data */ void pool_data_free(struct pool_data *pool) { LOG(3, NULL); if (pool->set_file) { if (pool->params.type != POOL_TYPE_BTT) pool_set_file_unmap_headers(pool->set_file); pool_set_file_close(pool->set_file); } while (!PMDK_TAILQ_EMPTY(&pool->arenas)) { struct arena *arenap = PMDK_TAILQ_FIRST(&pool->arenas); if (arenap->map) free(arenap->map); if (arenap->flog) free(arenap->flog); PMDK_TAILQ_REMOVE(&pool->arenas, arenap, next); free(arenap); } free(pool); } /* * pool_set_file_map -- return mapped address at given offset */ void * pool_set_file_map(struct pool_set_file *file, uint64_t offset) { if (file->addr == MAP_FAILED) return NULL; return (char *)file->addr + offset; } /* * pool_read -- read from pool set file or regular file * * 'buff' has to be a buffer at least 'nbytes' long * 'off' is an offset from the beginning of the pool */ int pool_read(struct pool_data *pool, void *buff, size_t nbytes, uint64_t off) { if (off + nbytes > pool->set_file->size) return -1; if (pool->params.type != POOL_TYPE_BTT) memcpy(buff, (char *)pool->set_file->addr + off, nbytes); else { if (pool_btt_lseek(pool, (os_off_t)off, SEEK_SET) == -1) return -1; if ((size_t)pool_btt_read(pool, buff, nbytes) != nbytes) return -1; } return 0; } /* * pool_write -- write to pool set file or regular file * * 'buff' has to be a buffer at least 'nbytes' long * 'off' is an offset from the beginning of the pool */ int pool_write(struct pool_data *pool, const void *buff, size_t nbytes, uint64_t off) { if (off + nbytes > pool->set_file->size) return -1; if (pool->params.type != POOL_TYPE_BTT) { memcpy((char *)pool->set_file->addr + off, buff, nbytes); util_persist_auto(pool->params.is_pmem, (char *)pool->set_file->addr + off, nbytes); } else { if (pool_btt_lseek(pool, (os_off_t)off, SEEK_SET) == -1) return -1; if ((size_t)pool_btt_write(pool, buff, nbytes) != nbytes) return -1; } return 0; } /* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path, int overwrite) { struct pool_set_file *file = pool->set_file; int dfd; int exists = util_file_exists(dst_path); if (exists < 0) return -1; if (exists) { if (!overwrite) { errno = EEXIST; return -1; } dfd = util_file_open(dst_path, NULL, 0, O_RDWR); } else { errno = 0; dfd = util_file_create(dst_path, file->size, 0); } if (dfd < 0) return -1; int result = 0; os_stat_t stat_buf; if (os_stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } if (pool_btt_lseek(pool, 0, SEEK_SET) == -1) { result = -1; goto out_free; } ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } out_free: free(buf); out_unmap: munmap(daddr, file->size); out_close: (void) os_close(dfd); return result; } /* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart, int overwrite) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; os_stat_t stat_buf; if (os_fstat(spart->fd, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr; int exists = util_file_exists(dpart->path); if (exists < 0) { result = -1; goto out_sunmap; } if (exists) { if (!overwrite) { errno = EEXIST; result = -1; goto out_sunmap; } daddr = pmem_map_file(dpart->path, 0, 0, S_IWRITE, &dmapped, &is_pmem); } else { errno = 0; daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); } if (!daddr) { result = -1; goto out_sunmap; } #ifdef DEBUG /* provide extra logging in case of wrong dmapped/smapped value */ if (dmapped < smapped) { LOG(1, "dmapped < smapped: dmapped = %lu, smapped = %lu", dmapped, smapped); ASSERT(0); } #endif if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); pmem_msync(daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; } /* * pool_memset -- memset pool part described by off and count */ int pool_memset(struct pool_data *pool, uint64_t off, int c, size_t count) { int result = 0; if (pool->params.type != POOL_TYPE_BTT) memset((char *)off, 0, count); else { if (pool_btt_lseek(pool, (os_off_t)off, SEEK_SET) == -1) return -1; size_t zero_size = min(count, RW_BUFFERING_SIZE); void *buf = malloc(zero_size); if (!buf) { ERR("!malloc"); return -1; } memset(buf, c, zero_size); ssize_t nwrite = 0; do { zero_size = min(zero_size, count); nwrite = pool_btt_write(pool, buf, zero_size); if (nwrite < 0) { result = -1; break; } count -= (size_t)nwrite; } while (count > 0); free(buf); } return result; } /* * pool_set_files_count -- get total number of parts of all replicas */ unsigned pool_set_files_count(struct pool_set_file *file) { unsigned ret = 0; unsigned nreplicas = file->poolset->nreplicas; for (unsigned r = 0; r < nreplicas; r++) { struct pool_replica *rep = file->poolset->replica[r]; ret += rep->nparts; } return ret; } /* * pool_set_file_map_headers -- map headers of each pool set part file */ int pool_set_file_map_headers(struct pool_set_file *file, int rdonly, int prv) { if (!file->poolset) return -1; for (unsigned r = 0; r < file->poolset->nreplicas; r++) { struct pool_replica *rep = file->poolset->replica[r]; for (unsigned p = 0; p < rep->nparts; p++) { struct pool_set_part *part = &rep->part[p]; if (util_map_hdr(part, prv ? MAP_PRIVATE : MAP_SHARED, rdonly)) { part->hdr = NULL; goto err; } } } return 0; err: pool_set_file_unmap_headers(file); return -1; } /* * pool_set_file_unmap_headers -- unmap headers of each pool set part file */ void pool_set_file_unmap_headers(struct pool_set_file *file) { if (!file->poolset) return; for (unsigned r = 0; r < file->poolset->nreplicas; r++) { struct pool_replica *rep = file->poolset->replica[r]; for (unsigned p = 0; p < rep->nparts; p++) { struct pool_set_part *part = &rep->part[p]; util_unmap_hdr(part); } } } /* * pool_get_signature -- (internal) return signature of specified pool type */ static const char * pool_get_signature(enum pool_type type) { switch (type) { case POOL_TYPE_LOG: return LOG_HDR_SIG; case POOL_TYPE_BLK: return BLK_HDR_SIG; case POOL_TYPE_OBJ: return OBJ_HDR_SIG; default: return NULL; } } /* * pool_hdr_default -- return default pool header values */ void pool_hdr_default(enum pool_type type, struct pool_hdr *hdrp) { memset(hdrp, 0, sizeof(*hdrp)); const char *sig = pool_get_signature(type); ASSERTne(sig, NULL); memcpy(hdrp->signature, sig, POOL_HDR_SIG_LEN); switch (type) { case POOL_TYPE_LOG: hdrp->major = LOG_FORMAT_MAJOR; hdrp->features = log_format_feat_default; break; case POOL_TYPE_BLK: hdrp->major = BLK_FORMAT_MAJOR; hdrp->features = blk_format_feat_default; break; case POOL_TYPE_OBJ: hdrp->major = OBJ_FORMAT_MAJOR; hdrp->features = obj_format_feat_default; break; default: break; } } /* * pool_hdr_get_type -- return pool type based on pool header data */ enum pool_type pool_hdr_get_type(const struct pool_hdr *hdrp) { if (memcmp(hdrp->signature, LOG_HDR_SIG, POOL_HDR_SIG_LEN) == 0) return POOL_TYPE_LOG; else if (memcmp(hdrp->signature, BLK_HDR_SIG, POOL_HDR_SIG_LEN) == 0) return POOL_TYPE_BLK; else if (memcmp(hdrp->signature, OBJ_HDR_SIG, POOL_HDR_SIG_LEN) == 0) return POOL_TYPE_OBJ; else return POOL_TYPE_UNKNOWN; } /* * pool_get_pool_type_str -- return human-readable pool type string */ const char * pool_get_pool_type_str(enum pool_type type) { switch (type) { case POOL_TYPE_BTT: return "btt"; case POOL_TYPE_LOG: return "pmemlog"; case POOL_TYPE_BLK: return "pmemblk"; case POOL_TYPE_OBJ: return "pmemobj"; default: return "unknown"; } } /* * pool_set_type -- get pool type of a poolset */ enum pool_type pool_set_type(struct pool_set *set) { struct pool_hdr hdr; /* open the first part file to read the pool header values */ const struct pool_set_part *part = PART(REP(set, 0), 0); if (util_file_pread(part->path, &hdr, sizeof(hdr), 0) != sizeof(hdr)) { ERR("cannot read pool header from poolset"); return POOL_TYPE_UNKNOWN; } util_convert2h_hdr_nocheck(&hdr); enum pool_type type = pool_hdr_get_type(&hdr); return type; } /* * pool_btt_info_valid -- check consistency of BTT Info header */ int pool_btt_info_valid(struct btt_info *infop) { if (memcmp(infop->sig, BTTINFO_SIG, BTTINFO_SIG_LEN) != 0) return 0; return util_checksum(infop, sizeof(*infop), &infop->checksum, 0, 0); } /* * pool_blk_get_first_valid_arena -- get first valid BTT Info in arena */ int pool_blk_get_first_valid_arena(struct pool_data *pool, struct arena *arenap) { arenap->zeroed = true; uint64_t offset = pool_get_first_valid_btt(pool, &arenap->btt_info, 2 * BTT_ALIGNMENT, &arenap->zeroed); if (offset != 0) { arenap->offset = offset; arenap->valid = true; return 1; } return 0; } /* * pool_next_arena_offset -- get offset of next arena * * Calculated offset is theoretical. Function does not check if such arena can * exist. */ uint64_t pool_next_arena_offset(struct pool_data *pool, uint64_t offset) { uint64_t lastoff = (pool->set_file->size & ~(BTT_ALIGNMENT - 1)); uint64_t nextoff = min(offset + BTT_MAX_ARENA, lastoff); return nextoff; } /* * pool_get_first_valid_btt -- return offset to first valid BTT Info * * - Return offset to valid BTT Info header in pool file. * - Start looking from given offset. * - Convert BTT Info header to host endianness. * - Return the BTT Info header by pointer. * - If zeroed pointer provided would check if all checked BTT Info are zeroed * which is useful for BLK pools */ uint64_t pool_get_first_valid_btt(struct pool_data *pool, struct btt_info *infop, uint64_t offset, bool *zeroed) { /* if we have valid arena get BTT Info header from it */ if (pool->narenas != 0) { struct arena *arenap = PMDK_TAILQ_FIRST(&pool->arenas); memcpy(infop, &arenap->btt_info, sizeof(*infop)); return arenap->offset; } const size_t info_size = sizeof(*infop); /* theoretical offsets to BTT Info header and backup */ uint64_t offsets[2] = {offset, 0}; while (offsets[0] < pool->set_file->size) { /* calculate backup offset */ offsets[1] = pool_next_arena_offset(pool, offsets[0]) - info_size; /* check both offsets: header and backup */ for (int i = 0; i < 2; ++i) { if (pool_read(pool, infop, info_size, offsets[i])) continue; /* check if all possible BTT Info are zeroed */ if (zeroed) *zeroed &= util_is_zeroed((const void *)infop, info_size); /* check if read BTT Info is valid */ if (pool_btt_info_valid(infop)) { btt_info_convert2h(infop); return offsets[i]; } } /* jump to next arena */ offsets[0] += BTT_MAX_ARENA; } return 0; } /* * pool_get_min_size -- return the minimum pool size of a pool of a given type */ size_t pool_get_min_size(enum pool_type type) { switch (type) { case POOL_TYPE_LOG: return PMEMLOG_MIN_POOL; case POOL_TYPE_BLK: return PMEMBLK_MIN_POOL; case POOL_TYPE_OBJ: return PMEMOBJ_MIN_POOL; default: ERR("unknown type of a pool"); return SIZE_MAX; } } #if FAULT_INJECTION void pmempool_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at) { core_inject_fault_at(type, nth, at); } int pmempool_fault_injection_enabled(void) { return core_fault_injection_enabled(); } #endif pmdk-1.11.1/src/libpmempool/check.c0000664000000000000000000001105314123364546015565 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * check.c -- functions performing checks in proper order */ #include #include "out.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check.h" #include "check_util.h" #define CHECK_RESULT_IS_STOP(result)\ ((result) == CHECK_RESULT_ERROR ||\ (result) == CHECK_RESULT_INTERNAL_ERROR ||\ ((result) == CHECK_RESULT_CANNOT_REPAIR) ||\ ((result) == CHECK_RESULT_NOT_CONSISTENT)) struct step { void (*func)(PMEMpoolcheck *); enum pool_type type; bool part; }; static const struct step steps[] = { { .type = POOL_TYPE_ANY, .func = check_bad_blocks, .part = true, }, { .type = POOL_TYPE_ANY, .func = check_backup, .part = true, }, { .type = POOL_TYPE_BLK | POOL_TYPE_LOG | POOL_TYPE_OBJ, .func = check_sds, .part = true, }, { .type = POOL_TYPE_BLK | POOL_TYPE_LOG | POOL_TYPE_OBJ | POOL_TYPE_UNKNOWN, .func = check_pool_hdr, .part = true, }, { .type = POOL_TYPE_BLK | POOL_TYPE_LOG | POOL_TYPE_OBJ | POOL_TYPE_UNKNOWN, .func = check_pool_hdr_uuids, .part = true, }, { .type = POOL_TYPE_LOG, .func = check_log, .part = false, }, { .type = POOL_TYPE_BLK, .func = check_blk, .part = false, }, { .type = POOL_TYPE_BLK | POOL_TYPE_BTT, .func = check_btt_info, .part = false, }, { .type = POOL_TYPE_BLK | POOL_TYPE_BTT, .func = check_btt_map_flog, .part = false, }, { .type = POOL_TYPE_BLK | POOL_TYPE_LOG | POOL_TYPE_BTT, .func = check_write, .part = false, }, { .func = NULL, }, }; /* * check_init -- initialize check process */ int check_init(PMEMpoolcheck *ppc) { LOG(3, NULL); if (!(ppc->data = check_data_alloc())) goto error_data_malloc; if (!(ppc->pool = pool_data_alloc(ppc))) goto error_pool_malloc; return 0; error_pool_malloc: check_data_free(ppc->data); error_data_malloc: return -1; } #ifdef _WIN32 void convert_status_cache(PMEMpoolcheck *ppc, char *buf, size_t size) { cache_to_utf8(ppc->data, buf, size); } #endif /* * status_get -- (internal) get next check_status * * The assumed order of check_statuses is: all info messages, error or question. */ static struct check_status * status_get(PMEMpoolcheck *ppc) { struct check_status *status = NULL; /* clear cache if exists */ check_clear_status_cache(ppc->data); /* return next info if exists */ if ((status = check_pop_info(ppc->data))) return status; /* return error if exists */ if ((status = check_pop_error(ppc->data))) return status; if (ppc->result == CHECK_RESULT_ASK_QUESTIONS) { /* * push answer for previous question and return info if answer * is not valid */ if (check_push_answer(ppc)) if ((status = check_pop_info(ppc->data))) return status; /* if has next question ask it */ if ((status = check_pop_question(ppc->data))) return status; /* process answers otherwise */ ppc->result = CHECK_RESULT_PROCESS_ANSWERS; } else if (CHECK_RESULT_IS_STOP(ppc->result)) check_end(ppc->data); return NULL; } /* * check_step -- perform single check step */ struct check_status * check_step(PMEMpoolcheck *ppc) { LOG(3, NULL); struct check_status *status = NULL; /* return if we have information or questions to ask or check ended */ if ((status = status_get(ppc)) || check_is_end(ppc->data)) return status; /* get next step and check if exists */ const struct step *step = &steps[check_step_get(ppc->data)]; if (step->func == NULL) { check_end(ppc->data); return status; } /* * step would be performed if pool type is one of the required pool type * and it is not part if parts are excluded from current step */ if (!(step->type & ppc->pool->params.type) || (ppc->pool->params.is_part && !step->part)) { /* skip test */ check_step_inc(ppc->data); return NULL; } /* perform step */ step->func(ppc); /* move on to next step if no questions were generated */ if (ppc->result != CHECK_RESULT_ASK_QUESTIONS) check_step_inc(ppc->data); /* get current status and return */ return status_get(ppc); } /* * check_fini -- stop check process */ void check_fini(PMEMpoolcheck *ppc) { LOG(3, NULL); pool_data_free(ppc->pool); check_data_free(ppc->data); } /* * check_is_end -- return if check has ended */ int check_is_end(struct check_data *data) { return check_is_end_util(data); } /* * check_status_get -- extract pmempool_check_status from check_status */ struct pmempool_check_status * check_status_get(struct check_status *status) { return check_status_get_util(status); } pmdk-1.11.1/src/libpmempool/check_util.c0000664000000000000000000003632714123364546016635 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * check_util.c -- check utility functions */ #include #include #include "out.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" #define CHECK_END UINT_MAX /* separate info part of message from question part of message */ #define MSG_SEPARATOR '|' /* error part of message must have '.' at the end */ #define MSG_PLACE_OF_SEPARATION '.' #define MAX_MSG_STR_SIZE 8192 #define CHECK_ANSWER_YES "yes" #define CHECK_ANSWER_NO "no" #define STR_MAX 256 #define TIME_STR_FMT "%a %b %d %Y %H:%M:%S" #define UUID_STR_MAX 37 enum check_answer { PMEMPOOL_CHECK_ANSWER_EMPTY, PMEMPOOL_CHECK_ANSWER_YES, PMEMPOOL_CHECK_ANSWER_NO, PMEMPOOL_CHECK_ANSWER_DEFAULT, }; /* queue of check statuses */ struct check_status { PMDK_TAILQ_ENTRY(check_status) next; struct pmempool_check_status status; unsigned question; enum check_answer answer; char *msg; }; PMDK_TAILQ_HEAD(check_status_head, check_status); /* check control context */ struct check_data { unsigned step; location step_data; struct check_status *error; struct check_status_head infos; struct check_status_head questions; struct check_status_head answers; struct check_status *check_status_cache; }; /* * check_data_alloc -- allocate and initialize check_data structure */ struct check_data * check_data_alloc(void) { LOG(3, NULL); struct check_data *data = calloc(1, sizeof(*data)); if (data == NULL) { ERR("!calloc"); return NULL; } PMDK_TAILQ_INIT(&data->infos); PMDK_TAILQ_INIT(&data->questions); PMDK_TAILQ_INIT(&data->answers); return data; } /* * check_data_free -- clean and deallocate check_data */ void check_data_free(struct check_data *data) { LOG(3, NULL); if (data->error != NULL) { free(data->error); data->error = NULL; } if (data->check_status_cache != NULL) { free(data->check_status_cache); data->check_status_cache = NULL; } while (!PMDK_TAILQ_EMPTY(&data->infos)) { struct check_status *statp = PMDK_TAILQ_FIRST(&data->infos); PMDK_TAILQ_REMOVE(&data->infos, statp, next); free(statp); } while (!PMDK_TAILQ_EMPTY(&data->questions)) { struct check_status *statp = PMDK_TAILQ_FIRST(&data->questions); PMDK_TAILQ_REMOVE(&data->questions, statp, next); free(statp); } while (!PMDK_TAILQ_EMPTY(&data->answers)) { struct check_status *statp = PMDK_TAILQ_FIRST(&data->answers); PMDK_TAILQ_REMOVE(&data->answers, statp, next); free(statp); } free(data); } /* * check_step_get - return current check step number */ uint32_t check_step_get(struct check_data *data) { return data->step; } /* * check_step_inc -- move to next step number */ void check_step_inc(struct check_data *data) { if (check_is_end_util(data)) return; ++data->step; memset(&data->step_data, 0, sizeof(location)); } /* * check_get_step_data -- return pointer to check step data */ location * check_get_step_data(struct check_data *data) { return &data->step_data; } /* * check_end -- mark check as ended */ void check_end(struct check_data *data) { LOG(3, NULL); data->step = CHECK_END; } /* * check_is_end_util -- return if check has ended */ int check_is_end_util(struct check_data *data) { return data->step == CHECK_END; } /* * status_alloc -- (internal) allocate and initialize check_status */ static inline struct check_status * status_alloc(void) { struct check_status *status = malloc(sizeof(*status)); if (!status) FATAL("!malloc"); status->msg = malloc(sizeof(char) * MAX_MSG_STR_SIZE); if (!status->msg) { free(status); FATAL("!malloc"); } status->status.str.msg = status->msg; status->answer = PMEMPOOL_CHECK_ANSWER_EMPTY; status->question = CHECK_INVALID_QUESTION; return status; } /* * status_release -- (internal) release check_status */ static void status_release(struct check_status *status) { #ifdef _WIN32 /* dealloc duplicate string after conversion */ if (status->status.str.msg != status->msg) free((void *)status->status.str.msg); #endif free(status->msg); free(status); } /* * status_msg_info_only -- (internal) separate info part of the message * * If message is in form of "info.|question" it modifies it as follows * "info\0|question" */ static inline int status_msg_info_only(const char *msg) { char *sep = strchr(msg, MSG_SEPARATOR); if (sep) { ASSERTne(sep, msg); --sep; ASSERTeq(*sep, MSG_PLACE_OF_SEPARATION); *sep = '\0'; return 0; } return -1; } /* * status_msg_info_and_question -- (internal) join info and question * * If message is in form "info.|question" it will replace MSG_SEPARATOR '|' with * space to get "info. question" */ static inline int status_msg_info_and_question(const char *msg) { char *sep = strchr(msg, MSG_SEPARATOR); if (sep) { *sep = ' '; return 0; } return -1; } /* * status_push -- (internal) push single status object */ static int status_push(PMEMpoolcheck *ppc, struct check_status *st, uint32_t question) { if (st->status.type == PMEMPOOL_CHECK_MSG_TYPE_ERROR) { ASSERTeq(ppc->data->error, NULL); ppc->data->error = st; return -1; } else if (st->status.type == PMEMPOOL_CHECK_MSG_TYPE_INFO) { if (CHECK_IS(ppc, VERBOSE)) PMDK_TAILQ_INSERT_TAIL(&ppc->data->infos, st, next); else check_status_release(ppc, st); return 0; } /* st->status.type == PMEMPOOL_CHECK_MSG_TYPE_QUESTION */ if (CHECK_IS_NOT(ppc, REPAIR)) { /* error status */ if (status_msg_info_only(st->msg)) { ERR("no error message for the user"); st->msg[0] = '\0'; } st->status.type = PMEMPOOL_CHECK_MSG_TYPE_ERROR; return status_push(ppc, st, question); } if (CHECK_IS(ppc, ALWAYS_YES)) { if (!status_msg_info_only(st->msg)) { /* information status */ st->status.type = PMEMPOOL_CHECK_MSG_TYPE_INFO; status_push(ppc, st, question); st = status_alloc(); } /* answer status */ ppc->result = CHECK_RESULT_PROCESS_ANSWERS; st->question = question; st->answer = PMEMPOOL_CHECK_ANSWER_YES; st->status.type = PMEMPOOL_CHECK_MSG_TYPE_QUESTION; PMDK_TAILQ_INSERT_TAIL(&ppc->data->answers, st, next); } else { /* question message */ status_msg_info_and_question(st->msg); st->question = question; ppc->result = CHECK_RESULT_ASK_QUESTIONS; st->answer = PMEMPOOL_CHECK_ANSWER_EMPTY; PMDK_TAILQ_INSERT_TAIL(&ppc->data->questions, st, next); } return 0; } /* * check_status_create -- create single status, push it to proper queue * * MSG_SEPARATOR character in fmt is treated as message separator. If creating * question but check arguments do not allow to make any changes (asking any * question is pointless) it takes part of message before MSG_SEPARATOR * character and use it to create error message. Character just before separator * must be a MSG_PLACE_OF_SEPARATION character. Return non 0 value if error * status would be created. * * The arg is an additional argument for specified type of status. */ int check_status_create(PMEMpoolcheck *ppc, enum pmempool_check_msg_type type, uint32_t arg, const char *fmt, ...) { if (CHECK_IS_NOT(ppc, VERBOSE) && type == PMEMPOOL_CHECK_MSG_TYPE_INFO) return 0; struct check_status *st = status_alloc(); ASSERT(CHECK_IS(ppc, FORMAT_STR)); va_list ap; va_start(ap, fmt); int p = vsnprintf(st->msg, MAX_MSG_STR_SIZE, fmt, ap); va_end(ap); /* append possible strerror at the end of the message */ if (type != PMEMPOOL_CHECK_MSG_TYPE_QUESTION && arg && p > 0) { char buff[UTIL_MAX_ERR_MSG]; util_strerror((int)arg, buff, UTIL_MAX_ERR_MSG); int ret = util_snprintf(st->msg + p, MAX_MSG_STR_SIZE - (size_t)p, ": %s", buff); if (ret < 0) { ERR("!snprintf"); status_release(st); return -1; } } st->status.type = type; return status_push(ppc, st, arg); } /* * check_status_release -- release single status object */ void check_status_release(PMEMpoolcheck *ppc, struct check_status *status) { if (status->status.type == PMEMPOOL_CHECK_MSG_TYPE_ERROR) ppc->data->error = NULL; status_release(status); } /* * pop_status -- (internal) pop single message from check_status queue */ static struct check_status * pop_status(struct check_data *data, struct check_status_head *queue) { if (!PMDK_TAILQ_EMPTY(queue)) { ASSERTeq(data->check_status_cache, NULL); data->check_status_cache = PMDK_TAILQ_FIRST(queue); PMDK_TAILQ_REMOVE(queue, data->check_status_cache, next); return data->check_status_cache; } return NULL; } /* * check_pop_question -- pop single question from questions queue */ struct check_status * check_pop_question(struct check_data *data) { return pop_status(data, &data->questions); } /* * check_pop_info -- pop single info from information queue */ struct check_status * check_pop_info(struct check_data *data) { return pop_status(data, &data->infos); } /* * check_pop_error -- pop error from state */ struct check_status * check_pop_error(struct check_data *data) { if (data->error) { ASSERTeq(data->check_status_cache, NULL); data->check_status_cache = data->error; data->error = NULL; return data->check_status_cache; } return NULL; } #ifdef _WIN32 void cache_to_utf8(struct check_data *data, char *buf, size_t size) { if (data->check_status_cache == NULL) return; struct check_status *status = data->check_status_cache; /* if it was a question, convert it and the answer to utf8 */ if (status->status.type == PMEMPOOL_CHECK_MSG_TYPE_QUESTION) { struct pmempool_check_statusW *wstatus = (struct pmempool_check_statusW *)&status->status; wchar_t *wstring = (wchar_t *)wstatus->str.msg; status->status.str.msg = util_toUTF8(wstring); if (status->status.str.msg == NULL) FATAL("!malloc"); util_free_UTF16(wstring); if (util_toUTF8_buff(wstatus->str.answer, buf, size) != 0) FATAL("Invalid answer conversion %s", out_get_errormsg()); status->status.str.answer = buf; } } #endif /* * check_clear_status_cache -- release check_status from cache */ void check_clear_status_cache(struct check_data *data) { if (data->check_status_cache) { switch (data->check_status_cache->status.type) { case PMEMPOOL_CHECK_MSG_TYPE_INFO: case PMEMPOOL_CHECK_MSG_TYPE_ERROR: /* * Info and error statuses are disposable. After showing * them to the user we have to release them. */ status_release(data->check_status_cache); data->check_status_cache = NULL; break; case PMEMPOOL_CHECK_MSG_TYPE_QUESTION: /* * Question status after being showed to the user carry * users answer. It must be kept till answer would be * processed so it can not be released from cache. It * has to be pushed to the answers queue, processed and * released after that. */ break; default: ASSERT(0); } } } /* * status_answer_push -- (internal) push single answer to answers queue */ static void status_answer_push(struct check_data *data, struct check_status *st) { ASSERTeq(st->status.type, PMEMPOOL_CHECK_MSG_TYPE_QUESTION); PMDK_TAILQ_INSERT_TAIL(&data->answers, st, next); } /* * check_push_answer -- process answer and push it to answers queue */ int check_push_answer(PMEMpoolcheck *ppc) { if (ppc->data->check_status_cache == NULL) return 0; /* check if answer is "yes" or "no" */ struct check_status *status = ppc->data->check_status_cache; if (status->status.str.answer != NULL) { if (strcmp(status->status.str.answer, CHECK_ANSWER_YES) == 0) status->answer = PMEMPOOL_CHECK_ANSWER_YES; else if (strcmp(status->status.str.answer, CHECK_ANSWER_NO) == 0) status->answer = PMEMPOOL_CHECK_ANSWER_NO; } if (status->answer == PMEMPOOL_CHECK_ANSWER_EMPTY) { /* invalid answer provided */ status_answer_push(ppc->data, ppc->data->check_status_cache); ppc->data->check_status_cache = NULL; CHECK_INFO(ppc, "Answer must be either %s or %s", CHECK_ANSWER_YES, CHECK_ANSWER_NO); return -1; } /* push answer */ PMDK_TAILQ_INSERT_TAIL(&ppc->data->answers, ppc->data->check_status_cache, next); ppc->data->check_status_cache = NULL; return 0; } /* * check_has_error - check if error exists */ bool check_has_error(struct check_data *data) { return data->error != NULL; } /* * check_has_answer - check if any answer exists */ bool check_has_answer(struct check_data *data) { return !PMDK_TAILQ_EMPTY(&data->answers); } /* * pop_answer -- (internal) pop single answer from answers queue */ static struct check_status * pop_answer(struct check_data *data) { struct check_status *ret = NULL; if (!PMDK_TAILQ_EMPTY(&data->answers)) { ret = PMDK_TAILQ_FIRST(&data->answers); PMDK_TAILQ_REMOVE(&data->answers, ret, next); } return ret; } /* * check_status_get_util -- extract pmempool_check_status from check_status */ struct pmempool_check_status * check_status_get_util(struct check_status *status) { return &status->status; } /* * check_answer_loop -- loop through all available answers and process them */ int check_answer_loop(PMEMpoolcheck *ppc, location *data, void *ctx, int fail_on_no, int (*callback)(PMEMpoolcheck *, location *, uint32_t, void *ctx)) { struct check_status *answer; while ((answer = pop_answer(ppc->data)) != NULL) { /* if answer is "no" we cannot fix an issue */ if (answer->answer != PMEMPOOL_CHECK_ANSWER_YES) { if (fail_on_no || answer->answer != PMEMPOOL_CHECK_ANSWER_NO) { CHECK_ERR(ppc, "cannot complete repair, reverting changes"); ppc->result = CHECK_RESULT_NOT_CONSISTENT; goto error; } ppc->result = CHECK_RESULT_REPAIRED; check_status_release(ppc, answer); continue; } /* perform fix */ if (callback(ppc, data, answer->question, ctx)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; goto error; } if (ppc->result == CHECK_RESULT_ERROR) goto error; /* fix succeeded */ ppc->result = CHECK_RESULT_REPAIRED; check_status_release(ppc, answer); } return 0; error: check_status_release(ppc, answer); return -1; } /* * check_questions_sequence_validate -- generate return value from result * * Sequence of questions can result in one of the following results: CONSISTENT, * REPAIRED, ASK_QUESTIONS of PROCESS_ANSWERS. If result == ASK_QUESTIONS it * returns -1 to indicate existence of unanswered questions. */ int check_questions_sequence_validate(PMEMpoolcheck *ppc) { ASSERT(ppc->result == CHECK_RESULT_CONSISTENT || ppc->result == CHECK_RESULT_ASK_QUESTIONS || ppc->result == CHECK_RESULT_PROCESS_ANSWERS || ppc->result == CHECK_RESULT_REPAIRED); if (ppc->result == CHECK_RESULT_ASK_QUESTIONS) { ASSERT(!PMDK_TAILQ_EMPTY(&ppc->data->questions)); return -1; } return 0; } /* * check_get_time_str -- returns time in human-readable format */ const char * check_get_time_str(time_t time) { static char str_buff[STR_MAX] = {0, }; struct tm tm; if (util_localtime(&time, &tm)) strftime(str_buff, STR_MAX, TIME_STR_FMT, &tm); else { int ret = util_snprintf(str_buff, STR_MAX, "unknown"); if (ret < 0) { ERR("!snprintf"); return ""; } } return str_buff; } /* * check_get_uuid_str -- returns uuid in human readable format */ const char * check_get_uuid_str(uuid_t uuid) { static char uuid_str[UUID_STR_MAX] = {0, }; int ret = util_uuid_to_string(uuid, uuid_str); if (ret != 0) { ERR("failed to covert uuid to string"); return ""; } return uuid_str; } /* * pmempool_check_insert_arena -- insert arena to list */ void check_insert_arena(PMEMpoolcheck *ppc, struct arena *arenap) { PMDK_TAILQ_INSERT_TAIL(&ppc->pool->arenas, arenap, next); ppc->pool->narenas++; } pmdk-1.11.1/src/libpmempool/pool.h0000664000000000000000000000720314123364546015470 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * pool.h -- internal definitions for pool processing functions */ #ifndef POOL_H #define POOL_H #include #include #include "libpmemobj.h" #include "queue.h" #include "set.h" #include "log.h" #include "blk.h" #include "btt_layout.h" #ifdef __cplusplus extern "C" { #endif #include "alloc.h" #include "fault_injection.h" enum pool_type { POOL_TYPE_UNKNOWN = (1 << 0), POOL_TYPE_LOG = (1 << 1), POOL_TYPE_BLK = (1 << 2), POOL_TYPE_OBJ = (1 << 3), POOL_TYPE_BTT = (1 << 4), POOL_TYPE_ANY = POOL_TYPE_UNKNOWN | POOL_TYPE_LOG | POOL_TYPE_BLK | POOL_TYPE_OBJ | POOL_TYPE_BTT, }; struct pool_params { enum pool_type type; char signature[POOL_HDR_SIG_LEN]; features_t features; size_t size; mode_t mode; int is_poolset; int is_part; int is_dev_dax; int is_pmem; union { struct { uint64_t bsize; } blk; struct { char layout[PMEMOBJ_MAX_LAYOUT]; } obj; }; }; struct pool_set_file { int fd; char *fname; void *addr; size_t size; struct pool_set *poolset; time_t mtime; mode_t mode; }; struct arena { PMDK_TAILQ_ENTRY(arena) next; struct btt_info btt_info; uint32_t id; bool valid; bool zeroed; uint64_t offset; uint8_t *flog; size_t flogsize; uint32_t *map; size_t mapsize; }; struct pool_data { struct pool_params params; struct pool_set_file *set_file; int blk_no_layout; union { struct pool_hdr pool; struct pmemlog log; struct pmemblk blk; } hdr; enum { UUID_NOP = 0, UUID_FROM_BTT, UUID_NOT_FROM_BTT, } uuid_op; struct arena bttc; PMDK_TAILQ_HEAD(arenashead, arena) arenas; uint32_t narenas; }; struct pool_data *pool_data_alloc(PMEMpoolcheck *ppc); void pool_data_free(struct pool_data *pool); void pool_params_from_header(struct pool_params *params, const struct pool_hdr *hdr); int pool_set_parse(struct pool_set **setp, const char *path); void *pool_set_file_map(struct pool_set_file *file, uint64_t offset); int pool_read(struct pool_data *pool, void *buff, size_t nbytes, uint64_t off); int pool_write(struct pool_data *pool, const void *buff, size_t nbytes, uint64_t off); int pool_copy(struct pool_data *pool, const char *dst_path, int overwrite); int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart, int overwrite); int pool_memset(struct pool_data *pool, uint64_t off, int c, size_t count); unsigned pool_set_files_count(struct pool_set_file *file); int pool_set_file_map_headers(struct pool_set_file *file, int rdonly, int prv); void pool_set_file_unmap_headers(struct pool_set_file *file); void pool_hdr_default(enum pool_type type, struct pool_hdr *hdrp); enum pool_type pool_hdr_get_type(const struct pool_hdr *hdrp); enum pool_type pool_set_type(struct pool_set *set); const char *pool_get_pool_type_str(enum pool_type type); int pool_btt_info_valid(struct btt_info *infop); int pool_blk_get_first_valid_arena(struct pool_data *pool, struct arena *arenap); int pool_blk_bsize_valid(uint32_t bsize, uint64_t fsize); uint64_t pool_next_arena_offset(struct pool_data *pool, uint64_t header_offset); uint64_t pool_get_first_valid_btt(struct pool_data *pool, struct btt_info *infop, uint64_t offset, bool *zeroed); size_t pool_get_min_size(enum pool_type); #if FAULT_INJECTION void pmempool_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at); int pmempool_fault_injection_enabled(void); #else static inline void pmempool_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at) { abort(); } static inline int pmempool_fault_injection_enabled(void) { return 0; } #endif #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/libpmempool/libpmempool.link.in0000664000000000000000000000070514123364546020151 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # src/libpmempool.link -- linker link file for libpmempool # LIBPMEMPOOL_1.0 { global: pmempool_errormsg; pmempool_check_version; pmempool_check_init; pmempool_check; pmempool_check_end; pmempool_transform; pmempool_sync; pmempool_rm; pmempool_feature_enable; pmempool_feature_disable; pmempool_feature_query; fault_injection; local: *; }; pmdk-1.11.1/src/libpmempool/check_blk.c0000664000000000000000000001223514123364546016420 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * check_blk.c -- check pmemblk */ #include #include #include #include "out.h" #include "btt.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum question { Q_BLK_BSIZE, }; /* * blk_get_max_bsize -- (internal) return maximum size of block for given file * size */ static inline uint32_t blk_get_max_bsize(uint64_t fsize) { LOG(3, NULL); if (fsize == 0) return 0; /* default nfree */ uint32_t nfree = BTT_DEFAULT_NFREE; /* number of blocks must be at least 2 * nfree */ uint32_t internal_nlba = 2 * nfree; /* compute arena size from file size without pmemblk structure */ uint64_t arena_size = fsize - sizeof(struct pmemblk); if (arena_size > BTT_MAX_ARENA) arena_size = BTT_MAX_ARENA; arena_size = btt_arena_datasize(arena_size, nfree); /* compute maximum internal LBA size */ uint64_t internal_lbasize = (arena_size - BTT_ALIGNMENT) / internal_nlba - BTT_MAP_ENTRY_SIZE; ASSERT(internal_lbasize <= UINT32_MAX); if (internal_lbasize < BTT_MIN_LBA_SIZE) internal_lbasize = BTT_MIN_LBA_SIZE; internal_lbasize = roundup(internal_lbasize, BTT_INTERNAL_LBA_ALIGNMENT) - BTT_INTERNAL_LBA_ALIGNMENT; return (uint32_t)internal_lbasize; } /* * blk_read -- (internal) read pmemblk header */ static int blk_read(PMEMpoolcheck *ppc) { /* * Here we want to read the pmemblk header without the pool_hdr as we've * already done it before. * * Take the pointer to fields right after pool_hdr, compute the size and * offset of remaining fields. */ uint8_t *ptr = (uint8_t *)&ppc->pool->hdr.blk; ptr += sizeof(ppc->pool->hdr.blk.hdr); size_t size = sizeof(ppc->pool->hdr.blk) - sizeof(ppc->pool->hdr.blk.hdr); uint64_t offset = sizeof(ppc->pool->hdr.blk.hdr); if (pool_read(ppc->pool, ptr, size, offset)) { return CHECK_ERR(ppc, "cannot read pmemblk structure"); } /* endianness conversion */ ppc->pool->hdr.blk.bsize = le32toh(ppc->pool->hdr.blk.bsize); return 0; } /* * blk_bsize_valid -- (internal) check if block size is valid for given file * size */ static int blk_bsize_valid(uint32_t bsize, uint64_t fsize) { uint32_t max_bsize = blk_get_max_bsize(fsize); return (bsize >= max_bsize); } /* * blk_hdr_check -- (internal) check pmemblk header */ static int blk_hdr_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); CHECK_INFO(ppc, "checking pmemblk header"); if (blk_read(ppc)) { ppc->result = CHECK_RESULT_ERROR; return -1; } /* check for valid BTT Info arena as we can take bsize from it */ if (!ppc->pool->bttc.valid) pool_blk_get_first_valid_arena(ppc->pool, &ppc->pool->bttc); if (ppc->pool->bttc.valid) { const uint32_t btt_bsize = ppc->pool->bttc.btt_info.external_lbasize; if (ppc->pool->hdr.blk.bsize != btt_bsize) { CHECK_ASK(ppc, Q_BLK_BSIZE, "invalid pmemblk.bsize.|Do you want to set " "pmemblk.bsize to %u from BTT Info?", btt_bsize); } } else if (!ppc->pool->bttc.zeroed) { if (ppc->pool->hdr.blk.bsize < BTT_MIN_LBA_SIZE || blk_bsize_valid(ppc->pool->hdr.blk.bsize, ppc->pool->set_file->size)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "invalid pmemblk.bsize"); } } if (ppc->result == CHECK_RESULT_CONSISTENT || ppc->result == CHECK_RESULT_REPAIRED) CHECK_INFO(ppc, "pmemblk header correct"); return check_questions_sequence_validate(ppc); } /* * blk_hdr_fix -- (internal) fix pmemblk header */ static int blk_hdr_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); uint32_t btt_bsize; switch (question) { case Q_BLK_BSIZE: /* * check for valid BTT Info arena as we can take bsize from it */ if (!ppc->pool->bttc.valid) pool_blk_get_first_valid_arena(ppc->pool, &ppc->pool->bttc); btt_bsize = ppc->pool->bttc.btt_info.external_lbasize; CHECK_INFO(ppc, "setting pmemblk.b_size to 0x%x", btt_bsize); ppc->pool->hdr.blk.bsize = btt_bsize; break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); enum pool_type type; }; static const struct step steps[] = { { .check = blk_hdr_check, .type = POOL_TYPE_BLK }, { .fix = blk_hdr_fix, .type = POOL_TYPE_BLK }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static inline int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); ASSERTeq(ppc->pool->params.type, POOL_TYPE_BLK); const struct step *step = &steps[loc->step++]; if (!(step->type & ppc->pool->params.type)) return 0; if (!step->fix) return step->check(ppc, loc); if (blk_read(ppc)) { ppc->result = CHECK_RESULT_ERROR; return -1; } return check_answer_loop(ppc, loc, NULL, 1, step->fix); } /* * check_blk -- entry point for pmemblk checks */ void check_blk(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps)) { if (step_exe(ppc, loc)) break; } } pmdk-1.11.1/src/libpmempool/transform.c0000664000000000000000000006606414123364546016537 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * transform.c -- a module for poolset transforming */ #include #include #include #include #include #include #include #include #include #include "replica.h" #include "out.h" #include "file.h" #include "os.h" #include "libpmem.h" #include "util_pmem.h" /* * poolset_compare_status - a helping structure for gathering corresponding * replica numbers when comparing poolsets */ struct poolset_compare_status { unsigned nreplicas; unsigned flags; unsigned replica[]; }; /* * type of transform operation to be done */ enum transform_op { NOT_TRANSFORMABLE, ADD_REPLICAS, RM_REPLICAS, ADD_HDRS, RM_HDRS, }; /* * check_if_part_used_once -- (internal) check if the part is used only once in * the rest of the poolset */ static int check_if_part_used_once(struct pool_set *set, unsigned repn, unsigned partn) { LOG(3, "set %p, repn %u, partn %u", set, repn, partn); struct pool_replica *rep = REP(set, repn); char *path = util_part_realpath(PART(rep, partn)->path); if (path == NULL) { LOG(1, "cannot get absolute path for %s, replica %u, part %u", PART(rep, partn)->path, repn, partn); errno = 0; path = strdup(PART(rep, partn)->path); if (path == NULL) { ERR("!strdup"); return -1; } } int ret = 0; for (unsigned r = repn; r < set->nreplicas; ++r) { struct pool_replica *repr = set->replica[r]; /* skip remote replicas */ if (repr->remote != NULL) continue; /* avoid superfluous comparisons */ unsigned i = (r == repn) ? partn + 1 : 0; for (unsigned p = i; p < repr->nparts; ++p) { char *pathp = util_part_realpath(PART(repr, p)->path); if (pathp == NULL) { if (errno != ENOENT) { ERR("realpath failed for %s, errno %d", PART(repr, p)->path, errno); ret = -1; goto out; } LOG(1, "cannot get absolute path for %s," " replica %u, part %u", PART(rep, partn)->path, repn, partn); pathp = strdup(PART(repr, p)->path); errno = 0; } int result = util_compare_file_inodes(path, pathp); if (result == 0) { /* same file used multiple times */ ERR("some part file's path is" " used multiple times"); ret = -1; errno = EINVAL; free(pathp); goto out; } else if (result < 0) { ERR("comparing file inodes failed for %s and" " %s", path, pathp); ret = -1; free(pathp); goto out; } free(pathp); } } out: free(path); return ret; } /* * check_if_remote_replica_used_once -- (internal) check if remote replica is * used only once in the rest of the * poolset */ static int check_if_remote_replica_used_once(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct remote_replica *rep = REP(set, repn)->remote; ASSERTne(rep, NULL); for (unsigned r = repn + 1; r < set->nreplicas; ++r) { /* skip local replicas */ if (REP(set, r)->remote == NULL) continue; struct remote_replica *repr = REP(set, r)->remote; /* XXX: add comparing resolved addresses of the nodes */ if (strcmp(rep->node_addr, repr->node_addr) == 0 && strcmp(rep->pool_desc, repr->pool_desc) == 0) { ERR("remote replica %u is used multiple times", repn); errno = EINVAL; return -1; } } return 0; } /* * check_paths -- (internal) check if directories for part files exist * and if paths for part files do not repeat in the poolset */ static int check_paths(struct pool_set *set) { LOG(3, "set %p", set); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; if (rep->remote != NULL) { if (check_if_remote_replica_used_once(set, r)) return -1; } else { for (unsigned p = 0; p < rep->nparts; ++p) { if (replica_check_local_part_dir(set, r, p)) return -1; if (check_if_part_used_once(set, r, p)) return -1; } } } return 0; } /* * validate_args -- (internal) check whether passed arguments are valid */ static int validate_args(struct pool_set *set_in, struct pool_set *set_out) { LOG(3, "set_in %p, set_out %p", set_in, set_out); if (set_in->directory_based) { ERR("transform of directory poolsets is not supported"); errno = EINVAL; return -1; } /* * check if all parts in the target poolset are large enough * (now replication works only for pmemobj pools) */ if (replica_check_part_sizes(set_out, PMEMOBJ_MIN_POOL)) { ERR("part sizes check failed"); return -1; } /* * check if all directories for part files exist and if part files * do not reoccur in the poolset */ if (check_paths(set_out)) return -1; /* * check if set_out has enough size, i.e. if the target poolset * structure has enough capacity to accommodate the effective size of * the source poolset */ ssize_t master_pool_size = replica_get_pool_size(set_in, 0); if (master_pool_size < 0) { ERR("getting pool size from master replica failed"); return -1; } if (set_out->poolsize < (size_t)master_pool_size) { ERR("target poolset is too small"); errno = EINVAL; return -1; } return 0; } /* * create poolset_compare_status -- (internal) create structure for gathering * status of poolset comparison */ static int create_poolset_compare_status(struct pool_set *set, struct poolset_compare_status **set_sp) { LOG(3, "set %p, set_sp %p", set, set_sp); struct poolset_compare_status *set_s; set_s = Zalloc(sizeof(struct poolset_compare_status) + set->nreplicas * sizeof(unsigned)); if (set_s == NULL) { ERR("!Zalloc for poolset status"); return -1; } for (unsigned r = 0; r < set->nreplicas; ++r) set_s->replica[r] = UNDEF_REPLICA; set_s->nreplicas = set->nreplicas; *set_sp = set_s; return 0; } /* * compare_parts -- (internal) check if two parts can be considered the same */ static int compare_parts(struct pool_set_part *p1, struct pool_set_part *p2) { LOG(3, "p1 %p, p2 %p", p1, p2); LOG(4, "p1->path: %s, p1->filesize: %lu", p1->path, p1->filesize); LOG(4, "p2->path: %s, p2->filesize: %lu", p2->path, p2->filesize); return strcmp(p1->path, p2->path) || (p1->filesize != p2->filesize); } /* * compare_replicas -- (internal) check if two replicas are different */ static int compare_replicas(struct pool_replica *r1, struct pool_replica *r2) { LOG(3, "r1 %p, r2 %p", r1, r2); LOG(4, "r1->nparts: %u, r2->nparts: %u", r1->nparts, r2->nparts); /* both replicas are local */ if (r1->remote == NULL && r2->remote == NULL) { if (r1->nparts != r2->nparts) return 1; for (unsigned p = 0; p < r1->nparts; ++p) { if (compare_parts(&r1->part[p], &r2->part[p])) return 1; } return 0; } /* both replicas are remote */ if (r1->remote != NULL && r2->remote != NULL) { return strcmp(r1->remote->node_addr, r2->remote->node_addr) || strcmp(r1->remote->pool_desc, r2->remote->pool_desc); } /* a remote and a local replicas */ return 1; } /* * check_compare_poolsets_status -- (internal) find different replicas between * two poolsets; for each replica which has * a counterpart in the other poolset store * the other replica's number in a helping * structure */ static int check_compare_poolsets_status(struct pool_set *set_in, struct pool_set *set_out, struct poolset_compare_status *set_in_s, struct poolset_compare_status *set_out_s) { LOG(3, "set_in %p, set_out %p, set_in_s %p, set_out_s %p", set_in, set_out, set_in_s, set_out_s); for (unsigned ri = 0; ri < set_in->nreplicas; ++ri) { struct pool_replica *rep_in = REP(set_in, ri); for (unsigned ro = 0; ro < set_out->nreplicas; ++ro) { struct pool_replica *rep_out = REP(set_out, ro); LOG(1, "comparing rep_in %u with rep_out %u", ri, ro); /* skip different replicas */ if (compare_replicas(rep_in, rep_out)) continue; if (set_in_s->replica[ri] != UNDEF_REPLICA || set_out_s->replica[ro] != UNDEF_REPLICA) { /* there are more than one counterparts */ ERR("there are more then one corresponding" " replicas; cannot transform"); errno = EINVAL; return -1; } set_in_s->replica[ri] = ro; set_out_s->replica[ro] = ri; } } return 0; } /* * check_compare_poolset_options -- (internal) check poolset options */ static int check_compare_poolsets_options(struct pool_set *set_in, struct pool_set *set_out, struct poolset_compare_status *set_in_s, struct poolset_compare_status *set_out_s) { if (set_in->options & OPTION_SINGLEHDR) set_in_s->flags |= OPTION_SINGLEHDR; if (set_out->options & OPTION_SINGLEHDR) set_out_s->flags |= OPTION_SINGLEHDR; if ((set_in->options & OPTION_NOHDRS) || (set_out->options & OPTION_NOHDRS)) { errno = EINVAL; ERR( "the NOHDRS poolset option is not supported in local poolset files"); return -1; } return 0; } /* * compare_poolsets -- (internal) compare two poolsets; for each replica which * has a counterpart in the other poolset store the other * replica's number in a helping structure */ static int compare_poolsets(struct pool_set *set_in, struct pool_set *set_out, struct poolset_compare_status **set_in_s, struct poolset_compare_status **set_out_s) { LOG(3, "set_in %p, set_out %p, set_in_s %p, set_out_s %p", set_in, set_out, set_in_s, set_out_s); if (create_poolset_compare_status(set_in, set_in_s)) return -1; if (create_poolset_compare_status(set_out, set_out_s)) goto err_free_in; if (check_compare_poolsets_status(set_in, set_out, *set_in_s, *set_out_s)) goto err_free_out; if (check_compare_poolsets_options(set_in, set_out, *set_in_s, *set_out_s)) goto err_free_out; return 0; err_free_out: Free(*set_out_s); err_free_in: Free(*set_in_s); return -1; } /* * replica_counterpart -- (internal) returns index of a counterpart replica */ static unsigned replica_counterpart(unsigned repn, struct poolset_compare_status *set_s) { return set_s->replica[repn]; } /* * are_poolsets_transformable -- (internal) check if poolsets can be transformed * one into the other; also gather info about * replicas's health */ static enum transform_op identify_transform_operation(struct poolset_compare_status *set_in_s, struct poolset_compare_status *set_out_s, struct poolset_health_status *set_in_hs, struct poolset_health_status *set_out_hs) { LOG(3, "set_in_s %p, set_out_s %p", set_in_s, set_out_s); int has_replica_to_keep = 0; int is_removing_replicas = 0; int is_adding_replicas = 0; /* check if there are replicas to be removed */ for (unsigned r = 0; r < set_in_s->nreplicas; ++r) { unsigned c = replica_counterpart(r, set_in_s); if (c != UNDEF_REPLICA) { LOG(2, "replica %u has a counterpart %u", r, set_in_s->replica[r]); has_replica_to_keep = 1; REP_HEALTH(set_out_hs, c)->pool_size = REP_HEALTH(set_in_hs, r)->pool_size; } else { LOG(2, "replica %u has no counterpart", r); is_removing_replicas = 1; } } /* make sure we have at least one replica to keep */ if (!has_replica_to_keep) { ERR("there must be at least one replica left"); return NOT_TRANSFORMABLE; } /* check if there are replicas to be added */ for (unsigned r = 0; r < set_out_s->nreplicas; ++r) { if (replica_counterpart(r, set_out_s) == UNDEF_REPLICA) { LOG(2, "Replica %u from output set has no counterpart", r); if (is_removing_replicas) { ERR( "adding and removing replicas at the same time is not allowed"); return NOT_TRANSFORMABLE; } REP_HEALTH(set_out_hs, r)->flags |= IS_BROKEN; is_adding_replicas = 1; } } /* check if there is anything to do */ if (!is_removing_replicas && !is_adding_replicas && (set_in_s->flags & OPTION_SINGLEHDR) == (set_out_s->flags & OPTION_SINGLEHDR)) { ERR("both poolsets are equal"); return NOT_TRANSFORMABLE; } /* allow changing the SINGLEHDR option only as the sole operation */ if ((is_removing_replicas || is_adding_replicas) && (set_in_s->flags & OPTION_SINGLEHDR) != (set_out_s->flags & OPTION_SINGLEHDR)) { ERR( "cannot add/remove replicas and change the SINGLEHDR option at the same time"); return NOT_TRANSFORMABLE; } if (is_removing_replicas) return RM_REPLICAS; if (is_adding_replicas) return ADD_REPLICAS; if (set_out_s->flags & OPTION_SINGLEHDR) return RM_HDRS; if (set_in_s->flags & OPTION_SINGLEHDR) return ADD_HDRS; ASSERT(0); return NOT_TRANSFORMABLE; } /* * do_added_parts_exist -- (internal) check if any part of the replicas that are * to be added (marked as broken) already exists */ static int do_added_parts_exist(struct pool_set *set, struct poolset_health_status *set_hs) { for (unsigned r = 0; r < set->nreplicas; ++r) { /* skip unbroken (i.e. not being added) replicas */ if (!replica_is_replica_broken(r, set_hs)) continue; struct pool_replica *rep = REP(set, r); /* skip remote replicas */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { /* check if part file exists */ int oerrno = errno; int exists = util_file_exists(rep->part[p].path); if (exists < 0) return -1; if (exists && !rep->part[p].is_dev_dax) { LOG(1, "part file %s exists", rep->part[p].path); return 1; } errno = oerrno; } } return 0; } /* * delete_replicas -- (internal) delete replicas which do not have their * counterpart set in the helping status structure */ static int delete_replicas(struct pool_set *set, struct poolset_compare_status *set_s) { LOG(3, "set %p, set_s %p", set, set_s); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); if (replica_counterpart(r, set_s) == UNDEF_REPLICA) { if (!rep->remote) { if (util_replica_close_local(rep, r, DELETE_ALL_PARTS)) return -1; } else { if (util_replica_close_remote(rep, r, DELETE_ALL_PARTS)) return -1; } } } return 0; } /* * copy_replica_data_fw -- (internal) copy data between replicas of two * poolsets, starting from the beginning of the * second part */ static void copy_replica_data_fw(struct pool_set *set_dst, struct pool_set *set_src, unsigned repn) { LOG(3, "set_in %p, set_out %p, repn %u", set_src, set_dst, repn); ssize_t pool_size = replica_get_pool_size(set_src, repn); if (pool_size < 0) { LOG(1, "getting pool size from replica %u failed", repn); pool_size = (ssize_t)set_src->poolsize; } size_t len = (size_t)pool_size - POOL_HDR_SIZE - replica_get_part_data_len(set_src, repn, 0); void *src = PART(REP(set_src, repn), 1)->addr; void *dst = PART(REP(set_dst, repn), 1)->addr; size_t count = len / POOL_HDR_SIZE; while (count-- > 0) { pmem_memcpy_persist(dst, src, POOL_HDR_SIZE); src = ADDR_SUM(src, POOL_HDR_SIZE); dst = ADDR_SUM(dst, POOL_HDR_SIZE); } } /* * copy_replica_data_bw -- (internal) copy data between replicas of two * poolsets, starting from the end of the pool */ static void copy_replica_data_bw(struct pool_set *set_dst, struct pool_set *set_src, unsigned repn) { LOG(3, "set_in %p, set_out %p, repn %u", set_src, set_dst, repn); ssize_t pool_size = replica_get_pool_size(set_src, repn); if (pool_size < 0) { LOG(1, "getting pool size from replica %u failed", repn); pool_size = (ssize_t)set_src->poolsize; } size_t len = (size_t)pool_size - POOL_HDR_SIZE - replica_get_part_data_len(set_src, repn, 0); size_t count = len / POOL_HDR_SIZE; void *src = ADDR_SUM(PART(REP(set_src, repn), 1)->addr, len); void *dst = ADDR_SUM(PART(REP(set_dst, repn), 1)->addr, len); while (count-- > 0) { src = ADDR_SUM(src, -(ssize_t)POOL_HDR_SIZE); dst = ADDR_SUM(dst, -(ssize_t)POOL_HDR_SIZE); pmem_memcpy_persist(dst, src, POOL_HDR_SIZE); } } /* * create_missing_headers -- (internal) create headers for all parts but the * first one */ static int create_missing_headers(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_hdr *src_hdr = HDR(REP(set, repn), 0); for (unsigned p = 1; p < set->replica[repn]->nhdrs; ++p) { struct pool_attr attr; util_pool_hdr2attr(&attr, src_hdr); attr.features.incompat &= (uint32_t)(~POOL_FEAT_SINGLEHDR); if (util_header_create(set, repn, p, &attr, 1) != 0) { LOG(1, "part headers create failed for" " replica %u part %u", repn, p); errno = EINVAL; return -1; } } return 0; } /* * update_replica_header -- (internal) update field values in the first header * in the replica */ static void update_replica_header(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_replica *rep = REP(set, repn); struct pool_set_part *part = PART(REP(set, repn), 0); struct pool_hdr *hdr = (struct pool_hdr *)part->hdr; if (set->options & OPTION_SINGLEHDR) { hdr->features.incompat |= POOL_FEAT_SINGLEHDR; memcpy(hdr->next_part_uuid, hdr->uuid, POOL_HDR_UUID_LEN); memcpy(hdr->prev_part_uuid, hdr->uuid, POOL_HDR_UUID_LEN); } else { hdr->features.incompat &= (uint32_t)(~POOL_FEAT_SINGLEHDR); } util_checksum(hdr, sizeof(*hdr), &hdr->checksum, 1, POOL_HDR_CSUM_END_OFF(hdr)); util_persist_auto(rep->is_pmem, hdr, sizeof(*hdr)); } /* * fill_replica_struct_uuids -- (internal) gather all uuids required for the * replica in the helper structure */ static int fill_replica_struct_uuids(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_replica *rep = REP(set, repn); memcpy(PART(rep, 0)->uuid, HDR(rep, 0)->uuid, POOL_HDR_UUID_LEN); for (unsigned p = 1; p < rep->nhdrs; ++p) { if (util_uuid_generate(rep->part[p].uuid) < 0) { ERR("cannot generate part UUID"); errno = EINVAL; return -1; } } return 0; } /* * update_uuids -- (internal) update uuids in all headers in the replica */ static void update_uuids(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_replica *rep = REP(set, repn); struct pool_hdr *hdr0 = HDR(rep, 0); for (unsigned p = 0; p < rep->nhdrs; ++p) { struct pool_hdr *hdrp = HDR(rep, p); memcpy(hdrp->next_part_uuid, PARTN(rep, p)->uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->prev_part_uuid, PARTP(rep, p)->uuid, POOL_HDR_UUID_LEN); /* Avoid calling memcpy() on identical regions */ if (p != 0) { memcpy(hdrp->next_repl_uuid, hdr0->next_repl_uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->prev_repl_uuid, hdr0->prev_repl_uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->poolset_uuid, hdr0->poolset_uuid, POOL_HDR_UUID_LEN); } util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(hdrp)); util_persist(PART(rep, p)->is_dev_dax, hdrp, sizeof(*hdrp)); } } /* * copy_part_fds -- (internal) copy poolset part file descriptors between * two poolsets */ static void copy_part_fds(struct pool_set *set_dst, struct pool_set *set_src) { ASSERTeq(set_src->nreplicas, set_dst->nreplicas); for (unsigned r = 0; r < set_dst->nreplicas; ++r) { ASSERTeq(REP(set_src, r)->nparts, REP(set_dst, r)->nparts); for (unsigned p = 0; p < REP(set_dst, r)->nparts; ++p) { PART(REP(set_dst, r), p)->fd = PART(REP(set_src, r), p)->fd; } } } /* * remove_hdrs_replica -- (internal) remove headers from the replica */ static int remove_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out, unsigned repn) { LOG(3, "set %p, repn %u", set_in, repn); int ret = 0; /* open all part files of the input replica */ if (replica_open_replica_part_files(set_in, repn)) { LOG(1, "opening replica %u, part files failed", repn); ret = -1; goto out; } /* share part file descriptors between poolset structures */ copy_part_fds(set_out, set_in); /* map the whole input replica */ if (util_replica_open(set_in, repn, MAP_SHARED)) { LOG(1, "opening input replica failed: replica %u", repn); ret = -1; goto out_close; } /* map the whole output replica */ if (util_replica_open(set_out, repn, MAP_SHARED)) { LOG(1, "opening output replica failed: replica %u", repn); ret = -1; goto out_unmap_in; } /* move data between the two mappings of the replica */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_fw(set_out, set_in, repn); /* make changes to the first part's header */ update_replica_header(set_out, repn); util_replica_close(set_out, repn); out_unmap_in: util_replica_close(set_in, repn); out_close: util_replica_fdclose(REP(set_in, repn)); out: return ret; } /* * add_hdrs_replica -- (internal) add lacking headers to the replica * * when the operation fails and returns -1, the replica remains untouched */ static int add_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out, unsigned repn) { LOG(3, "set %p, repn %u", set_in, repn); int ret = 0; /* open all part files of the input replica */ if (replica_open_replica_part_files(set_in, repn)) { LOG(1, "opening replica %u, part files failed", repn); ret = -1; goto out; } /* share part file descriptors between poolset structures */ copy_part_fds(set_out, set_in); /* map the whole input replica */ if (util_replica_open(set_in, repn, MAP_SHARED)) { LOG(1, "opening input replica failed: replica %u", repn); ret = -1; goto out_close; } /* map the whole output replica */ if (util_replica_open(set_out, repn, MAP_SHARED)) { LOG(1, "opening output replica failed: replica %u", repn); ret = -1; goto out_unmap_in; } /* generate new uuids for lacking headers */ if (fill_replica_struct_uuids(set_out, repn)) { LOG(1, "generating lacking uuids for parts failed: replica %u", repn); ret = -1; goto out_unmap_out; } /* copy data between the two mappings of the replica */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_bw(set_out, set_in, repn); /* create the missing headers */ if (create_missing_headers(set_out, repn)) { LOG(1, "creating lacking headers failed: replica %u", repn); /* * copy the data back, so we could fall back to the original * state */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_fw(set_in, set_out, repn); ret = -1; goto out_unmap_out; } /* make changes to the first part's header */ update_replica_header(set_out, repn); /* store new uuids in all headers and update linkage in the replica */ update_uuids(set_out, repn); out_unmap_out: util_replica_close(set_out, repn); out_unmap_in: util_replica_close(set_in, repn); out_close: util_replica_fdclose(REP(set_in, repn)); out: return ret; } /* * remove_hdrs -- (internal) transform a poolset without the SINGLEHDR option * (with headers) into a poolset with the SINGLEHDR option * (without headers) */ static int remove_hdrs(struct pool_set *set_in, struct pool_set *set_out, struct poolset_health_status *set_in_hs, unsigned flags) { LOG(3, "set_in %p, set_out %p, set_in_hs %p, flags %u", set_in, set_out, set_in_hs, flags); for (unsigned r = 0; r < set_in->nreplicas; ++r) { if (remove_hdrs_replica(set_in, set_out, r)) { LOG(1, "removing headers from replica %u failed", r); /* mark all previous replicas as damaged */ while (--r < set_in->nreplicas) REP_HEALTH(set_in_hs, r)->flags |= IS_BROKEN; return -1; } } return 0; } /* * add_hdrs -- (internal) transform a poolset with the SINGLEHDR option (without * headers) into a poolset without the SINGLEHDR option (with * headers) */ static int add_hdrs(struct pool_set *set_in, struct pool_set *set_out, struct poolset_health_status *set_in_hs, unsigned flags) { LOG(3, "set_in %p, set_out %p, set_in_hs %p, flags %u", set_in, set_out, set_in_hs, flags); for (unsigned r = 0; r < set_in->nreplicas; ++r) { if (add_hdrs_replica(set_in, set_out, r)) { LOG(1, "adding headers to replica %u failed", r); /* mark all previous replicas as damaged */ while (--r < set_in->nreplicas) REP_HEALTH(set_in_hs, r)->flags |= IS_BROKEN; return -1; } } return 0; } /* * transform_replica -- transforming one poolset into another */ int replica_transform(struct pool_set *set_in, struct pool_set *set_out, unsigned flags) { LOG(3, "set_in %p, set_out %p", set_in, set_out); int ret = 0; /* validate user arguments */ if (validate_args(set_in, set_out)) return -1; /* check if the source poolset is healthy */ struct poolset_health_status *set_in_hs = NULL; if (replica_check_poolset_health(set_in, &set_in_hs, 0 /* called from transform */, flags)) { ERR("source poolset health check failed"); return -1; } if (!replica_is_poolset_healthy(set_in_hs)) { ERR("source poolset is broken"); ret = -1; errno = EINVAL; goto free_hs_in; } /* copy value of the ignore_sds flag from the input poolset */ set_out->ignore_sds = set_in->ignore_sds; struct poolset_health_status *set_out_hs = NULL; if (replica_create_poolset_health_status(set_out, &set_out_hs)) { ERR("creating poolset health status failed"); ret = -1; goto free_hs_in; } /* check if the poolsets are transformable */ struct poolset_compare_status *set_in_cs = NULL; struct poolset_compare_status *set_out_cs = NULL; if (compare_poolsets(set_in, set_out, &set_in_cs, &set_out_cs)) { ERR("comparing poolsets failed"); ret = -1; goto free_hs_out; } enum transform_op operation = identify_transform_operation(set_in_cs, set_out_cs, set_in_hs, set_out_hs); if (operation == NOT_TRANSFORMABLE) { LOG(1, "poolsets are not transformable"); ret = -1; errno = EINVAL; goto free_cs; } if (operation == RM_HDRS) { if (!is_dry_run(flags) && remove_hdrs(set_in, set_out, set_in_hs, flags)) { ERR("removing headers failed; falling back to the " "input poolset"); if (replica_sync(set_in, set_in_hs, flags | IS_TRANSFORMED)) { LOG(1, "falling back to the input poolset " "failed"); } else { LOG(1, "falling back to the input poolset " "succeeded"); } ret = -1; } goto free_cs; } if (operation == ADD_HDRS) { if (!is_dry_run(flags) && add_hdrs(set_in, set_out, set_in_hs, flags)) { ERR("adding headers failed; falling back to the " "input poolset"); if (replica_sync(set_in, set_in_hs, flags | IS_TRANSFORMED)) { LOG(1, "falling back to the input poolset " "failed"); } else { LOG(1, "falling back to the input poolset " "succeeded"); } ret = -1; } goto free_cs; } if (operation == ADD_REPLICAS) { /* * check if any of the parts that are to be added already exists */ if (do_added_parts_exist(set_out, set_out_hs)) { ERR("some parts being added already exist"); ret = -1; errno = EINVAL; goto free_cs; } } /* signal that sync is called by transform */ if (replica_sync(set_out, set_out_hs, flags | IS_TRANSFORMED)) { ret = -1; goto free_cs; } if (operation == RM_REPLICAS) { if (!is_dry_run(flags) && delete_replicas(set_in, set_in_cs)) ret = -1; } free_cs: Free(set_in_cs); Free(set_out_cs); free_hs_out: replica_free_poolset_health_status(set_out_hs); free_hs_in: replica_free_poolset_health_status(set_in_hs); return ret; } pmdk-1.11.1/src/libpmempool/libpmempool.vcxproj.filters0000664000000000000000000001775714123364546021770 0ustar rootroot Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files {cd079c79-5441-413e-b2ba-99fed2b0b779} {9ad93d4f-a9d1-4e38-94a1-77e36acc268f} Source Files Source Files pmdk-1.11.1/src/libpmempool/replica.h0000664000000000000000000001411314123364546016134 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * replica.h -- module for synchronizing and transforming poolset */ #ifndef REPLICA_H #define REPLICA_H #include "libpmempool.h" #include "pool.h" #include "badblocks.h" #ifdef __cplusplus extern "C" { #endif #define UNDEF_REPLICA UINT_MAX #define UNDEF_PART UINT_MAX /* * A part marked as broken does not exist or is damaged so that * it cannot be opened and has to be recreated. */ #define IS_BROKEN (1U << 0) /* * A replica marked as inconsistent exists but has inconsistent metadata * (e.g. inconsistent parts or replicas linkage) */ #define IS_INCONSISTENT (1U << 1) /* * A part or replica marked in this way has bad blocks inside. */ #define HAS_BAD_BLOCKS (1U << 2) /* * A part marked in this way has bad blocks in the header */ #define HAS_CORRUPTED_HEADER (1U << 3) /* * A flag which can be passed to sync_replica() to indicate that the function is * called by pmempool_transform */ #define IS_TRANSFORMED (1U << 10) /* * Number of lanes utilized when working with remote replicas */ #define REMOTE_NLANES 1 /* * Helping structures for storing part's health status */ struct part_health_status { unsigned flags; struct badblocks bbs; /* structure with bad blocks */ char *recovery_file_name; /* name of bad block recovery file */ int recovery_file_exists; /* bad block recovery file exists */ }; /* * Helping structures for storing replica and poolset's health status */ struct replica_health_status { unsigned nparts; unsigned nhdrs; /* a flag for the replica */ unsigned flags; /* effective size of a pool, valid only for healthy replica */ size_t pool_size; /* flags for each part */ struct part_health_status part[]; }; struct poolset_health_status { unsigned nreplicas; /* a flag for the poolset */ unsigned flags; /* health statuses for each replica */ struct replica_health_status *replica[]; }; /* get index of the (r)th replica health status */ static inline unsigned REP_HEALTHidx(struct poolset_health_status *set, unsigned r) { ASSERTne(set->nreplicas, 0); return (set->nreplicas + r) % set->nreplicas; } /* get index of the (r + 1)th replica health status */ static inline unsigned REPN_HEALTHidx(struct poolset_health_status *set, unsigned r) { ASSERTne(set->nreplicas, 0); return (set->nreplicas + r + 1) % set->nreplicas; } /* get (p)th part health status */ static inline unsigned PART_HEALTHidx(struct replica_health_status *rep, unsigned p) { ASSERTne(rep->nparts, 0); return (rep->nparts + p) % rep->nparts; } /* get (r)th replica health status */ static inline struct replica_health_status * REP_HEALTH(struct poolset_health_status *set, unsigned r) { return set->replica[REP_HEALTHidx(set, r)]; } /* get (p)th part health status */ static inline unsigned PART_HEALTH(struct replica_health_status *rep, unsigned p) { return rep->part[PART_HEALTHidx(rep, p)].flags; } uint64_t replica_get_part_offset(struct pool_set *set, unsigned repn, unsigned partn); void replica_align_badblock_offset_length(size_t *offset, size_t *length, struct pool_set *set_in, unsigned repn, unsigned partn); size_t replica_get_part_data_len(struct pool_set *set_in, unsigned repn, unsigned partn); uint64_t replica_get_part_data_offset(struct pool_set *set_in, unsigned repn, unsigned part); /* * is_dry_run -- (internal) check whether only verification mode is enabled */ static inline bool is_dry_run(unsigned flags) { /* * PMEMPOOL_SYNC_DRY_RUN and PMEMPOOL_TRANSFORM_DRY_RUN * have to have the same value in order to use this common function. */ ASSERT_COMPILE_ERROR_ON(PMEMPOOL_SYNC_DRY_RUN != PMEMPOOL_TRANSFORM_DRY_RUN); return flags & PMEMPOOL_SYNC_DRY_RUN; } /* * fix_bad_blocks -- (internal) fix bad blocks - it causes reading or creating * bad blocks recovery files * (depending on if they exist or not) */ static inline bool fix_bad_blocks(unsigned flags) { return flags & PMEMPOOL_SYNC_FIX_BAD_BLOCKS; } int replica_remove_all_recovery_files(struct poolset_health_status *set_hs); int replica_remove_part(struct pool_set *set, unsigned repn, unsigned partn, int fix_bad_blocks); int replica_create_poolset_health_status(struct pool_set *set, struct poolset_health_status **set_hsp); void replica_free_poolset_health_status(struct poolset_health_status *set_s); int replica_check_poolset_health(struct pool_set *set, struct poolset_health_status **set_hs, int called_from_sync, unsigned flags); int replica_is_part_broken(unsigned repn, unsigned partn, struct poolset_health_status *set_hs); int replica_has_bad_blocks(unsigned repn, struct poolset_health_status *set_hs); int replica_part_has_bad_blocks(struct part_health_status *phs); int replica_part_has_corrupted_header(unsigned repn, unsigned partn, struct poolset_health_status *set_hs); unsigned replica_find_unbroken_part(unsigned repn, struct poolset_health_status *set_hs); int replica_is_replica_broken(unsigned repn, struct poolset_health_status *set_hs); int replica_is_replica_consistent(unsigned repn, struct poolset_health_status *set_hs); int replica_is_replica_healthy(unsigned repn, struct poolset_health_status *set_hs); unsigned replica_find_healthy_replica( struct poolset_health_status *set_hs); unsigned replica_find_replica_healthy_header( struct poolset_health_status *set_hs); int replica_is_poolset_healthy(struct poolset_health_status *set_hs); int replica_is_poolset_transformed(unsigned flags); ssize_t replica_get_pool_size(struct pool_set *set, unsigned repn); int replica_check_part_sizes(struct pool_set *set, size_t min_size); int replica_check_part_dirs(struct pool_set *set); int replica_check_local_part_dir(struct pool_set *set, unsigned repn, unsigned partn); int replica_open_replica_part_files(struct pool_set *set, unsigned repn); int replica_open_poolset_part_files(struct pool_set *set); int replica_sync(struct pool_set *set_in, struct poolset_health_status *set_hs, unsigned flags); int replica_transform(struct pool_set *set_in, struct pool_set *set_out, unsigned flags); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/libpmempool/check_backup.c0000664000000000000000000001744014123364546017120 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * check_backup.c -- pre-check backup */ #include #include #include #include "out.h" #include "file.h" #include "os.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum question { Q_OVERWRITE_EXISTING_FILE, Q_OVERWRITE_EXISTING_PARTS }; /* * location_release -- (internal) release poolset structure */ static void location_release(location *loc) { if (loc->set) { util_poolset_free(loc->set); loc->set = NULL; } } /* * backup_nonpoolset_requirements -- (internal) check backup requirements */ static int backup_nonpoolset_requirements(PMEMpoolcheck *ppc, location *loc) { LOG(3, "backup_path %s", ppc->backup_path); int exists = util_file_exists(ppc->backup_path); if (exists < 0) { return CHECK_ERR(ppc, "unable to access the backup destination: %s", ppc->backup_path); } if (!exists) { errno = 0; return 0; } if ((size_t)util_file_get_size(ppc->backup_path) != ppc->pool->set_file->size) { ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "destination of the backup does not match the size of the source pool file: %s", ppc->backup_path); } if (CHECK_WITHOUT_FIXING(ppc)) { location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } CHECK_ASK(ppc, Q_OVERWRITE_EXISTING_FILE, "destination of the backup already exists.|Do you want to overwrite it?"); return check_questions_sequence_validate(ppc); } /* * backup_nonpoolset_overwrite -- (internal) overwrite pool */ static int backup_nonpoolset_overwrite(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_OVERWRITE_EXISTING_FILE: if (pool_copy(ppc->pool, ppc->backup_path, 1 /* overwrite */)) { location_release(loc); ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "cannot perform backup"); } location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; default: ERR("not implemented question id: %u", question); } return 0; } /* * backup_nonpoolset_create -- (internal) create backup */ static int backup_nonpoolset_create(PMEMpoolcheck *ppc, location *loc) { CHECK_INFO(ppc, "creating backup file: %s", ppc->backup_path); if (pool_copy(ppc->pool, ppc->backup_path, 0)) { location_release(loc); ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "cannot perform backup"); } location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } /* * backup_poolset_requirements -- (internal) check backup requirements */ static int backup_poolset_requirements(PMEMpoolcheck *ppc, location *loc) { LOG(3, "backup_path %s", ppc->backup_path); if (ppc->pool->set_file->poolset->nreplicas > 1) { CHECK_INFO(ppc, "backup of a poolset with multiple replicas is not supported"); goto err; } if (pool_set_parse(&loc->set, ppc->backup_path)) { CHECK_INFO_ERRNO(ppc, "invalid poolset backup file: %s", ppc->backup_path); goto err; } if (loc->set->nreplicas > 1) { CHECK_INFO(ppc, "backup to a poolset with multiple replicas is not supported"); goto err_poolset; } ASSERTeq(loc->set->nreplicas, 1); struct pool_replica *srep = ppc->pool->set_file->poolset->replica[0]; struct pool_replica *drep = loc->set->replica[0]; if (srep->nparts != drep->nparts) { CHECK_INFO(ppc, "number of part files in the backup poolset must match number of part files in the source poolset"); goto err_poolset; } int overwrite_required = 0; for (unsigned p = 0; p < srep->nparts; p++) { int exists = util_file_exists(drep->part[p].path); if (exists < 0) { CHECK_INFO(ppc, "unable to access the part of the destination poolset: %s", ppc->backup_path); goto err_poolset; } if (srep->part[p].filesize != drep->part[p].filesize) { CHECK_INFO(ppc, "size of the part %u of the backup poolset does not match source poolset", p); goto err_poolset; } if (!exists) { errno = 0; continue; } overwrite_required = true; if ((size_t)util_file_get_size(drep->part[p].path) != srep->part[p].filesize) { CHECK_INFO(ppc, "destination of the backup part does not match size of the source part file: %s", drep->part[p].path); goto err_poolset; } } if (CHECK_WITHOUT_FIXING(ppc)) { location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } if (overwrite_required) { CHECK_ASK(ppc, Q_OVERWRITE_EXISTING_PARTS, "part files of the destination poolset of the backup already exist.|" "Do you want to overwrite them?"); } return check_questions_sequence_validate(ppc); err_poolset: location_release(loc); err: ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "unable to backup poolset"); } /* * backup_poolset -- (internal) backup the poolset */ static int backup_poolset(PMEMpoolcheck *ppc, location *loc, int overwrite) { struct pool_replica *srep = ppc->pool->set_file->poolset->replica[0]; struct pool_replica *drep = loc->set->replica[0]; for (unsigned p = 0; p < srep->nparts; p++) { if (overwrite == 0) { CHECK_INFO(ppc, "creating backup file: %s", drep->part[p].path); } if (pool_set_part_copy(&drep->part[p], &srep->part[p], overwrite)) { location_release(loc); ppc->result = CHECK_RESULT_ERROR; CHECK_INFO(ppc, "unable to create backup file"); return CHECK_ERR(ppc, "unable to backup poolset"); } } return 0; } /* * backup_poolset_overwrite -- (internal) backup poolset with overwrite */ static int backup_poolset_overwrite(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_OVERWRITE_EXISTING_PARTS: if (backup_poolset(ppc, loc, 1 /* overwrite */)) { location_release(loc); ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "cannot perform backup"); } location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; default: ERR("not implemented question id: %u", question); } return 0; } /* * backup_poolset_create -- (internal) backup poolset */ static int backup_poolset_create(PMEMpoolcheck *ppc, location *loc) { if (backup_poolset(ppc, loc, 0)) { location_release(loc); ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "cannot perform backup"); } location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); int poolset; }; static const struct step steps[] = { { .check = backup_nonpoolset_requirements, .poolset = false, }, { .fix = backup_nonpoolset_overwrite, .poolset = false, }, { .check = backup_nonpoolset_create, .poolset = false }, { .check = backup_poolset_requirements, .poolset = true, }, { .fix = backup_poolset_overwrite, .poolset = true, }, { .check = backup_poolset_create, .poolset = true }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); const struct step *step = &steps[loc->step++]; if (step->poolset == 0 && ppc->pool->params.is_poolset == 1) return 0; if (!step->fix) return step->check(ppc, loc); if (!check_has_answer(ppc->data)) return 0; if (check_answer_loop(ppc, loc, NULL, 1, step->fix)) return -1; ppc->result = CHECK_RESULT_CONSISTENT; return 0; } /* * check_backup -- perform backup if requested and needed */ void check_backup(PMEMpoolcheck *ppc) { LOG(3, "backup_path %s", ppc->backup_path); if (ppc->backup_path == NULL) return; location *loc = check_get_step_data(ppc->data); /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps)) { if (step_exe(ppc, loc)) break; } } pmdk-1.11.1/src/libpmempool/replica.c0000664000000000000000000017112614123364546016137 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * replica.c -- groups all commands for replica manipulation */ #include "replica.h" #include #include #include #include #include #include #include #include #include #include "obj.h" #include "palloc.h" #include "file.h" #include "os.h" #include "out.h" #include "pool_hdr.h" #include "set.h" #include "util.h" #include "uuid.h" #include "shutdown_state.h" #include "badblocks.h" #include "set_badblocks.h" /* * check_flags_sync -- (internal) check if flags are supported for sync */ static int check_flags_sync(unsigned flags) { flags &= ~(PMEMPOOL_SYNC_DRY_RUN | PMEMPOOL_SYNC_FIX_BAD_BLOCKS); return flags > 0; } /* * check_flags_transform -- (internal) check if flags are supported for * transform */ static int check_flags_transform(unsigned flags) { flags &= ~PMEMPOOL_TRANSFORM_DRY_RUN; return flags > 0; } /* * replica_align_badblock_offset_length -- align offset and length * of the bad block for the given part */ void replica_align_badblock_offset_length(size_t *offset, size_t *length, struct pool_set *set_in, unsigned repn, unsigned partn) { LOG(3, "offset %zu, length %zu, pool_set %p, replica %u, part %u", *offset, *length, set_in, repn, partn); size_t alignment = set_in->replica[repn]->part[partn].alignment; size_t off = ALIGN_DOWN(*offset, alignment); size_t len = ALIGN_UP(*length + (*offset - off), alignment); *offset = off; *length = len; } /* * replica_get_part_data_len -- get data length for given part */ size_t replica_get_part_data_len(struct pool_set *set_in, unsigned repn, unsigned partn) { size_t alignment = set_in->replica[repn]->part[partn].alignment; size_t hdrsize = (set_in->options & OPTION_SINGLEHDR) ? 0 : alignment; return ALIGN_DOWN(set_in->replica[repn]->part[partn].filesize, alignment) - ((partn == 0) ? POOL_HDR_SIZE : hdrsize); } /* * replica_get_part_offset -- get part's offset from the beginning of replica */ uint64_t replica_get_part_offset(struct pool_set *set, unsigned repn, unsigned partn) { return (uint64_t)set->replica[repn]->part[partn].addr - (uint64_t)set->replica[repn]->part[0].addr; } /* * replica_get_part_data_offset -- get data length before given part */ uint64_t replica_get_part_data_offset(struct pool_set *set, unsigned repn, unsigned partn) { if (partn == 0) return POOL_HDR_SIZE; return (uint64_t)set->replica[repn]->part[partn].addr - (uint64_t)set->replica[repn]->part[0].addr; } /* * replica_remove_part -- unlink part from replica */ int replica_remove_part(struct pool_set *set, unsigned repn, unsigned partn, int fix_bad_blocks) { LOG(3, "set %p repn %u partn %u fix_bad_blocks %i", set, repn, partn, fix_bad_blocks); struct pool_set_part *part = PART(REP(set, repn), partn); if (part->fd != -1) { os_close(part->fd); part->fd = -1; } int olderrno = errno; enum file_type type = util_file_get_type(part->path); if (type == OTHER_ERROR) return -1; /* if the part is a device dax, clear its bad blocks */ if (type == TYPE_DEVDAX && fix_bad_blocks && badblocks_clear_all(part->path)) { ERR("clearing bad blocks in device dax failed -- '%s'", part->path); errno = EIO; return -1; } if (type == TYPE_NORMAL && util_unlink(part->path)) { ERR("!removing part %u from replica %u failed", partn, repn); return -1; } errno = olderrno; LOG(4, "Removed part %s number %u from replica %u", part->path, partn, repn); return 0; } /* * create_replica_health_status -- (internal) create helping structure for * storing replica's health status */ static struct replica_health_status * create_replica_health_status(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); unsigned nparts = set->replica[repn]->nparts; struct replica_health_status *replica_hs; replica_hs = Zalloc(sizeof(struct replica_health_status) + nparts * sizeof(struct part_health_status)); if (replica_hs == NULL) { ERR("!Zalloc for replica health status"); return NULL; } replica_hs->nparts = nparts; replica_hs->nhdrs = set->replica[repn]->nhdrs; return replica_hs; } /* * replica_part_remove_recovery_file -- remove bad blocks' recovery file */ static int replica_part_remove_recovery_file(struct part_health_status *phs) { LOG(3, "phs %p", phs); if (phs->recovery_file_name == NULL || phs->recovery_file_exists == 0) return 0; if (os_unlink(phs->recovery_file_name) < 0) { ERR("!removing the bad block recovery file failed -- '%s'", phs->recovery_file_name); return -1; } LOG(3, "bad block recovery file removed -- '%s'", phs->recovery_file_name); phs->recovery_file_exists = 0; return 0; } /* * replica_remove_all_recovery_files -- remove all recovery files */ int replica_remove_all_recovery_files(struct poolset_health_status *set_hs) { LOG(3, "set_hs %p", set_hs); int ret = 0; for (unsigned r = 0; r < set_hs->nreplicas; ++r) { struct replica_health_status *rhs = set_hs->replica[r]; for (unsigned p = 0; p < rhs->nparts; ++p) ret |= replica_part_remove_recovery_file(&rhs->part[p]); } return ret; } /* * replica_free_poolset_health_status -- free memory allocated for helping * structure */ void replica_free_poolset_health_status(struct poolset_health_status *set_hs) { LOG(3, "set_hs %p", set_hs); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { struct replica_health_status *rep_hs = set_hs->replica[r]; for (unsigned p = 0; p < rep_hs->nparts; ++p) { Free(rep_hs->part[p].recovery_file_name); Free(rep_hs->part[p].bbs.bbv); } Free(set_hs->replica[r]); } Free(set_hs); } /* * replica_create_poolset_health_status -- create helping structure for storing * poolset's health status */ int replica_create_poolset_health_status(struct pool_set *set, struct poolset_health_status **set_hsp) { LOG(3, "set %p, set_hsp %p", set, set_hsp); unsigned nreplicas = set->nreplicas; struct poolset_health_status *set_hs; set_hs = Zalloc(sizeof(struct poolset_health_status) + nreplicas * sizeof(struct replica_health_status *)); if (set_hs == NULL) { ERR("!Zalloc for poolset health state"); return -1; } set_hs->nreplicas = nreplicas; for (unsigned i = 0; i < nreplicas; ++i) { struct replica_health_status *replica_hs = create_replica_health_status(set, i); if (replica_hs == NULL) { replica_free_poolset_health_status(set_hs); return -1; } set_hs->replica[i] = replica_hs; } *set_hsp = set_hs; return 0; } /* * replica_is_part_broken -- check if part is marked as broken in the helping * structure */ int replica_is_part_broken(unsigned repn, unsigned partn, struct poolset_health_status *set_hs) { struct replica_health_status *rhs = REP_HEALTH(set_hs, repn); return (rhs->flags & IS_BROKEN) || (PART_HEALTH(rhs, partn) & IS_BROKEN); } /* * is_replica_broken -- check if any part in the replica is marked as broken */ int replica_is_replica_broken(unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "repn %u, set_hs %p", repn, set_hs); struct replica_health_status *r_hs = REP_HEALTH(set_hs, repn); if (r_hs->flags & IS_BROKEN) return 1; for (unsigned p = 0; p < r_hs->nparts; ++p) { if (replica_is_part_broken(repn, p, set_hs)) return 1; } return 0; } /* * replica_is_replica_consistent -- check if replica is not marked as * inconsistent */ int replica_is_replica_consistent(unsigned repn, struct poolset_health_status *set_hs) { return !(REP_HEALTH(set_hs, repn)->flags & IS_INCONSISTENT); } /* * replica_has_bad_blocks -- check if replica has bad blocks */ int replica_has_bad_blocks(unsigned repn, struct poolset_health_status *set_hs) { return REP_HEALTH(set_hs, repn)->flags & HAS_BAD_BLOCKS; } /* * replica_part_has_bad_blocks -- check if replica's part has bad blocks */ int replica_part_has_bad_blocks(struct part_health_status *phs) { return phs->flags & HAS_BAD_BLOCKS; } /* * replica_part_has_corrupted_header -- (internal) check if replica's part * has bad blocks in the header (corrupted header) */ int replica_part_has_corrupted_header(unsigned repn, unsigned partn, struct poolset_health_status *set_hs) { struct replica_health_status *rhs = REP_HEALTH(set_hs, repn); return PART_HEALTH(rhs, partn) & HAS_CORRUPTED_HEADER; } /* * replica_has_corrupted_header -- (internal) check if replica has bad blocks * in the header (corrupted header) */ static int replica_has_corrupted_header(unsigned repn, struct poolset_health_status *set_hs) { return REP_HEALTH(set_hs, repn)->flags & HAS_CORRUPTED_HEADER; } /* * replica_is_replica_healthy -- check if replica is unbroken and consistent */ int replica_is_replica_healthy(unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "repn %u, set_hs %p", repn, set_hs); int ret = !replica_is_replica_broken(repn, set_hs) && replica_is_replica_consistent(repn, set_hs) && !replica_has_bad_blocks(repn, set_hs); LOG(4, "return %i", ret); return ret; } /* * replica_has_healthy_header -- (internal) check if replica has healthy headers */ static int replica_has_healthy_header(unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "repn %u, set_hs %p", repn, set_hs); int ret = !replica_is_replica_broken(repn, set_hs) && replica_is_replica_consistent(repn, set_hs) && !replica_has_corrupted_header(repn, set_hs); LOG(4, "return %i", ret); return ret; } /* * replica_is_poolset_healthy -- check if all replicas in a poolset are not * marked as broken nor inconsistent in the * helping structure */ int replica_is_poolset_healthy(struct poolset_health_status *set_hs) { LOG(3, "set_hs %p", set_hs); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { if (!replica_is_replica_healthy(r, set_hs)) return 0; } return 1; } /* * replica_is_poolset_transformed -- check if the flag indicating a call from * pmempool_transform is on */ int replica_is_poolset_transformed(unsigned flags) { return flags & IS_TRANSFORMED; } /* * replica_find_unbroken_part_with_header -- find a part number in a given * replica, which is not marked as broken in the helping structure and contains * a pool header */ unsigned replica_find_unbroken_part(unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "repn %u, set_hs %p", repn, set_hs); for (unsigned p = 0; p < REP_HEALTH(set_hs, repn)->nhdrs; ++p) { if (!replica_is_part_broken(repn, p, set_hs)) return p; } return UNDEF_PART; } /* * replica_find_healthy_replica -- find a replica which is a good source of data */ unsigned replica_find_healthy_replica(struct poolset_health_status *set_hs) { LOG(3, "set_hs %p", set_hs); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { if (replica_is_replica_healthy(r, set_hs)) { LOG(4, "return %i", r); return r; } } LOG(4, "return %i", UNDEF_REPLICA); return UNDEF_REPLICA; } /* * replica_find_replica_healthy_header -- find a replica with a healthy header */ unsigned replica_find_replica_healthy_header(struct poolset_health_status *set_hs) { LOG(3, "set_hs %p", set_hs); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { if (replica_has_healthy_header(r, set_hs)) { LOG(4, "return %i", r); return r; } } LOG(4, "return %i", UNDEF_REPLICA); return UNDEF_REPLICA; } /* * replica_check_store_size -- (internal) store size from pool descriptor for * replica */ static int replica_check_store_size(struct pool_set *set, struct poolset_health_status *set_hs, unsigned repn) { LOG(3, "set %p, set_hs %p, repn %u", set, set_hs, repn); struct pool_replica *rep = set->replica[repn]; struct pmemobjpool pop; if (rep->remote) { memcpy(&pop.hdr, rep->part[0].hdr, sizeof(pop.hdr)); void *descr = (void *)((uintptr_t)&pop + POOL_HDR_SIZE); if (Rpmem_read(rep->remote->rpp, descr, POOL_HDR_SIZE, sizeof(pop) - POOL_HDR_SIZE, 0)) { return -1; } } else { /* round up map size to Mmap align size */ if (util_map_part(&rep->part[0], NULL, ALIGN_UP(sizeof(pop), rep->part[0].alignment), 0, MAP_SHARED, 1)) { return -1; } memcpy(&pop, rep->part[0].addr, sizeof(pop)); util_unmap_part(&rep->part[0]); } void *dscp = (void *)((uintptr_t)&pop + sizeof(pop.hdr)); if (!util_checksum(dscp, OBJ_DSC_P_SIZE, &pop.checksum, 0, 0)) { set_hs->replica[repn]->flags |= IS_BROKEN; return 0; } set_hs->replica[repn]->pool_size = pop.heap_offset + pop.heap_size; return 0; } /* * check_store_all_sizes -- (internal) store sizes from pool descriptor for all * healthy replicas */ static int check_store_all_sizes(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { if (!replica_has_healthy_header(r, set_hs)) continue; if (replica_check_store_size(set, set_hs, r)) return -1; } return 0; } /* * check_and_open_poolset_part_files -- (internal) for each part in a poolset * check if the part files are accessible, and if not, mark it as broken * in a helping structure; then open the part file */ static int check_and_open_poolset_part_files(struct pool_set *set, struct poolset_health_status *set_hs, unsigned flags) { LOG(3, "set %p, set_hs %p, flags %u", set, set_hs, flags); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; if (rep->remote) { if (util_replica_open_remote(set, r, 0)) { LOG(1, "cannot open remote replica no %u", r); return -1; } unsigned nlanes = REMOTE_NLANES; int ret = util_poolset_remote_open(rep, r, rep->repsize, 0, rep->part[0].addr, rep->resvsize, &nlanes); if (ret) { rep_hs->flags |= IS_BROKEN; LOG(1, "remote replica #%u marked as BROKEN", r); } continue; } for (unsigned p = 0; p < rep->nparts; ++p) { const char *path = rep->part[p].path; enum file_type type = util_file_get_type(path); if (type < 0 || os_access(path, R_OK|W_OK) != 0) { LOG(1, "part file %s is not accessible", path); errno = 0; rep_hs->part[p].flags |= IS_BROKEN; if (is_dry_run(flags)) continue; } if (util_part_open(&rep->part[p], 0, 0)) { if (type == TYPE_DEVDAX) { LOG(1, "opening part on Device DAX %s failed", path); return -1; } LOG(1, "opening part %s failed", path); errno = 0; rep_hs->part[p].flags |= IS_BROKEN; } } } return 0; } /* * map_all_unbroken_headers -- (internal) map all headers in a poolset, * skipping those marked as broken in a helping * structure */ static int map_all_unbroken_headers(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; if (rep->remote) continue; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(r, p, set_hs)) continue; LOG(4, "mapping header for part %u, replica %u", p, r); if (util_map_hdr(&rep->part[p], MAP_SHARED, 0) != 0) { LOG(1, "header mapping failed - part #%d", p); rep_hs->part[p].flags |= IS_BROKEN; } } } return 0; } /* * unmap_all_headers -- (internal) unmap all headers in a poolset */ static int unmap_all_headers(struct pool_set *set) { LOG(3, "set %p", set); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; util_replica_close(set, r); if (rep->remote && rep->remote->rpp) { Rpmem_close(rep->remote->rpp); rep->remote->rpp = NULL; } } return 0; } /* * check_checksums_and_signatures -- (internal) check if checksums * and signatures are correct for parts * in a given replica */ static int check_checksums_and_signatures(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); struct replica_health_status *rep_hs = REP_HEALTH(set_hs, r); /* * Checksums and signatures of remote replicas are checked * during opening them on the remote side by the rpmem daemon. * The local version of remote headers does not contain * such data. */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(r, p, set_hs)) continue; /* check part's checksum */ LOG(4, "checking checksum for part %u, replica %u", p, r); struct pool_hdr *hdr = HDR(rep, p); if (!util_checksum(hdr, sizeof(*hdr), &hdr->checksum, 0, POOL_HDR_CSUM_END_OFF(hdr))) { ERR("invalid checksum of pool header"); rep_hs->part[p].flags |= IS_BROKEN; } else if (util_is_zeroed(hdr, sizeof(*hdr))) { rep_hs->part[p].flags |= IS_BROKEN; } enum pool_type type = pool_hdr_get_type(hdr); if (type == POOL_TYPE_UNKNOWN) { ERR("invalid signature"); rep_hs->part[p].flags |= IS_BROKEN; } } } return 0; } /* * replica_badblocks_recovery_file_save -- save bad blocks in the bad blocks * recovery file before clearing them */ static int replica_badblocks_recovery_file_save(struct part_health_status *part_hs) { LOG(3, "part_health_status %p", part_hs); ASSERTeq(part_hs->recovery_file_exists, 1); ASSERTne(part_hs->recovery_file_name, NULL); struct badblocks *bbs = &part_hs->bbs; char *path = part_hs->recovery_file_name; int ret = -1; int fd = os_open(path, O_WRONLY | O_TRUNC); if (fd < 0) { ERR("!opening bad block recovery file failed -- '%s'", path); return -1; } FILE *recovery_file_name = os_fdopen(fd, "w"); if (recovery_file_name == NULL) { ERR( "!opening a file stream for bad block recovery file failed -- '%s'", path); os_close(fd); return -1; } /* save bad blocks */ for (unsigned i = 0; i < bbs->bb_cnt; i++) { ASSERT(bbs->bbv[i].length != 0); fprintf(recovery_file_name, "%zu %zu\n", bbs->bbv[i].offset, bbs->bbv[i].length); } if (fflush(recovery_file_name) == EOF) { ERR("!flushing bad block recovery file failed -- '%s'", path); goto exit_error; } if (os_fsync(fd) < 0) { ERR("!syncing bad block recovery file failed -- '%s'", path); goto exit_error; } /* save the finish flag */ fprintf(recovery_file_name, "0 0\n"); if (fflush(recovery_file_name) == EOF) { ERR("!flushing bad block recovery file failed -- '%s'", path); goto exit_error; } if (os_fsync(fd) < 0) { ERR("!syncing bad block recovery file failed -- '%s'", path); goto exit_error; } LOG(3, "bad blocks saved in the recovery file -- '%s'", path); ret = 0; exit_error: os_fclose(recovery_file_name); return ret; } /* * replica_part_badblocks_recovery_file_read -- read bad blocks * from the bad block recovery file * for the current part */ static int replica_part_badblocks_recovery_file_read(struct part_health_status *part_hs) { LOG(3, "part_health_status %p", part_hs); ASSERT(part_hs->recovery_file_exists); ASSERTne(part_hs->recovery_file_name, NULL); VEC(bbsvec, struct bad_block) bbv = VEC_INITIALIZER; char *path = part_hs->recovery_file_name; struct bad_block bb; int ret = -1; FILE *recovery_file = os_fopen(path, "r"); if (!recovery_file) { ERR("!opening the recovery file for reading failed -- '%s'", path); return -1; } unsigned long long min_offset = 0; /* minimum possible offset */ do { if (fscanf(recovery_file, "%zu %zu\n", &bb.offset, &bb.length) < 2) { LOG(1, "incomplete bad block recovery file -- '%s'", path); ret = 1; goto error_exit; } if (bb.offset == 0 && bb.length == 0) { /* finish_flag */ break; } /* check if bad blocks build an increasing sequence */ if (bb.offset < min_offset) { ERR( "wrong format of bad block recovery file (bad blocks are not sorted by the offset in ascending order) -- '%s'", path); errno = EINVAL; ret = -1; goto error_exit; } /* update the minimum possible offset */ min_offset = bb.offset + bb.length; bb.nhealthy = NO_HEALTHY_REPLICA; /* unknown healthy replica */ /* add the new bad block to the vector */ if (VEC_PUSH_BACK(&bbv, bb)) goto error_exit; } while (1); part_hs->bbs.bbv = VEC_ARR(&bbv); part_hs->bbs.bb_cnt = (unsigned)VEC_SIZE(&bbv); os_fclose(recovery_file); LOG(1, "bad blocks read from the recovery file -- '%s'", path); return 0; error_exit: VEC_DELETE(&bbv); os_fclose(recovery_file); return ret; } /* status returned by the replica_badblocks_recovery_files_check() function */ enum badblocks_recovery_files_status { RECOVERY_FILES_ERROR = -1, RECOVERY_FILES_DO_NOT_EXIST = 0, RECOVERY_FILES_EXIST_ALL = 1, RECOVERY_FILES_NOT_ALL_EXIST = 2 }; /* * replica_badblocks_recovery_files_check -- (internal) check if bad blocks * recovery files exist */ static enum badblocks_recovery_files_status replica_badblocks_recovery_files_check(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); int recovery_file_exists = 0; int recovery_file_does_not_exist = 0; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; if (rep->remote) { /* * Bad blocks in remote replicas currently are fixed * during opening by removing and recreating * the whole remote replica. */ continue; } for (unsigned p = 0; p < rep->nparts; ++p) { const char *path = PART(rep, p)->path; struct part_health_status *part_hs = &rep_hs->part[p]; int exists = util_file_exists(path); if (exists < 0) return -1; if (!exists) { /* part file does not exist - skip it */ continue; } part_hs->recovery_file_name = badblocks_recovery_file_alloc(set->path, r, p); if (part_hs->recovery_file_name == NULL) { LOG(1, "allocating name of bad block recovery file failed"); return RECOVERY_FILES_ERROR; } exists = util_file_exists(part_hs->recovery_file_name); if (exists < 0) return -1; part_hs->recovery_file_exists = exists; if (part_hs->recovery_file_exists) { LOG(3, "bad block recovery file exists: %s", part_hs->recovery_file_name); recovery_file_exists = 1; } else { LOG(3, "bad block recovery file does not exist: %s", part_hs->recovery_file_name); recovery_file_does_not_exist = 1; } } } if (recovery_file_exists) { if (recovery_file_does_not_exist) { LOG(4, "return RECOVERY_FILES_NOT_ALL_EXIST"); return RECOVERY_FILES_NOT_ALL_EXIST; } else { LOG(4, "return RECOVERY_FILES_EXIST_ALL"); return RECOVERY_FILES_EXIST_ALL; } } LOG(4, "return RECOVERY_FILES_DO_NOT_EXIST"); return RECOVERY_FILES_DO_NOT_EXIST; } /* * replica_badblocks_recovery_files_read -- (internal) read bad blocks from all * bad block recovery files for all parts */ static int replica_badblocks_recovery_files_read(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); int ret; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; /* XXX: not supported yet */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { const char *path = PART(rep, p)->path; struct part_health_status *part_hs = &rep_hs->part[p]; int exists = util_file_exists(path); if (exists < 0) return -1; if (!exists) { /* the part does not exist */ continue; } LOG(1, "reading bad blocks from the recovery file -- '%s'", part_hs->recovery_file_name); ret = replica_part_badblocks_recovery_file_read( part_hs); if (ret < 0) { LOG(1, "reading bad blocks from the recovery file failed -- '%s'", part_hs->recovery_file_name); return -1; } if (ret > 0) { LOG(1, "incomplete bad block recovery file detected -- '%s'", part_hs->recovery_file_name); return 1; } if (part_hs->bbs.bb_cnt) { LOG(3, "part %u contains %u bad blocks -- '%s'", p, part_hs->bbs.bb_cnt, path); } } } return 0; } /* * replica_badblocks_recovery_files_create_empty -- (internal) create one empty * bad block recovery file * for each part file */ static int replica_badblocks_recovery_files_create_empty(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); struct part_health_status *part_hs; const char *path; int fd; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; /* XXX: not supported yet */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { part_hs = &rep_hs->part[p]; path = PART(rep, p)->path; if (!part_hs->recovery_file_name) continue; fd = os_open(part_hs->recovery_file_name, O_RDWR | O_CREAT | O_EXCL, 0600); if (fd < 0) { ERR( "!creating an empty bad block recovery file failed -- '%s' (part file '%s')", part_hs->recovery_file_name, path); return -1; } os_close(fd); char *file_name = Strdup(part_hs->recovery_file_name); if (file_name == NULL) { ERR("!Strdup"); return -1; } char *dir_name = dirname(file_name); /* fsync the file's directory */ if (os_fsync_dir(dir_name) < 0) { ERR( "!syncing the directory of the bad block recovery file failed -- '%s' (part file '%s')", dir_name, path); Free(file_name); return -1; } Free(file_name); part_hs->recovery_file_exists = 1; } } return 0; } /* * replica_badblocks_recovery_files_save -- (internal) save bad blocks * in the bad block recovery files */ static int replica_badblocks_recovery_files_save(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; /* XXX: not supported yet */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { struct part_health_status *part_hs = &rep_hs->part[p]; if (!part_hs->recovery_file_name) continue; int ret = replica_badblocks_recovery_file_save(part_hs); if (ret < 0) { LOG(1, "opening bad block recovery file failed -- '%s'", part_hs->recovery_file_name); return -1; } } } return 0; } /* * replica_badblocks_get -- (internal) get all bad blocks and save them * in part_hs->bbs structures. * Returns 1 if any bad block was found, 0 otherwise. */ static int replica_badblocks_get(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); int bad_blocks_found = 0; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; /* XXX: not supported yet */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { const char *path = PART(rep, p)->path; struct part_health_status *part_hs = &rep_hs->part[p]; int exists = util_file_exists(path); if (exists < 0) return -1; if (!exists) continue; int ret = badblocks_get(path, &part_hs->bbs); if (ret < 0) { ERR( "!checking the pool part for bad blocks failed -- '%s'", path); return -1; } if (part_hs->bbs.bb_cnt) { LOG(3, "part %u contains %u bad blocks -- '%s'", p, part_hs->bbs.bb_cnt, path); bad_blocks_found = 1; } } } return bad_blocks_found; } /* * check_badblocks_in_header -- (internal) check if bad blocks corrupted * the header */ static int check_badblocks_in_header(struct badblocks *bbs) { for (unsigned b = 0; b < bbs->bb_cnt; b++) if (bbs->bbv[b].offset < POOL_HDR_SIZE) return 1; return 0; } /* * replica_badblocks_clear -- (internal) clear all bad blocks */ static int replica_badblocks_clear(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); int ret; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; /* XXX: not supported yet */ if (rep->remote) continue; for (unsigned p = 0; p < rep->nparts; ++p) { const char *path = PART(rep, p)->path; struct part_health_status *part_hs = &rep_hs->part[p]; int exists = util_file_exists(path); if (exists < 0) return -1; if (!exists) { /* the part does not exist */ continue; } if (part_hs->bbs.bb_cnt == 0) { /* no bad blocks found */ continue; } /* bad blocks were found */ part_hs->flags |= HAS_BAD_BLOCKS; rep_hs->flags |= HAS_BAD_BLOCKS; if (check_badblocks_in_header(&part_hs->bbs)) { part_hs->flags |= HAS_CORRUPTED_HEADER; if (p == 0) rep_hs->flags |= HAS_CORRUPTED_HEADER; } ret = badblocks_clear(path, &part_hs->bbs); if (ret < 0) { LOG(1, "clearing bad blocks in replica failed -- '%s'", path); return -1; } } } return 0; } /* * replica_badblocks_check_or_clear -- (internal) check if replica contains * bad blocks when in dry run * or clear them otherwise */ static int replica_badblocks_check_or_clear(struct pool_set *set, struct poolset_health_status *set_hs, int dry_run, int called_from_sync, int check_bad_blocks, int fix_bad_blocks) { LOG(3, "set %p, set_hs %p, dry_run %i, called_from_sync %i, " "check_bad_blocks %i, fix_bad_blocks %i", set, set_hs, dry_run, called_from_sync, check_bad_blocks, fix_bad_blocks); #define ERR_MSG_BB \ " please read the manual first and use this option\n"\ " ONLY IF you are sure that you know what you are doing" enum badblocks_recovery_files_status status; int ret; /* check all bad block recovery files */ status = replica_badblocks_recovery_files_check(set, set_hs); /* phase #1 - error handling */ switch (status) { case RECOVERY_FILES_ERROR: LOG(1, "checking bad block recovery files failed"); return -1; case RECOVERY_FILES_EXIST_ALL: case RECOVERY_FILES_NOT_ALL_EXIST: if (!called_from_sync) { ERR( "error: a bad block recovery file exists, run 'pmempool sync --bad-blocks' to fix bad blocks first"); return -1; } if (!fix_bad_blocks) { ERR( "error: a bad block recovery file exists, but the '--bad-blocks' option is not set\n" ERR_MSG_BB); return -1; } break; default: break; }; /* * The pool is checked for bad blocks only if: * 1) compat feature POOL_FEAT_CHECK_BAD_BLOCKS is set * OR: * 2) the '--bad-blocks' option is set * * Bad blocks are cleared and fixed only if: * - the '--bad-blocks' option is set */ if (!fix_bad_blocks && !check_bad_blocks) { LOG(3, "skipping bad blocks checking"); return 0; } /* phase #2 - reading recovery files */ switch (status) { case RECOVERY_FILES_EXIST_ALL: /* read all bad block recovery files */ ret = replica_badblocks_recovery_files_read(set, set_hs); if (ret < 0) { LOG(1, "checking bad block recovery files failed"); return -1; } if (ret > 0) { /* incomplete bad block recovery file was detected */ LOG(1, "warning: incomplete bad block recovery file detected\n" " - all recovery files will be removed"); /* changing status to RECOVERY_FILES_NOT_ALL_EXIST */ status = RECOVERY_FILES_NOT_ALL_EXIST; } break; case RECOVERY_FILES_NOT_ALL_EXIST: LOG(1, "warning: one of bad block recovery files does not exist\n" " - all recovery files will be removed"); break; default: break; }; if (status == RECOVERY_FILES_NOT_ALL_EXIST) { /* * At least one of bad block recovery files does not exist, * or an incomplete bad block recovery file was detected, * so all recovery files have to be removed. */ if (!dry_run) { LOG(1, "removing all bad block recovery files..."); ret = replica_remove_all_recovery_files(set_hs); if (ret < 0) { LOG(1, "removing bad block recovery files failed"); return -1; } } else { LOG(1, "all bad block recovery files would be removed"); } /* changing status to RECOVERY_FILES_DO_NOT_EXIST */ status = RECOVERY_FILES_DO_NOT_EXIST; } if (status == RECOVERY_FILES_DO_NOT_EXIST) { /* * There are no bad block recovery files, * so let's check bad blocks. */ int bad_blocks_found = replica_badblocks_get(set, set_hs); if (bad_blocks_found < 0) { if (errno == ENOTSUP) { LOG(1, BB_NOT_SUPP); return -1; } LOG(1, "checking bad blocks failed"); return -1; } if (!bad_blocks_found) { LOG(4, "no bad blocks found"); return 0; } /* bad blocks were found */ if (!called_from_sync) { ERR( "error: bad blocks found, run 'pmempool sync --bad-blocks' to fix bad blocks first"); return -1; } if (!fix_bad_blocks) { ERR( "error: bad blocks found, but the '--bad-blocks' option is not set\n" ERR_MSG_BB); return -1; } if (dry_run) { /* dry-run - do nothing */ LOG(1, "warning: bad blocks were found"); return 0; } /* create one empty recovery file for each part file */ ret = replica_badblocks_recovery_files_create_empty(set, set_hs); if (ret < 0) { LOG(1, "creating empty bad block recovery files failed"); return -1; } /* save bad blocks in recovery files */ ret = replica_badblocks_recovery_files_save(set, set_hs); if (ret < 0) { LOG(1, "saving bad block recovery files failed"); return -1; } } if (dry_run) { /* dry-run - do nothing */ LOG(1, "bad blocks would be cleared"); return 0; } ret = replica_badblocks_clear(set, set_hs); if (ret < 0) { ERR("clearing bad blocks failed"); return -1; } return 0; } /* * check_shutdown_state -- (internal) check if replica has * healthy shutdown_state */ static int check_shutdown_state(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) {\ struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; struct pool_hdr *hdrp = HDR(rep, 0); if (rep->remote) continue; if (hdrp == NULL) { /* cannot verify shutdown state */ rep_hs->flags |= IS_BROKEN; continue; } struct shutdown_state curr_sds; shutdown_state_init(&curr_sds, NULL); for (unsigned p = 0; p < rep->nparts; ++p) { if (PART(rep, p)->fd < 0) continue; if (shutdown_state_add_part(&curr_sds, PART(rep, p)->fd, NULL)) { rep_hs->flags |= IS_BROKEN; break; } } if (rep_hs->flags & IS_BROKEN) continue; /* make a copy of sds as we shouldn't modify a pool */ struct shutdown_state pool_sds = hdrp->sds; if (shutdown_state_check(&curr_sds, &pool_sds, NULL)) rep_hs->flags |= IS_BROKEN; } return 0; } /* * check_uuids_between_parts -- (internal) check if uuids between adjacent * parts are consistent for a given replica */ static int check_uuids_between_parts(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, set_hs %p", set, repn, set_hs); struct pool_replica *rep = REP(set, repn); /* check poolset_uuid consistency between replica's parts */ LOG(4, "checking consistency of poolset uuid in replica %u", repn); uuid_t poolset_uuid; int uuid_stored = 0; unsigned part_stored = UNDEF_PART; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; if (!uuid_stored) { memcpy(poolset_uuid, HDR(rep, p)->poolset_uuid, POOL_HDR_UUID_LEN); uuid_stored = 1; part_stored = p; continue; } if (uuidcmp(HDR(rep, p)->poolset_uuid, poolset_uuid)) { ERR( "different poolset uuids in parts from the same replica (repn %u, parts %u and %u) - cannot synchronize", repn, part_stored, p); errno = EINVAL; return -1; } } /* check if all uuids for adjacent replicas are the same across parts */ LOG(4, "checking consistency of adjacent replicas' uuids in replica %u", repn); unsigned unbroken_p = UNDEF_PART; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; if (unbroken_p == UNDEF_PART) { unbroken_p = p; continue; } struct pool_hdr *hdrp = HDR(rep, p); int prev_differ = uuidcmp(HDR(rep, unbroken_p)->prev_repl_uuid, hdrp->prev_repl_uuid); int next_differ = uuidcmp(HDR(rep, unbroken_p)->next_repl_uuid, hdrp->next_repl_uuid); if (prev_differ || next_differ) { ERR( "different adjacent replica UUID between parts (repn %u, parts %u and %u) - cannot synchronize", repn, unbroken_p, p); errno = EINVAL; return -1; } } /* check parts linkage */ LOG(4, "checking parts linkage in replica %u", repn); for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; struct pool_hdr *hdrp = HDR(rep, p); struct pool_hdr *next_hdrp = HDRN(rep, p); int next_is_broken = replica_is_part_broken(repn, p + 1, set_hs); if (!next_is_broken) { int next_decoupled = uuidcmp(next_hdrp->prev_part_uuid, hdrp->uuid) || uuidcmp(hdrp->next_part_uuid, next_hdrp->uuid); if (next_decoupled) { ERR( "two consecutive unbroken parts are not linked to each other (repn %u, parts %u and %u) - cannot synchronize", repn, p, p + 1); errno = EINVAL; return -1; } } } return 0; } /* * check_replicas_consistency -- (internal) check if all uuids within each * replica are consistent */ static int check_replicas_consistency(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { if (check_uuids_between_parts(set, r, set_hs)) return -1; } return 0; } /* * check_replica_options -- (internal) check if options are consistent in the * replica */ static int check_replica_options(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, set_hs %p", set, repn, set_hs); struct pool_replica *rep = REP(set, repn); struct replica_health_status *rep_hs = REP_HEALTH(set_hs, repn); for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; struct pool_hdr *hdr = HDR(rep, p); if (((hdr->features.incompat & POOL_FEAT_SINGLEHDR) == 0) != ((set->options & OPTION_SINGLEHDR) == 0)) { LOG(1, "improper options are set in part %u's header in replica %u", p, repn); rep_hs->part[p].flags |= IS_BROKEN; } } return 0; } /* * check_options -- (internal) check if options are consistent in all replicas */ static int check_options(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { if (check_replica_options(set, r, set_hs)) return -1; } return 0; } /* * check_replica_poolset_uuids - (internal) check if poolset_uuid fields are * consistent among all parts of a replica; * the replica is initially considered as * consistent */ static int check_replica_poolset_uuids(struct pool_set *set, unsigned repn, uuid_t poolset_uuid, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, poolset_uuid %p, set_hs %p", set, repn, poolset_uuid, set_hs); struct pool_replica *rep = REP(set, repn); for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; if (uuidcmp(HDR(rep, p)->poolset_uuid, poolset_uuid)) { /* * two internally consistent replicas have * different poolset_uuid */ return -1; } else { /* * it is sufficient to check only one part * from internally consistent replica */ break; } } return 0; } /* * check_poolset_uuids -- (internal) check if poolset_uuid fields are consistent * among all internally consistent replicas */ static int check_poolset_uuids(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); /* find a replica with healthy header */ unsigned r_h = replica_find_replica_healthy_header(set_hs); if (r_h == UNDEF_REPLICA) { ERR("no healthy replica found"); return -1; } uuid_t poolset_uuid; memcpy(poolset_uuid, HDR(REP(set, r_h), 0)->poolset_uuid, POOL_HDR_UUID_LEN); for (unsigned r = 0; r < set->nreplicas; ++r) { /* skip inconsistent replicas */ if (!replica_is_replica_consistent(r, set_hs) || r == r_h) continue; if (check_replica_poolset_uuids(set, r, poolset_uuid, set_hs)) { ERR( "inconsistent poolset uuids between replicas %u and %u - cannot synchronize", r_h, r); return -1; } } return 0; } /* * get_replica_uuid -- (internal) get replica uuid */ static int get_replica_uuid(struct pool_replica *rep, unsigned repn, struct poolset_health_status *set_hs, uuid_t **uuidpp) { unsigned nhdrs = rep->nhdrs; if (!replica_is_part_broken(repn, 0, set_hs)) { /* the first part is not broken */ *uuidpp = &HDR(rep, 0)->uuid; return 0; } else if (nhdrs > 1 && !replica_is_part_broken(repn, 1, set_hs)) { /* the second part is not broken */ *uuidpp = &HDR(rep, 1)->prev_part_uuid; return 0; } else if (nhdrs > 1 && !replica_is_part_broken(repn, nhdrs - 1, set_hs)) { /* the last part is not broken */ *uuidpp = &HDR(rep, nhdrs - 1)->next_part_uuid; return 0; } else { /* cannot get replica uuid */ return -1; } } /* * check_uuids_between_replicas -- (internal) check if uuids between internally * consistent adjacent replicas are consistent */ static int check_uuids_between_replicas(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { /* skip comparing inconsistent pairs of replicas */ if (!replica_is_replica_consistent(r, set_hs) || !replica_is_replica_consistent(r + 1, set_hs)) continue; struct pool_replica *rep = REP(set, r); struct pool_replica *rep_n = REPN(set, r); /* get uuids of the two adjacent replicas */ uuid_t *rep_uuidp = NULL; uuid_t *rep_n_uuidp = NULL; unsigned r_n = REPN_HEALTHidx(set_hs, r); if (get_replica_uuid(rep, r, set_hs, &rep_uuidp)) LOG(2, "cannot get replica uuid, replica %u", r); if (get_replica_uuid(rep_n, r_n, set_hs, &rep_n_uuidp)) LOG(2, "cannot get replica uuid, replica %u", r_n); /* * check if replica uuids are consistent between two adjacent * replicas */ unsigned p = replica_find_unbroken_part(r, set_hs); unsigned p_n = replica_find_unbroken_part(r_n, set_hs); if (p_n != UNDEF_PART && rep_uuidp != NULL && uuidcmp(*rep_uuidp, HDR(rep_n, p_n)->prev_repl_uuid)) { ERR( "inconsistent replica uuids between replicas %u and %u", r, r_n); return -1; } if (p != UNDEF_PART && rep_n_uuidp != NULL && uuidcmp(*rep_n_uuidp, HDR(rep, p)->next_repl_uuid)) { ERR( "inconsistent replica uuids between replicas %u and %u", r, r_n); return -1; } /* * check if replica uuids on borders of a broken replica are * consistent */ unsigned r_nn = REPN_HEALTHidx(set_hs, r_n); if (set->nreplicas > 1 && p != UNDEF_PART && replica_is_replica_broken(r_n, set_hs) && replica_is_replica_consistent(r_nn, set_hs)) { unsigned p_nn = replica_find_unbroken_part(r_nn, set_hs); if (p_nn == UNDEF_PART) { LOG(2, "cannot compare uuids on borders of replica %u", r); continue; } struct pool_replica *rep_nn = REP(set, r_nn); if (uuidcmp(HDR(rep, p)->next_repl_uuid, HDR(rep_nn, p_nn)->prev_repl_uuid)) { ERR( "inconsistent replica uuids on borders of replica %u", r); return -1; } } } return 0; } /* * check_replica_cycles -- (internal) check if healthy replicas form cycles * shorter than the number of all replicas */ static int check_replica_cycles(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); unsigned first_healthy; unsigned count_healthy = 0; for (unsigned r = 0; r < set->nreplicas; ++r) { if (!replica_is_replica_healthy(r, set_hs)) { count_healthy = 0; continue; } if (count_healthy == 0) first_healthy = r; ++count_healthy; struct pool_hdr *hdrh = PART(REP(set, first_healthy), 0)->hdr; struct pool_hdr *hdr = PART(REP(set, r), 0)->hdr; if (uuidcmp(hdrh->uuid, hdr->next_repl_uuid) == 0 && count_healthy < set->nreplicas) { /* * Healthy replicas form a cycle shorter than * the number of all replicas; for the user it * means that: */ ERR( "alien replica found (probably coming from a different poolset)"); return -1; } } return 0; } /* * check_replica_sizes -- (internal) check if all replicas are large * enough to hold data from a healthy replica */ static int check_replica_sizes(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); ssize_t pool_size = -1; for (unsigned r = 0; r < set->nreplicas; ++r) { /* skip broken replicas */ if (!replica_is_replica_healthy(r, set_hs)) continue; /* get the size of a pool in the replica */ ssize_t replica_pool_size; if (REP(set, r)->remote) /* XXX: no way to get the size of a remote pool yet */ replica_pool_size = (ssize_t)set->poolsize; else replica_pool_size = replica_get_pool_size(set, r); if (replica_pool_size < 0) { LOG(1, "getting pool size from replica %u failed", r); set_hs->replica[r]->flags |= IS_BROKEN; continue; } /* check if the pool is bigger than minimum size */ enum pool_type type = pool_hdr_get_type(HDR(REP(set, r), 0)); if ((size_t)replica_pool_size < pool_get_min_size(type)) { LOG(1, "pool size from replica %u is smaller than the minimum size allowed for the pool", r); set_hs->replica[r]->flags |= IS_BROKEN; continue; } /* check if each replica is big enough to hold the pool data */ if (set->poolsize < (size_t)replica_pool_size) { ERR( "some replicas are too small to hold synchronized data"); return -1; } if (pool_size < 0) { pool_size = replica_pool_size; continue; } /* check if pools in all healthy replicas are of equal size */ if (pool_size != replica_pool_size) { ERR("pool sizes from different replicas differ"); return -1; } } return 0; } /* * replica_read_features -- (internal) read features from the header */ static int replica_read_features(struct pool_set *set, struct poolset_health_status *set_hs, features_t *features) { LOG(3, "set %p set_hs %p features %p", set, set_hs, features); ASSERTne(features, NULL); for (unsigned r = 0; r < set->nreplicas; r++) { struct pool_replica *rep = set->replica[r]; struct replica_health_status *rep_hs = set_hs->replica[r]; if (rep->remote) { if (rep_hs->flags & IS_BROKEN) continue; struct pool_hdr *hdrp = rep->part[0].hdr; memcpy(features, &hdrp->features, sizeof(*features)); return 0; } for (unsigned p = 0; p < rep->nparts; p++) { struct pool_set_part *part = &rep->part[p]; if (part->fd == -1) continue; if (util_map_hdr(part, MAP_SHARED, 0) != 0) { LOG(1, "header mapping failed"); return -1; } struct pool_hdr *hdrp = part->hdr; memcpy(features, &hdrp->features, sizeof(*features)); util_unmap_hdr(part); return 0; } } /* no healthy replica/part found */ return -1; } /* * replica_check_poolset_health -- check if a given poolset can be considered as * healthy, and store the status in a helping structure */ int replica_check_poolset_health(struct pool_set *set, struct poolset_health_status **set_hsp, int called_from_sync, unsigned flags) { LOG(3, "set %p, set_hsp %p, called_from_sync %i, flags %u", set, set_hsp, called_from_sync, flags); if (replica_create_poolset_health_status(set, set_hsp)) { LOG(1, "creating poolset health status failed"); return -1; } struct poolset_health_status *set_hs = *set_hsp; /* check if part files exist and are accessible */ if (check_and_open_poolset_part_files(set, set_hs, flags)) { LOG(1, "poolset part files check failed"); goto err; } features_t features; int check_bad_blks; int fix_bad_blks = called_from_sync && fix_bad_blocks(flags); if (fix_bad_blks) { /* * We will fix bad blocks, so we cannot read features here, * because reading could fail, because of bad blocks. * We will read features after having bad blocks fixed. * * Fixing bad blocks implies checking bad blocks. */ check_bad_blks = 1; } else { /* * We will not fix bad blocks, so we have to read features here. */ if (replica_read_features(set, set_hs, &features)) { LOG(1, "reading features failed"); goto err; } check_bad_blks = features.compat & POOL_FEAT_CHECK_BAD_BLOCKS; } /* check for bad blocks when in dry run or clear them otherwise */ if (replica_badblocks_check_or_clear(set, set_hs, is_dry_run(flags), called_from_sync, check_bad_blks, fix_bad_blks)) { LOG(1, "replica bad_blocks check failed"); goto err; } /* read features after fixing bad blocks */ if (fix_bad_blks && replica_read_features(set, set_hs, &features)) { LOG(1, "reading features failed"); goto err; } /* set ignore_sds flag basing on features read from the header */ set->ignore_sds = !(features.incompat & POOL_FEAT_SDS); /* map all headers */ map_all_unbroken_headers(set, set_hs); /* * Check if checksums and signatures are correct for all parts * in all replicas. */ check_checksums_and_signatures(set, set_hs); /* check if option flags are consistent */ if (check_options(set, set_hs)) { LOG(1, "flags check failed"); goto err; } if (!set->ignore_sds && check_shutdown_state(set, set_hs)) { LOG(1, "replica shutdown_state check failed"); goto err; } /* check if uuids in parts across each replica are consistent */ if (check_replicas_consistency(set, set_hs)) { LOG(1, "replica consistency check failed"); goto err; } /* check poolset_uuid values between replicas */ if (check_poolset_uuids(set, set_hs)) { LOG(1, "poolset uuids check failed"); goto err; } /* check if uuids for adjacent replicas are consistent */ if (check_uuids_between_replicas(set, set_hs)) { LOG(1, "replica uuids check failed"); goto err; } /* check if healthy replicas make up another poolset */ if (check_replica_cycles(set, set_hs)) { LOG(1, "replica cycles check failed"); goto err; } /* check if replicas are large enough */ if (check_replica_sizes(set, set_hs)) { LOG(1, "replica sizes check failed"); goto err; } if (check_store_all_sizes(set, set_hs)) { LOG(1, "reading pool sizes failed"); goto err; } unmap_all_headers(set); util_poolset_fdclose_always(set); return 0; err: errno = EINVAL; unmap_all_headers(set); util_poolset_fdclose_always(set); replica_free_poolset_health_status(set_hs); return -1; } /* * replica_get_pool_size -- find the effective size (mapped) of a pool based * on metadata from given replica */ ssize_t replica_get_pool_size(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_set_part *part = PART(REP(set, repn), 0); int should_close_part = 0; int should_unmap_part = 0; if (part->fd == -1) { if (util_part_open(part, 0, 0)) return -1; should_close_part = 1; } if (part->addr == NULL) { if (util_map_part(part, NULL, ALIGN_UP(sizeof(PMEMobjpool), part->alignment), 0, MAP_SHARED, 1)) { util_part_fdclose(part); return -1; } should_unmap_part = 1; } PMEMobjpool *pop = (PMEMobjpool *)part->addr; ssize_t ret = (ssize_t)(pop->heap_offset + pop->heap_size); if (should_unmap_part) util_unmap_part(part); if (should_close_part) util_part_fdclose(part); return ret; } /* * replica_check_part_sizes -- check if all parts are large enough */ int replica_check_part_sizes(struct pool_set *set, size_t min_size) { LOG(3, "set %p, min_size %zu", set, min_size); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; if (rep->remote != NULL) /* skip remote replicas */ continue; for (unsigned p = 0; p < rep->nparts; ++p) { if (PART(rep, p)->filesize < min_size) { ERR("replica %u, part %u: file is too small", r, p); errno = EINVAL; return -1; } } } return 0; } /* * replica_check_local_part_dir -- check if directory for the part file * exists */ int replica_check_local_part_dir(struct pool_set *set, unsigned repn, unsigned partn) { LOG(3, "set %p, repn %u, partn %u", set, repn, partn); char *path = Strdup(PART(REP(set, repn), partn)->path); const char *dir = dirname(path); os_stat_t sb; if (os_stat(dir, &sb) != 0 || !(sb.st_mode & S_IFDIR)) { ERR( "directory %s for part %u in replica %u does not exist or is not accessible", path, partn, repn); Free(path); return -1; } Free(path); return 0; } /* * replica_check_part_dirs -- (internal) check if directories for part files * exist */ int replica_check_part_dirs(struct pool_set *set) { LOG(3, "set %p", set); for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = set->replica[r]; if (rep->remote != NULL) /* skip remote replicas */ continue; for (unsigned p = 0; p < rep->nparts; ++p) { if (replica_check_local_part_dir(set, r, p)) return -1; } } return 0; } /* * replica_open_replica_part_files -- open all part files for a replica */ int replica_open_replica_part_files(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_replica *rep = set->replica[repn]; for (unsigned p = 0; p < rep->nparts; ++p) { /* skip already opened files */ if (rep->part[p].fd != -1) continue; if (util_part_open(&rep->part[p], 0, 0)) { LOG(1, "part files open failed for replica %u, part %u", repn, p); errno = EINVAL; goto err; } } return 0; err: util_replica_fdclose(set->replica[repn]); return -1; } /* * replica_open_poolset_part_files -- open all part files for a poolset */ int replica_open_poolset_part_files(struct pool_set *set) { LOG(3, "set %p", set); for (unsigned r = 0; r < set->nreplicas; ++r) { if (set->replica[r]->remote) continue; if (replica_open_replica_part_files(set, r)) { LOG(1, "opening replica %u, part files failed", r); goto err; } } return 0; err: util_poolset_fdclose_always(set); return -1; } /* * pmempool_syncU -- synchronize replicas within a poolset */ #ifndef _WIN32 static inline #endif int pmempool_syncU(const char *poolset, unsigned flags) { LOG(3, "poolset %s, flags %u", poolset, flags); ASSERTne(poolset, NULL); /* check if poolset has correct signature */ if (util_is_poolset_file(poolset) != 1) { ERR("file is not a poolset file"); goto err; } /* check if flags are supported */ if (check_flags_sync(flags)) { ERR("unsupported flags"); errno = EINVAL; goto err; } /* open poolset file */ int fd = util_file_open(poolset, NULL, 0, O_RDONLY); if (fd < 0) { ERR("cannot open a poolset file"); goto err; } /* fill up pool_set structure */ struct pool_set *set = NULL; if (util_poolset_parse(&set, poolset, fd)) { ERR("parsing input poolset failed"); goto err_close_file; } if (set->nreplicas == 1) { ERR("no replica(s) found in the pool set"); errno = EINVAL; goto err_close_file; } if (set->remote && util_remote_load()) { ERR("remote replication not available"); errno = ENOTSUP; goto err_close_file; } /* sync all replicas */ if (replica_sync(set, NULL, flags)) { LOG(1, "synchronization failed"); goto err_close_all; } util_poolset_close(set, DO_NOT_DELETE_PARTS); os_close(fd); return 0; err_close_all: util_poolset_close(set, DO_NOT_DELETE_PARTS); err_close_file: os_close(fd); err: if (errno == 0) errno = EINVAL; return -1; } #ifndef _WIN32 /* * pmempool_sync -- synchronize replicas within a poolset */ int pmempool_sync(const char *poolset, unsigned flags) { return pmempool_syncU(poolset, flags); } #else /* * pmempool_syncW -- synchronize replicas within a poolset in widechar */ int pmempool_syncW(const wchar_t *poolset, unsigned flags) { char *path = util_toUTF8(poolset); if (path == NULL) { ERR("Invalid poolest file path."); return -1; } int ret = pmempool_syncU(path, flags); util_free_UTF8(path); return ret; } #endif /* * pmempool_transformU -- alter poolset structure */ #ifndef _WIN32 static inline #endif int pmempool_transformU(const char *poolset_src, const char *poolset_dst, unsigned flags) { LOG(3, "poolset_src %s, poolset_dst %s, flags %u", poolset_src, poolset_dst, flags); ASSERTne(poolset_src, NULL); ASSERTne(poolset_dst, NULL); /* check if the source poolset has correct signature */ if (util_is_poolset_file(poolset_src) != 1) { ERR("source file is not a poolset file"); goto err; } /* check if the destination poolset has correct signature */ if (util_is_poolset_file(poolset_dst) != 1) { ERR("destination file is not a poolset file"); goto err; } /* check if flags are supported */ if (check_flags_transform(flags)) { ERR("unsupported flags"); errno = EINVAL; goto err; } /* open the source poolset file */ int fd_in = util_file_open(poolset_src, NULL, 0, O_RDONLY); if (fd_in < 0) { ERR("cannot open source poolset file"); goto err; } /* parse the source poolset file */ struct pool_set *set_in = NULL; if (util_poolset_parse(&set_in, poolset_src, fd_in)) { ERR("parsing source poolset failed"); os_close(fd_in); goto err; } os_close(fd_in); /* open the destination poolset file */ int fd_out = util_file_open(poolset_dst, NULL, 0, O_RDONLY); if (fd_out < 0) { ERR("cannot open destination poolset file"); goto err; } enum del_parts_mode del = DO_NOT_DELETE_PARTS; /* parse the destination poolset file */ struct pool_set *set_out = NULL; if (util_poolset_parse(&set_out, poolset_dst, fd_out)) { ERR("parsing destination poolset failed"); os_close(fd_out); goto err_free_poolin; } os_close(fd_out); /* check if the source poolset is of a correct type */ enum pool_type ptype = pool_set_type(set_in); if (ptype != POOL_TYPE_OBJ) { errno = EINVAL; ERR("transform is not supported for given pool type: %s", pool_get_pool_type_str(ptype)); goto err_free_poolout; } /* load remote library if needed */ if (set_in->remote && util_remote_load()) { ERR("remote replication not available"); goto err_free_poolout; } if (set_out->remote && util_remote_load()) { ERR("remote replication not available"); goto err_free_poolout; } del = is_dry_run(flags) ? DO_NOT_DELETE_PARTS : DELETE_CREATED_PARTS; /* transform poolset */ if (replica_transform(set_in, set_out, flags)) { LOG(1, "transformation failed"); goto err_free_poolout; } util_poolset_close(set_in, DO_NOT_DELETE_PARTS); util_poolset_close(set_out, DO_NOT_DELETE_PARTS); return 0; err_free_poolout: util_poolset_close(set_out, del); err_free_poolin: util_poolset_close(set_in, DO_NOT_DELETE_PARTS); err: if (errno == 0) errno = EINVAL; return -1; } #ifndef _WIN32 /* * pmempool_transform -- alter poolset structure */ int pmempool_transform(const char *poolset_src, const char *poolset_dst, unsigned flags) { return pmempool_transformU(poolset_src, poolset_dst, flags); } #else /* * pmempool_transformW -- alter poolset structure in widechar */ int pmempool_transformW(const wchar_t *poolset_src, const wchar_t *poolset_dst, unsigned flags) { char *path_src = util_toUTF8(poolset_src); if (path_src == NULL) { ERR("Invalid source poolest file path."); return -1; } char *path_dst = util_toUTF8(poolset_dst); if (path_dst == NULL) { ERR("Invalid destination poolest file path."); Free(path_src); return -1; } int ret = pmempool_transformU(path_src, path_dst, flags); util_free_UTF8(path_src); util_free_UTF8(path_dst); return ret; } #endif pmdk-1.11.1/src/libpmempool/feature.c0000664000000000000000000004160114123364546016145 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * feature.c -- implementation of pmempool_feature_(enable|disable|query)() */ #include #include #include #include #include #include "libpmempool.h" #include "util_pmem.h" #include "pool_hdr.h" #include "pool.h" #define RW 0 #define RDONLY 1 #define FEATURE_INCOMPAT(X) \ (features_t)FEAT_INCOMPAT(X) static const features_t f_singlehdr = FEAT_INCOMPAT(SINGLEHDR); static const features_t f_cksum_2k = FEAT_INCOMPAT(CKSUM_2K); static const features_t f_sds = FEAT_INCOMPAT(SDS); static const features_t f_chkbb = FEAT_COMPAT(CHECK_BAD_BLOCKS); #define FEAT_INVALID \ {UINT32_MAX, UINT32_MAX, UINT32_MAX}; static const features_t f_invalid = FEAT_INVALID; #define FEATURE_MAXPRINT ((size_t)1024) /* * buff_concat -- (internal) concat formatted string to string buffer */ static int buff_concat(char *buff, size_t *pos, const char *fmt, ...) { va_list ap; va_start(ap, fmt); const size_t size = FEATURE_MAXPRINT - *pos - 1; int ret = vsnprintf(buff + *pos, size, fmt, ap); va_end(ap); if (ret < 0) { ERR("vsprintf"); return ret; } if ((size_t)ret >= size) { ERR("buffer truncated %d >= %zu", ret, size); return -1; } *pos += (size_t)ret; return 0; } /* * buff_concat_features -- (internal) concat features string to string buffer */ static int buff_concat_features(char *buff, size_t *pos, features_t f) { return buff_concat(buff, pos, "{compat 0x%x, incompat 0x%x, ro_compat 0x%x}", f.compat, f.incompat, f.ro_compat); } /* * poolset_close -- (internal) close pool set */ static void poolset_close(struct pool_set *set) { for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); ASSERT(!rep->remote); for (unsigned p = 0; p < rep->nparts; ++p) { util_unmap_hdr(PART(rep, p)); } } util_poolset_close(set, DO_NOT_DELETE_PARTS); } /* * features_check -- (internal) check if features are correct */ static int features_check(features_t *f, struct pool_hdr *hdrp) { static char msg[FEATURE_MAXPRINT]; struct pool_hdr hdr; memcpy(&hdr, hdrp, sizeof(hdr)); util_convert2h_hdr_nocheck(&hdr); /* (f != f_invlaid) <=> features is set */ if (!util_feature_cmp(*f, f_invalid)) { /* features from current and previous headers have to match */ if (!util_feature_cmp(*f, hdr.features)) { size_t pos = 0; if (buff_concat_features(msg, &pos, hdr.features)) goto err; if (buff_concat(msg, &pos, "%s", " != ")) goto err; if (buff_concat_features(msg, &pos, *f)) goto err; ERR("features mismatch detected: %s", msg); return -1; } else { return 0; } } features_t unknown = util_get_unknown_features( hdr.features, (features_t)POOL_FEAT_VALID); /* all features are known */ if (util_feature_is_zero(unknown)) { memcpy(f, &hdr.features, sizeof(*f)); return 0; } /* unknown features detected - print error message */ size_t pos = 0; if (buff_concat_features(msg, &pos, unknown)) goto err; ERR("invalid features detected: %s", msg); err: return -1; } /* * get_pool_open_flags -- (internal) generate pool open flags */ static inline unsigned get_pool_open_flags(struct pool_set *set, int rdonly) { unsigned flags = 0; if (rdonly == RDONLY && !util_pool_has_device_dax(set)) flags = POOL_OPEN_COW; flags |= POOL_OPEN_IGNORE_BAD_BLOCKS; return flags; } /* * get_mmap_flags -- (internal) generate mmap flags */ static inline int get_mmap_flags(struct pool_set_part *part, int rdonly) { if (part->is_dev_dax) return MAP_SHARED; else return rdonly ? MAP_PRIVATE : MAP_SHARED; } /* * poolset_open -- (internal) open pool set */ static struct pool_set * poolset_open(const char *path, int rdonly) { struct pool_set *set; features_t f = FEAT_INVALID; /* read poolset */ int ret = util_poolset_create_set(&set, path, 0, 0, true); if (ret < 0) { ERR("cannot open pool set -- '%s'", path); goto err_poolset; } if (set->remote) { ERR("poolsets with remote replicas are not supported"); errno = EINVAL; goto err_open; } /* open a memory pool */ unsigned flags = get_pool_open_flags(set, rdonly); if (util_pool_open_nocheck(set, flags)) goto err_open; /* map all headers and check features */ for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); ASSERT(!rep->remote); for (unsigned p = 0; p < rep->nparts; ++p) { struct pool_set_part *part = PART(rep, p); int mmap_flags = get_mmap_flags(part, rdonly); if (util_map_hdr(part, mmap_flags, rdonly)) { part->hdr = NULL; goto err_map_hdr; } if (features_check(&f, HDR(rep, p))) { ERR( "invalid features - replica #%d part #%d", r, p); goto err_open; } } } return set; err_map_hdr: /* unmap all headers */ for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); ASSERT(!rep->remote); for (unsigned p = 0; p < rep->nparts; ++p) { util_unmap_hdr(PART(rep, p)); } } err_open: /* close the memory pool and release pool set structure */ util_poolset_close(set, DO_NOT_DELETE_PARTS); err_poolset: return NULL; } /* * get_hdr -- (internal) read header in host byte order */ static struct pool_hdr * get_hdr(struct pool_set *set, unsigned rep, unsigned part) { static struct pool_hdr hdr; /* copy header */ struct pool_hdr *hdrp = HDR(REP(set, rep), part); memcpy(&hdr, hdrp, sizeof(hdr)); /* convert to host byte order and return */ util_convert2h_hdr_nocheck(&hdr); return &hdr; } /* * set_hdr -- (internal) convert header to little-endian, checksum and write */ static void set_hdr(struct pool_set *set, unsigned rep, unsigned part, struct pool_hdr *src) { /* convert to little-endian and set new checksum */ const size_t skip_off = POOL_HDR_CSUM_END_OFF(src); util_convert2le_hdr(src); util_checksum(src, sizeof(*src), &src->checksum, 1, skip_off); /* write header */ struct pool_replica *replica = REP(set, rep); struct pool_hdr *dst = HDR(replica, part); memcpy(dst, src, sizeof(*src)); util_persist_auto(PART(replica, part)->is_dev_dax, dst, sizeof(*src)); } typedef enum { DISABLED, ENABLED } fstate_t; #define FEATURE_IS_ENABLED_STR "feature already enabled: %s" #define FEATURE_IS_DISABLED_STR "feature already disabled: %s" /* * require_feature_is -- (internal) check if required feature is enabled * (or disabled) */ static int require_feature_is(struct pool_set *set, features_t feature, fstate_t req_state) { struct pool_hdr *hdrp = get_hdr((set), 0, 0); fstate_t state = util_feature_is_set(hdrp->features, feature) ? ENABLED : DISABLED; if (state == req_state) return 1; const char *msg = (state == ENABLED) ? FEATURE_IS_ENABLED_STR : FEATURE_IS_DISABLED_STR; LOG(3, msg, util_feature2str(feature, NULL)); return 0; } #define FEATURE_IS_NOT_ENABLED_PRIOR_STR "enable %s prior to %s %s" #define FEATURE_IS_NOT_DISABLED_PRIOR_STR "disable %s prior to %s %s" /* * require_other_feature_is -- (internal) check if other feature is enabled * (or disabled) in case the other feature has to be enabled (or disabled) * prior to the main one */ static int require_other_feature_is(struct pool_set *set, features_t other, fstate_t req_state, features_t feature, const char *cause) { struct pool_hdr *hdrp = get_hdr((set), 0, 0); fstate_t state = util_feature_is_set(hdrp->features, other) ? ENABLED : DISABLED; if (state == req_state) return 1; const char *msg = (req_state == ENABLED) ? FEATURE_IS_NOT_ENABLED_PRIOR_STR : FEATURE_IS_NOT_DISABLED_PRIOR_STR; ERR(msg, util_feature2str(other, NULL), cause, util_feature2str(feature, NULL)); return 0; } /* * feature_set -- (internal) enable (or disable) feature */ static void feature_set(struct pool_set *set, features_t feature, int value) { for (unsigned r = 0; r < set->nreplicas; ++r) { for (unsigned p = 0; p < REP(set, r)->nparts; ++p) { struct pool_hdr *hdrp = get_hdr(set, r, p); if (value == ENABLED) util_feature_enable(&hdrp->features, feature); else util_feature_disable(&hdrp->features, feature); set_hdr(set, r, p, hdrp); } } } /* * query_feature -- (internal) query feature value */ static int query_feature(const char *path, features_t feature) { struct pool_set *set = poolset_open(path, RDONLY); if (!set) goto err_open; struct pool_hdr *hdrp = get_hdr(set, 0, 0); const int query = util_feature_is_set(hdrp->features, feature); poolset_close(set); return query; err_open: return -1; } /* * unsupported_feature -- (internal) report unsupported feature */ static inline int unsupported_feature(features_t feature) { ERR("unsupported feature: %s", util_feature2str(feature, NULL)); errno = EINVAL; return -1; } /* * enable_singlehdr -- (internal) enable POOL_FEAT_SINGLEHDR */ static int enable_singlehdr(const char *path) { return unsupported_feature(f_singlehdr); } /* * disable_singlehdr -- (internal) disable POOL_FEAT_SINGLEHDR */ static int disable_singlehdr(const char *path) { return unsupported_feature(f_singlehdr); } /* * query_singlehdr -- (internal) query POOL_FEAT_SINGLEHDR */ static int query_singlehdr(const char *path) { return query_feature(path, f_singlehdr); } /* * enable_checksum_2k -- (internal) enable POOL_FEAT_CKSUM_2K */ static int enable_checksum_2k(const char *path) { struct pool_set *set = poolset_open(path, RW); if (!set) return -1; if (require_feature_is(set, f_cksum_2k, DISABLED)) feature_set(set, f_cksum_2k, ENABLED); poolset_close(set); return 0; } /* * disable_checksum_2k -- (internal) disable POOL_FEAT_CKSUM_2K */ static int disable_checksum_2k(const char *path) { struct pool_set *set = poolset_open(path, RW); if (!set) return -1; int ret = 0; if (!require_feature_is(set, f_cksum_2k, ENABLED)) goto exit; /* check if POOL_FEAT_SDS is disabled */ if (!require_other_feature_is(set, f_sds, DISABLED, f_cksum_2k, "disabling")) { ret = -1; goto exit; } feature_set(set, f_cksum_2k, DISABLED); exit: poolset_close(set); return ret; } /* * query_checksum_2k -- (internal) query POOL_FEAT_CKSUM_2K */ static int query_checksum_2k(const char *path) { return query_feature(path, f_cksum_2k); } /* * enable_shutdown_state -- (internal) enable POOL_FEAT_SDS */ static int enable_shutdown_state(const char *path) { struct pool_set *set = poolset_open(path, RW); if (!set) return -1; int ret = 0; if (!require_feature_is(set, f_sds, DISABLED)) goto exit; /* check if POOL_FEAT_CKSUM_2K is enabled */ if (!require_other_feature_is(set, f_cksum_2k, ENABLED, f_sds, "enabling")) { ret = -1; goto exit; } feature_set(set, f_sds, ENABLED); exit: poolset_close(set); return ret; } /* * reset_shutdown_state -- zero all shutdown structures */ static void reset_shutdown_state(struct pool_set *set) { for (unsigned rep = 0; rep < set->nreplicas; ++rep) { for (unsigned part = 0; part < REP(set, rep)->nparts; ++part) { struct pool_hdr *hdrp = HDR(REP(set, rep), part); shutdown_state_init(&hdrp->sds, REP(set, rep)); } } } /* * disable_shutdown_state -- (internal) disable POOL_FEAT_SDS */ static int disable_shutdown_state(const char *path) { struct pool_set *set = poolset_open(path, RW); if (!set) return -1; if (require_feature_is(set, f_sds, ENABLED)) { feature_set(set, f_sds, DISABLED); reset_shutdown_state(set); } poolset_close(set); return 0; } /* * query_shutdown_state -- (internal) query POOL_FEAT_SDS */ static int query_shutdown_state(const char *path) { return query_feature(path, f_sds); } /* * enable_badblocks_checking -- (internal) enable POOL_FEAT_CHECK_BAD_BLOCKS */ static int enable_badblocks_checking(const char *path) { #ifdef _WIN32 ERR("bad blocks checking is not supported on Windows"); return -1; #else struct pool_set *set = poolset_open(path, RW); if (!set) return -1; if (require_feature_is(set, f_chkbb, DISABLED)) feature_set(set, f_chkbb, ENABLED); poolset_close(set); return 0; #endif } /* * disable_badblocks_checking -- (internal) disable POOL_FEAT_CHECK_BAD_BLOCKS */ static int disable_badblocks_checking(const char *path) { struct pool_set *set = poolset_open(path, RW); if (!set) return -1; int ret = 0; if (!require_feature_is(set, f_chkbb, ENABLED)) goto exit; feature_set(set, f_chkbb, DISABLED); exit: poolset_close(set); return ret; } /* * query_badblocks_checking -- (internal) query POOL_FEAT_CHECK_BAD_BLOCKS */ static int query_badblocks_checking(const char *path) { return query_feature(path, f_chkbb); } struct feature_funcs { int (*enable)(const char *); int (*disable)(const char *); int (*query)(const char *); }; static struct feature_funcs features[] = { { .enable = enable_singlehdr, .disable = disable_singlehdr, .query = query_singlehdr }, { .enable = enable_checksum_2k, .disable = disable_checksum_2k, .query = query_checksum_2k }, { .enable = enable_shutdown_state, .disable = disable_shutdown_state, .query = query_shutdown_state }, { .enable = enable_badblocks_checking, .disable = disable_badblocks_checking, .query = query_badblocks_checking }, }; #define FEATURE_FUNCS_MAX ARRAY_SIZE(features) /* * are_flags_valid -- (internal) check if flags are valid */ static inline int are_flags_valid(unsigned flags) { if (flags != 0) { ERR("invalid flags: 0x%x", flags); errno = EINVAL; return 0; } return 1; } /* * is_feature_valid -- (internal) check if feature is valid */ static inline int is_feature_valid(uint32_t feature) { if (feature >= FEATURE_FUNCS_MAX) { ERR("invalid feature: 0x%x", feature); errno = EINVAL; return 0; } return 1; } /* * pmempool_feature_enableU -- enable pool set feature */ #ifndef _WIN32 static inline #endif int pmempool_feature_enableU(const char *path, enum pmempool_feature feature, unsigned flags) { LOG(3, "path %s feature %x flags %x", path, feature, flags); if (!is_feature_valid(feature)) return -1; if (!are_flags_valid(flags)) return -1; return features[feature].enable(path); } /* * pmempool_feature_disableU -- disable pool set feature */ #ifndef _WIN32 static inline #endif int pmempool_feature_disableU(const char *path, enum pmempool_feature feature, unsigned flags) { LOG(3, "path %s feature %x flags %x", path, feature, flags); if (!is_feature_valid(feature)) return -1; if (!are_flags_valid(flags)) return -1; return features[feature].disable(path); } /* * pmempool_feature_queryU -- query pool set feature */ #ifndef _WIN32 static inline #endif int pmempool_feature_queryU(const char *path, enum pmempool_feature feature, unsigned flags) { LOG(3, "path %s feature %x flags %x", path, feature, flags); /* * XXX: Windows does not allow function call in a constant expressions */ #ifndef _WIN32 #define CHECK_INCOMPAT_MAPPING(FEAT, ENUM) \ COMPILE_ERROR_ON( \ util_feature2pmempool_feature(FEATURE_INCOMPAT(FEAT)) != ENUM) CHECK_INCOMPAT_MAPPING(SINGLEHDR, PMEMPOOL_FEAT_SINGLEHDR); CHECK_INCOMPAT_MAPPING(CKSUM_2K, PMEMPOOL_FEAT_CKSUM_2K); CHECK_INCOMPAT_MAPPING(SDS, PMEMPOOL_FEAT_SHUTDOWN_STATE); #undef CHECK_INCOMPAT_MAPPING #endif if (!is_feature_valid(feature)) return -1; if (!are_flags_valid(flags)) return -1; return features[feature].query(path); } #ifndef _WIN32 /* * pmempool_feature_enable -- enable pool set feature */ int pmempool_feature_enable(const char *path, enum pmempool_feature feature, unsigned flags) { return pmempool_feature_enableU(path, feature, flags); } #else /* * pmempool_feature_enableW -- enable pool set feature as widechar */ int pmempool_feature_enableW(const wchar_t *path, enum pmempool_feature feature, unsigned flags) { char *upath = util_toUTF8(path); if (upath == NULL) { ERR("Invalid poolest/pool file path."); return -1; } int ret = pmempool_feature_enableU(upath, feature, flags); util_free_UTF8(upath); return ret; } #endif #ifndef _WIN32 /* * pmempool_feature_disable -- disable pool set feature */ int pmempool_feature_disable(const char *path, enum pmempool_feature feature, unsigned flags) { return pmempool_feature_disableU(path, feature, flags); } #else /* * pmempool_feature_disableW -- disable pool set feature as widechar */ int pmempool_feature_disableW(const wchar_t *path, enum pmempool_feature feature, unsigned flags) { char *upath = util_toUTF8(path); if (upath == NULL) { ERR("Invalid poolest/pool file path."); return -1; } int ret = pmempool_feature_disableU(upath, feature, flags); util_free_UTF8(upath); return ret; } #endif #ifndef _WIN32 /* * pmempool_feature_query -- query pool set feature */ int pmempool_feature_query(const char *path, enum pmempool_feature feature, unsigned flags) { return pmempool_feature_queryU(path, feature, flags); } #else /* * pmempool_feature_queryW -- query pool set feature as widechar */ int pmempool_feature_queryW(const wchar_t *path, enum pmempool_feature feature, unsigned flags) { char *upath = util_toUTF8(path); if (upath == NULL) { ERR("Invalid poolest/pool file path."); return -1; } int ret = pmempool_feature_queryU(upath, feature, flags); util_free_UTF8(upath); return ret; } #endif pmdk-1.11.1/src/libpmempool/Makefile0000664000000000000000000000244114123364546016005 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/libpmempool/Makefile -- Makefile for libpmempool # LIBRARY_NAME = pmempool LIBRARY_SO_VERSION = 1 LIBRARY_VERSION = 0.0 INCS += -I$(TOP)/src/libpmemlog INCS += -I$(TOP)/src/libpmemblk INCS += -I$(TOP)/src/libpmemobj INCS += -I$(TOP)/src/rpmem_common INCS += -I$(TOP)/src/librpmem INCS += -I$(TOP)/src/libpmem2 vpath %.c ../librpmem include ../core/pmemcore.inc include ../common/pmemcommon.inc SOURCE +=\ libpmempool.c\ check.c\ check_bad_blocks.c\ check_backup.c\ check_btt_info.c\ check_btt_map_flog.c\ check_log.c\ check_blk.c\ check_pool_hdr.c\ check_sds.c\ check_util.c\ check_write.c\ pool.c\ replica.c\ feature.c\ $(RPMEM_COMMON)/rpmem_common.c\ rpmem_ssh.c\ rpmem_cmd.c\ rpmem_util.c\ sync.c\ transform.c\ rm.c LIBPMEMBLK_PRIV_FUNCS=btt_info_set btt_arena_datasize btt_flog_size\ btt_map_size btt_flog_get_valid map_entry_is_initial btt_info_convert2h\ btt_info_convert2le btt_flog_convert2h btt_flog_convert2le include ../Makefile.inc CFLAGS += $(LIBNDCTL_CFLAGS) LIBS += -pthread -lpmem $(LIBDL) $(LIBNDCTL_LIBS) CFLAGS += -DUSE_LIBDL CFLAGS += -DUSE_RPMEM pmemblk_priv_funcs.o: $(PMEMBLK_PRIV_OBJ) $(OBJCOPY) --localize-hidden $(addprefix -G, $(LIBPMEMBLK_PRIV_FUNCS)) \ $< $@ pmdk-1.11.1/src/libpmempool/libpmempool_main.c0000664000000000000000000000126714123364546020041 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2017, Intel Corporation */ /* * libpmempool_main.c -- entry point for libpmempool.dll * * XXX - This is a placeholder. All the library initialization/cleanup * that is done in library ctors/dtors, as well as TLS initialization * should be moved here. */ #include void libpmempool_init(void); void libpmempool_fini(void); int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: libpmempool_init(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: libpmempool_fini(); break; } return TRUE; } pmdk-1.11.1/src/libpmempool/libpmempool.vcxproj0000664000000000000000000001746114123364546020311 0ustar rootroot Debug x64 Release x64 {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {901f04db-e1a5-4a41-8b81-9d31c19acd59} {CF9A0883-6334-44C7-AC29-349468C78E27} DynamicLibrary libpmempool libpmempool en-US 14.0 10.0.17134.0 10.0.10240.0 DynamicLibrary true v140 DynamicLibrary false false v140 $(SolutionDir)\libpmemobj;$(SolutionDir)\libpmemblk;$(SolutionDir)\libpmemlog;$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmemobj;$(SolutionDir)\libpmemblk;$(SolutionDir)\libpmemlog;$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/libpmempool/rm.c0000664000000000000000000001103414123364546015125 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rm.c -- implementation of pmempool_rm() function */ #include #include #include "libpmempool.h" #include "out.h" #include "os.h" #include "util.h" #include "set.h" #include "file.h" #define PMEMPOOL_RM_ALL_FLAGS (\ PMEMPOOL_RM_FORCE |\ PMEMPOOL_RM_POOLSET_LOCAL |\ PMEMPOOL_RM_POOLSET_REMOTE) #define ERR_F(f, ...) do {\ if (CHECK_FLAG((f), FORCE))\ LOG(2, "!(ignored) " __VA_ARGS__);\ else\ ERR(__VA_ARGS__);\ } while (0) #define CHECK_FLAG(f, i) ((f) & PMEMPOOL_RM_##i) struct cb_args { unsigned flags; int error; }; /* * rm_local -- (internal) remove single local file */ static int rm_local(const char *path, unsigned flags, int is_part_file) { int ret = util_unlink_flock(path); if (!ret) { LOG(3, "%s: removed", path); return 0; } int oerrno = errno; os_stat_t buff; ret = os_stat(path, &buff); if (!ret) { if (S_ISDIR(buff.st_mode)) { errno = EISDIR; if (is_part_file) ERR("%s: removing file failed", path); else ERR("removing file failed"); return -1; } } errno = oerrno; if (is_part_file) ERR_F(flags, "%s: removing file failed", path); else ERR_F(flags, "removing file failed"); if (CHECK_FLAG(flags, FORCE)) return 0; return -1; } /* * rm_remote -- (internal) remove remote replica */ static int rm_remote(const char *node, const char *path, unsigned flags) { if (!Rpmem_remove) { ERR_F(flags, "cannot remove remote replica" " -- missing librpmem"); return -1; } int rpmem_flags = 0; if (CHECK_FLAG(flags, FORCE)) rpmem_flags |= RPMEM_REMOVE_FORCE; if (CHECK_FLAG(flags, POOLSET_REMOTE)) rpmem_flags |= RPMEM_REMOVE_POOL_SET; int ret = Rpmem_remove(node, path, rpmem_flags); if (ret) { ERR_F(flags, "%s/%s removing failed", node, path); if (CHECK_FLAG(flags, FORCE)) ret = 0; } else { LOG(3, "%s/%s: removed", node, path); } return ret; } /* * rm_cb -- (internal) foreach part callback */ static int rm_cb(struct part_file *pf, void *arg) { struct cb_args *args = (struct cb_args *)arg; int ret; if (pf->is_remote) { ret = rm_remote(pf->remote->node_addr, pf->remote->pool_desc, args->flags); } else { ret = rm_local(pf->part->path, args->flags, 1); } if (ret) args->error = ret; return 0; } /* * pmempool_rmU -- remove pool files or poolsets */ #ifndef _WIN32 static inline #endif int pmempool_rmU(const char *path, unsigned flags) { LOG(3, "path %s flags %x", path, flags); int ret; if (flags & ~PMEMPOOL_RM_ALL_FLAGS) { ERR("invalid flags specified"); errno = EINVAL; return -1; } int is_poolset = util_is_poolset_file(path); if (is_poolset < 0) { os_stat_t buff; ret = os_stat(path, &buff); if (!ret) { if (S_ISDIR(buff.st_mode)) { errno = EISDIR; ERR("removing file failed"); return -1; } } ERR_F(flags, "removing file failed"); if (CHECK_FLAG(flags, FORCE)) return 0; return -1; } if (!is_poolset) { LOG(2, "%s: not a poolset file", path); return rm_local(path, flags, 0); } LOG(2, "%s: poolset file", path); /* fill up pool_set structure */ struct pool_set *set = NULL; int fd = os_open(path, O_RDONLY); if (fd == -1 || util_poolset_parse(&set, path, fd)) { ERR_F(flags, "parsing poolset file failed"); if (fd != -1) os_close(fd); if (CHECK_FLAG(flags, FORCE)) return 0; return -1; } os_close(fd); if (set->remote) { /* ignore error - it will be handled in rm_remote() */ (void) util_remote_load(); } util_poolset_free(set); struct cb_args args; args.flags = flags; args.error = 0; ret = util_poolset_foreach_part(path, rm_cb, &args); if (ret == -1) { ERR_F(flags, "parsing poolset file failed"); if (CHECK_FLAG(flags, FORCE)) return 0; return ret; } ASSERTeq(ret, 0); if (args.error) return args.error; if (CHECK_FLAG(flags, POOLSET_LOCAL)) { ret = rm_local(path, flags, 0); if (ret) { ERR_F(flags, "removing pool set file failed"); } else { LOG(3, "%s: removed", path); } if (CHECK_FLAG(flags, FORCE)) return 0; return ret; } return 0; } #ifndef _WIN32 /* * pmempool_rm -- remove pool files or poolsets */ int pmempool_rm(const char *path, unsigned flags) { return pmempool_rmU(path, flags); } #else /* * pmempool_rmW -- remove pool files or poolsets in widechar */ int pmempool_rmW(const wchar_t *path, unsigned flags) { char *upath = util_toUTF8(path); if (upath == NULL) { ERR("Invalid poolest/pool file path."); return -1; } int ret = pmempool_rmU(upath, flags); util_free_UTF8(upath); return ret; } #endif pmdk-1.11.1/src/libpmempool/check_log.c0000664000000000000000000001123014123364546016423 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * check_log.c -- check pmemlog */ #include #include #include #include "out.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum question { Q_LOG_START_OFFSET, Q_LOG_END_OFFSET, Q_LOG_WRITE_OFFSET, }; /* * log_read -- (internal) read pmemlog header */ static int log_read(PMEMpoolcheck *ppc) { /* * Here we want to read the pmemlog header without the pool_hdr as we've * already done it before. * * Take the pointer to fields right after pool_hdr, compute the size and * offset of remaining fields. */ uint8_t *ptr = (uint8_t *)&ppc->pool->hdr.log; ptr += sizeof(ppc->pool->hdr.log.hdr); size_t size = sizeof(ppc->pool->hdr.log) - sizeof(ppc->pool->hdr.log.hdr); uint64_t offset = sizeof(ppc->pool->hdr.log.hdr); if (pool_read(ppc->pool, ptr, size, offset)) return CHECK_ERR(ppc, "cannot read pmemlog structure"); /* endianness conversion */ log_convert2h(&ppc->pool->hdr.log); return 0; } /* * log_hdr_check -- (internal) check pmemlog header */ static int log_hdr_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); CHECK_INFO(ppc, "checking pmemlog header"); if (log_read(ppc)) { ppc->result = CHECK_RESULT_ERROR; return -1; } /* determine constant values for pmemlog */ const uint64_t d_start_offset = roundup(sizeof(ppc->pool->hdr.log), LOG_FORMAT_DATA_ALIGN); if (ppc->pool->hdr.log.start_offset != d_start_offset) { if (CHECK_ASK(ppc, Q_LOG_START_OFFSET, "invalid pmemlog.start_offset: 0x%jx.|Do you " "want to set pmemlog.start_offset to default " "0x%jx?", ppc->pool->hdr.log.start_offset, d_start_offset)) goto error; } if (ppc->pool->hdr.log.end_offset != ppc->pool->set_file->size) { if (CHECK_ASK(ppc, Q_LOG_END_OFFSET, "invalid pmemlog.end_offset: 0x%jx.|Do you " "want to set pmemlog.end_offset to 0x%jx?", ppc->pool->hdr.log.end_offset, ppc->pool->set_file->size)) goto error; } if (ppc->pool->hdr.log.write_offset < d_start_offset || ppc->pool->hdr.log.write_offset > ppc->pool->set_file->size) { if (CHECK_ASK(ppc, Q_LOG_WRITE_OFFSET, "invalid pmemlog.write_offset: 0x%jx.|Do you " "want to set pmemlog.write_offset to " "pmemlog.end_offset?", ppc->pool->hdr.log.write_offset)) goto error; } if (ppc->result == CHECK_RESULT_CONSISTENT || ppc->result == CHECK_RESULT_REPAIRED) CHECK_INFO(ppc, "pmemlog header correct"); return check_questions_sequence_validate(ppc); error: ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); return -1; } /* * log_hdr_fix -- (internal) fix pmemlog header */ static int log_hdr_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); uint64_t d_start_offset; switch (question) { case Q_LOG_START_OFFSET: /* determine constant values for pmemlog */ d_start_offset = roundup(sizeof(ppc->pool->hdr.log), LOG_FORMAT_DATA_ALIGN); CHECK_INFO(ppc, "setting pmemlog.start_offset to 0x%jx", d_start_offset); ppc->pool->hdr.log.start_offset = d_start_offset; break; case Q_LOG_END_OFFSET: CHECK_INFO(ppc, "setting pmemlog.end_offset to 0x%jx", ppc->pool->set_file->size); ppc->pool->hdr.log.end_offset = ppc->pool->set_file->size; break; case Q_LOG_WRITE_OFFSET: CHECK_INFO(ppc, "setting pmemlog.write_offset to " "pmemlog.end_offset"); ppc->pool->hdr.log.write_offset = ppc->pool->set_file->size; break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); enum pool_type type; }; static const struct step steps[] = { { .check = log_hdr_check, .type = POOL_TYPE_LOG }, { .fix = log_hdr_fix, .type = POOL_TYPE_LOG }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static inline int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); ASSERTeq(ppc->pool->params.type, POOL_TYPE_LOG); const struct step *step = &steps[loc->step++]; if (!(step->type & ppc->pool->params.type)) return 0; if (!step->fix) return step->check(ppc, loc); if (log_read(ppc)) { ppc->result = CHECK_RESULT_ERROR; return -1; } return check_answer_loop(ppc, loc, NULL, 1, step->fix); } /* * check_log -- entry point for pmemlog checks */ void check_log(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps)) { if (step_exe(ppc, loc)) break; } } pmdk-1.11.1/src/libpmempool/check_sds.c0000664000000000000000000001461214123364546016442 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2020, Intel Corporation */ /* * check_shutdown_state.c -- shutdown state check */ #include #include #include #include #include "out.h" #include "util_pmem.h" #include "libpmempool.h" #include "libpmem.h" #include "pmempool.h" #include "pool.h" #include "set.h" #include "check_util.h" enum question { Q_RESET_SDS, }; #define SDS_CHECK_STR "checking shutdown state" #define SDS_OK_STR "shutdown state correct" #define SDS_DIRTY_STR "shutdown state is dirty" #define ADR_FAILURE_STR \ "an ADR failure was detected - your pool might be corrupted" #define ZERO_SDS_STR \ "Do you want to zero shutdown state?" #define RESET_SDS_STR \ "Do you want to reset shutdown state at your own risk? " \ "If you have more then one replica you will have to " \ "synchronize your pool after this operation." #define SDS_FAIL_MSG(hdrp) \ IGNORE_SDS(hdrp) ? SDS_DIRTY_STR : ADR_FAILURE_STR #define SDS_REPAIR_MSG(hdrp) \ IGNORE_SDS(hdrp) \ ? SDS_DIRTY_STR ".|" ZERO_SDS_STR \ : ADR_FAILURE_STR ".|" RESET_SDS_STR /* * sds_check_replica -- (internal) check if replica is healthy */ static int sds_check_replica(location *loc) { LOG(3, NULL); struct pool_replica *rep = REP(loc->set, loc->replica); if (rep->remote) return 0; /* make a copy of sds as we shouldn't modify a pool */ struct shutdown_state old_sds = loc->hdr.sds; struct shutdown_state curr_sds; if (IGNORE_SDS(&loc->hdr)) return util_is_zeroed(&old_sds, sizeof(old_sds)) ? 0 : -1; shutdown_state_init(&curr_sds, NULL); /* get current shutdown state */ for (unsigned p = 0; p < rep->nparts; ++p) { if (shutdown_state_add_part(&curr_sds, PART(rep, p)->fd, NULL)) return -1; } /* compare current and old shutdown state */ return shutdown_state_check(&curr_sds, &old_sds, NULL); } /* * sds_check -- (internal) check shutdown_state */ static int sds_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); CHECK_INFO(ppc, "%s" SDS_CHECK_STR, loc->prefix); /* shutdown state is valid */ if (!sds_check_replica(loc)) { CHECK_INFO(ppc, "%s" SDS_OK_STR, loc->prefix); loc->step = CHECK_STEP_COMPLETE; return 0; } /* shutdown state is NOT valid and can NOT be repaired */ if (CHECK_IS_NOT(ppc, REPAIR)) { check_end(ppc->data); ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%s%s", loc->prefix, SDS_FAIL_MSG(&loc->hdr)); } /* shutdown state is NOT valid but can be repaired */ CHECK_ASK(ppc, Q_RESET_SDS, "%s%s", loc->prefix, SDS_REPAIR_MSG(&loc->hdr)); return check_questions_sequence_validate(ppc); } /* * sds_fix -- (internal) fix shutdown state */ static int sds_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); switch (question) { case Q_RESET_SDS: CHECK_INFO(ppc, "%sresetting pool_hdr.sds", loc->prefix); memset(&loc->hdr.sds, 0, sizeof(loc->hdr.sds)); ++loc->healthy_replicas; break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); }; static const struct step steps[] = { { .check = sds_check, }, { .fix = sds_fix, }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static int step_exe(PMEMpoolcheck *ppc, location *loc) { const struct step *step = &steps[loc->step++]; if (!step->fix) return step->check(ppc, loc); if (!check_has_answer(ppc->data)) return 0; if (check_answer_loop(ppc, loc, NULL, 0 /* fail on no */, step->fix)) return -1; util_convert2le_hdr(&loc->hdr); memcpy(loc->hdrp, &loc->hdr, sizeof(loc->hdr)); util_persist_auto(loc->is_dev_dax, loc->hdrp, sizeof(*loc->hdrp)); util_convert2h_hdr_nocheck(&loc->hdr); loc->pool_hdr_modified = 1; return 0; } /* * init_prefix -- prepare prefix for messages */ static void init_prefix(location *loc) { if (loc->set->nreplicas > 1) { int ret = util_snprintf(loc->prefix, PREFIX_MAX_SIZE, "replica %u: ", loc->replica); if (ret < 0) FATAL("!snprintf"); } else loc->prefix[0] = '\0'; loc->step = 0; } /* * init_location_data -- (internal) prepare location information */ static void init_location_data(PMEMpoolcheck *ppc, location *loc) { ASSERTeq(loc->part, 0); loc->set = ppc->pool->set_file->poolset; if (ppc->result != CHECK_RESULT_PROCESS_ANSWERS) init_prefix(loc); struct pool_replica *rep = REP(loc->set, loc->replica); loc->hdrp = HDR(rep, loc->part); memcpy(&loc->hdr, loc->hdrp, sizeof(loc->hdr)); util_convert2h_hdr_nocheck(&loc->hdr); loc->is_dev_dax = PART(rep, 0)->is_dev_dax; } /* * sds_get_healthy_replicas_num -- (internal) get number of healthy replicas */ static void sds_get_healthy_replicas_num(PMEMpoolcheck *ppc, location *loc) { const unsigned nreplicas = ppc->pool->set_file->poolset->nreplicas; loc->healthy_replicas = 0; loc->part = 0; for (; loc->replica < nreplicas; loc->replica++) { init_location_data(ppc, loc); if (!sds_check_replica(loc)) { ++loc->healthy_replicas; /* healthy replica found */ } } loc->replica = 0; /* reset replica index */ } /* * check_sds -- entry point for shutdown state checks */ void check_sds(PMEMpoolcheck *ppc) { LOG(3, NULL); const unsigned nreplicas = ppc->pool->set_file->poolset->nreplicas; location *loc = check_get_step_data(ppc->data); if (!loc->init_done) { sds_get_healthy_replicas_num(ppc, loc); if (loc->healthy_replicas == nreplicas) { /* all replicas have healthy shutdown state */ /* print summary */ for (; loc->replica < nreplicas; loc->replica++) { init_prefix(loc); CHECK_INFO(ppc, "%s" SDS_CHECK_STR, loc->prefix); CHECK_INFO(ppc, "%s" SDS_OK_STR, loc->prefix); } return; } else if (loc->healthy_replicas > 0) { ppc->sync_required = true; return; } loc->init_done = true; } /* produce single healthy replica */ loc->part = 0; for (; loc->replica < nreplicas; loc->replica++) { init_location_data(ppc, loc); while (CHECK_NOT_COMPLETE(loc, steps)) { ASSERT(loc->step < ARRAY_SIZE(steps)); if (step_exe(ppc, loc)) return; } if (loc->healthy_replicas) break; } if (loc->healthy_replicas == 0) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; CHECK_ERR(ppc, "cannot complete repair, reverting changes"); } else if (loc->healthy_replicas < nreplicas) { ppc->sync_required = true; } } pmdk-1.11.1/src/libpmempool/libpmempool.c0000664000000000000000000002166614123364546017042 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * libpmempool.c -- entry points for libpmempool */ #include #include #include #include #include "pmemcommon.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check.h" #ifdef USE_RPMEM #include "rpmem_common.h" #include "rpmem_util.h" #endif #ifdef _WIN32 #define ANSWER_BUFFSIZE 256 #endif /* * libpmempool_init -- load-time initialization for libpmempool * * Called automatically by the run-time loader. */ ATTR_CONSTRUCTOR void libpmempool_init(void) { common_init(PMEMPOOL_LOG_PREFIX, PMEMPOOL_LOG_LEVEL_VAR, PMEMPOOL_LOG_FILE_VAR, PMEMPOOL_MAJOR_VERSION, PMEMPOOL_MINOR_VERSION); LOG(3, NULL); #ifdef USE_RPMEM util_remote_init(); rpmem_util_cmds_init(); #endif } /* * libpmempool_fini -- libpmempool cleanup routine * * Called automatically when the process terminates. */ ATTR_DESTRUCTOR void libpmempool_fini(void) { LOG(3, NULL); #ifdef USE_RPMEM util_remote_unload(); util_remote_fini(); rpmem_util_cmds_fini(); #endif common_fini(); } /* * pmempool_check_versionU -- see if library meets application version * requirements */ #ifndef _WIN32 static inline #endif const char * pmempool_check_versionU(unsigned major_required, unsigned minor_required) { LOG(3, "major_required %u minor_required %u", major_required, minor_required); if (major_required != PMEMPOOL_MAJOR_VERSION) { ERR("libpmempool major version mismatch (need %u, found %u)", major_required, PMEMPOOL_MAJOR_VERSION); return out_get_errormsg(); } if (minor_required > PMEMPOOL_MINOR_VERSION) { ERR("libpmempool minor version mismatch (need %u, found %u)", minor_required, PMEMPOOL_MINOR_VERSION); return out_get_errormsg(); } return NULL; } #ifndef _WIN32 /* * pmempool_check_version -- see if lib meets application version requirements */ const char * pmempool_check_version(unsigned major_required, unsigned minor_required) { return pmempool_check_versionU(major_required, minor_required); } #else /* * pmempool_check_versionW -- see if library meets application version * requirements as widechar */ const wchar_t * pmempool_check_versionW(unsigned major_required, unsigned minor_required) { if (pmempool_check_versionU(major_required, minor_required) != NULL) return out_get_errormsgW(); else return NULL; } #endif /* * pmempool_errormsgU -- return last error message */ #ifndef _WIN32 static inline #endif const char * pmempool_errormsgU(void) { return out_get_errormsg(); } #ifndef _WIN32 /* * pmempool_errormsg -- return last error message */ const char * pmempool_errormsg(void) { return pmempool_errormsgU(); } #else /* * pmempool_errormsgW -- return last error message as widechar */ const wchar_t * pmempool_errormsgW(void) { return out_get_errormsgW(); } #endif /* * pmempool_ppc_set_default -- (internal) set default values of check context */ static void pmempool_ppc_set_default(PMEMpoolcheck *ppc) { /* all other fields should be zeroed */ const PMEMpoolcheck ppc_default = { .args = { .pool_type = PMEMPOOL_POOL_TYPE_DETECT, }, .result = CHECK_RESULT_CONSISTENT, }; *ppc = ppc_default; } /* * pmempool_check_initU -- initialize check context */ #ifndef _WIN32 static inline #endif PMEMpoolcheck * pmempool_check_initU(struct pmempool_check_argsU *args, size_t args_size) { LOG(3, "path %s backup_path %s pool_type %u flags %x", args->path, args->backup_path, args->pool_type, args->flags); /* * Currently one size of args structure is supported. The version of the * pmempool_check_args structure can be distinguished based on provided * args_size. */ if (args_size < sizeof(struct pmempool_check_args)) { ERR("provided args_size is not supported"); errno = EINVAL; return NULL; } /* * Dry run does not allow to made changes possibly performed during * repair. Advanced allow to perform more complex repairs. Questions * are ask only if repairs are made. So dry run, advanced and always_yes * can be set only if repair is set. */ if (util_flag_isclr(args->flags, PMEMPOOL_CHECK_REPAIR) && util_flag_isset(args->flags, PMEMPOOL_CHECK_DRY_RUN | PMEMPOOL_CHECK_ADVANCED | PMEMPOOL_CHECK_ALWAYS_YES)) { ERR("dry_run, advanced and always_yes are applicable only if " "repair is set"); errno = EINVAL; return NULL; } /* * dry run does not modify anything so performing backup is redundant */ if (util_flag_isset(args->flags, PMEMPOOL_CHECK_DRY_RUN) && args->backup_path != NULL) { ERR("dry run does not allow one to perform backup"); errno = EINVAL; return NULL; } /* * libpmempool uses str format of communication so it must be set */ if (util_flag_isclr(args->flags, PMEMPOOL_CHECK_FORMAT_STR)) { ERR("PMEMPOOL_CHECK_FORMAT_STR flag must be set"); errno = EINVAL; return NULL; } PMEMpoolcheck *ppc = calloc(1, sizeof(*ppc)); if (ppc == NULL) { ERR("!calloc"); return NULL; } pmempool_ppc_set_default(ppc); memcpy(&ppc->args, args, sizeof(ppc->args)); ppc->path = strdup(args->path); if (!ppc->path) { ERR("!strdup"); goto error_path_malloc; } ppc->args.path = ppc->path; if (args->backup_path != NULL) { ppc->backup_path = strdup(args->backup_path); if (!ppc->backup_path) { ERR("!strdup"); goto error_backup_path_malloc; } ppc->args.backup_path = ppc->backup_path; } if (check_init(ppc) != 0) goto error_check_init; return ppc; error_check_init: /* in case errno not set by any of the used functions set its value */ if (errno == 0) errno = EINVAL; free(ppc->backup_path); error_backup_path_malloc: free(ppc->path); error_path_malloc: free(ppc); return NULL; } #ifndef _WIN32 /* * pmempool_check_init -- initialize check context */ PMEMpoolcheck * pmempool_check_init(struct pmempool_check_args *args, size_t args_size) { return pmempool_check_initU(args, args_size); } #else /* * pmempool_check_initW -- initialize check context as widechar */ PMEMpoolcheck * pmempool_check_initW(struct pmempool_check_argsW *args, size_t args_size) { char *upath = util_toUTF8(args->path); if (upath == NULL) return NULL; char *ubackup_path = NULL; if (args->backup_path != NULL) { ubackup_path = util_toUTF8(args->backup_path); if (ubackup_path == NULL) { util_free_UTF8(upath); return NULL; } } struct pmempool_check_argsU uargs = { .path = upath, .backup_path = ubackup_path, .pool_type = args->pool_type, .flags = args->flags }; PMEMpoolcheck *ret = pmempool_check_initU(&uargs, args_size); util_free_UTF8(ubackup_path); util_free_UTF8(upath); return ret; } #endif /* * pmempool_checkU -- continue check till produce status to consume for caller */ #ifndef _WIN32 static inline #endif struct pmempool_check_statusU * pmempool_checkU(PMEMpoolcheck *ppc) { LOG(3, NULL); ASSERTne(ppc, NULL); struct check_status *result; do { result = check_step(ppc); if (check_is_end(ppc->data) && result == NULL) return NULL; } while (result == NULL); return check_status_get(result); } #ifndef _WIN32 /* * pmempool_check -- continue check till produce status to consume for caller */ struct pmempool_check_status * pmempool_check(PMEMpoolcheck *ppc) { return pmempool_checkU(ppc); } #else /* * pmempool_checkW -- continue check till produce status to consume for caller */ struct pmempool_check_statusW * pmempool_checkW(PMEMpoolcheck *ppc) { LOG(3, NULL); ASSERTne(ppc, NULL); /* check the cache and convert msg and answer */ char buf[ANSWER_BUFFSIZE]; memset(buf, 0, ANSWER_BUFFSIZE); convert_status_cache(ppc, buf, ANSWER_BUFFSIZE); struct check_status *uresult; do { uresult = check_step(ppc); if (check_is_end(ppc->data) && uresult == NULL) return NULL; } while (uresult == NULL); struct pmempool_check_statusU *uret_res = check_status_get(uresult); const wchar_t *wmsg = util_toUTF16(uret_res->str.msg); if (wmsg == NULL) FATAL("!malloc"); struct pmempool_check_statusW *wret_res = (struct pmempool_check_statusW *)uret_res; /* pointer to old message is freed in next check step */ wret_res->str.msg = wmsg; return wret_res; } #endif /* * pmempool_check_end -- end check and release check context */ enum pmempool_check_result pmempool_check_end(PMEMpoolcheck *ppc) { LOG(3, NULL); const enum check_result result = ppc->result; const unsigned sync_required = ppc->sync_required; check_fini(ppc); free(ppc->path); free(ppc->backup_path); free(ppc); if (sync_required) { switch (result) { case CHECK_RESULT_CONSISTENT: case CHECK_RESULT_REPAIRED: return PMEMPOOL_CHECK_RESULT_SYNC_REQ; default: /* other results require fixing prior to sync */ ; } } switch (result) { case CHECK_RESULT_CONSISTENT: return PMEMPOOL_CHECK_RESULT_CONSISTENT; case CHECK_RESULT_NOT_CONSISTENT: return PMEMPOOL_CHECK_RESULT_NOT_CONSISTENT; case CHECK_RESULT_REPAIRED: return PMEMPOOL_CHECK_RESULT_REPAIRED; case CHECK_RESULT_CANNOT_REPAIR: return PMEMPOOL_CHECK_RESULT_CANNOT_REPAIR; default: return PMEMPOOL_CHECK_RESULT_ERROR; } } pmdk-1.11.1/src/libpmempool/check_write.c0000664000000000000000000001205414123364546017001 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * check_write.c -- write fixed data back */ #include #include #include "out.h" #include "btt.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum questions { Q_REPAIR_MAP, Q_REPAIR_FLOG, }; /* * log_write -- (internal) write all structures for log pool */ static int log_write(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (CHECK_WITHOUT_FIXING(ppc)) return 0; /* endianness conversion */ struct pmemlog *log = &ppc->pool->hdr.log; log_convert2le(log); if (pool_write(ppc->pool, log, sizeof(*log), 0)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "writing pmemlog structure failed"); } return 0; } /* * blk_write_flog -- (internal) convert and write flog to file */ static int blk_write_flog(PMEMpoolcheck *ppc, struct arena *arenap) { if (!arenap->flog) { ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "flog is missing"); } uint64_t flogoff = arenap->offset + arenap->btt_info.flogoff; uint8_t *ptr = arenap->flog; uint32_t i; for (i = 0; i < arenap->btt_info.nfree; i++) { struct btt_flog *flog = (struct btt_flog *)ptr; btt_flog_convert2le(&flog[0]); btt_flog_convert2le(&flog[1]); ptr += BTT_FLOG_PAIR_ALIGN; } if (pool_write(ppc->pool, arenap->flog, arenap->flogsize, flogoff)) { CHECK_INFO(ppc, "%s", ppc->path); ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "arena %u: writing BTT FLOG failed\n", arenap->id); } return 0; } /* * blk_write_map -- (internal) convert and write map to file */ static int blk_write_map(PMEMpoolcheck *ppc, struct arena *arenap) { if (!arenap->map) { ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "map is missing"); } uint64_t mapoff = arenap->offset + arenap->btt_info.mapoff; uint32_t i; for (i = 0; i < arenap->btt_info.external_nlba; i++) arenap->map[i] = htole32(arenap->map[i]); if (pool_write(ppc->pool, arenap->map, arenap->mapsize, mapoff)) { CHECK_INFO(ppc, "%s", ppc->path); ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "arena %u: writing BTT map failed\n", arenap->id); } return 0; } /* * blk_write -- (internal) write all structures for blk pool */ static int blk_write(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (CHECK_WITHOUT_FIXING(ppc)) return 0; /* endianness conversion */ ppc->pool->hdr.blk.bsize = htole32(ppc->pool->hdr.blk.bsize); if (pool_write(ppc->pool, &ppc->pool->hdr.blk, sizeof(ppc->pool->hdr.blk), 0)) { CHECK_INFO(ppc, "%s", ppc->path); ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "writing pmemblk structure failed"); } return 0; } /* * btt_data_write -- (internal) write BTT data */ static int btt_data_write(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); struct arena *arenap; PMDK_TAILQ_FOREACH(arenap, &ppc->pool->arenas, next) { if (ppc->pool->uuid_op == UUID_NOT_FROM_BTT) { memcpy(arenap->btt_info.parent_uuid, ppc->pool->hdr.pool.poolset_uuid, sizeof(arenap->btt_info.parent_uuid)); util_checksum(&arenap->btt_info, sizeof(arenap->btt_info), &arenap->btt_info.checksum, 1, 0); } if (pool_write(ppc->pool, &arenap->btt_info, sizeof(arenap->btt_info), arenap->offset)) { CHECK_INFO(ppc, "%s", ppc->path); CHECK_ERR(ppc, "arena %u: writing BTT Info failed", arenap->id); goto error; } if (pool_write(ppc->pool, &arenap->btt_info, sizeof(arenap->btt_info), arenap->offset + le64toh(arenap->btt_info.infooff))) { CHECK_INFO(ppc, "%s", ppc->path); CHECK_ERR(ppc, "arena %u: writing BTT Info backup failed", arenap->id); goto error; } if (blk_write_flog(ppc, arenap)) goto error; if (blk_write_map(ppc, arenap)) goto error; } return 0; error: ppc->result = CHECK_RESULT_CANNOT_REPAIR; return -1; } struct step { int (*func)(PMEMpoolcheck *, location *loc); enum pool_type type; }; static const struct step steps[] = { { .func = log_write, .type = POOL_TYPE_LOG, }, { .func = blk_write, .type = POOL_TYPE_BLK, }, { .func = btt_data_write, .type = POOL_TYPE_BLK | POOL_TYPE_BTT, }, { .func = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static inline int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); const struct step *step = &steps[loc->step++]; /* check step conditions */ if (!(step->type & ppc->pool->params.type)) return 0; return step->func(ppc, loc); } /* * check_write -- write fixed data back */ void check_write(PMEMpoolcheck *ppc) { /* * XXX: Disabling individual checks based on type should be done in the * step structure. This however requires refactor of the step * processing code. */ if (CHECK_IS_NOT(ppc, REPAIR)) return; location *loc = (location *)check_get_step_data(ppc->data); /* do all steps */ while (loc->step != CHECK_STEP_COMPLETE && steps[loc->step].func != NULL) { if (step_exe(ppc, loc)) return; } } pmdk-1.11.1/src/libpmempool/check_btt_info.c0000664000000000000000000002672714123364546017467 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * check_btt_info.c -- check BTT Info */ #include #include #include #include "out.h" #include "util.h" #include "btt.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum question { Q_RESTORE_FROM_BACKUP, Q_REGENERATE, Q_REGENERATE_CHECKSUM, Q_RESTORE_FROM_HEADER }; /* * location_release -- (internal) release check_btt_info_loc allocations */ static void location_release(location *loc) { free(loc->arenap); loc->arenap = NULL; } /* * btt_info_checksum -- (internal) check BTT Info checksum */ static int btt_info_checksum(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); loc->arenap = calloc(1, sizeof(struct arena)); if (!loc->arenap) { ERR("!calloc"); ppc->result = CHECK_RESULT_INTERNAL_ERROR; CHECK_ERR(ppc, "cannot allocate memory for arena"); goto error_cleanup; } /* read the BTT Info header at well known offset */ if (pool_read(ppc->pool, &loc->arenap->btt_info, sizeof(loc->arenap->btt_info), loc->offset)) { CHECK_ERR(ppc, "arena %u: cannot read BTT Info header", loc->arenap->id); ppc->result = CHECK_RESULT_ERROR; goto error_cleanup; } loc->arenap->id = ppc->pool->narenas; /* BLK is consistent even without BTT Layout */ if (ppc->pool->params.type == POOL_TYPE_BLK) { int is_zeroed = util_is_zeroed((const void *) &loc->arenap->btt_info, sizeof(loc->arenap->btt_info)); if (is_zeroed) { CHECK_INFO(ppc, "BTT Layout not written"); loc->step = CHECK_STEP_COMPLETE; ppc->pool->blk_no_layout = 1; location_release(loc); check_end(ppc->data); return 0; } } /* check consistency of BTT Info */ if (pool_btt_info_valid(&loc->arenap->btt_info)) { CHECK_INFO(ppc, "arena %u: BTT Info header checksum correct", loc->arenap->id); loc->valid.btti_header = 1; } else if (CHECK_IS_NOT(ppc, REPAIR)) { CHECK_ERR(ppc, "arena %u: BTT Info header checksum incorrect", loc->arenap->id); ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); goto error_cleanup; } return 0; error_cleanup: location_release(loc); return -1; } /* * btt_info_backup -- (internal) check BTT Info backup */ static int btt_info_backup(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); /* check BTT Info backup consistency */ const size_t btt_info_size = sizeof(ppc->pool->bttc.btt_info); uint64_t btt_info_off = pool_next_arena_offset(ppc->pool, loc->offset) - btt_info_size; if (pool_read(ppc->pool, &ppc->pool->bttc.btt_info, btt_info_size, btt_info_off)) { CHECK_ERR(ppc, "arena %u: cannot read BTT Info backup", loc->arenap->id); goto error; } /* check whether this BTT Info backup is valid */ if (pool_btt_info_valid(&ppc->pool->bttc.btt_info)) { loc->valid.btti_backup = 1; /* restore BTT Info from backup */ if (!loc->valid.btti_header && CHECK_IS(ppc, REPAIR)) CHECK_ASK(ppc, Q_RESTORE_FROM_BACKUP, "arena %u: BTT " "Info header checksum incorrect.|Restore BTT " "Info from backup?", loc->arenap->id); } /* * if BTT Info backup require repairs it will be fixed in further steps */ return check_questions_sequence_validate(ppc); error: ppc->result = CHECK_RESULT_ERROR; location_release(loc); return -1; } /* * btt_info_from_backup_fix -- (internal) fix BTT Info using its backup */ static int btt_info_from_backup_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); ASSERTeq(ctx, NULL); ASSERTne(loc, NULL); switch (question) { case Q_RESTORE_FROM_BACKUP: CHECK_INFO(ppc, "arena %u: restoring BTT Info header from backup", loc->arenap->id); memcpy(&loc->arenap->btt_info, &ppc->pool->bttc.btt_info, sizeof(loc->arenap->btt_info)); loc->valid.btti_header = 1; break; default: ERR("not implemented question id: %u", question); } return 0; } /* * btt_info_gen -- (internal) ask whether try to regenerate BTT Info */ static int btt_info_gen(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (loc->valid.btti_header) return 0; ASSERT(CHECK_IS(ppc, REPAIR)); if (!loc->pool_valid.btti_offset) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); return CHECK_ERR(ppc, "can not find any valid BTT Info"); } CHECK_ASK(ppc, Q_REGENERATE, "arena %u: BTT Info header checksum incorrect.|Do you want to " "regenerate BTT Info?", loc->arenap->id); return check_questions_sequence_validate(ppc); } /* * btt_info_gen_fix -- (internal) fix by regenerating BTT Info */ static int btt_info_gen_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); ASSERTeq(ctx, NULL); ASSERTne(loc, NULL); switch (question) { case Q_REGENERATE: CHECK_INFO(ppc, "arena %u: regenerating BTT Info header", loc->arenap->id); /* * We do not have valid BTT Info backup so we get first valid * BTT Info and try to calculate BTT Info for current arena */ uint64_t arena_size = ppc->pool->set_file->size - loc->offset; if (arena_size > BTT_MAX_ARENA) arena_size = BTT_MAX_ARENA; uint64_t space_left = ppc->pool->set_file->size - loc->offset - arena_size; struct btt_info *bttd = &loc->arenap->btt_info; struct btt_info *btts = &loc->pool_valid.btti; btt_info_convert2h(bttd); /* * all valid BTT Info structures have the same signature, UUID, * parent UUID, flags, major, minor, external LBA size, internal * LBA size, nfree, info size and data offset */ memcpy(bttd->sig, btts->sig, BTTINFO_SIG_LEN); memcpy(bttd->uuid, btts->uuid, BTTINFO_UUID_LEN); memcpy(bttd->parent_uuid, btts->parent_uuid, BTTINFO_UUID_LEN); memset(bttd->unused, 0, BTTINFO_UNUSED_LEN); bttd->flags = btts->flags; bttd->major = btts->major; bttd->minor = btts->minor; /* other parameters can be calculated */ if (btt_info_set(bttd, btts->external_lbasize, btts->nfree, arena_size, space_left)) { CHECK_ERR(ppc, "can not restore BTT Info"); return -1; } ASSERTeq(bttd->external_lbasize, btts->external_lbasize); ASSERTeq(bttd->internal_lbasize, btts->internal_lbasize); ASSERTeq(bttd->nfree, btts->nfree); ASSERTeq(bttd->infosize, btts->infosize); ASSERTeq(bttd->dataoff, btts->dataoff); return 0; default: ERR("not implemented question id: %u", question); return -1; } } /* * btt_info_checksum_retry -- (internal) check BTT Info checksum */ static int btt_info_checksum_retry(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (loc->valid.btti_header) return 0; btt_info_convert2le(&loc->arenap->btt_info); /* check consistency of BTT Info */ if (pool_btt_info_valid(&loc->arenap->btt_info)) { CHECK_INFO(ppc, "arena %u: BTT Info header checksum correct", loc->arenap->id); loc->valid.btti_header = 1; return 0; } if (CHECK_IS_NOT(ppc, ADVANCED)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, REQUIRE_ADVANCED); CHECK_ERR(ppc, "arena %u: BTT Info header checksum incorrect", loc->arenap->id); check_end(ppc->data); goto error_cleanup; } CHECK_ASK(ppc, Q_REGENERATE_CHECKSUM, "arena %u: BTT Info header checksum incorrect.|Do you want to " "regenerate BTT Info checksum?", loc->arenap->id); return check_questions_sequence_validate(ppc); error_cleanup: location_release(loc); return -1; } /* * btt_info_checksum_fix -- (internal) fix by regenerating BTT Info checksum */ static int btt_info_checksum_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); ASSERTeq(ctx, NULL); ASSERTne(loc, NULL); switch (question) { case Q_REGENERATE_CHECKSUM: util_checksum(&loc->arenap->btt_info, sizeof(struct btt_info), &loc->arenap->btt_info.checksum, 1, 0); loc->valid.btti_header = 1; break; default: ERR("not implemented question id: %u", question); } return 0; } /* * btt_info_backup_checksum -- (internal) check BTT Info backup checksum */ static int btt_info_backup_checksum(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); ASSERT(loc->valid.btti_header); if (loc->valid.btti_backup) return 0; /* BTT Info backup is not valid so it must be fixed */ if (CHECK_IS_NOT(ppc, REPAIR)) { CHECK_ERR(ppc, "arena %u: BTT Info backup checksum incorrect", loc->arenap->id); ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); goto error_cleanup; } CHECK_ASK(ppc, Q_RESTORE_FROM_HEADER, "arena %u: BTT Info backup checksum incorrect.|Do you want to " "restore it from BTT Info header?", loc->arenap->id); return check_questions_sequence_validate(ppc); error_cleanup: location_release(loc); return -1; } /* * btt_info_backup_fix -- (internal) prepare restore BTT Info backup from header */ static int btt_info_backup_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); ASSERTeq(ctx, NULL); ASSERTne(loc, NULL); switch (question) { case Q_RESTORE_FROM_HEADER: /* BTT Info backup would be restored in check_write step */ CHECK_INFO(ppc, "arena %u: restoring BTT Info backup from header", loc->arenap->id); break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); }; static const struct step steps[] = { { .check = btt_info_checksum, }, { .check = btt_info_backup, }, { .fix = btt_info_from_backup_fix, }, { .check = btt_info_gen, }, { .fix = btt_info_gen_fix, }, { .check = btt_info_checksum_retry, }, { .fix = btt_info_checksum_fix, }, { .check = btt_info_backup_checksum, }, { .fix = btt_info_backup_fix, }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static inline int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); const struct step *step = &steps[loc->step++]; if (!step->fix) return step->check(ppc, loc); if (!check_answer_loop(ppc, loc, NULL, 1, step->fix)) return 0; if (check_has_error(ppc->data)) location_release(loc); return -1; } /* * check_btt_info -- entry point for btt info check */ void check_btt_info(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); uint64_t nextoff = 0; /* initialize check */ if (!loc->offset) { CHECK_INFO(ppc, "checking BTT Info headers"); loc->offset = sizeof(struct pool_hdr); if (ppc->pool->params.type == POOL_TYPE_BLK) loc->offset += ALIGN_UP(sizeof(struct pmemblk) - sizeof(struct pool_hdr), BLK_FORMAT_DATA_ALIGN); loc->pool_valid.btti_offset = pool_get_first_valid_btt( ppc->pool, &loc->pool_valid.btti, loc->offset, NULL); /* Without valid BTT Info we can not proceed */ if (!loc->pool_valid.btti_offset) { if (ppc->pool->params.type == POOL_TYPE_BTT) { CHECK_ERR(ppc, "can not find any valid BTT Info"); ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); return; } } else btt_info_convert2h(&loc->pool_valid.btti); } do { /* jump to next offset */ if (ppc->result != CHECK_RESULT_PROCESS_ANSWERS) { loc->offset += nextoff; loc->step = 0; loc->valid.btti_header = 0; loc->valid.btti_backup = 0; } /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps)) { if (step_exe(ppc, loc) || ppc->pool->blk_no_layout == 1) return; } /* save offset and insert BTT to cache for next steps */ loc->arenap->offset = loc->offset; loc->arenap->valid = true; check_insert_arena(ppc, loc->arenap); nextoff = le64toh(loc->arenap->btt_info.nextoff); } while (nextoff > 0); } pmdk-1.11.1/src/libpmempool/libpmempool.rc0000664000000000000000000000044714123364546017216 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * libpmempool.rc -- libpmempool resource file */ #include #define FILE_NAME "libpmempool.dll" #define DESCRIPTION "libpmempool - pool management library" #define TYPE VFT_DLL #include pmdk-1.11.1/src/libpmempool/check_btt_map_flog.c0000664000000000000000000003656614123364546020322 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * check_btt_map_flog.c -- check BTT Map and Flog */ #include #include #include #include "out.h" #include "btt.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" enum questions { Q_REPAIR_MAP, Q_REPAIR_FLOG, }; /* * flog_read -- (internal) read and convert flog from file */ static int flog_read(PMEMpoolcheck *ppc, struct arena *arenap) { uint64_t flogoff = arenap->offset + arenap->btt_info.flogoff; arenap->flogsize = btt_flog_size(arenap->btt_info.nfree); arenap->flog = malloc(arenap->flogsize); if (!arenap->flog) { ERR("!malloc"); goto error_malloc; } if (pool_read(ppc->pool, arenap->flog, arenap->flogsize, flogoff)) goto error_read; uint8_t *ptr = arenap->flog; uint32_t i; for (i = 0; i < arenap->btt_info.nfree; i++) { struct btt_flog *flog = (struct btt_flog *)ptr; btt_flog_convert2h(&flog[0]); btt_flog_convert2h(&flog[1]); ptr += BTT_FLOG_PAIR_ALIGN; } return 0; error_read: free(arenap->flog); arenap->flog = NULL; error_malloc: return -1; } /* * map_read -- (internal) read and convert map from file */ static int map_read(PMEMpoolcheck *ppc, struct arena *arenap) { uint64_t mapoff = arenap->offset + arenap->btt_info.mapoff; arenap->mapsize = btt_map_size(arenap->btt_info.external_nlba); ASSERT(arenap->mapsize != 0); arenap->map = malloc(arenap->mapsize); if (!arenap->map) { ERR("!malloc"); goto error_malloc; } if (pool_read(ppc->pool, arenap->map, arenap->mapsize, mapoff)) { goto error_read; } uint32_t i; for (i = 0; i < arenap->btt_info.external_nlba; i++) arenap->map[i] = le32toh(arenap->map[i]); return 0; error_read: free(arenap->map); arenap->map = NULL; error_malloc: return -1; } /* * list_item -- item for simple list */ struct list_item { PMDK_LIST_ENTRY(list_item) next; uint32_t val; }; /* * list -- simple list for storing numbers */ struct list { PMDK_LIST_HEAD(listhead, list_item) head; uint32_t count; }; /* * list_alloc -- (internal) allocate an empty list */ static struct list * list_alloc(void) { struct list *list = malloc(sizeof(struct list)); if (!list) { ERR("!malloc"); return NULL; } PMDK_LIST_INIT(&list->head); list->count = 0; return list; } /* * list_push -- (internal) insert new element to the list */ static struct list_item * list_push(struct list *list, uint32_t val) { struct list_item *item = malloc(sizeof(*item)); if (!item) { ERR("!malloc"); return NULL; } item->val = val; list->count++; PMDK_LIST_INSERT_HEAD(&list->head, item, next); return item; } /* * list_pop -- (internal) pop element from list head */ static int list_pop(struct list *list, uint32_t *valp) { if (!PMDK_LIST_EMPTY(&list->head)) { struct list_item *i = PMDK_LIST_FIRST(&list->head); PMDK_LIST_REMOVE(i, next); if (valp) *valp = i->val; free(i); list->count--; return 1; } return 0; } /* * list_free -- (internal) free the list */ static void list_free(struct list *list) { while (list_pop(list, NULL)) ; free(list); } /* * cleanup -- (internal) prepare resources for map and flog check */ static int cleanup(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (loc->list_unmap) list_free(loc->list_unmap); if (loc->list_flog_inval) list_free(loc->list_flog_inval); if (loc->list_inval) list_free(loc->list_inval); if (loc->fbitmap) free(loc->fbitmap); if (loc->bitmap) free(loc->bitmap); if (loc->dup_bitmap) free(loc->dup_bitmap); return 0; } /* * init -- (internal) initialize map and flog check */ static int init(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); struct arena *arenap = loc->arenap; /* read flog and map entries */ if (flog_read(ppc, arenap)) { CHECK_ERR(ppc, "arena %u: cannot read BTT Flog", arenap->id); goto error; } if (map_read(ppc, arenap)) { CHECK_ERR(ppc, "arena %u: cannot read BTT Map", arenap->id); goto error; } /* create bitmaps for checking duplicated blocks */ uint32_t bitmapsize = howmany(arenap->btt_info.internal_nlba, 8); loc->bitmap = calloc(bitmapsize, 1); if (!loc->bitmap) { ERR("!calloc"); CHECK_ERR(ppc, "arena %u: cannot allocate memory for blocks " "bitmap", arenap->id); goto error; } loc->dup_bitmap = calloc(bitmapsize, 1); if (!loc->dup_bitmap) { ERR("!calloc"); CHECK_ERR(ppc, "arena %u: cannot allocate memory for " "duplicated blocks bitmap", arenap->id); goto error; } loc->fbitmap = calloc(bitmapsize, 1); if (!loc->fbitmap) { ERR("!calloc"); CHECK_ERR(ppc, "arena %u: cannot allocate memory for BTT Flog " "bitmap", arenap->id); goto error; } /* list of invalid map entries */ loc->list_inval = list_alloc(); if (!loc->list_inval) { CHECK_ERR(ppc, "arena %u: cannot allocate memory for invalid BTT map " "entries list", arenap->id); goto error; } /* list of invalid flog entries */ loc->list_flog_inval = list_alloc(); if (!loc->list_flog_inval) { CHECK_ERR(ppc, "arena %u: cannot allocate memory for invalid BTT Flog " "entries list", arenap->id); goto error; } /* list of unmapped blocks */ loc->list_unmap = list_alloc(); if (!loc->list_unmap) { CHECK_ERR(ppc, "arena %u: cannot allocate memory for unmaped blocks " "list", arenap->id); goto error; } return 0; error: ppc->result = CHECK_RESULT_ERROR; cleanup(ppc, loc); return -1; } /* * map_get_postmap_lba -- extract postmap LBA from map entry */ static inline uint32_t map_get_postmap_lba(struct arena *arenap, uint32_t i) { uint32_t entry = arenap->map[i]; /* if map record is in initial state (flags == 0b00) */ if (map_entry_is_initial(entry)) return i; /* read postmap LBA otherwise */ return entry & BTT_MAP_ENTRY_LBA_MASK; } /* * map_entry_check -- (internal) check single map entry */ static int map_entry_check(PMEMpoolcheck *ppc, location *loc, uint32_t i) { struct arena *arenap = loc->arenap; uint32_t lba = map_get_postmap_lba(arenap, i); /* add duplicated and invalid entries to list */ if (lba < arenap->btt_info.internal_nlba) { if (util_isset(loc->bitmap, lba)) { CHECK_INFO(ppc, "arena %u: BTT Map entry %u duplicated " "at %u", arenap->id, lba, i); util_setbit(loc->dup_bitmap, lba); if (!list_push(loc->list_inval, i)) return -1; } else util_setbit(loc->bitmap, lba); } else { CHECK_INFO(ppc, "arena %u: invalid BTT Map entry at %u", arenap->id, i); if (!list_push(loc->list_inval, i)) return -1; } return 0; } /* * flog_entry_check -- (internal) check single flog entry */ static int flog_entry_check(PMEMpoolcheck *ppc, location *loc, uint32_t i, uint8_t **ptr) { struct arena *arenap = loc->arenap; /* flog entry consists of two btt_flog structures */ struct btt_flog *flog = (struct btt_flog *)*ptr; int next; struct btt_flog *flog_cur = btt_flog_get_valid(flog, &next); /* insert invalid and duplicated indexes to list */ if (!flog_cur) { CHECK_INFO(ppc, "arena %u: invalid BTT Flog entry at %u", arenap->id, i); if (!list_push(loc->list_flog_inval, i)) return -1; goto next; } uint32_t entry = flog_cur->old_map & BTT_MAP_ENTRY_LBA_MASK; uint32_t new_entry = flog_cur->new_map & BTT_MAP_ENTRY_LBA_MASK; /* * Check if lba is in extranal_nlba range, and check if both old_map and * new_map are in internal_nlba range. */ if (flog_cur->lba >= arenap->btt_info.external_nlba || entry >= arenap->btt_info.internal_nlba || new_entry >= arenap->btt_info.internal_nlba) { CHECK_INFO(ppc, "arena %u: invalid BTT Flog entry at %u", arenap->id, i); if (!list_push(loc->list_flog_inval, i)) return -1; goto next; } if (util_isset(loc->fbitmap, entry)) { /* * here we have two flog entries which holds the same free block */ CHECK_INFO(ppc, "arena %u: duplicated BTT Flog entry at %u\n", arenap->id, i); if (!list_push(loc->list_flog_inval, i)) return -1; } else if (util_isset(loc->bitmap, entry)) { /* here we have probably an unfinished write */ if (util_isset(loc->bitmap, new_entry)) { /* Both old_map and new_map are already used in map. */ CHECK_INFO(ppc, "arena %u: duplicated BTT Flog entry " "at %u", arenap->id, i); util_setbit(loc->dup_bitmap, new_entry); if (!list_push(loc->list_flog_inval, i)) return -1; } else { /* * Unfinished write. Next time pool is opened, the map * will be updated to new_map. */ util_setbit(loc->bitmap, new_entry); util_setbit(loc->fbitmap, entry); } } else { int flog_valid = 1; /* * Either flog entry is in its initial state: * - current_btt_flog entry is first one in pair and * - current_btt_flog.old_map == current_btt_flog.new_map and * - current_btt_flog.seq == 0b01 and * - second flog entry in pair is zeroed * or * current_btt_flog.old_map != current_btt_flog.new_map */ if (entry == new_entry) flog_valid = (next == 1) && (flog_cur->seq == 1) && util_is_zeroed((const void *)&flog[1], sizeof(flog[1])); if (flog_valid) { /* totally fine case */ util_setbit(loc->bitmap, entry); util_setbit(loc->fbitmap, entry); } else { CHECK_INFO(ppc, "arena %u: invalid BTT Flog entry at " "%u", arenap->id, i); if (!list_push(loc->list_flog_inval, i)) return -1; } } next: *ptr += BTT_FLOG_PAIR_ALIGN; return 0; } /* * arena_map_flog_check -- (internal) check map and flog */ static int arena_map_flog_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); struct arena *arenap = loc->arenap; /* check map entries */ uint32_t i; for (i = 0; i < arenap->btt_info.external_nlba; i++) { if (map_entry_check(ppc, loc, i)) goto error_push; } /* check flog entries */ uint8_t *ptr = arenap->flog; for (i = 0; i < arenap->btt_info.nfree; i++) { if (flog_entry_check(ppc, loc, i, &ptr)) goto error_push; } /* check unmapped blocks and insert to list */ for (i = 0; i < arenap->btt_info.internal_nlba; i++) { if (!util_isset(loc->bitmap, i)) { CHECK_INFO(ppc, "arena %u: unmapped block %u", arenap->id, i); if (!list_push(loc->list_unmap, i)) goto error_push; } } if (loc->list_unmap->count) CHECK_INFO(ppc, "arena %u: number of unmapped blocks: %u", arenap->id, loc->list_unmap->count); if (loc->list_inval->count) CHECK_INFO(ppc, "arena %u: number of invalid BTT Map entries: " "%u", arenap->id, loc->list_inval->count); if (loc->list_flog_inval->count) CHECK_INFO(ppc, "arena %u: number of invalid BTT Flog entries: " "%u", arenap->id, loc->list_flog_inval->count); if (CHECK_IS_NOT(ppc, REPAIR) && loc->list_unmap->count > 0) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; check_end(ppc->data); goto cleanup; } /* * We are able to repair if and only if number of unmapped blocks is * equal to sum of invalid map and flog entries. */ if (loc->list_unmap->count != (loc->list_inval->count + loc->list_flog_inval->count)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_ERR(ppc, "arena %u: cannot repair BTT Map and Flog", arenap->id); goto cleanup; } if (CHECK_IS_NOT(ppc, ADVANCED) && loc->list_inval->count + loc->list_flog_inval->count > 0) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, REQUIRE_ADVANCED); CHECK_ERR(ppc, "BTT Map and / or BTT Flog contain invalid " "entries"); check_end(ppc->data); goto cleanup; } if (loc->list_inval->count > 0) { CHECK_ASK(ppc, Q_REPAIR_MAP, "Do you want to repair invalid " "BTT Map entries?"); } if (loc->list_flog_inval->count > 0) { CHECK_ASK(ppc, Q_REPAIR_FLOG, "Do you want to repair invalid " "BTT Flog entries?"); } return check_questions_sequence_validate(ppc); error_push: CHECK_ERR(ppc, "arena %u: cannot allocate momory for list item", arenap->id); ppc->result = CHECK_RESULT_ERROR; cleanup: cleanup(ppc, loc); return -1; } /* * arena_map_flog_fix -- (internal) fix map and flog */ static int arena_map_flog_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *ctx) { LOG(3, NULL); ASSERTeq(ctx, NULL); ASSERTne(loc, NULL); struct arena *arenap = loc->arenap; uint32_t inval; uint32_t unmap; switch (question) { case Q_REPAIR_MAP: /* * Cause first of duplicated map entries seems valid till we * find second of them we must find all first map entries * pointing to the postmap LBA's we know are duplicated to mark * them with error flag. */ for (uint32_t i = 0; i < arenap->btt_info.external_nlba; i++) { uint32_t lba = map_get_postmap_lba(arenap, i); if (lba >= arenap->btt_info.internal_nlba) continue; if (!util_isset(loc->dup_bitmap, lba)) continue; arenap->map[i] = BTT_MAP_ENTRY_ERROR | lba; util_clrbit(loc->dup_bitmap, lba); CHECK_INFO(ppc, "arena %u: storing 0x%x at %u BTT Map entry", arenap->id, arenap->map[i], i); } /* * repair invalid or duplicated map entries by using unmapped * blocks */ while (list_pop(loc->list_inval, &inval)) { if (!list_pop(loc->list_unmap, &unmap)) { ppc->result = CHECK_RESULT_ERROR; return -1; } arenap->map[inval] = unmap | BTT_MAP_ENTRY_ERROR; CHECK_INFO(ppc, "arena %u: storing 0x%x at %u BTT Map " "entry", arenap->id, arenap->map[inval], inval); } break; case Q_REPAIR_FLOG: /* repair invalid flog entries using unmapped blocks */ while (list_pop(loc->list_flog_inval, &inval)) { if (!list_pop(loc->list_unmap, &unmap)) { ppc->result = CHECK_RESULT_ERROR; return -1; } struct btt_flog *flog = (struct btt_flog *) (arenap->flog + inval * BTT_FLOG_PAIR_ALIGN); memset(&flog[1], 0, sizeof(flog[1])); uint32_t entry = unmap | BTT_MAP_ENTRY_ERROR; flog[0].lba = inval; flog[0].new_map = entry; flog[0].old_map = entry; flog[0].seq = 1; CHECK_INFO(ppc, "arena %u: repairing BTT Flog at %u " "with free block entry 0x%x", loc->arenap->id, inval, entry); } break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); }; static const struct step steps[] = { { .check = init, }, { .check = arena_map_flog_check, }, { .fix = arena_map_flog_fix, }, { .check = cleanup, }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static inline int step_exe(PMEMpoolcheck *ppc, location *loc) { ASSERT(loc->step < ARRAY_SIZE(steps)); const struct step *step = &steps[loc->step++]; if (!step->fix) return step->check(ppc, loc); if (!check_answer_loop(ppc, loc, NULL, 1, step->fix)) return 0; cleanup(ppc, loc); return -1; } /* * check_btt_map_flog -- perform check and fixing of map and flog */ void check_btt_map_flog(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); if (ppc->pool->blk_no_layout) return; /* initialize check */ if (!loc->arenap && loc->narena == 0 && ppc->result != CHECK_RESULT_PROCESS_ANSWERS) { CHECK_INFO(ppc, "checking BTT Map and Flog"); loc->arenap = PMDK_TAILQ_FIRST(&ppc->pool->arenas); loc->narena = 0; } while (loc->arenap != NULL) { /* add info about checking next arena */ if (ppc->result != CHECK_RESULT_PROCESS_ANSWERS && loc->step == 0) { CHECK_INFO(ppc, "arena %u: checking BTT Map and Flog", loc->narena); } /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps)) { if (step_exe(ppc, loc)) return; } /* jump to next arena */ loc->arenap = PMDK_TAILQ_NEXT(loc->arenap, next); loc->narena++; loc->step = 0; } } pmdk-1.11.1/src/libpmempool/check.h0000664000000000000000000000114214123364546015570 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * check.h -- internal definitions for logic performing check */ #ifndef CHECK_H #define CHECK_H #ifdef __cplusplus extern "C" { #endif int check_init(PMEMpoolcheck *ppc); struct check_status *check_step(PMEMpoolcheck *ppc); void check_fini(PMEMpoolcheck *ppc); int check_is_end(struct check_data *data); struct pmempool_check_status *check_status_get(struct check_status *status); #ifdef _WIN32 void convert_status_cache(PMEMpoolcheck *ppc, char *buf, size_t size); #endif #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/libpmempool/libpmempool.def0000664000000000000000000000116514123364546017346 0ustar rootroot;;;; Begin Copyright Notice ; SPDX-License-Identifier: BSD-3-Clause ; Copyright 2016, Intel Corporation ;;;; End Copyright Notice LIBRARY libpmempool VERSION 1.0 EXPORTS pmempool_check_versionU pmempool_check_versionW pmempool_errormsgU pmempool_errormsgW pmempool_check_initU pmempool_check_initW pmempool_checkU pmempool_checkW pmempool_check_end pmempool_syncU pmempool_syncW pmempool_transformU pmempool_transformW pmempool_rmU pmempool_rmW pmempool_feature_enableU pmempool_feature_enableW pmempool_feature_disableU pmempool_feature_disableW pmempool_feature_queryU pmempool_feature_queryW DllMain pmdk-1.11.1/src/libpmempool/check_pool_hdr.c0000664000000000000000000006436114123364546017465 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * check_pool_hdr.c -- pool header check */ #include #include #include #include #include "out.h" #include "util_pmem.h" #include "libpmempool.h" #include "libpmem.h" #include "pmempool.h" #include "pool.h" #include "set.h" #include "check_util.h" #define NO_COMMON_POOLSET_UUID "%sno common pool_hdr.poolset_uuid" #define INVALID_UUID "%sinvalid pool_hdr.uuid" #define INVALID_CHECKSUM "%sinvalid pool_hdr.checksum" enum question { Q_DEFAULT_SIGNATURE, Q_DEFAULT_MAJOR, Q_DEFAULT_COMPAT_FEATURES, Q_DEFAULT_INCOMPAT_FEATURES, Q_DEFAULT_RO_COMPAT_FEATURES, Q_ZERO_UNUSED_AREA, Q_ARCH_FLAGS, Q_CRTIME, Q_CHECKSUM, Q_POOLSET_UUID_SET, Q_POOLSET_UUID_FROM_BTT_INFO, Q_POOLSET_UUID_REGENERATE, Q_UUID_SET, Q_UUID_REGENERATE, Q_NEXT_PART_UUID_SET, Q_PREV_PART_UUID_SET, Q_NEXT_REPL_UUID_SET, Q_PREV_REPL_UUID_SET }; /* * pool_hdr_possible_type -- (internal) return possible type of pool */ static enum pool_type pool_hdr_possible_type(PMEMpoolcheck *ppc) { if (pool_blk_get_first_valid_arena(ppc->pool, &ppc->pool->bttc)) return POOL_TYPE_BLK; return POOL_TYPE_UNKNOWN; } /* * pool_hdr_valid -- (internal) return true if pool header is valid */ static int pool_hdr_valid(struct pool_hdr *hdrp) { return !util_is_zeroed((void *)hdrp, sizeof(*hdrp)) && util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 0, POOL_HDR_CSUM_END_OFF(hdrp)); } /* * pool_supported -- (internal) check if pool type is supported */ static int pool_supported(enum pool_type type) { switch (type) { case POOL_TYPE_LOG: return 1; case POOL_TYPE_BLK: return 1; case POOL_TYPE_OBJ: default: return 0; } } /* * pool_hdr_preliminary_check -- (internal) check pool header checksum and pool * parameters */ static int pool_hdr_preliminary_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); CHECK_INFO(ppc, "%schecking pool header", loc->prefix); if (util_is_zeroed((void *)&loc->hdr, sizeof(loc->hdr))) { if (CHECK_IS_NOT(ppc, REPAIR)) { check_end(ppc->data); ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sempty pool hdr", loc->prefix); } } else if (loc->hdr_valid) { enum pool_type type = pool_hdr_get_type(&loc->hdr); if (type == POOL_TYPE_UNKNOWN) { if (CHECK_IS_NOT(ppc, REPAIR)) { check_end(ppc->data); ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sinvalid signature", loc->prefix); } CHECK_INFO(ppc, "%sinvalid signature", loc->prefix); } else { /* valid check sum */ CHECK_INFO(ppc, "%spool header correct", loc->prefix); loc->step = CHECK_STEP_COMPLETE; return 0; } } else if (CHECK_IS_NOT(ppc, REPAIR)) { check_end(ppc->data); ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sincorrect pool header", loc->prefix); } else { CHECK_INFO(ppc, "%sincorrect pool header", loc->prefix); } ASSERT(CHECK_IS(ppc, REPAIR)); if (ppc->pool->params.type == POOL_TYPE_UNKNOWN) { ppc->pool->params.type = pool_hdr_possible_type(ppc); if (ppc->pool->params.type == POOL_TYPE_UNKNOWN) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "cannot determine pool type"); } } if (!pool_supported(ppc->pool->params.type)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; return CHECK_ERR(ppc, "the repair of %s pools is not supported", pool_get_pool_type_str(ppc->pool->params.type)); } return 0; } /* * pool_hdr_default_check -- (internal) check some default values in pool header */ static int pool_hdr_default_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); ASSERT(CHECK_IS(ppc, REPAIR)); struct pool_hdr def_hdr; pool_hdr_default(ppc->pool->params.type, &def_hdr); if (memcmp(loc->hdr.signature, def_hdr.signature, POOL_HDR_SIG_LEN)) { CHECK_ASK(ppc, Q_DEFAULT_SIGNATURE, "%spool_hdr.signature is not valid.|Do you want to set " "it to %.8s?", loc->prefix, def_hdr.signature); } if (loc->hdr.major != def_hdr.major) { CHECK_ASK(ppc, Q_DEFAULT_MAJOR, "%spool_hdr.major is not valid.|Do you want to set it " "to default value 0x%x?", loc->prefix, def_hdr.major); } features_t unknown = util_get_unknown_features( loc->hdr.features, def_hdr.features); if (unknown.compat) { CHECK_ASK(ppc, Q_DEFAULT_COMPAT_FEATURES, "%spool_hdr.features.compat is not valid.|Do you want " "to set it to default value 0x%x?", loc->prefix, def_hdr.features.compat); } if (unknown.incompat) { CHECK_ASK(ppc, Q_DEFAULT_INCOMPAT_FEATURES, "%spool_hdr.features.incompat is not valid.|Do you " "want to set it to default value 0x%x?", loc->prefix, def_hdr.features.incompat); } if (unknown.ro_compat) { CHECK_ASK(ppc, Q_DEFAULT_RO_COMPAT_FEATURES, "%spool_hdr.features.ro_compat is not valid.|Do you " "want to set it to default value 0x%x?", loc->prefix, def_hdr.features.ro_compat); } if (!util_is_zeroed(loc->hdr.unused, sizeof(loc->hdr.unused))) { CHECK_ASK(ppc, Q_ZERO_UNUSED_AREA, "%sunused area is not filled by zeros.|Do you want to " "fill it up?", loc->prefix); } return check_questions_sequence_validate(ppc); } /* * pool_hdr_default_fix -- (internal) fix some default values in pool header */ static int pool_hdr_default_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); struct pool_hdr def_hdr; pool_hdr_default(ppc->pool->params.type, &def_hdr); switch (question) { case Q_DEFAULT_SIGNATURE: CHECK_INFO(ppc, "%ssetting pool_hdr.signature to %.8s", loc->prefix, def_hdr.signature); memcpy(&loc->hdr.signature, &def_hdr.signature, POOL_HDR_SIG_LEN); break; case Q_DEFAULT_MAJOR: CHECK_INFO(ppc, "%ssetting pool_hdr.major to 0x%x", loc->prefix, def_hdr.major); loc->hdr.major = def_hdr.major; break; case Q_DEFAULT_COMPAT_FEATURES: CHECK_INFO(ppc, "%ssetting pool_hdr.features.compat to 0x%x", loc->prefix, def_hdr.features.compat); loc->hdr.features.compat = def_hdr.features.compat; break; case Q_DEFAULT_INCOMPAT_FEATURES: CHECK_INFO(ppc, "%ssetting pool_hdr.features.incompat to 0x%x", loc->prefix, def_hdr.features.incompat); loc->hdr.features.incompat = def_hdr.features.incompat; break; case Q_DEFAULT_RO_COMPAT_FEATURES: CHECK_INFO(ppc, "%ssetting pool_hdr.features.ro_compat to 0x%x", loc->prefix, def_hdr.features.ro_compat); loc->hdr.features.ro_compat = def_hdr.features.ro_compat; break; case Q_ZERO_UNUSED_AREA: CHECK_INFO(ppc, "%ssetting pool_hdr.unused to zeros", loc->prefix); memset(loc->hdr.unused, 0, sizeof(loc->hdr.unused)); break; default: ERR("not implemented question id: %u", question); } return 0; } /* * pool_hdr_quick_check -- (internal) end check if pool header is valid */ static int pool_hdr_quick_check(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (pool_hdr_valid(loc->hdrp)) loc->step = CHECK_STEP_COMPLETE; return 0; } /* * pool_hdr_nondefault -- (internal) validate custom value fields */ static int pool_hdr_nondefault(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (loc->hdr.crtime > (uint64_t)ppc->pool->set_file->mtime) { const char * const error = "%spool_hdr.crtime is not valid"; if (CHECK_IS_NOT(ppc, REPAIR)) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, error, loc->prefix); } else if (CHECK_IS_NOT(ppc, ADVANCED)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, "%s" REQUIRE_ADVANCED, loc->prefix); return CHECK_ERR(ppc, error, loc->prefix); } CHECK_ASK(ppc, Q_CRTIME, "%spool_hdr.crtime is not valid.|Do you want to set it " "to file's modtime [%s]?", loc->prefix, check_get_time_str(ppc->pool->set_file->mtime)); } if (loc->valid_part_hdrp && memcmp(&loc->valid_part_hdrp->arch_flags, &loc->hdr.arch_flags, sizeof(struct arch_flags)) != 0) { const char * const error = "%spool_hdr.arch_flags is not valid"; if (CHECK_IS_NOT(ppc, REPAIR)) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, error, loc->prefix); } CHECK_ASK(ppc, Q_ARCH_FLAGS, "%spool_hdr.arch_flags is not valid.|Do you want to " "copy it from a valid part?", loc->prefix); } return check_questions_sequence_validate(ppc); } /* * pool_hdr_nondefault_fix -- (internal) fix custom value fields */ static int pool_hdr_nondefault_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); uint64_t *flags = NULL; switch (question) { case Q_CRTIME: CHECK_INFO(ppc, "%ssetting pool_hdr.crtime to file's modtime: " "%s", loc->prefix, check_get_time_str(ppc->pool->set_file->mtime)); util_convert2h_hdr_nocheck(&loc->hdr); loc->hdr.crtime = (uint64_t)ppc->pool->set_file->mtime; util_convert2le_hdr(&loc->hdr); break; case Q_ARCH_FLAGS: flags = (uint64_t *)&loc->valid_part_hdrp->arch_flags; CHECK_INFO(ppc, "%ssetting pool_hdr.arch_flags to 0x%08" PRIx64 "%08" PRIx64, loc->prefix, flags[0], flags[1]); util_convert2h_hdr_nocheck(&loc->hdr); memcpy(&loc->hdr.arch_flags, &loc->valid_part_hdrp->arch_flags, sizeof(struct arch_flags)); util_convert2le_hdr(&loc->hdr); break; default: ERR("not implemented question id: %u", question); } return 0; } /* * pool_hdr_poolset_uuid -- (internal) check poolset_uuid field */ static int pool_hdr_poolset_uuid_find(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); /* * If the pool header is valid and there is not other parts or replicas * in the poolset its poolset_uuid is also valid. */ if (loc->hdr_valid && loc->single_repl && loc->single_part) return 0; if (loc->replica != 0 || loc->part != 0) goto after_lookup; /* for blk pool we can take the UUID from BTT Info header */ if (ppc->pool->params.type == POOL_TYPE_BLK && ppc->pool->bttc.valid) { loc->valid_puuid = &ppc->pool->bttc.btt_info.parent_uuid; if (uuidcmp(loc->hdr.poolset_uuid, *loc->valid_puuid) != 0) { CHECK_ASK(ppc, Q_POOLSET_UUID_FROM_BTT_INFO, "%sinvalid pool_hdr.poolset_uuid.|Do you want " "to set it to %s from BTT Info?", loc->prefix, check_get_uuid_str(*loc->valid_puuid)); goto exit_question; } } if (loc->single_part && loc->single_repl) { /* * If the pool is not blk pool or BTT Info header is invalid * there is no other way to validate poolset uuid. */ return 0; } /* * if all valid poolset part files have the same poolset uuid it is * the valid poolset uuid * if all part files have the same poolset uuid it is valid poolset uuid */ struct pool_set *poolset = ppc->pool->set_file->poolset; unsigned nreplicas = poolset->nreplicas; uuid_t *common_puuid = loc->valid_puuid; for (unsigned r = 0; r < nreplicas; r++) { struct pool_replica *rep = REP(poolset, r); for (unsigned p = 0; p < rep->nhdrs; p++) { struct pool_hdr *hdr = HDR(rep, p); /* * find poolset uuid if it is the same for all part * files */ if (common_puuid == NULL) { if (r == 0 && p == 0) { common_puuid = &hdr->poolset_uuid; } } else if (uuidcmp(*common_puuid, hdr->poolset_uuid) != 0) { common_puuid = NULL; } if (!pool_hdr_valid(hdr)) continue; /* * find poolset uuid if it is the same for all valid * part files */ if (loc->valid_puuid == NULL) { loc->valid_puuid = &hdr->poolset_uuid; } else if (uuidcmp(*loc->valid_puuid, hdr->poolset_uuid) != 0) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "the poolset contains " "part files from various poolsets"); } } } if (!loc->valid_puuid && common_puuid) loc->valid_puuid = common_puuid; if (loc->valid_puuid) goto after_lookup; if (CHECK_IS_NOT(ppc, REPAIR)) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, NO_COMMON_POOLSET_UUID, loc->prefix); } else if (CHECK_IS_NOT(ppc, ADVANCED)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, "%s" REQUIRE_ADVANCED, loc->prefix); return CHECK_ERR(ppc, NO_COMMON_POOLSET_UUID, loc->prefix); } else { CHECK_ASK(ppc, Q_POOLSET_UUID_REGENERATE, NO_COMMON_POOLSET_UUID ".|Do you want to regenerate pool_hdr.poolset_uuid?", loc->prefix); goto exit_question; } after_lookup: if (loc->valid_puuid) { if (uuidcmp(*loc->valid_puuid, loc->hdr.poolset_uuid) != 0) { if (CHECK_IS_NOT(ppc, REPAIR)) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sinvalid " "pool_hdr.poolset_uuid", loc->prefix); } CHECK_ASK(ppc, Q_POOLSET_UUID_SET, "%sinvalid " "pool_hdr.poolset_uuid.|Do you want to set " "it to %s from a valid part file?", loc->prefix, check_get_uuid_str(*loc->valid_puuid)); } } exit_question: return check_questions_sequence_validate(ppc); } /* * pool_hdr_poolset_uuid_fix -- (internal) fix poolset_uuid field */ static int pool_hdr_poolset_uuid_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_POOLSET_UUID_SET: case Q_POOLSET_UUID_FROM_BTT_INFO: CHECK_INFO(ppc, "%ssetting pool_hdr.poolset_uuid to %s", loc->prefix, check_get_uuid_str(*loc->valid_puuid)); memcpy(loc->hdr.poolset_uuid, loc->valid_puuid, POOL_HDR_UUID_LEN); if (question == Q_POOLSET_UUID_SET) ppc->pool->uuid_op = UUID_NOT_FROM_BTT; else ppc->pool->uuid_op = UUID_FROM_BTT; break; case Q_POOLSET_UUID_REGENERATE: if (util_uuid_generate(loc->hdr.poolset_uuid) != 0) { ppc->result = CHECK_RESULT_INTERNAL_ERROR; return CHECK_ERR(ppc, "%suuid generation failed", loc->prefix); } CHECK_INFO(ppc, "%ssetting pool_hdr.pooset_uuid to %s", loc->prefix, check_get_uuid_str(loc->hdr.poolset_uuid)); ppc->pool->uuid_op = UUID_NOT_FROM_BTT; break; default: ERR("not implemented question id: %u", question); } return 0; } #define COMPARE_TO_FIRST_PART_ONLY 2 /* * pool_hdr_uuid_find -- (internal) check UUID value */ static int pool_hdr_uuid_find(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); /* * If the pool header is valid and there is not other parts or replicas * in the poolset its uuid is also valid. */ if (loc->hdr_valid && loc->single_repl && loc->single_part) return 0; int hdrs_valid[] = { loc->next_part_hdr_valid, loc->prev_part_hdr_valid, loc->next_repl_hdr_valid, loc->prev_repl_hdr_valid}; uuid_t *uuids[] = { &loc->next_part_hdrp->prev_part_uuid, &loc->prev_part_hdrp->next_part_uuid, &loc->next_repl_hdrp->prev_repl_uuid, &loc->prev_repl_hdrp->next_repl_uuid }; /* * if all valid poolset part files have the same uuid links to this part * file it is valid uuid * if all links have the same uuid and it is single file pool it is also * the valid uuid */ loc->valid_uuid = NULL; if (loc->hdr_valid) loc->valid_uuid = &loc->hdr.uuid; uuid_t *common_uuid = uuids[0]; COMPILE_ERROR_ON(ARRAY_SIZE(uuids) != ARRAY_SIZE(hdrs_valid)); COMPILE_ERROR_ON(COMPARE_TO_FIRST_PART_ONLY >= ARRAY_SIZE(uuids)); for (unsigned i = 0; i < ARRAY_SIZE(uuids); ++i) { if (i > 0 && common_uuid != NULL) { if (uuidcmp(*common_uuid, *uuids[i]) != 0) { common_uuid = NULL; } } if (i >= COMPARE_TO_FIRST_PART_ONLY && loc->part != 0) continue; if (!hdrs_valid[i]) continue; if (!loc->valid_uuid) { loc->valid_uuid = uuids[i]; } else if (uuidcmp(*loc->valid_uuid, *uuids[i]) != 0) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sambiguous pool_hdr.uuid", loc->prefix); } } if (!loc->valid_uuid && common_uuid) loc->valid_uuid = common_uuid; if (loc->valid_uuid != NULL) { if (uuidcmp(*loc->valid_uuid, loc->hdr.uuid) != 0) { CHECK_ASK(ppc, Q_UUID_SET, INVALID_UUID ".|Do you want " "to set it to %s from a valid part file?", loc->prefix, check_get_uuid_str(*loc->valid_uuid)); } } else if (CHECK_IS(ppc, ADVANCED)) { CHECK_ASK(ppc, Q_UUID_REGENERATE, INVALID_UUID ".|Do you want " "to regenerate it?", loc->prefix); } else if (CHECK_IS(ppc, REPAIR)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, "%s" REQUIRE_ADVANCED, loc->prefix); return CHECK_ERR(ppc, INVALID_UUID, loc->prefix); } else { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, INVALID_UUID, loc->prefix); } return check_questions_sequence_validate(ppc); } /* * pool_hdr_uuid_fix -- (internal) fix UUID value */ static int pool_hdr_uuid_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_UUID_SET: CHECK_INFO(ppc, "%ssetting pool_hdr.uuid to %s", loc->prefix, check_get_uuid_str(*loc->valid_uuid)); memcpy(loc->hdr.uuid, loc->valid_uuid, POOL_HDR_UUID_LEN); break; case Q_UUID_REGENERATE: if (util_uuid_generate(loc->hdr.uuid) != 0) { ppc->result = CHECK_RESULT_INTERNAL_ERROR; return CHECK_ERR(ppc, "%suuid generation failed", loc->prefix); } CHECK_INFO(ppc, "%ssetting pool_hdr.uuid to %s", loc->prefix, check_get_uuid_str(loc->hdr.uuid)); break; default: ERR("not implemented question id: %u", question); } return 0; } /* * pool_hdr_uuid_links -- (internal) check UUID links values */ static int pool_hdr_uuid_links(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); /* * If the pool header is valid and there is not other parts or replicas * in the poolset its uuid links are also valid. */ if (loc->hdr_valid && loc->single_repl && loc->single_part) return 0; uuid_t *links[] = { &loc->hdr.next_part_uuid, &loc->hdr.prev_part_uuid, &loc->hdr.next_repl_uuid, &loc->hdr.prev_repl_uuid}; uuid_t *uuids[] = { &loc->next_part_hdrp->uuid, &loc->prev_part_hdrp->uuid, &loc->next_repl_hdrp->uuid, &loc->prev_repl_hdrp->uuid }; uint32_t questions[] = { Q_NEXT_PART_UUID_SET, Q_PREV_PART_UUID_SET, Q_NEXT_REPL_UUID_SET, Q_PREV_REPL_UUID_SET }; const char *fields[] = { "pool_hdr.next_part_uuid", "pool_hdr.prev_part_uuid", "pool_hdr.next_repl_uuid", "pool_hdr.prev_repl_uuid" }; COMPILE_ERROR_ON(ARRAY_SIZE(links) != ARRAY_SIZE(uuids)); COMPILE_ERROR_ON(ARRAY_SIZE(links) != ARRAY_SIZE(questions)); COMPILE_ERROR_ON(ARRAY_SIZE(links) != ARRAY_SIZE(fields)); for (uint64_t i = 0; i < ARRAY_SIZE(links); ++i) { if (uuidcmp(*links[i], *uuids[i]) == 0) continue; if (CHECK_IS(ppc, REPAIR)) { CHECK_ASK(ppc, questions[i], "%sinvalid %s.|Do you want to set it to a " "valid value?", loc->prefix, fields[i]); } else { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, "%sinvalid %s", loc->prefix, fields[i]); } } return check_questions_sequence_validate(ppc); } /* * pool_hdr_uuid_links_fix -- (internal) fix UUID links values */ static int pool_hdr_uuid_links_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_NEXT_PART_UUID_SET: CHECK_INFO(ppc, "%ssetting pool_hdr.next_part_uuid to %s", loc->prefix, check_get_uuid_str(loc->next_part_hdrp->uuid)); memcpy(loc->hdr.next_part_uuid, loc->next_part_hdrp->uuid, POOL_HDR_UUID_LEN); break; case Q_PREV_PART_UUID_SET: CHECK_INFO(ppc, "%ssetting pool_hdr.prev_part_uuid to %s", loc->prefix, check_get_uuid_str(loc->prev_part_hdrp->uuid)); memcpy(loc->hdr.prev_part_uuid, loc->prev_part_hdrp->uuid, POOL_HDR_UUID_LEN); break; case Q_NEXT_REPL_UUID_SET: CHECK_INFO(ppc, "%ssetting pool_hdr.next_repl_uuid to %s", loc->prefix, check_get_uuid_str(loc->next_repl_hdrp->uuid)); memcpy(loc->hdr.next_repl_uuid, loc->next_repl_hdrp->uuid, POOL_HDR_UUID_LEN); break; case Q_PREV_REPL_UUID_SET: CHECK_INFO(ppc, "%ssetting pool_hdr.prev_repl_uuid to %s", loc->prefix, check_get_uuid_str(loc->prev_repl_hdrp->uuid)); memcpy(loc->hdr.prev_repl_uuid, loc->prev_repl_hdrp->uuid, POOL_HDR_UUID_LEN); break; default: ERR("not implemented question id: %u", question); } return 0; } /* * pool_hdr_checksum -- (internal) validate checksum */ static int pool_hdr_checksum(PMEMpoolcheck *ppc, location *loc) { LOG(3, NULL); if (loc->hdr_valid) return 0; if (CHECK_IS_NOT(ppc, REPAIR)) { ppc->result = CHECK_RESULT_NOT_CONSISTENT; return CHECK_ERR(ppc, INVALID_CHECKSUM, loc->prefix); } else if (CHECK_IS_NOT(ppc, ADVANCED)) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_INFO(ppc, "%s" REQUIRE_ADVANCED, loc->prefix); return CHECK_ERR(ppc, INVALID_CHECKSUM, loc->prefix); } CHECK_ASK(ppc, Q_CHECKSUM, INVALID_CHECKSUM ".|Do you want to " "regenerate checksum?", loc->prefix); return check_questions_sequence_validate(ppc); } /* * pool_hdr_checksum_fix -- (internal) fix checksum */ static int pool_hdr_checksum_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); switch (question) { case Q_CHECKSUM: util_checksum(&loc->hdr, sizeof(loc->hdr), &loc->hdr.checksum, 1, POOL_HDR_CSUM_END_OFF(&loc->hdr)); CHECK_INFO(ppc, "%ssetting pool_hdr.checksum to 0x%jx", loc->prefix, le64toh(loc->hdr.checksum)); break; default: ERR("not implemented question id: %u", question); } return 0; } struct step { int (*check)(PMEMpoolcheck *, location *); int (*fix)(PMEMpoolcheck *, location *, uint32_t, void *); }; static const struct step steps_initial[] = { { .check = pool_hdr_preliminary_check, }, { .check = pool_hdr_default_check, }, { .fix = pool_hdr_default_fix, .check = pool_hdr_quick_check, }, { .check = pool_hdr_nondefault, }, { .fix = pool_hdr_nondefault_fix, }, { .check = NULL, .fix = NULL, }, }; static const struct step steps_uuids[] = { { .check = pool_hdr_poolset_uuid_find, }, { .fix = pool_hdr_poolset_uuid_fix, }, { .check = pool_hdr_uuid_find, }, { .fix = pool_hdr_uuid_fix, }, { .check = pool_hdr_uuid_links, }, { .fix = pool_hdr_uuid_links_fix, }, { .check = pool_hdr_checksum, }, { .fix = pool_hdr_checksum_fix, }, { .check = NULL, .fix = NULL, }, }; /* * step_exe -- (internal) perform single step according to its parameters */ static int step_exe(PMEMpoolcheck *ppc, const struct step *steps, location *loc, struct pool_replica *rep, unsigned nreplicas) { const struct step *step = &steps[loc->step++]; if (!step->fix) return step->check(ppc, loc); if (!check_has_answer(ppc->data)) return 0; if (check_answer_loop(ppc, loc, NULL, 1, step->fix)) return -1; util_convert2le_hdr(&loc->hdr); memcpy(loc->hdrp, &loc->hdr, sizeof(loc->hdr)); loc->hdr_valid = pool_hdr_valid(loc->hdrp); util_persist_auto(rep->part[0].is_dev_dax, loc->hdrp, sizeof(*loc->hdrp)); util_convert2h_hdr_nocheck(&loc->hdr); loc->pool_hdr_modified = 1; /* execute check after fix if available */ if (step->check) return step->check(ppc, loc); return 0; } /* * init_location_data -- (internal) prepare location information */ static void init_location_data(PMEMpoolcheck *ppc, location *loc) { /* prepare prefix for messages */ unsigned nfiles = pool_set_files_count(ppc->pool->set_file); if (ppc->result != CHECK_RESULT_PROCESS_ANSWERS) { if (nfiles > 1) { int ret = util_snprintf(loc->prefix, PREFIX_MAX_SIZE, "replica %u part %u: ", loc->replica, loc->part); if (ret < 0) FATAL("!snprintf"); } else loc->prefix[0] = '\0'; loc->step = 0; } /* get neighboring parts and replicas and briefly validate them */ const struct pool_set *poolset = ppc->pool->set_file->poolset; loc->single_repl = poolset->nreplicas == 1; loc->single_part = poolset->replica[loc->replica]->nparts == 1; struct pool_replica *rep = REP(poolset, loc->replica); struct pool_replica *next_rep = REPN(poolset, loc->replica); struct pool_replica *prev_rep = REPP(poolset, loc->replica); loc->hdrp = HDR(rep, loc->part); memcpy(&loc->hdr, loc->hdrp, sizeof(loc->hdr)); util_convert2h_hdr_nocheck(&loc->hdr); loc->hdr_valid = pool_hdr_valid(loc->hdrp); loc->next_part_hdrp = HDRN(rep, loc->part); loc->prev_part_hdrp = HDRP(rep, loc->part); loc->next_repl_hdrp = HDR(next_rep, 0); loc->prev_repl_hdrp = HDR(prev_rep, 0); loc->next_part_hdr_valid = pool_hdr_valid(loc->next_part_hdrp); loc->prev_part_hdr_valid = pool_hdr_valid(loc->prev_part_hdrp); loc->next_repl_hdr_valid = pool_hdr_valid(loc->next_repl_hdrp); loc->prev_repl_hdr_valid = pool_hdr_valid(loc->prev_repl_hdrp); if (!loc->valid_part_done || loc->valid_part_replica != loc->replica) { loc->valid_part_hdrp = NULL; for (unsigned p = 0; p < rep->nhdrs; ++p) { if (pool_hdr_valid(HDR(rep, p))) { loc->valid_part_hdrp = HDR(rep, p); break; } } loc->valid_part_done = true; } } /* * check_pool_hdr -- entry point for pool header checks */ void check_pool_hdr(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); unsigned nreplicas = ppc->pool->set_file->poolset->nreplicas; struct pool_set *poolset = ppc->pool->set_file->poolset; for (; loc->replica < nreplicas; loc->replica++) { struct pool_replica *rep = poolset->replica[loc->replica]; for (; loc->part < rep->nhdrs; loc->part++) { init_location_data(ppc, loc); /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps_initial)) { ASSERT(loc->step < ARRAY_SIZE(steps_initial)); if (step_exe(ppc, steps_initial, loc, rep, nreplicas)) return; } } loc->part = 0; } memcpy(&ppc->pool->hdr.pool, poolset->replica[0]->part[0].hdr, sizeof(struct pool_hdr)); if (loc->pool_hdr_modified) { struct pool_hdr hdr; memcpy(&hdr, &ppc->pool->hdr.pool, sizeof(struct pool_hdr)); util_convert2h_hdr_nocheck(&hdr); pool_params_from_header(&ppc->pool->params, &hdr); } } /* * check_pool_hdr_uuids -- entry point for pool header links checks */ void check_pool_hdr_uuids(PMEMpoolcheck *ppc) { LOG(3, NULL); location *loc = check_get_step_data(ppc->data); unsigned nreplicas = ppc->pool->set_file->poolset->nreplicas; struct pool_set *poolset = ppc->pool->set_file->poolset; for (; loc->replica < nreplicas; loc->replica++) { struct pool_replica *rep = poolset->replica[loc->replica]; for (; loc->part < rep->nparts; loc->part++) { init_location_data(ppc, loc); /* do all checks */ while (CHECK_NOT_COMPLETE(loc, steps_uuids)) { ASSERT(loc->step < ARRAY_SIZE(steps_uuids)); if (step_exe(ppc, steps_uuids, loc, rep, nreplicas)) return; } } loc->part = 0; } memcpy(&ppc->pool->hdr.pool, poolset->replica[0]->part[0].hdr, sizeof(struct pool_hdr)); if (loc->pool_hdr_modified) { struct pool_hdr hdr; memcpy(&hdr, &ppc->pool->hdr.pool, sizeof(struct pool_hdr)); util_convert2h_hdr_nocheck(&hdr); pool_params_from_header(&ppc->pool->params, &hdr); } } pmdk-1.11.1/src/libpmempool/check_bad_blocks.c0000664000000000000000000000246114123364546017733 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * check_bad_blocks.c -- pre-check bad_blocks */ #include #include #include #include "out.h" #include "libpmempool.h" #include "pmempool.h" #include "pool.h" #include "check_util.h" #include "set_badblocks.h" #include "badblocks.h" /* * check_bad_blocks -- check poolset for bad_blocks */ void check_bad_blocks(PMEMpoolcheck *ppc) { LOG(3, "ppc %p", ppc); int ret; if (!(ppc->pool->params.features.compat & POOL_FEAT_CHECK_BAD_BLOCKS)) { /* skipping checking poolset for bad blocks */ ppc->result = CHECK_RESULT_CONSISTENT; return; } if (ppc->pool->set_file->poolset) { ret = badblocks_check_poolset(ppc->pool->set_file->poolset, 0); } else { ret = badblocks_check_file(ppc->pool->set_file->fname); } if (ret < 0) { if (errno == ENOTSUP) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_ERR(ppc, BB_NOT_SUPP); return; } ppc->result = CHECK_RESULT_ERROR; CHECK_ERR(ppc, "checking poolset for bad blocks failed -- '%s'", ppc->path); return; } if (ret > 0) { ppc->result = CHECK_RESULT_CANNOT_REPAIR; CHECK_ERR(ppc, "poolset contains bad blocks, use 'pmempool info --bad-blocks=yes' to print or 'pmempool sync --bad-blocks' to clear them"); } } pmdk-1.11.1/src/libpmempool/check_util.h0000664000000000000000000001203214123364546016625 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * check_util.h -- internal definitions check util */ #ifndef CHECK_UTIL_H #define CHECK_UTIL_H #include #include #include #ifdef __cplusplus extern "C" { #endif #define CHECK_STEP_COMPLETE UINT_MAX #define CHECK_INVALID_QUESTION UINT_MAX #define REQUIRE_ADVANCED "the following error can be fixed using " \ "PMEMPOOL_CHECK_ADVANCED flag" #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif /* check control context */ struct check_data; struct arena; /* queue of check statuses */ struct check_status; /* container storing state of all check steps */ #define PREFIX_MAX_SIZE 30 typedef struct { unsigned init_done; unsigned step; unsigned replica; unsigned part; int single_repl; int single_part; struct pool_set *set; int is_dev_dax; struct pool_hdr *hdrp; /* copy of the pool header in host byte order */ struct pool_hdr hdr; int hdr_valid; /* * If pool header has been modified this field indicates that * the pool parameters structure requires refresh. */ int pool_hdr_modified; unsigned healthy_replicas; struct pool_hdr *next_part_hdrp; struct pool_hdr *prev_part_hdrp; struct pool_hdr *next_repl_hdrp; struct pool_hdr *prev_repl_hdrp; int next_part_hdr_valid; int prev_part_hdr_valid; int next_repl_hdr_valid; int prev_repl_hdr_valid; /* valid poolset uuid */ uuid_t *valid_puuid; /* valid part uuid */ uuid_t *valid_uuid; /* valid part pool header */ struct pool_hdr *valid_part_hdrp; int valid_part_done; unsigned valid_part_replica; char prefix[PREFIX_MAX_SIZE]; struct arena *arenap; uint64_t offset; uint32_t narena; uint8_t *bitmap; uint8_t *dup_bitmap; uint8_t *fbitmap; struct list *list_inval; struct list *list_flog_inval; struct list *list_unmap; struct { int btti_header; int btti_backup; } valid; struct { struct btt_info btti; uint64_t btti_offset; } pool_valid; } location; /* check steps */ void check_bad_blocks(PMEMpoolcheck *ppc); void check_backup(PMEMpoolcheck *ppc); void check_pool_hdr(PMEMpoolcheck *ppc); void check_pool_hdr_uuids(PMEMpoolcheck *ppc); void check_sds(PMEMpoolcheck *ppc); void check_log(PMEMpoolcheck *ppc); void check_blk(PMEMpoolcheck *ppc); void check_btt_info(PMEMpoolcheck *ppc); void check_btt_map_flog(PMEMpoolcheck *ppc); void check_write(PMEMpoolcheck *ppc); struct check_data *check_data_alloc(void); void check_data_free(struct check_data *data); uint32_t check_step_get(struct check_data *data); void check_step_inc(struct check_data *data); location *check_get_step_data(struct check_data *data); void check_end(struct check_data *data); int check_is_end_util(struct check_data *data); int check_status_create(PMEMpoolcheck *ppc, enum pmempool_check_msg_type type, uint32_t arg, const char *fmt, ...) FORMAT_PRINTF(4, 5); void check_status_release(PMEMpoolcheck *ppc, struct check_status *status); void check_clear_status_cache(struct check_data *data); struct check_status *check_pop_question(struct check_data *data); struct check_status *check_pop_error(struct check_data *data); struct check_status *check_pop_info(struct check_data *data); bool check_has_error(struct check_data *data); bool check_has_answer(struct check_data *data); int check_push_answer(PMEMpoolcheck *ppc); struct pmempool_check_status *check_status_get_util( struct check_status *status); int check_status_is(struct check_status *status, enum pmempool_check_msg_type type); /* create info status */ #define CHECK_INFO(ppc, ...)\ check_status_create(ppc, PMEMPOOL_CHECK_MSG_TYPE_INFO, 0, __VA_ARGS__) /* create info status and append error message based on errno */ #define CHECK_INFO_ERRNO(ppc, ...)\ check_status_create(ppc, PMEMPOOL_CHECK_MSG_TYPE_INFO,\ (uint32_t)errno, __VA_ARGS__) /* create error status */ #define CHECK_ERR(ppc, ...)\ check_status_create(ppc, PMEMPOOL_CHECK_MSG_TYPE_ERROR, 0, __VA_ARGS__) /* create question status */ #define CHECK_ASK(ppc, question, ...)\ check_status_create(ppc, PMEMPOOL_CHECK_MSG_TYPE_QUESTION, question,\ __VA_ARGS__) #define CHECK_NOT_COMPLETE(loc, steps)\ ((loc)->step != CHECK_STEP_COMPLETE &&\ ((steps)[(loc)->step].check != NULL ||\ (steps)[(loc)->step].fix != NULL)) int check_answer_loop(PMEMpoolcheck *ppc, location *data, void *ctx, int fail_on_no, int (*callback)(PMEMpoolcheck *, location *, uint32_t, void *ctx)); int check_questions_sequence_validate(PMEMpoolcheck *ppc); const char *check_get_time_str(time_t time); const char *check_get_uuid_str(uuid_t uuid); const char *check_get_pool_type_str(enum pool_type type); void check_insert_arena(PMEMpoolcheck *ppc, struct arena *arenap); #ifdef _WIN32 void cache_to_utf8(struct check_data *data, char *buf, size_t size); #endif #define CHECK_IS(ppc, flag)\ util_flag_isset((ppc)->args.flags, PMEMPOOL_CHECK_ ## flag) #define CHECK_IS_NOT(ppc, flag)\ util_flag_isclr((ppc)->args.flags, PMEMPOOL_CHECK_ ## flag) #define CHECK_WITHOUT_FIXING(ppc)\ CHECK_IS_NOT(ppc, REPAIR) || CHECK_IS(ppc, DRY_RUN) #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/libpmempool/pmempool.h0000664000000000000000000000164214123364546016350 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * pmempool.h -- internal definitions for libpmempool */ #ifndef PMEMPOOL_H #define PMEMPOOL_H #ifdef __cplusplus extern "C" { #endif #define PMEMPOOL_LOG_PREFIX "libpmempool" #define PMEMPOOL_LOG_LEVEL_VAR "PMEMPOOL_LOG_LEVEL" #define PMEMPOOL_LOG_FILE_VAR "PMEMPOOL_LOG_FILE" enum check_result { CHECK_RESULT_CONSISTENT, CHECK_RESULT_NOT_CONSISTENT, CHECK_RESULT_ASK_QUESTIONS, CHECK_RESULT_PROCESS_ANSWERS, CHECK_RESULT_REPAIRED, CHECK_RESULT_CANNOT_REPAIR, CHECK_RESULT_ERROR, CHECK_RESULT_INTERNAL_ERROR }; /* * pmempool_check_ctx -- context and arguments for check command */ struct pmempool_check_ctx { struct pmempool_check_args args; char *path; char *backup_path; struct check_data *data; struct pool_data *pool; enum check_result result; unsigned sync_required; }; #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/libpmempool/sync.c0000664000000000000000000012257514123364546015500 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * sync.c -- a module for poolset synchronizing */ #include #include #include #include #include #include #include #include "libpmem.h" #include "replica.h" #include "out.h" #include "os.h" #include "util_pmem.h" #include "util.h" #ifdef USE_RPMEM #include "rpmem_common.h" #include "rpmem_ssh.h" #endif #define BB_DATA_STR "offset 0x%zx, length 0x%zx, nhealthy %i" /* defines 'struct bb_vec' - the vector of the 'struct bad_block' structures */ VEC(bb_vec, struct bad_block); /* * validate_args -- (internal) check whether passed arguments are valid */ static int validate_args(struct pool_set *set) { LOG(3, "set %p", set); ASSERTne(set, NULL); /* the checks below help detect use of incorrect poolset file */ /* * check if all parts in the poolset are large enough * (now replication works only for pmemobj pools) */ if (replica_check_part_sizes(set, PMEMOBJ_MIN_POOL)) { LOG(2, "part sizes check failed"); goto err; } /* * check if all directories for part files exist */ if (replica_check_part_dirs(set)) { LOG(2, "part directories check failed"); goto err; } return 0; err: if (errno == 0) errno = EINVAL; return -1; } /* * sync_copy_data -- (internal) copy data from the healthy replica * to the broken one */ static int sync_copy_data(void *src_addr, void *dst_addr, size_t off, size_t len, struct pool_replica *rep_h, struct pool_replica *rep, const struct pool_set_part *part) { LOG(3, "src_addr %p dst_addr %p off %zu len %zu " "rep_h %p rep %p part %p", src_addr, dst_addr, off, len, rep_h, rep, part); int ret; if (rep->remote) { LOG(10, "copying data (offset 0x%zx length 0x%zx) to remote node -- '%s' on '%s'", off, len, rep->remote->pool_desc, rep->remote->node_addr); ret = Rpmem_persist(rep->remote->rpp, off, len, 0, 0); if (ret) { LOG(1, "copying data to remote node failed -- '%s' on '%s'", rep->remote->pool_desc, rep->remote->node_addr); return -1; } } else if (rep_h->remote) { LOG(10, "reading data (offset 0x%zx length 0x%zx) from remote node -- '%s' on '%s'", off, len, rep_h->remote->pool_desc, rep_h->remote->node_addr); ret = Rpmem_read(rep_h->remote->rpp, dst_addr, off, len, 0); if (ret) { LOG(1, "reading data from remote node failed -- '%s' on '%s'", rep_h->remote->pool_desc, rep_h->remote->node_addr); return -1; } } else { LOG(10, "copying data (offset 0x%zx length 0x%zx) from local replica -- '%s'", off, len, rep_h->part[0].path); /* copy all data */ memcpy(dst_addr, src_addr, len); util_persist(part->is_dev_dax, dst_addr, len); } return 0; } /* * sync_recreate_header -- (internal) recreate the header */ static int sync_recreate_header(struct pool_set *set, unsigned r, unsigned p, struct pool_hdr *src_hdr) { LOG(3, "set %p replica %u part %u src_hdr %p", set, r, p, src_hdr); struct pool_attr attr; util_pool_hdr2attr(&attr, src_hdr); if (util_header_create(set, r, p, &attr, 1) != 0) { LOG(1, "part headers create failed for replica %u part %u", r, p); errno = EINVAL; return -1; } return 0; } /* * sync_mark_replica_no_badblocks -- (internal) mark replica as not having * bad blocks */ static void sync_mark_replica_no_badblocks(unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "repn %u set_hs %p", repn, set_hs); struct replica_health_status *rhs = REP_HEALTH(set_hs, repn); if (rhs->flags & HAS_BAD_BLOCKS) { rhs->flags &= ~HAS_BAD_BLOCKS; LOG(4, "replica %u has no bad blocks now", repn); } } /* * sync_mark_part_no_badblocks -- (internal) mark part as not having bad blocks */ static void sync_mark_part_no_badblocks(unsigned repn, unsigned partn, struct poolset_health_status *set_hs) { LOG(3, "repn %u partn %u set_hs %p", repn, partn, set_hs); struct replica_health_status *rhs = REP_HEALTH(set_hs, repn); if (rhs->part[PART_HEALTHidx(rhs, partn)].flags & HAS_BAD_BLOCKS) { rhs->part[PART_HEALTHidx(rhs, partn)].flags &= ~HAS_BAD_BLOCKS; LOG(4, "replica %u part %u has no bad blocks now", repn, partn); } } /* * sync_recalc_badblocks -- (internal) recalculate offset and length * of bad blocks to absolute ones * (relative to the beginning of the pool) */ static int sync_recalc_badblocks(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p set_hs %p", set, set_hs); /* header size for all headers but the first one */ size_t hdrsize = (set->options & (OPTION_SINGLEHDR | OPTION_NOHDRS)) ? 0 : Mmap_align; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); struct replica_health_status *rep_hs = set_hs->replica[r]; for (unsigned p = 0; p < rep->nparts; ++p) { struct part_health_status *phs = &rep_hs->part[p]; if (!replica_part_has_bad_blocks(phs)) { /* skip parts with no bad blocks */ continue; } ASSERTne(phs->bbs.bb_cnt, 0); ASSERTne(phs->bbs.bbv, NULL); LOG(10, "Replica %u part %u HAS %u bad blocks", r, p, phs->bbs.bb_cnt); size_t part_off = replica_get_part_offset(set, r, p); for (unsigned i = 0; i < phs->bbs.bb_cnt; i++) { LOG(10, "relative bad block #%i: offset %zu, length %zu", i, phs->bbs.bbv[i].offset, phs->bbs.bbv[i].length); size_t off = phs->bbs.bbv[i].offset; size_t len = phs->bbs.bbv[i].length; if (len + off <= hdrsize) continue; /* parts #>0 are mapped without the header */ if (p > 0 && hdrsize > 0) { if (off >= hdrsize) { /* * Bad block does not overlap * with the header, so only * adjust the offset. */ off -= hdrsize; } else { /* * Bad block overlaps * with the header, * so adjust the length * and zero the offset. */ len -= hdrsize - off; off = 0; } } replica_align_badblock_offset_length(&off, &len, set, r, p); phs->bbs.bbv[i].offset = part_off + off; phs->bbs.bbv[i].length = (unsigned)len; LOG(10, "absolute bad block #%i: offset 0x%zx, length 0x%zx", i, phs->bbs.bbv[i].offset, phs->bbs.bbv[i].length); } } } return 0; } /* * sync_badblocks_find_healthy_replica -- (internal) look for a healthy replica * for each bad block * * This function looks for a healthy replica for each bad block. Bad blocks * can overlap across replicas, so each bad block may have to be divided * into smaller parts which can be fixed using different healthy replica. * * Key variables: * - bbv_all[] - array containing all (possibly divided) bad blocks * from all previous replicas. * - bbv_aux[] - array containing all (possibly divided) bad blocks * from all previous parts of the current replica merged with * these bad blocks from bbv_all[] that have offsets less or equal * the greatest bad block's offset in the previous part. * * This function merges bad blocks from bbv_all[] with bad blocks * from the current part and writes the outcome bad blocks to bbv_aux[]. * Only bad blocks with offsets less or equal the greatest bad block's offset * in the current part will be moved from bbv_all[] to bbv_aux[]. * The rest of them has to be moved at the end by sync_badblocks_move_vec(). * * bbv_aux[] becomes new bbv_all[] and bbv_aux[] is zeroed * before checking the next replica (bbv_all = bbv_aux; bbv_aux = 0). * * For example (all replicas have only one part): * - bbv_all with rep#0: |__----___________----__| * - merged with rep#1: |____----_______----____| * - gives such bbv_aux: |__11--00_______00--11__| * - merged with rep#2: |__________---__________| * - gives such bbv_aux: |__112200__000__002211__| (all bad blocks can be fixed) * * where: * '_' stands for a healthy block (no bad block) * '-' stands for a bad block with nhealthy == NO_HEALTHY_REPLICA * 'N' stands for a bad block with nhealthy == N (can be fixed using rep#N) */ static int sync_badblocks_find_healthy_replica(struct part_health_status *phs, int rep, struct bb_vec *pbbv_all, struct bb_vec *pbbv_aux, unsigned *i_all) { LOG(3, "phs %p rep %i pbbv_all %p pbbv_aux %p i_all %i", phs, rep, pbbv_all, pbbv_aux, *i_all); struct bad_block bb_add; /* the element which is being added */ struct bad_block bb_new; /* a new element */ struct bad_block *pbb_all; /* current element of bbv_all[] */ unsigned long long beg_prev; unsigned long long end_prev; unsigned long long beg_new; unsigned long long end_new; size_t len_prev; size_t len_new; size_t size_all = VEC_SIZE(pbbv_all); if (size_all == 0) { /* there were no bad blocks so far, so fill up bbv_aux[] */ for (unsigned i = 0; i < phs->bbs.bb_cnt; i++) { bb_add = phs->bbs.bbv[i]; if (rep > 0) /* bad block can be fixed with replica #0 */ bb_add.nhealthy = 0; if (VEC_PUSH_BACK(pbbv_aux, bb_add)) return -1; LOG(10, "added bad block (prev-empty): " BB_DATA_STR, bb_add.offset, bb_add.length, bb_add.nhealthy); } } else { if (*i_all < size_all) { pbb_all = VEC_GET(pbbv_all, (*i_all)++); } else { pbb_all = NULL; } for (unsigned i = 0; i < phs->bbs.bb_cnt; i++) { bb_new = phs->bbs.bbv[i]; LOG(10, " * (%u) inserting new bad block: " BB_DATA_STR, i + 1, bb_new.offset, bb_new.length, bb_new.nhealthy); if (pbb_all == NULL || pbb_all->length == 0) { if (*i_all < size_all) pbb_all = VEC_GET(pbbv_all, (*i_all)++); else pbb_all = NULL; } /* all from bbv_all before the bb_new */ while (pbb_all != NULL && pbb_all->offset + pbb_all->length - 1 < bb_new.offset) { if (pbb_all->nhealthy == NO_HEALTHY_REPLICA) /* can be fixed with this replica */ pbb_all->nhealthy = rep; if (VEC_PUSH_BACK(pbbv_aux, *pbb_all)) return -1; LOG(10, "added bad block (prev-before): " BB_DATA_STR, pbb_all->offset, pbb_all->length, pbb_all->nhealthy); if (*i_all < size_all) { pbb_all = VEC_GET(pbbv_all, (*i_all)++); } else { pbb_all = NULL; break; } } beg_new = bb_new.offset; len_new = bb_new.length; end_new = beg_new + len_new - 1; /* all pbb_all overlapping with the bb_new */ while (len_new > 0 && pbb_all != NULL) { beg_prev = pbb_all->offset; len_prev = pbb_all->length; end_prev = beg_prev + len_prev - 1; /* check if new overlaps with prev */ if (end_prev < beg_new || end_new < beg_prev) break; /* * 1st part: non-overlapping part * of pbb_all or bb_new */ if (beg_prev < beg_new) { /* non-overlapping part of pbb_all */ bb_add.offset = beg_prev; bb_add.length = (unsigned) (beg_new - beg_prev); if (pbb_all->nhealthy != NO_HEALTHY_REPLICA) { bb_add.nhealthy = pbb_all->nhealthy; } else { /* * It can be fixed with * this replica. */ bb_add.nhealthy = rep; } if (VEC_PUSH_BACK(pbbv_aux, bb_add)) return -1; LOG(10, "added bad block (prev-only): " BB_DATA_STR, bb_add.offset, bb_add.length, bb_add.nhealthy); beg_prev += bb_add.length; len_prev -= bb_add.length; } else if (beg_new < beg_prev) { /* non-overlapping part of bb_new */ bb_add.offset = beg_new; bb_add.length = (unsigned) (beg_prev - beg_new); if (rep == 0) { bb_add.nhealthy = NO_HEALTHY_REPLICA; } else { /* * It can be fixed with any * previous replica, so let's * choose replia #0. */ bb_add.nhealthy = 0; } if (VEC_PUSH_BACK(pbbv_aux, bb_add)) return -1; LOG(10, "added bad block (new-only): " BB_DATA_STR, bb_add.offset, bb_add.length, bb_add.nhealthy); beg_new += bb_add.length; len_new -= bb_add.length; } /* * 2nd part: overlapping part * of pbb_all and bb_new */ if (len_prev <= len_new) { bb_add.offset = beg_prev; bb_add.length = len_prev; beg_new += len_prev; len_new -= len_prev; /* whole pbb_all was added */ len_prev = 0; } else { bb_add.offset = beg_new; bb_add.length = len_new; beg_prev += len_new; len_prev -= len_new; /* whole bb_new was added */ len_new = 0; } bb_add.nhealthy = pbb_all->nhealthy; if (VEC_PUSH_BACK(pbbv_aux, bb_add)) return -1; LOG(10, "added bad block (common): " BB_DATA_STR, bb_add.offset, bb_add.length, bb_add.nhealthy); /* update pbb_all */ pbb_all->offset = beg_prev; pbb_all->length = len_prev; if (len_prev == 0) { if (*i_all < size_all) pbb_all = VEC_GET(pbbv_all, (*i_all)++); else pbb_all = NULL; } } /* the rest of the bb_new */ if (len_new > 0) { bb_add.offset = beg_new; bb_add.length = len_new; if (rep > 0) /* it can be fixed with replica #0 */ bb_add.nhealthy = 0; else bb_add.nhealthy = NO_HEALTHY_REPLICA; if (VEC_PUSH_BACK(pbbv_aux, bb_add)) return -1; LOG(10, "added bad block (new-rest): " BB_DATA_STR, bb_add.offset, bb_add.length, bb_add.nhealthy); } } if (pbb_all != NULL && pbb_all->length > 0 && *i_all > 0) /* this pbb_all will be used again in the next part */ (*i_all)--; } return 0; } /* * sync_badblocks_assign_healthy_replica -- (internal) assign healthy replica * for each bad block */ static int sync_badblocks_assign_healthy_replica(struct part_health_status *phs, int rep, struct bb_vec *pbbv_all, unsigned *i_all) { LOG(3, "phs %p rep %i pbbv_all %p i_all %i", phs, rep, pbbv_all, *i_all); struct bad_block bb_new; /* a new element */ struct bad_block bb_old; /* an old element */ struct bad_block *pbb_all; /* current element of bbv_all[] */ size_t length_left; struct bb_vec bbv_new = VEC_INITIALIZER; size_t size_all = VEC_SIZE(pbbv_all); pbb_all = VEC_GET(pbbv_all, *i_all); for (unsigned i = 0; i < phs->bbs.bb_cnt; i++) { bb_old = phs->bbs.bbv[i]; LOG(10, "assigning old bad block: " BB_DATA_STR, bb_old.offset, bb_old.length, bb_old.nhealthy); /* * Skip all bad blocks from bbv_all with offsets * less than the offset of the current bb_old. */ while (pbb_all->offset < bb_old.offset) { /* (*i_all) has to be less than (size_all - 1) */ ASSERT(*i_all < size_all - 1); pbb_all = VEC_GET(pbbv_all, ++(*i_all)); } bb_new.offset = bb_old.offset; length_left = bb_old.length; while (length_left > 0) { LOG(10, "checking saved bad block: " BB_DATA_STR, pbb_all->offset, pbb_all->length, pbb_all->nhealthy); ASSERTeq(pbb_all->offset, bb_new.offset); ASSERT(pbb_all->length <= length_left); bb_new.length = pbb_all->length; bb_new.nhealthy = pbb_all->nhealthy; if (VEC_PUSH_BACK(&bbv_new, bb_new)) goto error_exit; LOG(10, "added new bad block: " BB_DATA_STR, bb_new.offset, bb_new.length, bb_new.nhealthy); bb_new.offset += bb_new.length; length_left -= bb_new.length; if (length_left == 0) continue; /* (*i_all) has to be less than (size_all - 1) */ ASSERT(*i_all < size_all - 1); pbb_all = VEC_GET(pbbv_all, ++(*i_all)); } } Free(phs->bbs.bbv); phs->bbs.bbv = VEC_ARR(&bbv_new); phs->bbs.bb_cnt = (unsigned)VEC_SIZE(&bbv_new); LOG(10, "added %u new bad blocks", phs->bbs.bb_cnt); return 0; error_exit: VEC_DELETE(&bbv_new); return -1; } /* * sync_badblocks_move_vec -- (internal) move bad blocks from vector pbbv_all * to vector pbbv_aux */ static int sync_badblocks_move_vec(struct bb_vec *pbbv_all, struct bb_vec *pbbv_aux, unsigned i_all, unsigned rep) { LOG(3, "pbbv_all %p pbbv_aux %p i_all %u rep %u", pbbv_all, pbbv_aux, i_all, rep); size_t size_all = VEC_SIZE(pbbv_all); struct bad_block *pbb_all; while (i_all < size_all) { pbb_all = VEC_GET(pbbv_all, i_all++); if (pbb_all->length == 0) continue; if (pbb_all->nhealthy == NO_HEALTHY_REPLICA && rep > 0) /* it can be fixed using the last replica */ pbb_all->nhealthy = (int)rep; if (VEC_PUSH_BACK(pbbv_aux, *pbb_all)) return -1; LOG(10, "added bad block (prev-after): " BB_DATA_STR, pbb_all->offset, pbb_all->length, pbb_all->nhealthy); } return 0; } /* * sync_check_bad_blocks_overlap -- (internal) check if there are uncorrectable * bad blocks (bad blocks overlapping * in all replicas) */ static int sync_check_bad_blocks_overlap(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p set_hs %p", set, set_hs); struct bb_vec bbv_all = VEC_INITIALIZER; struct bb_vec bbv_aux = VEC_INITIALIZER; int ret = -1; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); struct replica_health_status *rep_hs = set_hs->replica[r]; unsigned i_all = 0; /* index in bbv_all */ for (unsigned p = 0; p < rep->nparts; ++p) { struct part_health_status *phs = &rep_hs->part[p]; if (!replica_part_has_bad_blocks(phs)) { /* skip parts with no bad blocks */ continue; } ASSERTne(phs->bbs.bb_cnt, 0); ASSERTne(phs->bbs.bbv, NULL); LOG(10, "Replica %u part %u HAS %u bad blocks", r, p, phs->bbs.bb_cnt); /* * This function merges bad blocks from bbv_all * with bad blocks from the current part * and writes the outcome bad blocks to bbv_aux. * Only bad blocks with offsets less or equal * the greatest bad block's offset in the current part * will be moved from bbv_all to bbv_aux. * The rest of them has to be moved at the end * by sync_badblocks_move_vec() below. */ if (sync_badblocks_find_healthy_replica(phs, (int)r, &bbv_all, &bbv_aux, &i_all)) goto exit; } /* * Move the rest of bad blocks from bbv_all to bbv_aux * (for more details see the comment above). * All these bad blocks can be fixed using the last replica 'r'. */ if (sync_badblocks_move_vec(&bbv_all, &bbv_aux, i_all, r)) return -1; /* bbv_aux becomes a new bbv_all */ VEC_MOVE(&bbv_all, &bbv_aux); i_all = 0; } ret = 0; /* check if there is an uncorrectable bad block */ size_t size_all = VEC_SIZE(&bbv_all); for (unsigned i = 0; i < size_all; i++) { struct bad_block *pbb_all = VEC_GET(&bbv_all, i); if (pbb_all->nhealthy == NO_HEALTHY_REPLICA) { ret = 1; /* this bad block cannot be fixed */ LOG(1, "uncorrectable bad block found: offset 0x%zx, length 0x%zx", pbb_all->offset, pbb_all->length); goto exit; } } /* * All bad blocks can be fixed, * so assign healthy replica for each of them. */ for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); struct replica_health_status *rep_hs = set_hs->replica[r]; if (!replica_has_bad_blocks(r, set_hs)) { /* skip replicas with no bad blocks */ continue; } unsigned i_all = 0; /* index in bbv_all */ for (unsigned p = 0; p < rep->nparts; ++p) { struct part_health_status *phs = &rep_hs->part[p]; if (!replica_part_has_bad_blocks(phs)) { /* skip parts with no bad blocks */ continue; } if (sync_badblocks_assign_healthy_replica(phs, (int)r, &bbv_all, &i_all)) goto exit; } } exit: VEC_DELETE(&bbv_aux); VEC_DELETE(&bbv_all); return ret; } /* * sync_badblocks_data -- (internal) clear bad blocks in replica */ static int sync_badblocks_data(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); struct pool_replica *rep_h; for (unsigned r = 0; r < set->nreplicas; ++r) { struct pool_replica *rep = REP(set, r); struct replica_health_status *rep_hs = set_hs->replica[r]; for (unsigned p = 0; p < rep->nparts; ++p) { struct part_health_status *phs = &rep_hs->part[p]; if (!replica_part_has_bad_blocks(phs)) { /* skip parts with no bad blocks */ continue; } ASSERTne(phs->bbs.bb_cnt, 0); ASSERTne(phs->bbs.bbv, NULL); const struct pool_set_part *part = &rep->part[p]; size_t part_off = replica_get_part_offset(set, r, p); for (unsigned i = 0; i < phs->bbs.bb_cnt; i++) { size_t off = phs->bbs.bbv[i].offset - part_off; size_t len = phs->bbs.bbv[i].length; ASSERT(phs->bbs.bbv[i].nhealthy >= 0); rep_h = REP(set, (unsigned)phs->bbs.bbv[i].nhealthy); void *src_addr = ADDR_SUM(rep_h->part[0].addr, part_off + off); void *dst_addr = ADDR_SUM(part->addr, off); if (sync_copy_data(src_addr, dst_addr, part_off + off, len, rep_h, rep, part)) return -1; } /* free array of bad blocks */ Free(phs->bbs.bbv); phs->bbs.bbv = NULL; /* mark part as having no bad blocks */ sync_mark_part_no_badblocks(r, p, set_hs); } /* mark replica as having no bad blocks */ sync_mark_replica_no_badblocks(r, set_hs); } LOG(1, "all bad blocks have been fixed"); if (replica_remove_all_recovery_files(set_hs)) { LOG(1, "removing bad block recovery files failed"); return -1; } return 0; } /* * recreate_broken_parts -- (internal) create parts in place of the broken ones */ static int recreate_broken_parts(struct pool_set *set, struct poolset_health_status *set_hs, int fix_bad_blocks) { LOG(3, "set %p set_hs %p fix_bad_blocks %i", set, set_hs, fix_bad_blocks); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { if (set->replica[r]->remote) continue; struct pool_replica *broken_r = set->replica[r]; for (unsigned p = 0; p < set_hs->replica[r]->nparts; ++p) { /* skip unbroken parts */ if (!replica_is_part_broken(r, p, set_hs)) continue; /* remove parts from broken replica */ if (replica_remove_part(set, r, p, fix_bad_blocks)) { LOG(2, "cannot remove part"); return -1; } /* create removed part and open it */ if (util_part_open(&broken_r->part[p], 0, 1 /* create */)) { LOG(2, "cannot open/create parts"); return -1; } sync_mark_part_no_badblocks(r, p, set_hs); } } return 0; } /* * fill_struct_part_uuids -- (internal) set part uuids in pool_set structure */ static void fill_struct_part_uuids(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, set_hs %p", set, repn, set_hs); struct pool_replica *rep = REP(set, repn); struct pool_hdr *hdrp; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip broken parts */ if (replica_is_part_broken(repn, p, set_hs)) continue; hdrp = HDR(rep, p); memcpy(rep->part[p].uuid, hdrp->uuid, POOL_HDR_UUID_LEN); } } /* * is_uuid_already_used -- (internal) check if given uuid is assigned to * any of the earlier replicas */ static int is_uuid_already_used(uuid_t uuid, struct pool_set *set, unsigned repn) { for (unsigned r = 0; r < repn; ++r) { if (uuidcmp(uuid, PART(REP(set, r), 0)->uuid) == 0) return 1; } return 0; } /* * fill_struct_broken_part_uuids -- (internal) set part uuids in pool_set * structure */ static int fill_struct_broken_part_uuids(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs, unsigned flags) { LOG(3, "set %p, repn %u, set_hs %p, flags %u", set, repn, set_hs, flags); struct pool_replica *rep = REP(set, repn); struct pool_hdr *hdrp; for (unsigned p = 0; p < rep->nhdrs; ++p) { /* skip unbroken parts */ if (!replica_is_part_broken(repn, p, set_hs)) continue; /* check if part was damaged or was added by transform */ if (replica_is_poolset_transformed(flags)) { /* generate new uuid for this part */ if (util_uuid_generate(rep->part[p].uuid) < 0) { ERR("cannot generate pool set part UUID"); errno = EINVAL; return -1; } continue; } if (!replica_is_part_broken(repn, p - 1, set_hs) && !(set->options & OPTION_SINGLEHDR)) { /* try to get part uuid from the previous part */ hdrp = HDRP(rep, p); memcpy(rep->part[p].uuid, hdrp->next_part_uuid, POOL_HDR_UUID_LEN); } else if (!replica_is_part_broken(repn, p + 1, set_hs) && !(set->options & OPTION_SINGLEHDR)) { /* try to get part uuid from the next part */ hdrp = HDRN(rep, p); memcpy(rep->part[p].uuid, hdrp->prev_part_uuid, POOL_HDR_UUID_LEN); } else if (p == 0 && !replica_is_part_broken(repn - 1, 0, set_hs)) { /* try to get part uuid from the previous replica */ hdrp = HDR(REPP(set, repn), 0); if (is_uuid_already_used(hdrp->next_repl_uuid, set, repn)) { ERR( "repeated uuid - some replicas were created with a different poolset file"); errno = EINVAL; return -1; } memcpy(rep->part[p].uuid, hdrp->next_repl_uuid, POOL_HDR_UUID_LEN); } else if (p == 0 && !replica_is_part_broken(repn + 1, 0, set_hs)) { /* try to get part uuid from the next replica */ hdrp = HDR(REPN(set, repn), 0); if (is_uuid_already_used(hdrp->prev_repl_uuid, set, repn)) { ERR( "repeated uuid - some replicas were created with a different poolset file"); errno = EINVAL; return -1; } memcpy(rep->part[p].uuid, hdrp->prev_repl_uuid, POOL_HDR_UUID_LEN); } else { /* generate new uuid for this part */ if (util_uuid_generate(rep->part[p].uuid) < 0) { ERR("cannot generate pool set part UUID"); errno = EINVAL; return -1; } } } return 0; } /* * fill_struct_uuids -- (internal) fill fields in pool_set needed for further * altering of uuids */ static int fill_struct_uuids(struct pool_set *set, unsigned src_replica, struct poolset_health_status *set_hs, unsigned flags) { LOG(3, "set %p, src_replica %u, set_hs %p, flags %u", set, src_replica, set_hs, flags); /* set poolset uuid */ struct pool_hdr *src_hdr0 = HDR(REP(set, src_replica), 0); memcpy(set->uuid, src_hdr0->poolset_uuid, POOL_HDR_UUID_LEN); /* set unbroken parts' uuids */ for (unsigned r = 0; r < set->nreplicas; ++r) { fill_struct_part_uuids(set, r, set_hs); } /* set broken parts' uuids */ for (unsigned r = 0; r < set->nreplicas; ++r) { if (fill_struct_broken_part_uuids(set, r, set_hs, flags)) return -1; } return 0; } /* * create_headers_for_broken_parts -- (internal) create headers for all new * parts created in place of the broken ones */ static int create_headers_for_broken_parts(struct pool_set *set, unsigned src_replica, struct poolset_health_status *set_hs) { LOG(3, "set %p, src_replica %u, set_hs %p", set, src_replica, set_hs); struct pool_hdr *src_hdr = HDR(REP(set, src_replica), 0); for (unsigned r = 0; r < set_hs->nreplicas; ++r) { /* skip unbroken replicas */ if (!replica_is_replica_broken(r, set_hs) && !replica_has_bad_blocks(r, set_hs)) continue; for (unsigned p = 0; p < set_hs->replica[r]->nhdrs; p++) { /* skip unbroken parts */ if (!replica_is_part_broken(r, p, set_hs) && !replica_part_has_corrupted_header(r, p, set_hs)) continue; if (sync_recreate_header(set, r, p, src_hdr)) return -1; } } return 0; } /* * copy_data_to_broken_parts -- (internal) copy data to all parts created * in place of the broken ones */ static int copy_data_to_broken_parts(struct pool_set *set, unsigned healthy_replica, unsigned flags, struct poolset_health_status *set_hs) { LOG(3, "set %p, healthy_replica %u, flags %u, set_hs %p", set, healthy_replica, flags, set_hs); /* get pool size from healthy replica */ size_t poolsize = set->poolsize; for (unsigned r = 0; r < set_hs->nreplicas; ++r) { /* skip unbroken and consistent replicas */ if (replica_is_replica_healthy(r, set_hs)) continue; struct pool_replica *rep = REP(set, r); struct pool_replica *rep_h = REP(set, healthy_replica); for (unsigned p = 0; p < rep->nparts; ++p) { /* skip unbroken parts from consistent replicas */ if (!replica_is_part_broken(r, p, set_hs) && replica_is_replica_consistent(r, set_hs)) continue; const struct pool_set_part *part = &rep->part[p]; size_t off = replica_get_part_data_offset(set, r, p); size_t len = replica_get_part_data_len(set, r, p); /* do not allow copying too much data */ if (off >= poolsize) continue; if (off + len > poolsize || rep->remote) len = poolsize - off; /* * First part of replica is mapped * with header */ size_t fpoff = (p == 0) ? POOL_HDR_SIZE : 0; void *src_addr = ADDR_SUM(rep_h->part[0].addr, off); void *dst_addr = ADDR_SUM(part->addr, fpoff); if (sync_copy_data(src_addr, dst_addr, off, len, rep_h, rep, part)) return -1; } } return 0; } /* * grant_created_parts_perm -- (internal) set RW permission rights to all * the parts created in place of the broken ones */ static int grant_created_parts_perm(struct pool_set *set, unsigned src_repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, src_repn %u, set_hs %p", set, src_repn, set_hs); /* choose the default permissions */ mode_t def_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; /* get permissions of the first part of the source replica */ mode_t src_mode; os_stat_t sb; if (REP(set, src_repn)->remote) { src_mode = def_mode; } else if (os_stat(PART(REP(set, src_repn), 0)->path, &sb) != 0) { ERR("cannot check file permissions of %s (replica %u, part %u)", PART(REP(set, src_repn), 0)->path, src_repn, 0); src_mode = def_mode; } else { src_mode = sb.st_mode; } /* set permissions to all recreated parts */ for (unsigned r = 0; r < set_hs->nreplicas; ++r) { /* skip unbroken replicas */ if (!replica_is_replica_broken(r, set_hs)) continue; if (set->replica[r]->remote) continue; for (unsigned p = 0; p < set_hs->replica[r]->nparts; p++) { /* skip parts which were not created */ if (!PART(REP(set, r), p)->created) continue; LOG(4, "setting permissions for part %u, replica %u", p, r); /* set rights to those of existing part files */ if (os_chmod(PART(REP(set, r), p)->path, src_mode)) { ERR( "cannot set permission rights for created parts: replica %u, part %u", r, p); errno = EPERM; return -1; } } } return 0; } /* * update_parts_linkage -- (internal) set uuids linking recreated parts within * a replica */ static int update_parts_linkage(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, set_hs %p", set, repn, set_hs); struct pool_replica *rep = REP(set, repn); for (unsigned p = 0; p < rep->nhdrs; ++p) { struct pool_hdr *hdrp = HDR(rep, p); struct pool_hdr *prev_hdrp = HDRP(rep, p); struct pool_hdr *next_hdrp = HDRN(rep, p); /* set uuids in the current part */ memcpy(hdrp->prev_part_uuid, PARTP(rep, p)->uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->next_part_uuid, PARTN(rep, p)->uuid, POOL_HDR_UUID_LEN); util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(hdrp)); /* set uuids in the previous part */ memcpy(prev_hdrp->next_part_uuid, PART(rep, p)->uuid, POOL_HDR_UUID_LEN); util_checksum(prev_hdrp, sizeof(*prev_hdrp), &prev_hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(prev_hdrp)); /* set uuids in the next part */ memcpy(next_hdrp->prev_part_uuid, PART(rep, p)->uuid, POOL_HDR_UUID_LEN); util_checksum(next_hdrp, sizeof(*next_hdrp), &next_hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(next_hdrp)); /* store pool's header */ util_persist(PART(rep, p)->is_dev_dax, hdrp, sizeof(*hdrp)); util_persist(PARTP(rep, p)->is_dev_dax, prev_hdrp, sizeof(*prev_hdrp)); util_persist(PARTN(rep, p)->is_dev_dax, next_hdrp, sizeof(*next_hdrp)); } return 0; } /* * update_replicas_linkage -- (internal) update uuids linking replicas */ static int update_replicas_linkage(struct pool_set *set, unsigned repn) { LOG(3, "set %p, repn %u", set, repn); struct pool_replica *rep = REP(set, repn); struct pool_replica *prev_r = REPP(set, repn); struct pool_replica *next_r = REPN(set, repn); ASSERT(rep->nparts > 0); ASSERT(prev_r->nparts > 0); ASSERT(next_r->nparts > 0); /* set uuids in the current replica */ for (unsigned p = 0; p < rep->nhdrs; ++p) { struct pool_hdr *hdrp = HDR(rep, p); memcpy(hdrp->prev_repl_uuid, PART(prev_r, 0)->uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->next_repl_uuid, PART(next_r, 0)->uuid, POOL_HDR_UUID_LEN); util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(hdrp)); /* store pool's header */ util_persist(PART(rep, p)->is_dev_dax, hdrp, sizeof(*hdrp)); } /* set uuids in the previous replica */ for (unsigned p = 0; p < prev_r->nhdrs; ++p) { struct pool_hdr *prev_hdrp = HDR(prev_r, p); memcpy(prev_hdrp->next_repl_uuid, PART(rep, 0)->uuid, POOL_HDR_UUID_LEN); util_checksum(prev_hdrp, sizeof(*prev_hdrp), &prev_hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(prev_hdrp)); /* store pool's header */ util_persist(PART(prev_r, p)->is_dev_dax, prev_hdrp, sizeof(*prev_hdrp)); } /* set uuids in the next replica */ for (unsigned p = 0; p < next_r->nhdrs; ++p) { struct pool_hdr *next_hdrp = HDR(next_r, p); memcpy(next_hdrp->prev_repl_uuid, PART(rep, 0)->uuid, POOL_HDR_UUID_LEN); util_checksum(next_hdrp, sizeof(*next_hdrp), &next_hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(next_hdrp)); /* store pool's header */ util_persist(PART(next_r, p)->is_dev_dax, next_hdrp, sizeof(*next_hdrp)); } return 0; } /* * update_poolset_uuids -- (internal) update poolset uuid in recreated parts */ static int update_poolset_uuids(struct pool_set *set, unsigned repn, struct poolset_health_status *set_hs) { LOG(3, "set %p, repn %u, set_hs %p", set, repn, set_hs); struct pool_replica *rep = REP(set, repn); for (unsigned p = 0; p < rep->nhdrs; ++p) { struct pool_hdr *hdrp = HDR(rep, p); memcpy(hdrp->poolset_uuid, set->uuid, POOL_HDR_UUID_LEN); util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 1, POOL_HDR_CSUM_END_OFF(hdrp)); /* store pool's header */ util_persist(PART(rep, p)->is_dev_dax, hdrp, sizeof(*hdrp)); } return 0; } /* * update_remote_headers -- (internal) update headers of existing remote * replicas */ static int update_remote_headers(struct pool_set *set) { LOG(3, "set %p", set); for (unsigned r = 0; r < set->nreplicas; ++r) { /* skip local or just created replicas */ if (REP(set, r)->remote == NULL || PART(REP(set, r), 0)->created == 1) continue; if (util_update_remote_header(set, r)) { LOG(1, "updating header of a remote replica no. %u failed", r); return -1; } } return 0; } /* * update_uuids -- (internal) set all uuids that might have changed or be unset * after recreating parts */ static int update_uuids(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; ++r) { if (!replica_is_replica_healthy(r, set_hs)) update_parts_linkage(set, r, set_hs); update_replicas_linkage(set, r); update_poolset_uuids(set, r, set_hs); } if (update_remote_headers(set)) return -1; return 0; } /* * remove_remote -- (internal) remove remote pool */ static int remove_remote(const char *target, const char *pool_set) { LOG(3, "target %s, pool_set %s", target, pool_set); #ifdef USE_RPMEM struct rpmem_target_info *info = rpmem_target_parse(target); if (!info) goto err_parse; struct rpmem_ssh *ssh = rpmem_ssh_exec(info, "--remove", pool_set, "--force", NULL); if (!ssh) { goto err_ssh_exec; } if (rpmem_ssh_monitor(ssh, 0)) goto err_ssh_monitor; int ret = rpmem_ssh_close(ssh); rpmem_target_free(info); return ret; err_ssh_monitor: rpmem_ssh_close(ssh); err_ssh_exec: rpmem_target_free(info); err_parse: return -1; #else FATAL("remote replication not supported"); return -1; #endif } /* * open_remote_replicas -- (internal) open all unbroken remote replicas */ static int open_remote_replicas(struct pool_set *set, struct poolset_health_status *set_hs) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; r++) { struct pool_replica *rep = set->replica[r]; if (!rep->remote) continue; if (!replica_is_replica_healthy(r, set_hs)) continue; unsigned nlanes = REMOTE_NLANES; int ret = util_poolset_remote_replica_open(set, r, set->poolsize, 0, &nlanes); if (ret) { LOG(1, "Opening '%s' on '%s' failed", rep->remote->pool_desc, rep->remote->node_addr); return ret; } } return 0; } /* * create_remote_replicas -- (internal) recreate all broken replicas */ static int create_remote_replicas(struct pool_set *set, struct poolset_health_status *set_hs, unsigned flags) { LOG(3, "set %p, set_hs %p", set, set_hs); for (unsigned r = 0; r < set->nreplicas; r++) { struct pool_replica *rep = set->replica[r]; if (!rep->remote) continue; if (replica_is_replica_healthy(r, set_hs)) continue; if (!replica_is_poolset_transformed(flags)) { /* ignore errors from remove operation */ remove_remote(rep->remote->node_addr, rep->remote->pool_desc); } unsigned nlanes = REMOTE_NLANES; int ret = util_poolset_remote_replica_open(set, r, set->poolsize, 1, &nlanes); if (ret) { LOG(1, "Creating '%s' on '%s' failed", rep->remote->pool_desc, rep->remote->node_addr); return ret; } } return 0; } /* * sync_replica -- synchronize data across replicas within a poolset */ int replica_sync(struct pool_set *set, struct poolset_health_status *s_hs, unsigned flags) { LOG(3, "set %p, flags %u", set, flags); int ret = 0; struct poolset_health_status *set_hs = NULL; /* check if we already know the poolset health status */ if (s_hs == NULL) { /* validate poolset before checking its health */ if (validate_args(set)) return -1; /* examine poolset's health */ if (replica_check_poolset_health(set, &set_hs, 1 /* called from sync */, flags)) { LOG(1, "poolset health check failed"); return -1; } /* check if poolset is broken; if not, nothing to do */ if (replica_is_poolset_healthy(set_hs)) { LOG(1, "poolset is healthy"); goto out; } } else { set_hs = s_hs; } /* find a replica with healthy header; it will be the source of data */ unsigned healthy_replica = replica_find_healthy_replica(set_hs); unsigned healthy_header = healthy_replica; if (healthy_header == UNDEF_REPLICA) { healthy_header = replica_find_replica_healthy_header(set_hs); if (healthy_header == UNDEF_REPLICA) { ERR("no healthy replica found"); errno = EINVAL; ret = -1; goto out; } } /* in dry-run mode we can stop here */ if (is_dry_run(flags)) { LOG(1, "Sync in dry-run mode finished successfully"); goto out; } /* recreate broken parts */ if (recreate_broken_parts(set, set_hs, fix_bad_blocks(flags))) { ERR("recreating broken parts failed"); ret = -1; goto out; } /* open all part files */ if (replica_open_poolset_part_files(set)) { ERR("opening poolset part files failed"); ret = -1; goto out; } /* map all replicas */ if (util_poolset_open(set)) { ERR("opening poolset failed"); ret = -1; goto out; } /* this is required for opening remote pools */ set->poolsize = set_hs->replica[healthy_header]->pool_size; LOG(3, "setting the pool size (%zu) from replica #%u", set->poolsize, healthy_header); /* open all remote replicas */ if (open_remote_replicas(set, set_hs)) { ERR("opening remote replicas failed"); ret = -1; goto out; } /* recalculate offset and length of bad blocks */ if (sync_recalc_badblocks(set, set_hs)) { LOG(1, "syncing bad blocks data failed"); ret = -1; goto out; } /* * Check if there are uncorrectable bad blocks * (bad blocks overlapping in all replicas). */ int status = sync_check_bad_blocks_overlap(set, set_hs); if (status == -1) { LOG(1, "checking bad blocks failed"); ret = -1; goto out; } if (status == 1) { ERR( "a part of the pool has uncorrectable errors in all replicas"); errno = EINVAL; ret = -1; goto out; } LOG(3, "bad blocks do not overlap"); /* sync data in bad blocks */ if (sync_badblocks_data(set, set_hs)) { LOG(1, "syncing bad blocks data failed"); ret = -1; goto out; } /* find one good replica; it will be the source of data */ healthy_replica = replica_find_healthy_replica(set_hs); if (healthy_replica == UNDEF_REPLICA) { ERR("no healthy replica found"); errno = EINVAL; ret = -1; goto out; } /* update uuid fields in the set structure with part headers */ if (fill_struct_uuids(set, healthy_replica, set_hs, flags)) { ERR("gathering uuids failed"); ret = -1; goto out; } /* create headers for broken parts */ if (create_headers_for_broken_parts(set, healthy_replica, set_hs)) { ERR("creating headers for broken parts failed"); ret = -1; goto out; } /* create all remote replicas */ if (create_remote_replicas(set, set_hs, flags)) { ERR("creating remote replicas failed"); ret = -1; goto out; } /* check and copy data if possible */ if (copy_data_to_broken_parts(set, healthy_replica, flags, set_hs)) { ERR("copying data to broken parts failed"); ret = -1; goto out; } /* update uuids of replicas and parts */ if (update_uuids(set, set_hs)) { ERR("updating uuids failed"); ret = -1; goto out; } /* grant permissions to all created parts */ if (grant_created_parts_perm(set, healthy_replica, set_hs)) { ERR("granting permissions to created parts failed"); ret = -1; } out: if (s_hs == NULL) replica_free_poolset_health_status(set_hs); return ret; } pmdk-1.11.1/src/librpmem/0000775000000000000000000000000014123364546013634 5ustar rootrootpmdk-1.11.1/src/librpmem/rpmem.c0000664000000000000000000005010214123364546015116 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem.c -- main source file for librpmem */ #include #include #include #include #include #include #include "librpmem.h" #include "out.h" #include "os.h" #include "os_thread.h" #include "util.h" #include "rpmem.h" #include "rpmem_common.h" #include "rpmem_util.h" #include "rpmem_obc.h" #include "rpmem_fip.h" #include "rpmem_fip_common.h" #include "rpmem_ssh.h" #include "rpmem_proto.h" #define RPMEM_REMOVE_FLAGS_ALL (\ RPMEM_REMOVE_FORCE | \ RPMEM_REMOVE_POOL_SET \ ) #define RPMEM_CHECK_FORK() do {\ if (Rpmem_fork_unsafe) {\ ERR("libfabric is initialized without fork() support");\ return NULL;\ }\ } while (0) static os_once_t Rpmem_fork_unsafe_key_once = OS_ONCE_INIT; /* * rpmem_pool -- remote pool context */ struct rpmem_pool { struct rpmem_obc *obc; /* out-of-band connection handle */ struct rpmem_fip *fip; /* fabric provider handle */ struct rpmem_target_info *info; char fip_service[NI_MAXSERV]; enum rpmem_provider provider; size_t max_wq_size; /* max WQ size supported by provider */ os_thread_t monitor; int closing; int no_headers; /* * Last error code, need to be volatile because it can * be accessed by multiple threads. */ volatile int error; }; /* * env_get_bool -- parse value of specified environment variable as a bool * * Return values: * 0 - defined, valp has value * 1 - not defined * -1 - parsing error */ static int env_get_bool(const char *name, int *valp) { LOG(3, "name %s, valp %p", name, valp); const char *env = os_getenv(name); if (!env) return 1; char *endptr; errno = 0; long val = strtol(env, &endptr, 10); if (*endptr != '\0' || errno) goto err; if (val < INT_MIN || val > INT_MAX) goto err; *valp = (int)val; return 0; err: RPMEM_LOG(ERR, "!parsing '%s' environment variable failed", name); return -1; } /* * rpmem_get_provider -- set provider based on node address and environment */ static int rpmem_set_provider(RPMEMpool *rpp, const char *node) { LOG(3, "rpp %p, node %s", rpp, node); struct rpmem_fip_probe probe; enum rpmem_provider prov = RPMEM_PROV_UNKNOWN; int ret = rpmem_fip_probe_get(node, &probe); if (ret) return -1; /* * The sockets provider can be used only if specified environment * variable is set to 1. */ if (rpmem_fip_probe(probe, RPMEM_PROV_LIBFABRIC_SOCKETS)) { int enable; ret = env_get_bool(RPMEM_PROV_SOCKET_ENV, &enable); if (!ret && enable) { prov = RPMEM_PROV_LIBFABRIC_SOCKETS; } } /* * The verbs provider is enabled by default. If appropriate * environment variable is set to 0, the verbs provider is disabled. * * The verbs provider has higher priority than sockets provider. */ if (rpmem_fip_probe(probe, RPMEM_PROV_LIBFABRIC_VERBS)) { int enable; ret = env_get_bool(RPMEM_PROV_VERBS_ENV, &enable); if (ret == 1 || (!ret && enable)) prov = RPMEM_PROV_LIBFABRIC_VERBS; } if (prov == RPMEM_PROV_UNKNOWN) return -1; RPMEM_ASSERT(prov < MAX_RPMEM_PROV); rpp->max_wq_size = probe.max_wq_size[prov]; rpp->provider = prov; return 0; } /* * rpmem_monitor_thread -- connection monitor background thread */ static void * rpmem_monitor_thread(void *arg) { LOG(3, "arg %p", arg); RPMEMpool *rpp = arg; int ret = rpmem_obc_monitor(rpp->obc, 0); if (ret && !rpp->closing) { RPMEM_LOG(ERR, "unexpected data received"); rpp->error = errno; } return NULL; } /* * rpmem_common_init -- common routine for initialization */ static RPMEMpool * rpmem_common_init(const char *target) { LOG(3, "target %s", target); int ret; RPMEMpool *rpp = calloc(1, sizeof(*rpp)); if (!rpp) { ERR("!calloc"); goto err_malloc_rpmem; } rpp->info = rpmem_target_parse(target); if (!rpp->info) { ERR("!parsing target node address failed"); goto err_target_split; } ret = rpmem_set_provider(rpp, rpp->info->node); if (ret) { errno = ENOMEDIUM; ERR("cannot find provider"); goto err_provider; } RPMEM_LOG(NOTICE, "provider: %s", rpmem_provider_to_str(rpp->provider)); if (rpp->provider == RPMEM_PROV_LIBFABRIC_SOCKETS) { /* libfabric's sockets provider does not support IPv6 */ RPMEM_LOG(NOTICE, "forcing using IPv4"); rpp->info->flags |= RPMEM_FLAGS_USE_IPV4; } rpp->obc = rpmem_obc_init(); if (!rpp->obc) { ERR("!out-of-band connection initialization failed"); goto err_obc_init; } RPMEM_LOG(INFO, "establishing out-of-band connection"); ret = rpmem_obc_connect(rpp->obc, rpp->info); if (ret) { ERR("!out-of-band connection failed"); goto err_obc_connect; } RPMEM_LOG(NOTICE, "out-of-band connection established"); return rpp; err_obc_connect: rpmem_obc_fini(rpp->obc); err_obc_init: err_provider: rpmem_target_free(rpp->info); err_target_split: free(rpp); err_malloc_rpmem: return NULL; } /* * rpmem_common_fini -- common routing for deinitialization */ static void rpmem_common_fini(RPMEMpool *rpp, int join) { LOG(3, "rpp %p, join %d", rpp, join); rpmem_obc_disconnect(rpp->obc); if (join) { int ret = os_thread_join(&rpp->monitor, NULL); if (ret) { errno = ret; ERR("joining monitor thread failed"); } } rpmem_obc_fini(rpp->obc); rpmem_target_free(rpp->info); free(rpp); } /* * rpmem_common_fip_init -- common routine for initializing fabric provider */ static int rpmem_common_fip_init(RPMEMpool *rpp, struct rpmem_req_attr *req, struct rpmem_resp_attr *resp, void *pool_addr, size_t pool_size, unsigned *nlanes, size_t buff_size) { LOG(3, "rpp %p, req %p, resp %p, pool_addr %p, pool_size %zu, nlanes " "%p", rpp, req, resp, pool_addr, pool_size, nlanes); int ret; struct rpmem_fip_attr fip_attr = { .provider = req->provider, .max_wq_size = rpp->max_wq_size, .persist_method = resp->persist_method, .laddr = pool_addr, .size = pool_size, .buff_size = buff_size, .nlanes = min(*nlanes, resp->nlanes), .raddr = (void *)resp->raddr, .rkey = resp->rkey, }; ret = util_snprintf(rpp->fip_service, sizeof(rpp->fip_service), "%u", resp->port); if (ret < 0) { ERR("!snprintf"); goto err_port; } rpp->fip = rpmem_fip_init(rpp->info->node, rpp->fip_service, &fip_attr, nlanes); if (!rpp->fip) { ERR("!in-band connection initialization failed"); ret = -1; goto err_fip_init; } RPMEM_LOG(NOTICE, "final nlanes: %u", *nlanes); RPMEM_LOG(INFO, "establishing in-band connection"); ret = rpmem_fip_connect(rpp->fip); if (ret) { ERR("!establishing in-band connection failed"); goto err_fip_connect; } RPMEM_LOG(NOTICE, "in-band connection established"); return 0; err_fip_connect: rpmem_fip_fini(rpp->fip); err_fip_init: err_port: return ret; } /* * rpmem_common_fip_fini -- common routine for deinitializing fabric provider */ static void rpmem_common_fip_fini(RPMEMpool *rpp) { LOG(3, "rpp %p", rpp); RPMEM_LOG(INFO, "closing in-band connection"); rpmem_fip_fini(rpp->fip); RPMEM_LOG(NOTICE, "in-band connection closed"); } /* * rpmem_log_args -- log input arguments for rpmem_create and rpmem_open */ static void rpmem_log_args(const char *req, const char *target, const char *pool_set_name, void *pool_addr, size_t pool_size, unsigned nlanes) { LOG(3, "req %s, target %s, pool_set_name %s, pool_addr %p, pool_size " "%zu, nlanes %d", req, target, pool_set_name, pool_addr, pool_size, nlanes); RPMEM_LOG(NOTICE, "%s request:", req); RPMEM_LOG(NOTICE, "\ttarget: %s", target); RPMEM_LOG(NOTICE, "\tpool set: %s", pool_set_name); RPMEM_LOG(INFO, "\tpool addr: %p", pool_addr); RPMEM_LOG(INFO, "\tpool size: %lu", pool_size); RPMEM_LOG(NOTICE, "\tnlanes: %u", nlanes); } /* * rpmem_log_resp -- log response attributes */ static void rpmem_log_resp(const char *req, const struct rpmem_resp_attr *resp) { LOG(3, "req %s, resp %p", req, resp); RPMEM_LOG(NOTICE, "%s request response:", req); RPMEM_LOG(NOTICE, "\tnlanes: %u", resp->nlanes); RPMEM_LOG(NOTICE, "\tport: %u", resp->port); RPMEM_LOG(NOTICE, "\tpersist method: %s", rpmem_persist_method_to_str(resp->persist_method)); RPMEM_LOG(NOTICE, "\tremote addr: 0x%" PRIx64, resp->raddr); } /* * rpmem_check_args -- validate user's arguments */ static int rpmem_check_args(void *pool_addr, size_t pool_size, unsigned *nlanes) { LOG(3, "pool_addr %p, pool_size %zu, nlanes %p", pool_addr, pool_size, nlanes); if (!pool_addr) { errno = EINVAL; ERR("invalid pool address"); return -1; } if (!IS_PAGE_ALIGNED((uintptr_t)pool_addr)) { errno = EINVAL; ERR("Pool address must be aligned to page size (%llu)", Pagesize); return -1; } if (!IS_PAGE_ALIGNED(pool_size)) { errno = EINVAL; ERR("Pool size must be aligned to page size (%llu)", Pagesize); return -1; } if (!pool_size) { errno = EINVAL; ERR("invalid pool size"); return -1; } if (!nlanes) { errno = EINVAL; ERR("lanes pointer cannot be NULL"); return -1; } if (!(*nlanes)) { errno = EINVAL; ERR("number of lanes must be positive"); return -1; } return 0; } /* * rpmem_create -- create remote pool on target node * * target -- target node in format [@][:] * pool_set_name -- remote pool set name * pool_addr -- local pool memory address which will be replicated * pool_size -- required pool size * nlanes -- number of lanes * create_attr -- pool attributes used for creating the pool on remote node */ RPMEMpool * rpmem_create(const char *target, const char *pool_set_name, void *pool_addr, size_t pool_size, unsigned *nlanes, const struct rpmem_pool_attr *create_attr) { LOG(3, "target %s, pool_set_name %s, pool_addr %p, pool_size %zu, " "nlanes %p, create_attr %p", target, pool_set_name, pool_addr, pool_size, nlanes, create_attr); os_once(&Rpmem_fork_unsafe_key_once, &rpmem_fip_probe_fork_safety); RPMEM_CHECK_FORK(); rpmem_log_args("create", target, pool_set_name, pool_addr, pool_size, *nlanes); if (rpmem_check_args(pool_addr, pool_size, nlanes)) return NULL; RPMEMpool *rpp = rpmem_common_init(target); if (!rpp) goto err_common_init; size_t buff_size = RPMEM_DEF_BUFF_SIZE; struct rpmem_req_attr req = { .pool_size = pool_size, .nlanes = min(*nlanes, Rpmem_max_nlanes), .provider = rpp->provider, .pool_desc = pool_set_name, .buff_size = buff_size, }; struct rpmem_resp_attr resp; int ret = rpmem_obc_create(rpp->obc, &req, &resp, create_attr); if (ret) { RPMEM_LOG(ERR, "!create request failed"); goto err_obc_create; } if (create_attr == NULL || util_is_zeroed(create_attr, sizeof(*create_attr))) rpp->no_headers = 1; rpmem_log_resp("create", &resp); ret = rpmem_common_fip_init(rpp, &req, &resp, pool_addr, pool_size, nlanes, buff_size); if (ret) goto err_fip_init; ret = os_thread_create(&rpp->monitor, NULL, rpmem_monitor_thread, rpp); if (ret) { errno = ret; ERR("!starting monitor thread"); goto err_monitor; } return rpp; err_monitor: rpmem_common_fip_fini(rpp); err_fip_init: rpmem_obc_close(rpp->obc, RPMEM_CLOSE_FLAGS_REMOVE); err_obc_create: rpmem_common_fini(rpp, 0); err_common_init: return NULL; } /* * rpmem_open -- open remote pool on target node * * target -- target node in format [@][:] * pool_set_name -- remote pool set name * pool_addr -- local pool memory address which will be replicated * pool_size -- required pool size * nlanes -- number of lanes * open_attr -- pool attributes, received from remote host */ RPMEMpool * rpmem_open(const char *target, const char *pool_set_name, void *pool_addr, size_t pool_size, unsigned *nlanes, struct rpmem_pool_attr *open_attr) { LOG(3, "target %s, pool_set_name %s, pool_addr %p, pool_size %zu, " "nlanes %p, create_attr %p", target, pool_set_name, pool_addr, pool_size, nlanes, open_attr); os_once(&Rpmem_fork_unsafe_key_once, &rpmem_fip_probe_fork_safety); RPMEM_CHECK_FORK(); rpmem_log_args("open", target, pool_set_name, pool_addr, pool_size, *nlanes); if (rpmem_check_args(pool_addr, pool_size, nlanes)) return NULL; RPMEMpool *rpp = rpmem_common_init(target); if (!rpp) goto err_common_init; size_t buff_size = RPMEM_DEF_BUFF_SIZE; struct rpmem_req_attr req = { .pool_size = pool_size, .nlanes = min(*nlanes, Rpmem_max_nlanes), .provider = rpp->provider, .pool_desc = pool_set_name, .buff_size = buff_size, }; struct rpmem_resp_attr resp; int ret = rpmem_obc_open(rpp->obc, &req, &resp, open_attr); if (ret) { RPMEM_LOG(ERR, "!open request failed"); goto err_obc_create; } if (open_attr == NULL || util_is_zeroed(open_attr, sizeof(*open_attr))) rpp->no_headers = 1; rpmem_log_resp("open", &resp); ret = rpmem_common_fip_init(rpp, &req, &resp, pool_addr, pool_size, nlanes, buff_size); if (ret) goto err_fip_init; ret = os_thread_create(&rpp->monitor, NULL, rpmem_monitor_thread, rpp); if (ret) { errno = ret; ERR("!starting monitor thread"); goto err_monitor; } return rpp; err_monitor: rpmem_common_fip_fini(rpp); err_fip_init: rpmem_obc_close(rpp->obc, 0); err_obc_create: rpmem_common_fini(rpp, 0); err_common_init: return NULL; } /* * rpmem_close -- close remote pool on target node */ int rpmem_close(RPMEMpool *rpp) { LOG(3, "rpp %p", rpp); RPMEM_LOG(INFO, "closing out-of-band connection"); util_fetch_and_or32(&rpp->closing, 1); rpmem_fip_close(rpp->fip); int ret = rpmem_obc_close(rpp->obc, 0); if (ret) ERR("!close request failed"); RPMEM_LOG(NOTICE, "out-of-band connection closed"); rpmem_common_fip_fini(rpp); rpmem_common_fini(rpp, 1); return ret; } /* * rpmem_flush -- flush to target node operation * * rpp -- remote pool handle * offset -- offset in pool * length -- length of flush operation * lane -- lane number * flags -- additional flags */ int rpmem_flush(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane, unsigned flags) { LOG(3, "rpp %p, offset %zu, length %zu, lane %d, flags 0x%x", rpp, offset, length, lane, flags); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } if (flags & RPMEM_FLUSH_FLAGS_MASK) { ERR("invalid flags (0x%x)", flags); errno = EINVAL; return -1; } if (rpp->no_headers == 0 && offset < RPMEM_HDR_SIZE) { ERR("offset (%zu) in pool is less than %ld bytes", offset, RPMEM_HDR_SIZE); errno = EINVAL; return -1; } /* * By default use RDMA SEND flush mode which has atomicity * guarantees. For relaxed flush use RDMA WRITE. */ unsigned mode = RPMEM_PERSIST_SEND; if (flags & RPMEM_FLUSH_RELAXED) mode = RPMEM_FLUSH_WRITE; int ret = rpmem_fip_flush(rpp->fip, offset, length, lane, mode); if (unlikely(ret)) { LOG(2, "flush operation failed"); rpp->error = ret; errno = rpp->error; return -1; } return 0; } /* * rpmem_drain -- drain on target node operation * * rpp -- remote pool handle * lane -- lane number * flags -- additional flags */ int rpmem_drain(RPMEMpool *rpp, unsigned lane, unsigned flags) { LOG(3, "rpp %p, lane %d, flags 0x%x", rpp, lane, flags); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } if (flags != 0) { ERR("invalid flags (0x%x)", flags); errno = EINVAL; return -1; } int ret = rpmem_fip_drain(rpp->fip, lane); if (unlikely(ret)) { LOG(2, "drain operation failed"); rpp->error = ret; errno = rpp->error; return -1; } return 0; } /* * rpmem_persist -- persist operation on target node * * rpp -- remote pool handle * offset -- offset in pool * length -- length of persist operation * lane -- lane number */ int rpmem_persist(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane, unsigned flags) { LOG(3, "rpp %p, offset %zu, length %zu, lane %d, flags 0x%x", rpp, offset, length, lane, flags); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } if (flags & RPMEM_PERSIST_FLAGS_MASK) { ERR("invalid flags (0x%x)", flags); errno = EINVAL; return -1; } if (rpp->no_headers == 0 && offset < RPMEM_HDR_SIZE) { ERR("offset (%zu) in pool is less than %ld bytes", offset, RPMEM_HDR_SIZE); errno = EINVAL; return -1; } /* * By default use RDMA SEND persist mode which has atomicity * guarantees. For relaxed persist use RDMA WRITE. */ unsigned mode = RPMEM_PERSIST_SEND; if (flags & RPMEM_PERSIST_RELAXED) mode = RPMEM_FLUSH_WRITE; int ret = rpmem_fip_persist(rpp->fip, offset, length, lane, mode); if (unlikely(ret)) { LOG(2, "persist operation failed"); rpp->error = ret; errno = rpp->error; return -1; } return 0; } /* * rpmem_deep_persist -- deep flush operation on target node * * rpp -- remote pool handle * offset -- offset in pool * length -- length of deep flush operation * lane -- lane number */ int rpmem_deep_persist(RPMEMpool *rpp, size_t offset, size_t length, unsigned lane) { LOG(3, "rpp %p, offset %zu, length %zu, lane %d", rpp, offset, length, lane); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } if (offset < RPMEM_HDR_SIZE) { ERR("offset (%zu) in pool is less than %ld bytes", offset, RPMEM_HDR_SIZE); errno = EINVAL; return -1; } int ret = rpmem_fip_persist(rpp->fip, offset, length, lane, RPMEM_DEEP_PERSIST); if (unlikely(ret)) { ERR("persist operation failed"); rpp->error = ret; errno = rpp->error; return -1; } return 0; } /* * rpmem_read -- read data from remote pool: * * rpp -- remote pool handle * buff -- output buffer * offset -- offset in pool * length -- length of read operation */ int rpmem_read(RPMEMpool *rpp, void *buff, size_t offset, size_t length, unsigned lane) { LOG(3, "rpp %p, buff %p, offset %zu, length %zu, lane %d", rpp, buff, offset, length, lane); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } if (rpp->no_headers == 0 && offset < RPMEM_HDR_SIZE) LOG(1, "reading from pool at offset (%zu) less than %ld bytes", offset, RPMEM_HDR_SIZE); int ret = rpmem_fip_read(rpp->fip, buff, length, offset, lane); if (unlikely(ret)) { errno = ret; ERR("!read operation failed"); rpp->error = ret; return -1; } return 0; } /* * rpmem_set_attr -- overwrite pool attributes on the remote node * * rpp -- remote pool handle * attr -- new pool attributes for the pool on remote node */ int rpmem_set_attr(RPMEMpool *rpp, const struct rpmem_pool_attr *attr) { LOG(3, "rpp %p, attr %p", rpp, attr); if (unlikely(rpp->error)) { errno = rpp->error; return -1; } int ret = rpmem_obc_set_attr(rpp->obc, attr); if (ret) { RPMEM_LOG(ERR, "!set attributes request failed"); } return ret; } /* * rpmem_remove -- remove pool from remote node * * target -- target node in format [@][:] * pool_set_name -- remote pool set name * flags -- bitwise OR of one or more of the following flags: * - RPMEM_REMOVE_FORCE * - RPMEM_REMOVE_POOL_SET */ int rpmem_remove(const char *target, const char *pool_set, int flags) { LOG(3, "target %s, pool_set %s, flags %d", target, pool_set, flags); if (flags & ~(RPMEM_REMOVE_FLAGS_ALL)) { ERR("invalid flags specified"); errno = EINVAL; return -1; } struct rpmem_target_info *info = rpmem_target_parse(target); if (!info) { ERR("!parsing target node address failed"); goto err_target; } const char *argv[5]; argv[0] = "--remove"; argv[1] = pool_set; const char **cur = &argv[2]; if (flags & RPMEM_REMOVE_FORCE) *cur++ = "--force"; if (flags & RPMEM_REMOVE_POOL_SET) *cur++ = "--pool-set"; *cur = NULL; struct rpmem_ssh *ssh = rpmem_ssh_execv(info, argv); if (!ssh) { ERR("!executing ssh command failed"); goto err_ssh_exec; } int ret; ret = rpmem_ssh_monitor(ssh, 0); if (ret) { ERR("!waiting for remote command failed"); goto err_ssh_monitor; } ret = rpmem_ssh_close(ssh); if (ret) { errno = ret; ERR("remote command failed"); goto err_ssh_close; } rpmem_target_free(info); return 0; err_ssh_monitor: rpmem_ssh_close(ssh); err_ssh_close: err_ssh_exec: rpmem_target_free(info); err_target: return -1; } #if FAULT_INJECTION void rpmem_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at) { return core_inject_fault_at(type, nth, at); } int rpmem_fault_injection_enabled(void) { return core_fault_injection_enabled(); } #endif pmdk-1.11.1/src/librpmem/rpmem_ssh.h0000664000000000000000000000154514123364546016007 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_ssh.h -- rpmem ssh transport layer header file */ #ifndef RPMEM_SSH_H #define RPMEM_SSH_H 1 #include #ifdef __cplusplus extern "C" { #endif struct rpmem_ssh; struct rpmem_ssh *rpmem_ssh_open(const struct rpmem_target_info *info); struct rpmem_ssh *rpmem_ssh_exec(const struct rpmem_target_info *info, ...); struct rpmem_ssh *rpmem_ssh_execv(const struct rpmem_target_info *info, const char **argv); int rpmem_ssh_close(struct rpmem_ssh *rps); int rpmem_ssh_send(struct rpmem_ssh *rps, const void *buff, size_t len); int rpmem_ssh_recv(struct rpmem_ssh *rps, void *buff, size_t len); int rpmem_ssh_monitor(struct rpmem_ssh *rps, int nonblock); const char *rpmem_ssh_strerror(struct rpmem_ssh *rps, int oerrno); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/librpmem/librpmem.link.in0000664000000000000000000000063314123364546016731 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # src/librpmem/librpmem.link -- linker link file for librpmem # LIBRPMEM_1.0 { global: rpmem_create; rpmem_open; rpmem_set_attr; rpmem_close; rpmem_remove; rpmem_flush; rpmem_drain; rpmem_persist; rpmem_deep_persist; rpmem_read; rpmem_check_version; rpmem_errormsg; fault_injection; local: *; }; pmdk-1.11.1/src/librpmem/rpmem_util.c0000664000000000000000000001134114123364546016155 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * rpmem_util.c -- util functions for librpmem source file */ #include #include #include #include #include "out.h" #include "os.h" #include "librpmem.h" #include "rpmem_proto.h" #include "rpmem_common.h" #include "rpmem_util.h" static const struct rpmem_err_str_errno { int err; const char *str; } rpmem_err_str_errno[MAX_RPMEM_ERR] = { [RPMEM_SUCCESS] = { .err = 0, .str = "Success", }, [RPMEM_ERR_BADPROTO] = { .err = EPROTONOSUPPORT, .str = "Protocol version number mismatch", }, [RPMEM_ERR_BADNAME] = { .err = EINVAL, .str = "Invalid pool descriptor", }, [RPMEM_ERR_BADSIZE] = { .err = EFBIG, .str = "Invalid pool size", }, [RPMEM_ERR_BADNLANES] = { .err = EINVAL, .str = "Invalid number of lanes", }, [RPMEM_ERR_BADPROVIDER] = { .err = EINVAL, .str = "Invalid provider", }, [RPMEM_ERR_FATAL] = { .err = EREMOTEIO, .str = "Fatal error", }, [RPMEM_ERR_FATAL_CONN] = { .err = ECONNABORTED, .str = "Fatal in-band connection error", }, [RPMEM_ERR_BUSY] = { .err = EBUSY, .str = "Pool already in use", }, [RPMEM_ERR_EXISTS] = { .err = EEXIST, .str = "Pool already exists", }, [RPMEM_ERR_PROVNOSUP] = { .err = EMEDIUMTYPE, .str = "Provider not supported", }, [RPMEM_ERR_NOEXIST] = { .err = ENOENT, .str = "Pool set or its part doesn't exist or it is " "unavailable", }, [RPMEM_ERR_NOACCESS] = { .err = EACCES, .str = "Pool set permission denied", }, [RPMEM_ERR_POOL_CFG] = { .err = EINVAL, .str = "Invalid pool set configuration", }, }; static char *Rpmem_cmds; static char **Rpmem_cmd_arr; static size_t Rpmem_current_cmd; static size_t Rpmem_ncmds; #define RPMEM_CMD_SEPARATOR '|' /* * rpmem_util_proto_errstr -- return error string for error code */ const char * rpmem_util_proto_errstr(enum rpmem_err err) { RPMEM_ASSERT(err < MAX_RPMEM_ERR); const char *ret = rpmem_err_str_errno[err].str; RPMEM_ASSERT(ret); return ret; } /* * rpmem_util_proto_errno -- return appropriate errno value for error code */ int rpmem_util_proto_errno(enum rpmem_err err) { RPMEM_ASSERT(err < MAX_RPMEM_ERR); return rpmem_err_str_errno[err].err; } /* * rpmem_util_cmds_inc -- increase size of array for rpmem commands */ static void rpmem_util_cmds_inc(void) { Rpmem_ncmds++; Rpmem_cmd_arr = realloc(Rpmem_cmd_arr, Rpmem_ncmds * sizeof(*Rpmem_cmd_arr)); if (!Rpmem_cmd_arr) RPMEM_FATAL("!realloc"); } /* * rpmem_util_cmds_init -- read a RPMEM_CMD from the environment variable */ void rpmem_util_cmds_init(void) { char *cmd = os_getenv(RPMEM_CMD_ENV); if (!cmd) cmd = RPMEM_DEF_CMD; Rpmem_cmds = strdup(cmd); if (!Rpmem_cmds) RPMEM_FATAL("!strdup"); char *next = Rpmem_cmds; while (next) { rpmem_util_cmds_inc(); Rpmem_cmd_arr[Rpmem_ncmds - 1] = next; next = strchr(next, RPMEM_CMD_SEPARATOR); if (next) { *next = '\0'; next++; } } } /* * rpmem_util_env_fini -- release RPMEM_CMD copy */ void rpmem_util_cmds_fini(void) { RPMEM_ASSERT(Rpmem_cmds); RPMEM_ASSERT(Rpmem_cmd_arr); RPMEM_ASSERT(Rpmem_current_cmd < Rpmem_ncmds); free(Rpmem_cmds); Rpmem_cmds = NULL; free(Rpmem_cmd_arr); Rpmem_cmd_arr = NULL; Rpmem_ncmds = 0; Rpmem_current_cmd = 0; } /* * rpmem_util_cmd_get -- get a next command from RPMEM_CMD * * RPMEM_CMD can contain multiple commands separated by RPMEM_CMD_SEPARATOR. * Commands from RPMEM_CMD are read sequentially and used to establish out of * band connections to remote nodes in the order read from a poolset file. * */ const char * rpmem_util_cmd_get(void) { RPMEM_ASSERT(Rpmem_cmds); RPMEM_ASSERT(Rpmem_cmd_arr); RPMEM_ASSERT(Rpmem_current_cmd < Rpmem_ncmds); char *ret = Rpmem_cmd_arr[Rpmem_current_cmd]; Rpmem_current_cmd = (Rpmem_current_cmd + 1) % Rpmem_ncmds; return ret; } /* * rpmem_util_get_env_uint -- read the unsigned value from environment */ static void rpmem_util_get_env_uint(const char *env, unsigned *pval) { char *env_val = os_getenv(env); if (env_val && env_val[0] != '\0') { char *endptr; errno = 0; long val = strtol(env_val, &endptr, 10); if (endptr[0] != '\0' || val <= 0 || (errno == ERANGE && val == LONG_MAX)) { RPMEM_LOG(ERR, "%s variable must be a positive integer", env); } else { *pval = val < UINT_MAX ? (unsigned)val: UINT_MAX; } } } /* * rpmem_util_get_env_max_nlanes -- read the maximum number of lanes from * RPMEM_MAX_NLANES */ void rpmem_util_get_env_max_nlanes(unsigned *max_nlanes) { rpmem_util_get_env_uint(RPMEM_MAX_NLANES_ENV, max_nlanes); } /* * rpmem_util_get_env_wq_size -- read the required WQ size from env */ void rpmem_util_get_env_wq_size(unsigned *wq_size) { rpmem_util_get_env_uint(RPMEM_WQ_SIZE_ENV, wq_size); } pmdk-1.11.1/src/librpmem/librpmem.c0000664000000000000000000000327314123364546015614 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * librpmem.c -- entry points for librpmem */ #include #include #include "librpmem.h" #include "rpmem.h" #include "rpmem_common.h" #include "rpmem_util.h" #include "rpmem_fip.h" #include "util.h" #include "out.h" /* * librpmem_init -- load-time initialization for librpmem * * Called automatically by the run-time loader. */ ATTR_CONSTRUCTOR void librpmem_init(void) { util_init(); out_init(RPMEM_LOG_PREFIX, RPMEM_LOG_LEVEL_VAR, RPMEM_LOG_FILE_VAR, RPMEM_MAJOR_VERSION, RPMEM_MINOR_VERSION); LOG(3, NULL); rpmem_util_cmds_init(); rpmem_util_get_env_max_nlanes(&Rpmem_max_nlanes); rpmem_util_get_env_wq_size(&Rpmem_wq_size); } /* * librpmem_fini -- librpmem cleanup routine * * Called automatically when the process terminates. */ ATTR_DESTRUCTOR void librpmem_fini(void) { LOG(3, NULL); rpmem_util_cmds_fini(); out_fini(); } /* * rpmem_check_version -- see if library meets application version requirements */ const char * rpmem_check_version(unsigned major_required, unsigned minor_required) { LOG(3, "major_required %u minor_required %u", major_required, minor_required); if (major_required != RPMEM_MAJOR_VERSION) { ERR("librpmem major version mismatch (need %u, found %u)", major_required, RPMEM_MAJOR_VERSION); return out_get_errormsg(); } if (minor_required > RPMEM_MINOR_VERSION) { ERR("librpmem minor version mismatch (need %u, found %u)", minor_required, RPMEM_MINOR_VERSION); return out_get_errormsg(); } return NULL; } /* * rpmem_errormsg -- return the last error message */ const char * rpmem_errormsg(void) { return out_get_errormsg(); } pmdk-1.11.1/src/librpmem/rpmem_fip.c0000664000000000000000000013406614123364546015770 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2021, Intel Corporation */ /* * rpmem_fip.c -- rpmem libfabric provider module source file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "out.h" #include "util.h" #include "os_thread.h" #include "os.h" #include "page_size.h" #include "rpmem_common.h" #include "rpmem_fip_common.h" #include "rpmem_proto.h" #include "rpmem_util.h" #include "rpmem_fip_msg.h" #include "rpmem_fip.h" #include "valgrind_internal.h" #define RPMEM_FI_ERR(e, fmt, args...)\ ERR(fmt ": %s", ## args, fi_strerror((e))) #define RPMEM_FI_CLOSE(f, fmt, args...) (\ {\ int oerrno = errno;\ int ret = fi_close(&(f)->fid);\ if (ret)\ RPMEM_FI_ERR(ret, fmt, ## args);\ errno = oerrno;\ ret;\ }) #define LANE_ALIGN_SIZE CACHELINE_SIZE #define LANE_ALIGN __attribute__((aligned(LANE_ALIGN_SIZE))) #define RPMEM_RAW_BUFF_SIZE PMEM_PAGESIZE #define RPMEM_RAW_SIZE 8 typedef ssize_t (*rpmem_fip_flush_fn)(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags); typedef int (*rpmem_fip_drain_fn)(struct rpmem_fip *fip, unsigned lane); typedef ssize_t (*rpmem_fip_persist_fn)(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags); typedef int (*rpmem_fip_init_fn)(struct rpmem_fip *fip); typedef void (*rpmem_fip_fini_fn)(struct rpmem_fip *fip); typedef ssize_t (*cq_read_fn)(struct fid_cq *cq, void *buf, size_t count); static ssize_t cq_read_infinite(struct fid_cq *cq, void *buf, size_t count) { return fi_cq_sread(cq, buf, count, NULL, -1); } /* * rpmem_fip_ops -- operations specific for persistency method */ struct rpmem_fip_ops { rpmem_fip_flush_fn flush; rpmem_fip_drain_fn drain; rpmem_fip_persist_fn persist; rpmem_fip_init_fn lanes_init; rpmem_fip_init_fn lanes_init_mem; rpmem_fip_fini_fn lanes_fini; rpmem_fip_init_fn lanes_post; }; /* * rpmem_fip_lane -- base lane structure */ struct rpmem_fip_lane { struct fid_ep *ep; /* endpoint */ struct fid_cq *cq; /* completion queue */ uint64_t event; size_t wq_elems; /* # of elements in work queue */ int wq_is_flushing; /* work queue is during flush */ }; /* * rpmem_fip_plane -- persist operation's lane */ struct rpmem_fip_plane { struct rpmem_fip_lane base; /* base lane structure */ struct rpmem_fip_rma write; /* WRITE message */ struct rpmem_fip_rma write_cq; /* WRITE message with completion */ struct rpmem_fip_rma read; /* READ message */ struct rpmem_fip_msg send; /* SEND message */ struct rpmem_fip_msg recv; /* RECV message */ } LANE_ALIGN; /* * rpmem_fip_rlane -- read operation's lane */ struct rpmem_fip_rlane { struct rpmem_fip_lane base; /* base lane structure */ struct rpmem_fip_rma read; /* READ message */ }; struct rpmem_fip { struct fi_info *fi; /* fabric interface information */ struct fid_fabric *fabric; /* fabric domain */ struct fid_domain *domain; /* fabric protection domain */ struct fid_eq *eq; /* event queue */ int closing; /* closing connections in progress */ size_t cq_size; /* completion queue size */ uint64_t raddr; /* remote memory base address */ uint64_t rkey; /* remote memory protection key */ void *laddr; /* local memory base address */ size_t size; /* memory size */ struct fid_mr *mr; /* local memory region */ void *mr_desc; /* local memory descriptor */ enum rpmem_persist_method persist_method; const struct rpmem_fip_ops *ops; unsigned nlanes; size_t buff_size; struct rpmem_fip_plane *lanes; os_thread_t monitor; void *pmsg; /* persist message buffer */ size_t pmsg_size; struct fid_mr *pmsg_mr; /* persist message memory region */ void *pmsg_mr_desc; /* persist message memory descriptor */ struct rpmem_msg_persist_resp *pres; /* persist response buffer */ struct fid_mr *pres_mr; /* persist response memory region */ void *pres_mr_desc; /* persist response memory descriptor */ void *raw_buff; /* READ-after-WRITE buffer */ struct fid_mr *raw_mr; /* RAW memory region */ void *raw_mr_desc; /* RAW memory descriptor */ cq_read_fn cq_read; /* CQ read function */ }; /* * rpmem_fip_is_closing -- (internal) atomically reads and returns the * closing flag */ static inline int rpmem_fip_is_closing(struct rpmem_fip *fip) { int ret; util_atomic_load_explicit32(&fip->closing, &ret, memory_order_acquire); return ret; } /* * rpmem_fip_set_closing -- (internal) atomically set the closing flag */ static inline void rpmem_fip_set_closing(struct rpmem_fip *fip) { /* * load and store without barriers should be good enough here. * fetch_and_or are used as workaround for helgrind issue. */ util_fetch_and_or32(&fip->closing, 1); } /* * rpmem_fip_lane_begin -- (internal) initialize list of events for lane */ static inline void rpmem_fip_lane_begin(struct rpmem_fip_lane *lanep, uint64_t event) { lanep->event = event; } /* * rpmem_fip_lane_init -- (internal) initialize single lane */ static int rpmem_fip_lane_init(struct rpmem_fip *fip, struct rpmem_fip_lane *lanep) { int ret; struct fi_cq_attr cq_attr = { .size = fip->cq_size, .flags = 0, .format = FI_CQ_FORMAT_MSG, .wait_obj = FI_WAIT_UNSPEC, .signaling_vector = 0, .wait_cond = FI_CQ_COND_NONE, .wait_set = NULL, }; /* create a completion queue */ ret = fi_cq_open(fip->domain, &cq_attr, &lanep->cq, NULL); if (ret) { RPMEM_FI_ERR(ret, "opening completion queue"); goto err_cq_open; } /* create an endpoint */ ret = fi_endpoint(fip->domain, fip->fi, &lanep->ep, NULL); if (ret) { RPMEM_FI_ERR(ret, "allocating endpoint"); goto err_endpoint; } /* * Bind an event queue to an endpoint to get * connection-related events for the endpoint. */ ret = fi_ep_bind(lanep->ep, &fip->eq->fid, 0); if (ret) { RPMEM_FI_ERR(ret, "binding event queue to endpoint"); goto err_ep_bind_eq; } /* * Bind a completion queue to an endpoint to get completion * events of specified inbound/outbound operations. * * FI_SELECTIVE_COMPLETION means all inbound/outbound operations * must explicitly specify if the completion event should be * generated or not using FI_COMPLETION flag. * * The completion events received are highly related to the * persistency method used and are configured in lanes * initialization specified for persistency method utilized. */ ret = fi_ep_bind(lanep->ep, &lanep->cq->fid, FI_RECV | FI_TRANSMIT | FI_SELECTIVE_COMPLETION); if (ret) { RPMEM_FI_ERR(ret, "binding completion queue to endpoint"); goto err_ep_bind_cq; } /* * Enable endpoint so it is possible to post inbound/outbound * operations if required. */ ret = fi_enable(lanep->ep); if (ret) { RPMEM_FI_ERR(ret, "activating endpoint"); goto err_fi_enable; } return 0; err_fi_enable: err_ep_bind_cq: err_ep_bind_eq: err_endpoint: RPMEM_FI_CLOSE(lanep->cq, "closing completion queue"); err_cq_open: return -1; } /* * rpmem_fip_lane_fini -- (internal) deinitialize single lane */ static int rpmem_fip_lane_fini(struct rpmem_fip_lane *lanep) { int ret; int lret = 0; ret = RPMEM_FI_CLOSE(lanep->ep, "closing endpoint"); if (ret) lret = ret; ret = RPMEM_FI_CLOSE(lanep->cq, "closing completion queue"); if (ret) lret = ret; return lret; } /* * rpmem_fip_lane_wait -- (internal) wait for specific event on completion queue */ static int rpmem_fip_lane_wait(struct rpmem_fip *fip, struct rpmem_fip_lane *lanep, uint64_t e) { ssize_t sret = 0; struct fi_cq_err_entry err; const char *str_err; int ret = 0; struct fi_cq_msg_entry cq_entry; while (lanep->event & e) { if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; sret = fip->cq_read(lanep->cq, &cq_entry, 1); if (unlikely(sret == -FI_EAGAIN) || sret == 0) continue; if (unlikely(sret < 0)) { ret = (int)sret; goto err_cq_read; } lanep->event &= ~cq_entry.flags; } return 0; err_cq_read: sret = fi_cq_readerr(lanep->cq, &err, 0); if (sret < 0) { RPMEM_FI_ERR((int)sret, "error reading from completion queue: " "cannot read error from event queue"); goto err; } str_err = fi_cq_strerror(lanep->cq, err.prov_errno, NULL, NULL, 0); RPMEM_LOG(ERR, "error reading from completion queue: %s", str_err); err: if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ return ret; } /* * rpmem_fip_set_nlanes -- (internal) set maximum number of lanes supported */ static void rpmem_fip_set_nlanes(struct rpmem_fip *fip, unsigned nlanes) { size_t max_nlanes = rpmem_fip_max_nlanes(fip->fi); RPMEM_ASSERT(max_nlanes < UINT_MAX); fip->nlanes = min((unsigned)max_nlanes, nlanes); } /* * rpmem_fip_getinfo -- (internal) get fabric interface information */ static int rpmem_fip_getinfo(struct rpmem_fip *fip, const char *node, const char *service, enum rpmem_provider provider, size_t max_wq_size, enum rpmem_persist_method pm) { int ret = -1; struct fi_info *hints = rpmem_fip_get_hints(provider); if (!hints) { RPMEM_LOG(ERR, "!getting fabric interface information hints"); goto err_hints; } /* * WQ size is: * - >= size required by persist method (pm_wq_size) * - >= size forced by environment variable (Rpmem_wq_size) * - but it has to be <= max_wq_size reported by provider */ size_t pm_wq_size = rpmem_fip_wq_size(pm, RPMEM_FIP_NODE_CLIENT); hints->tx_attr->size = min( max(pm_wq_size, Rpmem_wq_size), max_wq_size); hints->rx_attr->size = rpmem_fip_rx_size(pm, RPMEM_FIP_NODE_CLIENT); /* get maximum available */ ret = fi_getinfo(RPMEM_FIVERSION, node, service, 0, hints, &fip->fi); if (ret) { RPMEM_FI_ERR(ret, "getting fabric interface information"); goto err_fi_getinfo; } rpmem_fip_print_info(fip->fi); /* fallback to free the hints */ err_fi_getinfo: fi_freeinfo(hints); err_hints: return ret; } /* * rpmem_fip_init_fabric_res -- (internal) initialize common fabric resources */ static int rpmem_fip_init_fabric_res(struct rpmem_fip *fip) { int ret; ret = fi_fabric(fip->fi->fabric_attr, &fip->fabric, NULL); if (ret) { RPMEM_FI_ERR(ret, "opening fabric domain"); goto err_fi_fabric; } ret = fi_domain(fip->fabric, fip->fi, &fip->domain, NULL); if (ret) { RPMEM_FI_ERR(ret, "opening fabric access domain"); goto err_fi_domain; } struct fi_eq_attr eq_attr = { .size = 0, /* use default value */ .flags = 0, .wait_obj = FI_WAIT_UNSPEC, .signaling_vector = 0, .wait_set = NULL, }; ret = fi_eq_open(fip->fabric, &eq_attr, &fip->eq, NULL); if (ret) { RPMEM_FI_ERR(ret, "opening event queue"); goto err_eq_open; } return 0; err_eq_open: RPMEM_FI_CLOSE(fip->domain, "closing fabric access domain"); err_fi_domain: RPMEM_FI_CLOSE(fip->fabric, "closing fabric domain"); err_fi_fabric: return ret; } /* * rpmem_fip_fini_fabric_res -- (internal) deinitialize common fabric resources */ static void rpmem_fip_fini_fabric_res(struct rpmem_fip *fip) { RPMEM_FI_CLOSE(fip->eq, "closing event queue"); RPMEM_FI_CLOSE(fip->domain, "closing fabric access domain"); RPMEM_FI_CLOSE(fip->fabric, "closing fabric domain"); } /* * rpmem_fip_init_memory -- (internal) initialize common memory resources */ static int rpmem_fip_init_memory(struct rpmem_fip *fip) { ASSERTne(Pagesize, 0); int ret; /* * Register local memory space. The local memory will be used * with WRITE operation in rpmem_fip_persist function thus * the FI_WRITE access flag. */ ret = fi_mr_reg(fip->domain, fip->laddr, fip->size, FI_WRITE, 0, 0, 0, &fip->mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registrating memory"); return ret; } /* get local memory descriptor */ fip->mr_desc = fi_mr_desc(fip->mr); return 0; } /* * rpmem_fip_fini_memory -- (internal) deinitialize common memory resources */ static void rpmem_fip_fini_memory(struct rpmem_fip *fip) { RPMEM_FI_CLOSE(fip->mr, "unregistering memory"); } /* * rpmem_fip_lanes_init_common -- (internal) initialize common lanes resources */ static int rpmem_fip_lanes_init_common(struct rpmem_fip *fip) { int ret; ret = posix_memalign((void **)&fip->lanes, LANE_ALIGN_SIZE, fip->nlanes * sizeof(*fip->lanes)); if (ret) { RPMEM_LOG(ERR, "!allocating lanes"); goto err_alloc_lanes; } memset(fip->lanes, 0, fip->nlanes * sizeof(*fip->lanes)); unsigned i; for (i = 0; i < fip->nlanes; i++) { ret = rpmem_fip_lane_init(fip, &fip->lanes[i].base); if (ret) goto err_lane_init; } return 0; err_lane_init: for (unsigned j = 0; j < i; j++) rpmem_fip_lane_fini(&fip->lanes[i].base); free(fip->lanes); err_alloc_lanes: return -1; } /* * rpmem_fip_lanes_fini_common -- (internal) deinitialize common lanes * resources */ static int rpmem_fip_lanes_fini_common(struct rpmem_fip *fip) { int lret = 0; int ret; for (unsigned i = 0; i < fip->nlanes; i++) { ret = rpmem_fip_lane_fini(&fip->lanes[i].base); if (ret) lret = ret; } free(fip->lanes); return lret; } /* * rpmem_fip_lanes_init -- (internal) initialize lanes */ static int rpmem_fip_lanes_init(struct rpmem_fip *fip) { int ret; ret = rpmem_fip_lanes_init_common(fip); if (ret) return ret; ret = fip->ops->lanes_init(fip); if (ret) goto err_init_lanes; return 0; err_init_lanes: rpmem_fip_lanes_fini_common(fip); return ret; } /* * rpmem_fip_lane_connect -- (internal) connect on a single lane */ static int rpmem_fip_lane_connect(struct rpmem_fip *fip, struct rpmem_fip_lane *lanep) { struct fi_eq_cm_entry entry; int ret; ret = fi_connect(lanep->ep, fip->fi->dest_addr, NULL, 0); if (ret) { RPMEM_FI_ERR(ret, "initiating connection request"); return ret; } return rpmem_fip_read_eq_check(fip->eq, &entry, FI_CONNECTED, &lanep->ep->fid, RPMEM_CONNECT_TIMEOUT); } /* * rpmem_fip_lanes_connect -- (internal) establish connections on all lanes */ static int rpmem_fip_lanes_connect(struct rpmem_fip *fip) { int ret; for (unsigned i = 0; i < fip->nlanes; i++) { struct rpmem_fip_lane *lanep = &fip->lanes[i].base; ret = rpmem_fip_lane_connect(fip, lanep); if (ret) return ret; } return 0; } /* * rpmem_fip_lanes_shutdown -- shutdown all endpoints */ static int rpmem_fip_lanes_shutdown(struct rpmem_fip *fip) { int ret; int lret = 0; for (unsigned i = 0; i < fip->nlanes; i++) { ret = fi_shutdown(fip->lanes[i].base.ep, 0); if (ret) { RPMEM_FI_ERR(ret, "disconnecting endpoint"); lret = ret; } } return lret; } /* * rpmem_fip_lane_prep_write -- (internal) choose right WRITE structure * according to flags and prepare for collecting its completion */ static inline struct rpmem_fip_rma * rpmem_fip_lane_prep_write(struct rpmem_fip_plane *lanep, unsigned flags) { if (flags & RPMEM_COMPLETION) { rpmem_fip_lane_begin(&lanep->base, FI_WRITE); return &lanep->write_cq; } return &lanep->write; } /* * rpmem_fip_monitor_thread -- (internal) monitor in-band connection */ static void * rpmem_fip_monitor_thread(void *arg) { struct rpmem_fip *fip = (struct rpmem_fip *)arg; struct fi_eq_cm_entry entry; uint32_t event; int ret; while (!rpmem_fip_is_closing(fip)) { ret = rpmem_fip_read_eq(fip->eq, &entry, &event, RPMEM_MONITOR_TIMEOUT); if (unlikely(ret == 0) && event == FI_SHUTDOWN) { RPMEM_LOG(ERR, "event queue got FI_SHUTDOWN"); /* mark in-band connection as closing */ rpmem_fip_set_closing(fip); for (unsigned i = 0; i < fip->nlanes; i++) { fi_cq_signal(fip->lanes[i].base.cq); } } } return NULL; } /* * rpmem_fip_monitor_init -- (internal) initialize in-band monitor */ static int rpmem_fip_monitor_init(struct rpmem_fip *fip) { errno = os_thread_create(&fip->monitor, NULL, rpmem_fip_monitor_thread, fip); if (errno) { RPMEM_LOG(ERR, "!connenction monitor thread"); return -1; } return 0; } /* * rpmem_fip_monitor_fini -- (internal) finalize in-band monitor */ static int rpmem_fip_monitor_fini(struct rpmem_fip *fip) { rpmem_fip_set_closing(fip); int ret = os_thread_join(&fip->monitor, NULL); if (ret) { RPMEM_LOG(ERR, "joining monitor thread failed"); } return ret; } /* * rpmem_fip_init_lanes_common -- (internal) initialize lanes */ static int rpmem_fip_init_lanes_common(struct rpmem_fip *fip) { ASSERTne(Pagesize, 0); int ret = 0; /* allocate persist messages buffer */ fip->pmsg_size = roundup(sizeof(struct rpmem_msg_persist) + fip->buff_size, (size_t)64); size_t msg_size = fip->nlanes * fip->pmsg_size; msg_size = PAGE_ALIGNED_UP_SIZE(msg_size); errno = posix_memalign((void **)&fip->pmsg, Pagesize, msg_size); if (errno) { RPMEM_LOG(ERR, "!allocating messages buffer"); ret = -1; goto err_malloc_pmsg; } /* * Register persist messages buffer. The persist messages * are sent to daemon thus the FI_SEND access flag. */ ret = fi_mr_reg(fip->domain, fip->pmsg, msg_size, FI_SEND, 0, 0, 0, &fip->pmsg_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registering messages buffer"); goto err_fi_mr_reg_pmsg; } /* get persist messages buffer local descriptor */ fip->pmsg_mr_desc = fi_mr_desc(fip->pmsg_mr); /* allocate persist response messages buffer */ size_t msg_resp_size = fip->nlanes * sizeof(struct rpmem_msg_persist_resp); msg_resp_size = PAGE_ALIGNED_UP_SIZE(msg_resp_size); errno = posix_memalign((void **)&fip->pres, Pagesize, msg_resp_size); if (errno) { RPMEM_LOG(ERR, "!allocating messages response buffer"); ret = -1; goto err_malloc_pres; } /* * Register persist messages response buffer. The persist response * messages are received from daemon thus the FI_RECV access flag. */ ret = fi_mr_reg(fip->domain, fip->pres, msg_resp_size, FI_RECV, 0, 0, 0, &fip->pres_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registering messages response buffer"); goto err_fi_mr_reg_pres; } /* get persist response messages buffer local descriptor */ fip->pres_mr_desc = fi_mr_desc(fip->pres_mr); return 0; err_fi_mr_reg_pres: free(fip->pres); err_malloc_pres: RPMEM_FI_CLOSE(fip->pmsg_mr, "unregistering messages buffer"); err_fi_mr_reg_pmsg: free(fip->pmsg); err_malloc_pmsg: return ret; } /* * rpmem_fip_get_pmsg -- return persist message buffer */ static inline struct rpmem_msg_persist * rpmem_fip_get_pmsg(struct rpmem_fip *fip, size_t idx) { return (struct rpmem_msg_persist *) ((uintptr_t)fip->pmsg + idx * fip->pmsg_size); } /* * rpmem_fip_init_mem_lanes_gpspm -- initialize lanes rma structures */ static int rpmem_fip_init_mem_lanes_gpspm(struct rpmem_fip *fip) { /* * Initialize all required structures for: * WRITE, SEND and RECV operations. * * If the completion is required the FI_COMPLETION flag and * appropriate context should be used. * * In GPSPM only the RECV and SEND completions are required. * * For RECV the context is RECV operation structure used for * fi_recvmsg(3) function call. * * For SEND the context is lane structure. * * The received buffer contains a lane id which is used * to obtain a lane which must be signaled that operation * has been completed. */ unsigned i; for (i = 0; i < fip->nlanes; i++) { /* WRITE */ rpmem_fip_rma_init(&fip->lanes[i].write, fip->mr_desc, 0, fip->rkey, &fip->lanes[i], 0); /* SEND */ rpmem_fip_msg_init(&fip->lanes[i].send, fip->pmsg_mr_desc, 0, &fip->lanes[i], rpmem_fip_get_pmsg(fip, i), 0 /* size must be provided when sending msg */, FI_COMPLETION); /* RECV */ rpmem_fip_msg_init(&fip->lanes[i].recv, fip->pres_mr_desc, 0, &fip->lanes[i].recv, &fip->pres[i], sizeof(fip->pres[i]), FI_COMPLETION); } return 0; } /* * rpmem_fip_fini_lanes_common -- (internal) deinitialize lanes for GPSPM */ static void rpmem_fip_fini_lanes_common(struct rpmem_fip *fip) { RPMEM_FI_CLOSE(fip->pmsg_mr, "unregistering messages buffer"); RPMEM_FI_CLOSE(fip->pres_mr, "unregistering messages " "response buffer"); free(fip->pmsg); free(fip->pres); } /* * rpmem_fip_init_lanes_apm -- (internal) initialize lanes for APM */ static int rpmem_fip_init_lanes_apm(struct rpmem_fip *fip) { ASSERTne(Pagesize, 0); int ret; ret = rpmem_fip_init_lanes_common(fip); if (ret) goto err_init_lanes_common; ASSERT(IS_PAGE_ALIGNED(RPMEM_RAW_BUFF_SIZE)); errno = posix_memalign((void **)&fip->raw_buff, Pagesize, RPMEM_RAW_BUFF_SIZE); if (errno) { RPMEM_LOG(ERR, "!allocating APM RAW buffer"); goto err_malloc_raw; } /* register read-after-write buffer */ ret = fi_mr_reg(fip->domain, fip->raw_buff, RPMEM_RAW_BUFF_SIZE, FI_REMOTE_WRITE, 0, 0, 0, &fip->raw_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registering APM read buffer"); goto err_fi_raw_mr; } /* get read-after-write buffer local descriptor */ fip->raw_mr_desc = fi_mr_desc(fip->raw_mr); return 0; err_fi_raw_mr: free(fip->raw_buff); err_malloc_raw: rpmem_fip_fini_lanes_common(fip); err_init_lanes_common: return -1; } /* * rpmem_fip_init_mem_lanes_apm -- initialize lanes rma structures */ static int rpmem_fip_init_mem_lanes_apm(struct rpmem_fip *fip) { /* * Initialize all required structures for: * WRITE and READ operations. * * If the completion is required the FI_COMPLETION flag and * appropriate context should be used. * * In APM only the READ completion is required. * The context is a lane structure. */ for (unsigned i = 0; i < fip->nlanes; i++) { /* WRITE */ rpmem_fip_rma_init(&fip->lanes[i].write, fip->mr_desc, 0, fip->rkey, &fip->lanes[i], 0); /* WRITE + FI_COMPLETION */ rpmem_fip_rma_init(&fip->lanes[i].write_cq, fip->mr_desc, 0, fip->rkey, &fip->lanes[i], FI_COMPLETION); /* READ */ rpmem_fip_rma_init(&fip->lanes[i].read, fip->raw_mr_desc, 0, fip->rkey, &fip->lanes[i], FI_COMPLETION); /* SEND */ rpmem_fip_msg_init(&fip->lanes[i].send, fip->pmsg_mr_desc, 0, &fip->lanes[i], rpmem_fip_get_pmsg(fip, i), fip->pmsg_size, FI_COMPLETION); /* RECV */ rpmem_fip_msg_init(&fip->lanes[i].recv, fip->pres_mr_desc, 0, &fip->lanes[i].recv, &fip->pres[i], sizeof(fip->pres[i]), FI_COMPLETION); } return 0; } /* * rpmem_fip_fini_lanes_apm -- (internal) deinitialize lanes for APM */ static void rpmem_fip_fini_lanes_apm(struct rpmem_fip *fip) { RPMEM_FI_CLOSE(fip->raw_mr, "unregistering APM read buffer"); free(fip->raw_buff); rpmem_fip_fini_lanes_common(fip); } /* * rpmem_fip_wq_inc -- (internal) increment number of elements in WQ */ static inline void rpmem_fip_wq_inc(struct rpmem_fip_plane *lanep) { ++lanep->base.wq_elems; } /* * rpmem_fip_wq_set_empty -- (internal) zero number of elements in WQ */ static inline void rpmem_fip_wq_set_empty(struct rpmem_fip_plane *lanep) { RPMEM_ASSERT(!lanep->base.wq_is_flushing); lanep->base.wq_elems = 0; } /* * rpmem_fip_wq_require_flush -- (internal) is WQ almost full */ static inline int rpmem_fip_wq_require_flush(struct rpmem_fip *fip, struct rpmem_fip_plane *lanep) { RPMEM_ASSERT(lanep->base.wq_elems < fip->fi->tx_attr->size); return lanep->base.wq_elems + 1 == fip->fi->tx_attr->size; } /* * rpmem_fip_wq_is_flushing -- (internal) is WQ flush started */ static inline int rpmem_fip_wq_is_flushing(struct rpmem_fip_plane *lanep) { return lanep->base.wq_is_flushing; } /* * rpmem_fip_wq_set_flushing -- (internal) mark WQ flush start */ static inline void rpmem_fip_wq_set_flushing(struct rpmem_fip_plane *lanep) { lanep->base.wq_is_flushing = 1; } /* * if WQ is almost full last WRITE has to report its completion * otherwise it is unknown when subsequent commands can be posted */ #define RPMEM_FIP_WQ_FLUSH_REQ RPMEM_COMPLETION /* * rpmem_fip_wq_flush_wait -- (internal) wait for WRITE completion * to make sure WQ can accept subsequent commands */ static inline int rpmem_fip_wq_flush_wait(struct rpmem_fip *fip, struct rpmem_fip_plane *lanep) { RPMEM_ASSERT(lanep->base.wq_elems == fip->fi->tx_attr->size); RPMEM_ASSERT(lanep->base.wq_is_flushing); /* wait for WRITE completion */ int ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_WRITE); if (unlikely(ret)) { LOG(2, "waiting for WRITE completion failed"); return ret; } /* when WRITE completion is reaped WQ is empty */ lanep->base.wq_is_flushing = 0; rpmem_fip_wq_set_empty(lanep); return 0; } /* * rpmem_fip_wq_inc_and_flush -- (internal) increment number of elements in WQ * and flush it */ static inline int rpmem_fip_wq_inc_and_flush(struct rpmem_fip *fip, struct rpmem_fip_plane *lanep) { rpmem_fip_wq_inc(lanep); rpmem_fip_wq_set_flushing(lanep); return rpmem_fip_wq_flush_wait(fip, lanep); } /* * rpmem_fip_wq_flush_check -- (internal) check if WQ requires flush or it is * during flushing and handle each case */ static inline int rpmem_fip_wq_flush_check(struct rpmem_fip *fip, struct rpmem_fip_plane *lanep, unsigned *flags) { if (rpmem_fip_wq_is_flushing(lanep)) return rpmem_fip_wq_flush_wait(fip, lanep); if (rpmem_fip_wq_require_flush(fip, lanep)) *flags |= RPMEM_FIP_WQ_FLUSH_REQ; return 0; } /* * rpmem_fip_get_wq_size -- get WQ size (for validation purposes only) */ inline size_t rpmem_fip_get_wq_size(struct rpmem_fip *fip) { RPMEM_ASSERT(fip); RPMEM_ASSERT(fip->fi); RPMEM_ASSERT(fip->fi->tx_attr); return fip->fi->tx_attr->size; } /* * rpmem_fip_flush_raw -- (internal) perform flush operation using rma WRITE */ static int rpmem_fip_flush_raw(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; int ret; void *laddr = (void *)((uintptr_t)fip->laddr + offset); uint64_t raddr = fip->raddr + offset; struct rpmem_fip_rma *write = rpmem_fip_lane_prep_write(lanep, flags); /* WRITE for requested memory region */ ret = rpmem_fip_writemsg(lanep->base.ep, write, laddr, len, raddr); if (unlikely(ret)) { RPMEM_FI_ERR(ret, "RMA write"); return ret; } if (flags & RPMEM_FIP_WQ_FLUSH_REQ) rpmem_fip_wq_set_flushing(lanep); return 0; } /* * rpmem_fip_drain_raw -- (internal) perform drain operation using rma READ */ static int rpmem_fip_drain_raw(struct rpmem_fip *fip, unsigned lane) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; int ret; rpmem_fip_lane_begin(&lanep->base, FI_READ); /* READ to read-after-write buffer */ ret = rpmem_fip_readmsg(lanep->base.ep, &lanep->read, fip->raw_buff, RPMEM_RAW_SIZE, fip->raddr); if (unlikely(ret)) { RPMEM_FI_ERR(ret, "RMA read"); return ret; } /* wait for READ completion */ ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_READ); if (unlikely(ret)) { ERR("waiting for READ completion failed"); return ret; } return 0; } /* * rpmem_fip_persist_raw -- (internal) perform persist operation using * READ after WRITE mechanism */ static int rpmem_fip_persist_raw(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { int ret; ret = rpmem_fip_flush_raw(fip, offset, len, lane, flags); if (unlikely(ret)) return ret; /* flush WQ prior to posting subsequent message */ if (flags & RPMEM_FIP_WQ_FLUSH_REQ) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; ret = rpmem_fip_wq_inc_and_flush(fip, lanep); if (unlikely(ret)) return ret; } return rpmem_fip_drain_raw(fip, lane); } /* * rpmem_fip_post_resp -- (internal) post persist response message buffer */ static inline int rpmem_fip_post_resp(struct rpmem_fip *fip, struct rpmem_fip_plane *lanep) { int ret = rpmem_fip_recvmsg(lanep->base.ep, &lanep->recv); if (unlikely(ret)) { RPMEM_FI_ERR(ret, "posting recv buffer"); return ret; } return 0; } /* * rpmem_fip_persist_saw -- (internal) perform persist operation using * SEND after WRITE mechanism */ static int rpmem_fip_persist_saw(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; void *laddr = (void *)((uintptr_t)fip->laddr + offset); uint64_t raddr = fip->raddr + offset; struct rpmem_msg_persist *msg; int ret; ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_SEND); if (unlikely(ret)) { ERR("waiting for SEND completion failed"); return ret; } struct rpmem_fip_rma *write = rpmem_fip_lane_prep_write(lanep, flags); /* WRITE for requested memory region */ ret = rpmem_fip_writemsg(lanep->base.ep, write, laddr, len, raddr); if (unlikely(ret)) { RPMEM_FI_ERR((int)ret, "RMA write"); return ret; } /* flush WQ prior to posting subsequent message */ if (flags & RPMEM_FIP_WQ_FLUSH_REQ) { ret = rpmem_fip_wq_inc_and_flush(fip, lanep); if (unlikely(ret)) return ret; } rpmem_fip_lane_begin(&lanep->base, FI_RECV | FI_SEND); /* SEND persist message */ msg = rpmem_fip_msg_get_pmsg(&lanep->send); msg->flags = (flags & RPMEM_FLUSH_PERSIST_MASK); msg->lane = lane; msg->addr = raddr; msg->size = len; ret = rpmem_fip_sendmsg(lanep->base.ep, &lanep->send, sizeof(*msg)); if (unlikely(ret)) { RPMEM_FI_ERR(ret, "MSG send"); return ret; } /* wait for persist operation completion */ ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_RECV); if (unlikely(ret)) { ERR("waiting for RECV completion failed"); return ret; } ret = rpmem_fip_post_resp(fip, lanep); if (unlikely(ret)) { ERR("posting RECV buffer failed"); return ret; } return 0; } /* * rpmem_fip_persist_send -- (internal) perform persist operation using * RDMA SEND operation with data inlined in the message buffer. */ static int rpmem_fip_persist_send(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { RPMEM_ASSERT(len <= fip->buff_size); struct rpmem_fip_plane *lanep = &fip->lanes[lane]; void *laddr = (void *)((uintptr_t)fip->laddr + offset); uint64_t raddr = fip->raddr + offset; struct rpmem_msg_persist *msg; int ret; ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_SEND); if (unlikely(ret)) { ERR("waiting for SEND completion failed"); return ret; } rpmem_fip_lane_begin(&lanep->base, FI_RECV | FI_SEND); /* SEND persist message */ msg = rpmem_fip_msg_get_pmsg(&lanep->send); msg->flags = flags; msg->lane = lane; msg->addr = raddr; msg->size = len; memcpy(msg->data, laddr, len); ret = rpmem_fip_sendmsg(lanep->base.ep, &lanep->send, sizeof(*msg) + len); if (unlikely(ret)) { RPMEM_FI_ERR(ret, "MSG send"); return ret; } /* wait for persist operation completion */ ret = rpmem_fip_lane_wait(fip, &lanep->base, FI_RECV); if (unlikely(ret)) { ERR("waiting for RECV completion failed"); return ret; } ret = rpmem_fip_post_resp(fip, lanep); if (unlikely(ret)) { ERR("posting RECV buffer failed"); return ret; } return 0; } /* * rpmem_fip_persist_gpspm_sockets -- (internal) perform persist operation * for GPSPM - sockets provider implementation which doesn't use the * inline persist operation */ static ssize_t rpmem_fip_persist_gpspm_sockets(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { unsigned mode = flags & RPMEM_FLUSH_PERSIST_MASK; if (mode == RPMEM_PERSIST_SEND) flags = (flags & ~RPMEM_FLUSH_PERSIST_MASK) | RPMEM_FLUSH_WRITE; int ret = rpmem_fip_wq_flush_check(fip, &fip->lanes[lane], &flags); if (unlikely(ret)) return -abs(ret); /* Limit len to the max value of the return type. */ len = min(len, SSIZE_MAX); ret = rpmem_fip_persist_saw(fip, offset, len, lane, flags); if (ret) return -abs(ret); rpmem_fip_wq_set_empty(&fip->lanes[lane]); return (ssize_t)len; } /* * rpmem_fip_persist_apm_sockets -- (internal) perform persist operation * for APM - sockets provider implementation which doesn't use the * inline persist operation */ static ssize_t rpmem_fip_persist_apm_sockets(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { /* Limit len to the max value of the return type. */ len = min(len, SSIZE_MAX); int ret = rpmem_fip_wq_flush_check(fip, &fip->lanes[lane], &flags); if (unlikely(ret)) return -abs(ret); ret = rpmem_fip_persist_raw(fip, offset, len, lane, flags); if (unlikely(ret)) return -abs(ret); rpmem_fip_wq_set_empty(&fip->lanes[lane]); return (ssize_t)len; } /* * rpmem_fip_persist_gpspm -- (internal) perform persist operation for GPSPM */ static ssize_t rpmem_fip_persist_gpspm(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { /* Limit len to the max value of the return type. */ len = min(len, SSIZE_MAX); unsigned mode = flags & RPMEM_FLUSH_PERSIST_MASK; int ret = rpmem_fip_wq_flush_check(fip, &fip->lanes[lane], &flags); if (unlikely(ret)) return -abs(ret); if (mode == RPMEM_PERSIST_SEND) { len = min(len, fip->buff_size); ret = rpmem_fip_persist_send(fip, offset, len, lane, flags); } else { ret = rpmem_fip_persist_saw(fip, offset, len, lane, flags); } if (ret) return -abs(ret); rpmem_fip_wq_set_empty(&fip->lanes[lane]); return (ssize_t)len; } /* * rpmem_fip_drain_nop -- (internal) perform drain operation as NOP */ static int rpmem_fip_drain_nop(struct rpmem_fip *fip, unsigned lane) { (void) fip; (void) lane; return 0; } /* * rpmem_fip_flush_apm -- (internal) perform flush operation for APM */ static ssize_t rpmem_fip_flush_apm(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; int ret; /* Limit len to the max value of the return type. */ len = min(len, SSIZE_MAX); unsigned mode = flags & RPMEM_FLUSH_PERSIST_MASK; ret = rpmem_fip_wq_flush_check(fip, lanep, &flags); if (unlikely(ret)) return ret; if (mode == RPMEM_PERSIST_SEND) { /* * XXX: Probably posting Send in the flush and waiting for the * response in the drain will give some performance gains. */ len = min(len, fip->buff_size); ret = rpmem_fip_persist_send(fip, offset, len, lane, flags); } else { ret = rpmem_fip_flush_raw(fip, offset, len, lane, flags); } if (ret) return -abs(ret); rpmem_fip_wq_inc(lanep); return (ssize_t)len; } /* * rpmem_fip_drain_apm -- (internal) perform drain operation for APM */ static int rpmem_fip_drain_apm(struct rpmem_fip *fip, unsigned lane) { struct rpmem_fip_plane *lanep = &fip->lanes[lane]; int ret; if (unlikely(rpmem_fip_wq_is_flushing(lanep))) { ret = rpmem_fip_wq_flush_wait(fip, lanep); if (unlikely(ret)) return ret; } ret = rpmem_fip_drain_raw(fip, lane); /* successful drain means WQ is empty */ if (likely(!ret)) rpmem_fip_wq_set_empty(lanep); return ret; } /* * rpmem_fip_persist_apm -- (internal) perform persist operation for APM */ static ssize_t rpmem_fip_persist_apm(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { /* Limit len to the max value of the return type. */ len = min(len, SSIZE_MAX); unsigned mode = flags & RPMEM_FLUSH_PERSIST_MASK; int ret = rpmem_fip_wq_flush_check(fip, &fip->lanes[lane], &flags); if (unlikely(ret)) return -abs(ret); if (unlikely(mode == RPMEM_DEEP_PERSIST)) ret = rpmem_fip_persist_saw(fip, offset, len, lane, flags); else if (mode == RPMEM_PERSIST_SEND) { len = min(len, fip->buff_size); ret = rpmem_fip_persist_send(fip, offset, len, lane, flags); } else { ret = rpmem_fip_persist_raw(fip, offset, len, lane, flags); } if (unlikely(ret)) return -abs(ret); rpmem_fip_wq_set_empty(&fip->lanes[lane]); return (ssize_t)len; } /* * rpmem_fip_post_lanes_common -- (internal) post all persist response message * buffers */ static int rpmem_fip_post_lanes_common(struct rpmem_fip *fip) { int ret = 0; for (unsigned i = 0; i < fip->nlanes; i++) { ret = rpmem_fip_post_resp(fip, &fip->lanes[i]); if (ret) break; } return ret; } /* * rpmem_fip_ops -- some operations specific for persistency method used * * Note: GPSPM flush is emulated by persist whereas drain is a nop. * * Probably splitting Send-after-Write into two stages (flush + drain) * will give some performance gains for GPSPM mode. */ static const struct rpmem_fip_ops rpmem_fip_ops[MAX_RPMEM_PROV][MAX_RPMEM_PM] = { [RPMEM_PROV_LIBFABRIC_VERBS] = { [RPMEM_PM_GPSPM] = { .flush = rpmem_fip_persist_gpspm, .drain = rpmem_fip_drain_nop, .persist = rpmem_fip_persist_gpspm, .lanes_init = rpmem_fip_init_lanes_common, .lanes_init_mem = rpmem_fip_init_mem_lanes_gpspm, .lanes_fini = rpmem_fip_fini_lanes_common, .lanes_post = rpmem_fip_post_lanes_common, }, [RPMEM_PM_APM] = { .flush = rpmem_fip_flush_apm, .drain = rpmem_fip_drain_apm, .persist = rpmem_fip_persist_apm, .lanes_init = rpmem_fip_init_lanes_apm, .lanes_init_mem = rpmem_fip_init_mem_lanes_apm, .lanes_fini = rpmem_fip_fini_lanes_apm, .lanes_post = rpmem_fip_post_lanes_common, }, }, [RPMEM_PROV_LIBFABRIC_SOCKETS] = { [RPMEM_PM_GPSPM] = { .flush = rpmem_fip_persist_gpspm_sockets, .drain = rpmem_fip_drain_nop, .persist = rpmem_fip_persist_gpspm_sockets, .lanes_init = rpmem_fip_init_lanes_common, .lanes_init_mem = rpmem_fip_init_mem_lanes_gpspm, .lanes_fini = rpmem_fip_fini_lanes_common, .lanes_post = rpmem_fip_post_lanes_common, }, [RPMEM_PM_APM] = { .flush = rpmem_fip_flush_apm, .drain = rpmem_fip_drain_apm, .persist = rpmem_fip_persist_apm_sockets, .lanes_init = rpmem_fip_init_lanes_apm, .lanes_init_mem = rpmem_fip_init_mem_lanes_apm, .lanes_fini = rpmem_fip_fini_lanes_apm, .lanes_post = rpmem_fip_post_lanes_common, }, } }; /* * rpmem_fip_set_attr -- (internal) set required attributes */ static void rpmem_fip_set_attr(struct rpmem_fip *fip, struct rpmem_fip_attr *attr) { fip->raddr = (uint64_t)attr->raddr; fip->rkey = attr->rkey; fip->laddr = attr->laddr; fip->size = attr->size; fip->buff_size = attr->buff_size; fip->persist_method = attr->persist_method; rpmem_fip_set_nlanes(fip, attr->nlanes); /* one for read operation */ fip->cq_size = rpmem_fip_cq_size(fip->persist_method, RPMEM_FIP_NODE_CLIENT); fip->ops = &rpmem_fip_ops[attr->provider][fip->persist_method]; } /* * rpmem_fip_init -- initialize fabric provider */ struct rpmem_fip * rpmem_fip_init(const char *node, const char *service, struct rpmem_fip_attr *attr, unsigned *nlanes) { int ret; struct rpmem_fip *fip = calloc(1, sizeof(*fip)); if (!fip) { RPMEM_LOG(ERR, "!allocating fabric handle"); return NULL; } ret = rpmem_fip_getinfo(fip, node, service, attr->provider, attr->max_wq_size, attr->persist_method); if (ret) goto err_getinfo; fip->cq_read = attr->provider == RPMEM_PROV_LIBFABRIC_VERBS ? fi_cq_read : cq_read_infinite; rpmem_fip_set_attr(fip, attr); *nlanes = fip->nlanes; ret = rpmem_fip_init_fabric_res(fip); if (ret) goto err_init_fabric_res; ret = rpmem_fip_lanes_init(fip); if (ret) goto err_init_lanes; return fip; err_init_lanes: rpmem_fip_fini_fabric_res(fip); err_init_fabric_res: fi_freeinfo(fip->fi); err_getinfo: free(fip); return NULL; } /* * rpmem_fip_fini -- deinitialize fabric provider */ void rpmem_fip_fini(struct rpmem_fip *fip) { fip->ops->lanes_fini(fip); rpmem_fip_lanes_fini_common(fip); rpmem_fip_fini_fabric_res(fip); fi_freeinfo(fip->fi); free(fip); } /* * rpmem_fip_connect -- connect to remote peer */ int rpmem_fip_connect(struct rpmem_fip *fip) { int ret; ret = rpmem_fip_lanes_connect(fip); if (ret) goto err_lanes_connect; ret = rpmem_fip_monitor_init(fip); if (ret) goto err_monitor; ret = rpmem_fip_init_memory(fip); if (ret) goto err_init_memory; ret = fip->ops->lanes_init_mem(fip); if (ret) goto err_init_lanes_mem; ret = fip->ops->lanes_post(fip); if (ret) goto err_lanes_post; return 0; err_lanes_post: err_init_lanes_mem: rpmem_fip_fini_memory(fip); err_init_memory: rpmem_fip_monitor_fini(fip); err_monitor: rpmem_fip_lanes_shutdown(fip); err_lanes_connect: return ret; } /* * rpmem_fip_close -- close connection to remote peer */ int rpmem_fip_close(struct rpmem_fip *fip) { int ret; int lret = 0; if (unlikely(rpmem_fip_is_closing(fip))) goto close_monitor; rpmem_fip_fini_memory(fip); ret = rpmem_fip_lanes_shutdown(fip); if (ret) lret = ret; close_monitor: /* close fip monitor */ ret = rpmem_fip_monitor_fini(fip); if (ret) lret = ret; return lret; } /* * rpmem_fip_flush -- perform remote flush operation */ int rpmem_fip_flush(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { RPMEM_ASSERT((flags & RPMEM_FLUSH_PERSIST_MASK) <= RPMEM_PERSIST_MAX); RPMEM_ASSERT(flags != RPMEM_DEEP_PERSIST); if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ RPMEM_ASSERT(lane < fip->nlanes); if (unlikely(lane >= fip->nlanes)) return EINVAL; /* it will be passed to errno */ if (unlikely(offset >= fip->size || offset + len > fip->size)) return EINVAL; /* it will be passed to errno */ if (unlikely(len == 0)) return 0; int ret = 0; while (len > 0) { size_t tmplen = min(len, fip->fi->ep_attr->max_msg_size); ssize_t r = fip->ops->flush(fip, offset, tmplen, lane, flags); if (r < 0) { RPMEM_LOG(ERR, "flush operation failed"); ret = (int)r; goto err; } tmplen = (size_t)r; offset += tmplen; len -= tmplen; } err: if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ return ret; } /* * rpmem_fip_drain -- perform remote drain operation */ int rpmem_fip_drain(struct rpmem_fip *fip, unsigned lane) { if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ RPMEM_ASSERT(lane < fip->nlanes); if (unlikely(lane >= fip->nlanes)) return EINVAL; /* it will be passed to errno */ int ret = fip->ops->drain(fip, lane); if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ return ret; } /* * rpmem_fip_persist -- perform remote persist operation */ int rpmem_fip_persist(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags) { RPMEM_ASSERT((flags & RPMEM_FLUSH_PERSIST_MASK) <= RPMEM_PERSIST_MAX); if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ RPMEM_ASSERT(lane < fip->nlanes); if (unlikely(lane >= fip->nlanes)) return EINVAL; /* it will be passed to errno */ if (unlikely(offset >= fip->size || offset + len > fip->size)) return EINVAL; /* it will be passed to errno */ if (unlikely(len == 0)) return 0; int ret = 0; while (len > 0) { size_t tmplen = min(len, fip->fi->ep_attr->max_msg_size); ssize_t r = fip->ops->persist(fip, offset, tmplen, lane, flags); if (r < 0) { RPMEM_LOG(ERR, "persist operation failed"); ret = (int)r; goto err; } tmplen = (size_t)r; offset += tmplen; len -= tmplen; } err: if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ return ret; } /* * rpmem_fip_read -- perform read operation */ int rpmem_fip_read(struct rpmem_fip *fip, void *buff, size_t len, size_t off, unsigned lane) { int ret; if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ RPMEM_ASSERT(lane < fip->nlanes); if (unlikely(lane >= fip->nlanes)) return EINVAL; /* it will be passed to errno */ if (unlikely(len == 0)) { return 0; } size_t rd_buff_len = len < fip->fi->ep_attr->max_msg_size ? len : fip->fi->ep_attr->max_msg_size; void *rd_buff; /* buffer for read operation */ struct fid_mr *rd_mr; /* read buffer memory region */ void *rd_mr_desc; /* read buffer memory descriptor */ struct rpmem_fip_rlane rd_lane; /* allocate buffer for read operation */ errno = posix_memalign((void **)&rd_buff, Pagesize, rd_buff_len); if (errno) { RPMEM_LOG(ERR, "!allocating read buffer"); ret = errno; goto err_malloc_rd_buff; } /* * Register buffer for read operation. * The read operation utilizes READ operation thus * the FI_REMOTE_WRITE flag. */ ret = fi_mr_reg(fip->domain, rd_buff, rd_buff_len, FI_REMOTE_WRITE, 0, 0, 0, &rd_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registrating read buffer"); goto err_rd_mr; } /* get read buffer local memory descriptor */ rd_mr_desc = fi_mr_desc(rd_mr); /* * Initialize READ message. The completion is required in order * to signal thread that READ operation has been completed. */ rpmem_fip_rma_init(&rd_lane.read, rd_mr_desc, 0, fip->rkey, &rd_lane, FI_COMPLETION); size_t rd = 0; uint8_t *cbuff = buff; struct rpmem_fip_lane *lanep = &fip->lanes[lane].base; while (rd < len) { size_t rd_len = len - rd < rd_buff_len ? len - rd : rd_buff_len; size_t rd_off = off + rd; uint64_t raddr = fip->raddr + rd_off; rpmem_fip_lane_begin(lanep, FI_READ); ret = rpmem_fip_readmsg(lanep->ep, &rd_lane.read, rd_buff, rd_len, raddr); if (ret) { RPMEM_FI_ERR(ret, "RMA read"); goto err_readmsg; } VALGRIND_DO_MAKE_MEM_DEFINED(rd_buff, rd_len); ret = rpmem_fip_lane_wait(fip, lanep, FI_READ); if (ret) { ERR("error when processing read request"); goto err_lane_wait; } memcpy(&cbuff[rd], rd_buff, rd_len); rd += rd_len; } ret = 0; err_lane_wait: err_readmsg: RPMEM_FI_CLOSE(rd_mr, "unregistering memory"); err_rd_mr: free(rd_buff); err_malloc_rd_buff: if (unlikely(rpmem_fip_is_closing(fip))) return ECONNRESET; /* it will be passed to errno */ return ret; } /* * parse_bool -- convert string value to boolean */ static int parse_bool(const char *str_value) { if (strcmp(str_value, "0") == 0 || strcasecmp(str_value, "false") == 0 || strcasecmp(str_value, "no") == 0 || strcasecmp(str_value, "off") == 0) { return 0; } if (strcmp(str_value, "1") == 0 || strcasecmp(str_value, "true") == 0 || strcasecmp(str_value, "yes") == 0 || strcasecmp(str_value, "on") == 0) { return 1; } return -1; } /* * rpmem_fip_param_get -- read environment variable in the libfabric way * * - If parameter does not exist the output value is not changed. * - If the environment variable is not set the output value is not changed. * - If the environment variable is set and its value is not correct the output * value is set to error value. * - If the environment variable is set and its value is correct the output * value is set according to the environment variable value. */ static void rpmem_fip_param_get(const char *var_name, int *value) { struct fi_param *params; int count; int ret = fi_getparams(¶ms, &count); if (ret != FI_SUCCESS) { RPMEM_FI_ERR(ret, "getting fabric parameters list"); return; } for (int i = 0; i < count; ++i) { if (strcmp(params[i].name, var_name) != 0) continue; if (!params[i].value) { break; } *value = parse_bool(params[i].value); break; } fi_freeparams(params); } #define LIBFABRIC_FORK_UNSAFE_VAR "FI_FORK_UNSAFE" /* * rpmem_fip_probe_fork_safety -- probe if libfabric is fork safe */ void rpmem_fip_probe_fork_safety(void) { int *fork_unsafe = &Rpmem_fork_unsafe; /* false by default */ rpmem_fip_param_get(LIBFABRIC_FORK_UNSAFE_VAR, fork_unsafe); } pmdk-1.11.1/src/librpmem/rpmem_obc.h0000664000000000000000000000211714123364546015751 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_obc.h -- rpmem out-of-band connection client header file */ #ifndef RPMEM_OBC_H #define RPMEM_OBC_H 1 #include #include #include "librpmem.h" #ifdef __cplusplus extern "C" { #endif struct rpmem_obc; struct rpmem_obc *rpmem_obc_init(void); void rpmem_obc_fini(struct rpmem_obc *rpc); int rpmem_obc_connect(struct rpmem_obc *rpc, const struct rpmem_target_info *info); int rpmem_obc_disconnect(struct rpmem_obc *rpc); int rpmem_obc_monitor(struct rpmem_obc *rpc, int nonblock); int rpmem_obc_create(struct rpmem_obc *rpc, const struct rpmem_req_attr *req, struct rpmem_resp_attr *res, const struct rpmem_pool_attr *pool_attr); int rpmem_obc_open(struct rpmem_obc *rpc, const struct rpmem_req_attr *req, struct rpmem_resp_attr *res, struct rpmem_pool_attr *pool_attr); int rpmem_obc_set_attr(struct rpmem_obc *rpc, const struct rpmem_pool_attr *pool_attr); int rpmem_obc_close(struct rpmem_obc *rpc, int flags); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/librpmem/Makefile0000664000000000000000000000145314123364546015277 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/librpmem/Makefile -- Makefile for librpmem # include ../common.inc vpath %.c ../rpmem_common ifeq ($(BUILD_RPMEM),y) LIBRARY_NAME = rpmem LIBRARY_SO_VERSION = 1 LIBRARY_VERSION = 0.0 SOURCE = $(COMMON)/alloc.c\ $(COMMON)/os_posix.c\ $(COMMON)/os_thread_posix.c\ $(COMMON)/out.c\ $(COMMON)/util.c\ $(COMMON)/util_posix.c\ librpmem.c\ rpmem.c\ rpmem_obc.c\ rpmem_cmd.c\ rpmem_ssh.c\ rpmem_common.c\ rpmem_util.c\ rpmem_fip_common.c\ rpmem_fip.c else $(info NOTE: Skipping librpmem because $(BUILD_RPMEM_INFO)) endif include ../Makefile.inc ifeq ($(BUILD_RPMEM),y) LIBS += -pthread LIBS += $(LIBFABRIC_LIBS) CFLAGS += $(LIBFABRIC_CFLAGS) CFLAGS += -I. -I../rpmem_common CFLAGS += -DRPMEMC_LOG_RPMEM endif pmdk-1.11.1/src/librpmem/rpmem_fip.h0000664000000000000000000000262614123364546015771 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_fip.h -- rpmem libfabric provider module header file */ #ifndef RPMEM_FIP_H #define RPMEM_FIP_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct rpmem_fip; struct rpmem_fip_attr { enum rpmem_provider provider; size_t max_wq_size; enum rpmem_persist_method persist_method; void *laddr; size_t size; size_t buff_size; unsigned nlanes; void *raddr; uint64_t rkey; }; struct rpmem_fip *rpmem_fip_init(const char *node, const char *service, struct rpmem_fip_attr *attr, unsigned *nlanes); void rpmem_fip_fini(struct rpmem_fip *fip); int rpmem_fip_connect(struct rpmem_fip *fip); int rpmem_fip_close(struct rpmem_fip *fip); int rpmem_fip_process_start(struct rpmem_fip *fip); int rpmem_fip_process_stop(struct rpmem_fip *fip); int rpmem_fip_flush(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags); int rpmem_fip_drain(struct rpmem_fip *fip, unsigned lane); int rpmem_fip_persist(struct rpmem_fip *fip, size_t offset, size_t len, unsigned lane, unsigned flags); int rpmem_fip_read(struct rpmem_fip *fip, void *buff, size_t len, size_t off, unsigned lane); void rpmem_fip_probe_fork_safety(void); size_t rpmem_fip_get_wq_size(struct rpmem_fip *fip); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/librpmem/rpmem_obc.c0000664000000000000000000003606214123364546015752 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * rpmem_obc.c -- rpmem out-of-band connection client source file */ #include #include #include #include #include #include #include #include "librpmem.h" #include "rpmem.h" #include "rpmem_common.h" #include "rpmem_obc.h" #include "rpmem_proto.h" #include "rpmem_util.h" #include "rpmem_ssh.h" #include "out.h" #include "sys_util.h" #include "util.h" /* * rpmem_obc -- rpmem out-of-band client connection handle */ struct rpmem_obc { struct rpmem_ssh *ssh; }; /* * rpmem_obc_is_connected -- (internal) return non-zero value if client is * connected */ static inline int rpmem_obc_is_connected(struct rpmem_obc *rpc) { return rpc->ssh != NULL; } /* * rpmem_obc_check_ibc_attr -- (internal) check in-band connection * attributes */ static int rpmem_obc_check_ibc_attr(struct rpmem_msg_ibc_attr *ibc) { if (ibc->port == 0 || ibc->port > UINT16_MAX) { ERR("invalid port number received -- %u", ibc->port); errno = EPROTO; return -1; } if (ibc->persist_method != RPMEM_PM_GPSPM && ibc->persist_method != RPMEM_PM_APM) { ERR("invalid persistency method received -- %u", ibc->persist_method); errno = EPROTO; return -1; } return 0; } /* * rpmem_obc_check_port -- (internal) verify target node port number */ static int rpmem_obc_check_port(const struct rpmem_target_info *info) { if (!(info->flags & RPMEM_HAS_SERVICE)) return 0; if (*info->service == '\0') { ERR("invalid port number -- '%s'", info->service); goto err; } errno = 0; char *endptr; long port = strtol(info->service, &endptr, 10); if (errno || *endptr != '\0') { ERR("invalid port number -- '%s'", info->service); goto err; } if (port < 1) { ERR("port number must be positive -- '%s'", info->service); goto err; } if (port > UINT16_MAX) { ERR("port number too large -- '%s'", info->service); goto err; } return 0; err: errno = EINVAL; return -1; } /* * rpmem_obc_close_conn -- (internal) close connection */ static void rpmem_obc_close_conn(struct rpmem_obc *rpc) { rpmem_ssh_close(rpc->ssh); (void) util_fetch_and_and64(&rpc->ssh, 0); } /* * rpmem_obc_init_msg_hdr -- (internal) initialize message header */ static void rpmem_obc_set_msg_hdr(struct rpmem_msg_hdr *hdrp, enum rpmem_msg_type type, size_t size) { hdrp->type = type; hdrp->size = size; } /* * rpmem_obc_set_pool_desc -- (internal) fill the pool descriptor field */ static void rpmem_obc_set_pool_desc(struct rpmem_msg_pool_desc *pool_desc, const char *desc, size_t size) { RPMEM_ASSERT(size <= UINT32_MAX); RPMEM_ASSERT(size > 0); pool_desc->size = (uint32_t)size; memcpy(pool_desc->desc, desc, size); pool_desc->desc[size - 1] = '\0'; } /* * rpmem_obc_alloc_create_msg -- (internal) allocate and fill create request * message */ static struct rpmem_msg_create * rpmem_obc_alloc_create_msg(const struct rpmem_req_attr *req, const struct rpmem_pool_attr *pool_attr, size_t *msg_sizep) { size_t pool_desc_size = strlen(req->pool_desc) + 1; size_t msg_size = sizeof(struct rpmem_msg_create) + pool_desc_size; struct rpmem_msg_create *msg = malloc(msg_size); if (!msg) { ERR("!cannot allocate create request message"); return NULL; } rpmem_obc_set_msg_hdr(&msg->hdr, RPMEM_MSG_TYPE_CREATE, msg_size); msg->c.major = RPMEM_PROTO_MAJOR; msg->c.minor = RPMEM_PROTO_MINOR; msg->c.pool_size = req->pool_size; msg->c.nlanes = req->nlanes; msg->c.provider = req->provider; msg->c.buff_size = req->buff_size; rpmem_obc_set_pool_desc(&msg->pool_desc, req->pool_desc, pool_desc_size); if (pool_attr) { pack_rpmem_pool_attr(pool_attr, &msg->pool_attr); } else { RPMEM_LOG(INFO, "using zeroed pool attributes"); memset(&msg->pool_attr, 0, sizeof(msg->pool_attr)); } *msg_sizep = msg_size; return msg; } /* * rpmem_obc_check_req -- (internal) check request attributes */ static int rpmem_obc_check_req(const struct rpmem_req_attr *req) { if (req->provider >= MAX_RPMEM_PROV) { ERR("invalid provider specified -- %u", req->provider); errno = EINVAL; return -1; } return 0; } /* * rpmem_obj_check_hdr_resp -- (internal) check response message header */ static int rpmem_obc_check_hdr_resp(struct rpmem_msg_hdr_resp *resp, enum rpmem_msg_type type, size_t size) { if (resp->type != type) { ERR("invalid message type received -- %u", resp->type); errno = EPROTO; return -1; } if (resp->size != size) { ERR("invalid message size received -- %lu", resp->size); errno = EPROTO; return -1; } if (resp->status >= MAX_RPMEM_ERR) { ERR("invalid status received -- %u", resp->status); errno = EPROTO; return -1; } if (resp->status) { enum rpmem_err status = (enum rpmem_err)resp->status; ERR("%s", rpmem_util_proto_errstr(status)); errno = rpmem_util_proto_errno(status); return -1; } return 0; } /* * rpmem_obc_check_create_resp -- (internal) check create response message */ static int rpmem_obc_check_create_resp(struct rpmem_msg_create_resp *resp) { if (rpmem_obc_check_hdr_resp(&resp->hdr, RPMEM_MSG_TYPE_CREATE_RESP, sizeof(struct rpmem_msg_create_resp))) return -1; if (rpmem_obc_check_ibc_attr(&resp->ibc)) return -1; return 0; } /* * rpmem_obc_get_res -- (internal) read response attributes */ static void rpmem_obc_get_res(struct rpmem_resp_attr *res, struct rpmem_msg_ibc_attr *ibc) { res->port = (unsigned short)ibc->port; res->rkey = ibc->rkey; res->raddr = ibc->raddr; res->persist_method = (enum rpmem_persist_method)ibc->persist_method; res->nlanes = ibc->nlanes; } /* * rpmem_obc_alloc_open_msg -- (internal) allocate and fill open request message */ static struct rpmem_msg_open * rpmem_obc_alloc_open_msg(const struct rpmem_req_attr *req, const struct rpmem_pool_attr *pool_attr, size_t *msg_sizep) { size_t pool_desc_size = strlen(req->pool_desc) + 1; size_t msg_size = sizeof(struct rpmem_msg_open) + pool_desc_size; struct rpmem_msg_open *msg = malloc(msg_size); if (!msg) { ERR("!cannot allocate open request message"); return NULL; } rpmem_obc_set_msg_hdr(&msg->hdr, RPMEM_MSG_TYPE_OPEN, msg_size); msg->c.major = RPMEM_PROTO_MAJOR; msg->c.minor = RPMEM_PROTO_MINOR; msg->c.pool_size = req->pool_size; msg->c.nlanes = req->nlanes; msg->c.provider = req->provider; msg->c.buff_size = req->buff_size; rpmem_obc_set_pool_desc(&msg->pool_desc, req->pool_desc, pool_desc_size); *msg_sizep = msg_size; return msg; } /* * rpmem_obc_check_open_resp -- (internal) check open response message */ static int rpmem_obc_check_open_resp(struct rpmem_msg_open_resp *resp) { if (rpmem_obc_check_hdr_resp(&resp->hdr, RPMEM_MSG_TYPE_OPEN_RESP, sizeof(struct rpmem_msg_open_resp))) return -1; if (rpmem_obc_check_ibc_attr(&resp->ibc)) return -1; return 0; } /* * rpmem_obc_check_close_resp -- (internal) check close response message */ static int rpmem_obc_check_close_resp(struct rpmem_msg_close_resp *resp) { if (rpmem_obc_check_hdr_resp(&resp->hdr, RPMEM_MSG_TYPE_CLOSE_RESP, sizeof(struct rpmem_msg_close_resp))) return -1; return 0; } /* * rpmem_obc_check_set_attr_resp -- (internal) check set attributes response * message */ static int rpmem_obc_check_set_attr_resp(struct rpmem_msg_set_attr_resp *resp) { if (rpmem_obc_check_hdr_resp(&resp->hdr, RPMEM_MSG_TYPE_SET_ATTR_RESP, sizeof(struct rpmem_msg_set_attr_resp))) return -1; return 0; } /* * rpmem_obc_init -- initialize rpmem obc handle */ struct rpmem_obc * rpmem_obc_init(void) { struct rpmem_obc *rpc = calloc(1, sizeof(*rpc)); if (!rpc) { RPMEM_LOG(ERR, "!allocation of rpmem obc failed"); return NULL; } return rpc; } /* * rpmem_obc_fini -- destroy rpmem obc handle * * This function must be called with connection already closed - after calling * the rpmem_obc_disconnect or after receiving relevant value from * rpmem_obc_monitor. */ void rpmem_obc_fini(struct rpmem_obc *rpc) { free(rpc); } /* * rpmem_obc_connect -- connect to target node * * Connects to target node, the target must be in the following format: * [:]. If the port number is not specified the default * ssh port will be used. The is translated into IP address. * * Returns an error if connection is already established. */ int rpmem_obc_connect(struct rpmem_obc *rpc, const struct rpmem_target_info *info) { if (rpmem_obc_is_connected(rpc)) { errno = EALREADY; goto err_notconnected; } if (rpmem_obc_check_port(info)) goto err_port; rpc->ssh = rpmem_ssh_open(info); if (!rpc->ssh) goto err_ssh_open; return 0; err_ssh_open: err_port: err_notconnected: return -1; } /* * rpmem_obc_disconnect -- close the connection to target node * * Returns error if socket is not connected. */ int rpmem_obc_disconnect(struct rpmem_obc *rpc) { if (rpmem_obc_is_connected(rpc)) { rpmem_obc_close_conn(rpc); return 0; } errno = ENOTCONN; return -1; } /* * rpmem_obc_monitor -- monitor connection with target node * * The nonblock variable indicates whether this function should return * immediately (= 1) or may block (= 0). * * If the function detects that socket was closed by remote peer it is * closed on local side and set to -1, so there is no need to call * rpmem_obc_disconnect function. Please take a look at functions' * descriptions to see which functions cannot be used if the connection * has been already closed. * * This function expects there is no data pending on socket, if any data * is pending this function returns an error and sets errno to EPROTO. * * Return values: * 0 - not connected * 1 - connected * < 0 - error */ int rpmem_obc_monitor(struct rpmem_obc *rpc, int nonblock) { if (!rpmem_obc_is_connected(rpc)) return 0; return rpmem_ssh_monitor(rpc->ssh, nonblock); } /* * rpmem_obc_create -- perform create request operation * * Returns error if connection has not been established yet. */ int rpmem_obc_create(struct rpmem_obc *rpc, const struct rpmem_req_attr *req, struct rpmem_resp_attr *res, const struct rpmem_pool_attr *pool_attr) { if (!rpmem_obc_is_connected(rpc)) { ERR("out-of-band connection not established"); errno = ENOTCONN; goto err_notconnected; } if (rpmem_obc_check_req(req)) goto err_req; size_t msg_size; struct rpmem_msg_create *msg = rpmem_obc_alloc_create_msg(req, pool_attr, &msg_size); if (!msg) goto err_alloc_msg; RPMEM_LOG(INFO, "sending create request message"); rpmem_hton_msg_create(msg); if (rpmem_ssh_send(rpc->ssh, msg, msg_size)) { ERR("!sending create request message failed"); goto err_msg_send; } RPMEM_LOG(NOTICE, "create request message sent"); RPMEM_LOG(INFO, "receiving create request response"); struct rpmem_msg_create_resp resp; if (rpmem_ssh_recv(rpc->ssh, &resp, sizeof(resp))) { ERR("!receiving create request response failed"); goto err_msg_recv; } RPMEM_LOG(NOTICE, "create request response received"); rpmem_ntoh_msg_create_resp(&resp); if (rpmem_obc_check_create_resp(&resp)) goto err_msg_resp; rpmem_obc_get_res(res, &resp.ibc); free(msg); return 0; err_msg_resp: err_msg_recv: err_msg_send: free(msg); err_alloc_msg: err_req: err_notconnected: return -1; } /* * rpmem_obc_open -- perform open request operation * * Returns error if connection is not already established. */ int rpmem_obc_open(struct rpmem_obc *rpc, const struct rpmem_req_attr *req, struct rpmem_resp_attr *res, struct rpmem_pool_attr *pool_attr) { if (!rpmem_obc_is_connected(rpc)) { ERR("out-of-band connection not established"); errno = ENOTCONN; goto err_notconnected; } if (rpmem_obc_check_req(req)) goto err_req; size_t msg_size; struct rpmem_msg_open *msg = rpmem_obc_alloc_open_msg(req, pool_attr, &msg_size); if (!msg) goto err_alloc_msg; RPMEM_LOG(INFO, "sending open request message"); rpmem_hton_msg_open(msg); if (rpmem_ssh_send(rpc->ssh, msg, msg_size)) { ERR("!sending open request message failed"); goto err_msg_send; } RPMEM_LOG(NOTICE, "open request message sent"); RPMEM_LOG(INFO, "receiving open request response"); struct rpmem_msg_open_resp resp; if (rpmem_ssh_recv(rpc->ssh, &resp, sizeof(resp))) { ERR("!receiving open request response failed"); goto err_msg_recv; } RPMEM_LOG(NOTICE, "open request response received"); rpmem_ntoh_msg_open_resp(&resp); if (rpmem_obc_check_open_resp(&resp)) goto err_msg_resp; rpmem_obc_get_res(res, &resp.ibc); if (pool_attr) unpack_rpmem_pool_attr(&resp.pool_attr, pool_attr); free(msg); return 0; err_msg_resp: err_msg_recv: err_msg_send: free(msg); err_alloc_msg: err_req: err_notconnected: return -1; } /* * rpmem_obc_set_attr -- perform set attributes request operation * * Returns error if connection is not already established. */ int rpmem_obc_set_attr(struct rpmem_obc *rpc, const struct rpmem_pool_attr *pool_attr) { if (!rpmem_obc_is_connected(rpc)) { ERR("out-of-band connection not established"); errno = ENOTCONN; goto err_notconnected; } struct rpmem_msg_set_attr msg; rpmem_obc_set_msg_hdr(&msg.hdr, RPMEM_MSG_TYPE_SET_ATTR, sizeof(msg)); if (pool_attr) { memcpy(&msg.pool_attr, pool_attr, sizeof(msg.pool_attr)); } else { RPMEM_LOG(INFO, "using zeroed pool attributes"); memset(&msg.pool_attr, 0, sizeof(msg.pool_attr)); } RPMEM_LOG(INFO, "sending set attributes request message"); rpmem_hton_msg_set_attr(&msg); if (rpmem_ssh_send(rpc->ssh, &msg, sizeof(msg))) { ERR("!sending set attributes request message failed"); goto err_msg_send; } RPMEM_LOG(NOTICE, "set attributes request message sent"); RPMEM_LOG(INFO, "receiving set attributes request response"); struct rpmem_msg_set_attr_resp resp; if (rpmem_ssh_recv(rpc->ssh, &resp, sizeof(resp))) { ERR("!receiving set attributes request response failed"); goto err_msg_recv; } RPMEM_LOG(NOTICE, "set attributes request response received"); rpmem_ntoh_msg_set_attr_resp(&resp); if (rpmem_obc_check_set_attr_resp(&resp)) goto err_msg_resp; return 0; err_msg_resp: err_msg_recv: err_msg_send: err_notconnected: return -1; } /* * rpmem_obc_close -- perform close request operation * * Returns error if connection is not already established. * * NOTE: this function does not close the connection, but sends close request * message to remote node and receives a response. The connection must be * closed using rpmem_obc_disconnect function. */ int rpmem_obc_close(struct rpmem_obc *rpc, int flags) { if (!rpmem_obc_is_connected(rpc)) { errno = ENOTCONN; return -1; } struct rpmem_msg_close msg; rpmem_obc_set_msg_hdr(&msg.hdr, RPMEM_MSG_TYPE_CLOSE, sizeof(msg)); msg.flags = (uint32_t)flags; RPMEM_LOG(INFO, "sending close request message"); rpmem_hton_msg_close(&msg); if (rpmem_ssh_send(rpc->ssh, &msg, sizeof(msg))) { RPMEM_LOG(ERR, "!sending close request failed"); return -1; } RPMEM_LOG(NOTICE, "close request message sent"); RPMEM_LOG(INFO, "receiving close request response"); struct rpmem_msg_close_resp resp; if (rpmem_ssh_recv(rpc->ssh, &resp, sizeof(resp))) { RPMEM_LOG(ERR, "!receiving close request response failed"); return -1; } RPMEM_LOG(NOTICE, "close request response received"); rpmem_ntoh_msg_close_resp(&resp); if (rpmem_obc_check_close_resp(&resp)) return -1; return 0; } pmdk-1.11.1/src/librpmem/rpmem_cmd.c0000664000000000000000000001102114123364546015736 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_cmd.c -- simple interface for running an executable in child process */ #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "out.h" #include "os.h" #include "rpmem_common.h" #include "rpmem_util.h" #include "rpmem_cmd.h" /* * rpmem_cmd_init -- initialize command */ struct rpmem_cmd * rpmem_cmd_init(void) { struct rpmem_cmd *cmd = calloc(1, sizeof(*cmd)); if (!cmd) { RPMEM_LOG(ERR, "allocating command buffer"); goto err_alloc_cmd; } return cmd; err_alloc_cmd: return NULL; } /* * rpmem_cmd_fini -- deinitialize command */ void rpmem_cmd_fini(struct rpmem_cmd *cmd) { for (int i = 0; i < cmd->args.argc; i++) free(cmd->args.argv[i]); free(cmd->args.argv); free(cmd); } /* * rpmem_cmd_push -- push back command's argument */ int rpmem_cmd_push(struct rpmem_cmd *cmd, const char *arg) { size_t argv_count = (size_t)cmd->args.argc + 2; char **argv = realloc(cmd->args.argv, argv_count * sizeof(char *)); if (!argv) { RPMEM_LOG(ERR, "reallocating command argv"); goto err_realloc; } cmd->args.argv = argv; char *arg_dup = strdup(arg); if (!arg_dup) { RPMEM_LOG(ERR, "allocating argument"); goto err_strdup; } cmd->args.argv[cmd->args.argc] = arg_dup; cmd->args.argc++; cmd->args.argv[cmd->args.argc] = NULL; return 0; err_strdup: err_realloc: return -1; } /* * rpmem_cmd_log -- print executing command */ static void rpmem_cmd_log(struct rpmem_cmd *cmd) { RPMEM_ASSERT(cmd->args.argc > 0); size_t size = 0; for (int i = 0; i < cmd->args.argc; i++) { size += strlen(cmd->args.argv[i]) + 1; } char *buff = malloc(size); if (!buff) { RPMEM_LOG(ERR, "allocating log buffer for command"); return; } size_t pos = 0; for (int i = 0; pos < size && i < cmd->args.argc; i++) { int ret = util_snprintf(&buff[pos], size - pos, "%s%s", cmd->args.argv[i], i == cmd->args.argc - 1 ? "" : " "); if (ret < 0) { RPMEM_LOG(ERR, "!snprintf"); goto out; } pos += (size_t)ret; } RPMEM_LOG(INFO, "executing command '%s'", buff); out: free(buff); } /* * rpmem_cmd_run -- run command and connect with stdin, stdout and stderr * using unix sockets. * * The communication with child process is done via socketpairs on * stdin, stdout and stderr. The socketpairs are used instead of pipes * because reading from disconnected pipe causes a SIGPIPE signal. * When using socketpair it is possible to read data using recv(3) * function with MSG_NOSIGNAL flag, which doesn't send a signal. */ int rpmem_cmd_run(struct rpmem_cmd *cmd) { int fd_in[2]; int fd_out[2]; int fd_err[2]; rpmem_cmd_log(cmd); /* socketpair for stdin */ int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd_in); if (ret < 0) { RPMEM_LOG(ERR, "creating pipe for stdin"); goto err_pipe_in; } /* parent process stdin socket */ cmd->fd_in = fd_in[1]; /* socketpair for stdout */ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd_out); if (ret < 0) { RPMEM_LOG(ERR, "creating pipe for stdout"); goto err_pipe_out; } /* parent process stdout socket */ cmd->fd_out = fd_out[0]; /* socketpair for stderr */ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd_err); if (ret < 0) { RPMEM_LOG(ERR, "creating pipe for stderr"); goto err_pipe_err; } /* socketpair for stderr */ cmd->fd_err = fd_err[0]; cmd->pid = fork(); if (cmd->pid == -1) { RPMEM_LOG(ERR, "forking command"); goto err_fork; } if (!cmd->pid) { dup2(fd_in[0], 0); dup2(fd_out[1], 1); dup2(fd_err[1], 2); execvp(cmd->args.argv[0], cmd->args.argv); exit(EXIT_FAILURE); } os_close(fd_in[0]); os_close(fd_out[1]); os_close(fd_err[1]); return 0; err_fork: os_close(fd_err[0]); os_close(fd_err[1]); err_pipe_err: os_close(fd_out[0]); os_close(fd_out[1]); err_pipe_out: os_close(fd_in[0]); os_close(fd_in[1]); err_pipe_in: return -1; } /* * rpmem_cmd_wait -- wait for process to change state */ int rpmem_cmd_wait(struct rpmem_cmd *cmd, int *status) { if (cmd->pid <= 0) { RPMEM_LOG(ERR, "wrong PID: %i", cmd->pid); errno = EINVAL; return -1; } if (waitpid(cmd->pid, status, 0) != cmd->pid) { RPMEM_LOG(ERR, "!waitpid failed"); return -1; } return 0; } /* * rpmem_cmd_term -- close child process's unix sockets */ void rpmem_cmd_term(struct rpmem_cmd *cmd) { os_close(cmd->fd_in); os_close(cmd->fd_out); os_close(cmd->fd_err); RPMEM_ASSERT(cmd->pid > 0); } pmdk-1.11.1/src/librpmem/README0000664000000000000000000000034714123364546014520 0ustar rootrootThis directory contains a librpmem library which provides remote access to persistent memory over RDMA. ** DEPENDENCIES: ** The librpmem library depends on libfabric (version >= 1.4.2) library: https://github.com/ofiwg/libfabric pmdk-1.11.1/src/librpmem/rpmem_util.h0000664000000000000000000000216414123364546016165 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_util.h -- util functions for librpmem header file */ #ifndef RPMEM_UTIL_H #define RPMEM_UTIL_H 1 #ifdef __cplusplus extern "C" { #endif enum { LERR = 1, LWARN = 2, LNOTICE = 3, LINFO = 4, _LDBG = 10, }; #define RPMEM_LOG(level, fmt, args...) LOG(L##level, fmt, ## args) #define RPMEM_DBG(fmt, args...) LOG(_LDBG, fmt, ## args) #define RPMEM_FATAL(fmt, args...) FATAL(fmt, ## args) #define RPMEM_ASSERT(cond) ASSERT(cond) #define RPMEM_PERSIST_FLAGS_ALL RPMEM_PERSIST_RELAXED #define RPMEM_PERSIST_FLAGS_MASK ((unsigned)(~RPMEM_PERSIST_FLAGS_ALL)) #define RPMEM_FLUSH_FLAGS_ALL RPMEM_FLUSH_RELAXED #define RPMEM_FLUSH_FLAGS_MASK ((unsigned)(~RPMEM_FLUSH_FLAGS_ALL)) const char *rpmem_util_proto_errstr(enum rpmem_err err); int rpmem_util_proto_errno(enum rpmem_err err); void rpmem_util_cmds_init(void); void rpmem_util_cmds_fini(void); const char *rpmem_util_cmd_get(void); void rpmem_util_get_env_max_nlanes(unsigned *max_nlanes); void rpmem_util_get_env_wq_size(unsigned *wq_size); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/librpmem/rpmem_cmd.h0000664000000000000000000000143114123364546015747 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_cmd.h -- helper module for invoking separate process */ #ifndef RPMEM_CMD_H #define RPMEM_CMD_H 1 #include #ifdef __cplusplus extern "C" { #endif struct rpmem_cmd { int fd_in; /* stdin */ int fd_out; /* stdout */ int fd_err; /* stderr */ struct { char **argv; int argc; } args; /* command arguments */ pid_t pid; /* pid of process */ }; struct rpmem_cmd *rpmem_cmd_init(void); int rpmem_cmd_push(struct rpmem_cmd *cmd, const char *arg); int rpmem_cmd_run(struct rpmem_cmd *cmd); void rpmem_cmd_term(struct rpmem_cmd *cmd); int rpmem_cmd_wait(struct rpmem_cmd *cmd, int *status); void rpmem_cmd_fini(struct rpmem_cmd *cmd); #ifdef __cplusplus } #endif #endif pmdk-1.11.1/src/librpmem/rpmem_ssh.c0000664000000000000000000002003514123364546015775 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_ssh.c -- rpmem ssh transport layer source file */ #include #include #include #include #include #include #include #include #include "util.h" #include "os.h" #include "out.h" #include "rpmem_common.h" #include "rpmem_ssh.h" #include "rpmem_cmd.h" #include "rpmem_util.h" #define ERR_BUFF_LEN 4095 /* +1 in order to be sure it is always null-terminated */ static char error_str[ERR_BUFF_LEN + 1]; struct rpmem_ssh { struct rpmem_cmd *cmd; }; /* * get_ssh -- return ssh command name */ static const char * get_ssh(void) { char *cmd = os_getenv(RPMEM_SSH_ENV); if (!cmd) cmd = RPMEM_DEF_SSH; return cmd; } /* * get_user_at_node -- returns string containing user@node */ static char * get_user_at_node(const struct rpmem_target_info *info) { char *user_at_node = NULL; if (info->flags & RPMEM_HAS_USER) { size_t ulen = strlen(info->user); size_t nlen = strlen(info->node); size_t len = ulen + 1 + nlen + 1; user_at_node = malloc(len); if (!user_at_node) goto err_malloc; int ret = util_snprintf(user_at_node, len, "%s@%s", info->user, info->node); if (ret < 0) goto err_printf; } else { user_at_node = strdup(info->node); if (!user_at_node) goto err_malloc; } return user_at_node; err_printf: free(user_at_node); err_malloc: return NULL; } /* * get_cmd -- return an RPMEM_CMD with appended list of arguments */ static char * get_cmd(const char **argv) { const char *env_cmd = rpmem_util_cmd_get(); char *cmd = strdup(env_cmd); if (!cmd) return NULL; size_t cmd_len = strlen(cmd) + 1; const char *arg; while ((arg = *argv++) != NULL) { size_t len = strlen(arg); size_t new_cmd_len = cmd_len + len + 1; char *tmp = realloc(cmd, new_cmd_len); if (!tmp) goto err; cmd = tmp; /* append the argument to the command */ cmd[cmd_len - 1] = ' '; memcpy(&cmd[cmd_len], arg, len); cmd[cmd_len + len] = '\0'; cmd_len = new_cmd_len; } return cmd; err: free(cmd); return NULL; } /* * valist_to_argv -- convert va_list to argv array */ static const char ** valist_to_argv(va_list args) { const char **argv = malloc(sizeof(const char *)); if (!argv) return NULL; argv[0] = NULL; size_t nargs = 0; const char *arg; while ((arg = va_arg(args, const char *)) != NULL) { nargs++; const char **tmp = realloc(argv, (nargs + 1) * sizeof(const char *)); if (!tmp) goto err; argv = tmp; argv[nargs - 1] = arg; argv[nargs] = NULL; } return argv; err: free(argv); return NULL; } /* * rpmem_ssh_execv -- open ssh connection and run $RPMEMD_CMD with * additional NULL-terminated list of arguments. */ struct rpmem_ssh * rpmem_ssh_execv(const struct rpmem_target_info *info, const char **argv) { struct rpmem_ssh *rps = calloc(1, sizeof(*rps)); if (!rps) goto err_zalloc; char *user_at_node = get_user_at_node(info); if (!user_at_node) goto err_user_node; rps->cmd = rpmem_cmd_init(); if (!rps->cmd) goto err_cmd_init; char *cmd = get_cmd(argv); if (!cmd) goto err_cmd; int ret = rpmem_cmd_push(rps->cmd, get_ssh()); if (ret) goto err_push; if (info->flags & RPMEM_HAS_SERVICE) { /* port number is optional */ ret = rpmem_cmd_push(rps->cmd, "-p"); if (ret) goto err_push; ret = rpmem_cmd_push(rps->cmd, info->service); if (ret) goto err_push; } /* * Disable allocating pseudo-terminal in order to transfer binary * data safely. */ ret = rpmem_cmd_push(rps->cmd, "-T"); if (ret) goto err_push; if (info->flags & RPMEM_FLAGS_USE_IPV4) { ret = rpmem_cmd_push(rps->cmd, "-4"); if (ret) goto err_push; } /* fail if password required for authentication */ ret = rpmem_cmd_push(rps->cmd, "-oBatchMode=yes"); if (ret) goto err_push; ret = rpmem_cmd_push(rps->cmd, user_at_node); if (ret) goto err_push; ret = rpmem_cmd_push(rps->cmd, cmd); if (ret) goto err_push; ret = rpmem_cmd_run(rps->cmd); if (ret) goto err_run; free(user_at_node); free(cmd); return rps; err_run: err_push: free(cmd); err_cmd: rpmem_cmd_fini(rps->cmd); err_cmd_init: free(user_at_node); err_user_node: free(rps); err_zalloc: return NULL; } /* * rpmem_ssh_exec -- open ssh connection and run $RPMEMD_CMD with * additional NULL-terminated list of arguments. */ struct rpmem_ssh * rpmem_ssh_exec(const struct rpmem_target_info *info, ...) { struct rpmem_ssh *ssh; va_list args; va_start(args, info); const char **argv = valist_to_argv(args); if (argv) ssh = rpmem_ssh_execv(info, argv); else ssh = NULL; va_end(args); free(argv); return ssh; } /* * rpmem_ssh_open -- open ssh connection with specified node and wait for status */ struct rpmem_ssh * rpmem_ssh_open(const struct rpmem_target_info *info) { struct rpmem_ssh *ssh = rpmem_ssh_exec(info, NULL); if (!ssh) return NULL; /* * Read initial status from invoked command. * This is for synchronization purposes and to make it possible * to inform client that command's initialization failed. */ int32_t status; int ret = rpmem_ssh_recv(ssh, &status, sizeof(status)); if (ret) { if (ret == 1 || errno == ECONNRESET) ERR("%s", rpmem_ssh_strerror(ssh, errno)); else ERR("!%s", info->node); goto err_recv_status; } if (status) { ERR("%s: unexpected status received -- '%d'", info->node, status); errno = status; goto err_status; } RPMEM_LOG(INFO, "received status: %u", status); return ssh; err_recv_status: err_status: rpmem_ssh_close(ssh); return NULL; } /* * rpmem_ssh_close -- close ssh connection */ int rpmem_ssh_close(struct rpmem_ssh *rps) { int ret, rv; rpmem_cmd_term(rps->cmd); rv = rpmem_cmd_wait(rps->cmd, &ret); if (rv) return rv; rpmem_cmd_fini(rps->cmd); free(rps); if (WIFEXITED(ret)) return WEXITSTATUS(ret); if (WIFSIGNALED(ret)) { ERR("signal received -- %d", WTERMSIG(ret)); return -1; } ERR("exit status -- %d", WEXITSTATUS(ret)); return -1; } /* * rpmem_ssh_send -- send data using ssh transport layer * * The data is encoded using base64. */ int rpmem_ssh_send(struct rpmem_ssh *rps, const void *buff, size_t len) { int ret = rpmem_xwrite(rps->cmd->fd_in, buff, len, MSG_NOSIGNAL); if (ret == 1) { errno = ECONNRESET; } else if (ret < 0) { if (errno == EPIPE) errno = ECONNRESET; } return ret; } /* * rpmem_ssh_recv -- receive data using ssh transport layer * * The received data is decoded using base64. */ int rpmem_ssh_recv(struct rpmem_ssh *rps, void *buff, size_t len) { int ret = rpmem_xread(rps->cmd->fd_out, buff, len, MSG_NOSIGNAL); if (ret == 1) { errno = ECONNRESET; } else if (ret < 0) { if (errno == EPIPE) errno = ECONNRESET; } return ret; } /* * rpmem_ssh_monitor -- check connection state of ssh * * Return value: * 0 - disconnected * 1 - connected * <0 - error */ int rpmem_ssh_monitor(struct rpmem_ssh *rps, int nonblock) { uint32_t buff; int flags = MSG_PEEK; if (nonblock) flags |= MSG_DONTWAIT; int ret = rpmem_xread(rps->cmd->fd_out, &buff, sizeof(buff), flags); if (!ret) { errno = EPROTO; return -1; } if (ret < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) return 1; else return ret; } return 0; } /* * rpmem_ssh_strerror -- read error using stderr channel */ const char * rpmem_ssh_strerror(struct rpmem_ssh *rps, int oerrno) { size_t len = 0; ssize_t ret; while ((ret = read(rps->cmd->fd_err, error_str + len, ERR_BUFF_LEN - len))) { if (ret < 0) return "reading error string failed"; len += (size_t)ret; } error_str[len] = '\0'; if (len == 0) { int ret; if (oerrno) { char buff[UTIL_MAX_ERR_MSG]; util_strerror(oerrno, buff, UTIL_MAX_ERR_MSG); ret = util_snprintf(error_str, ERR_BUFF_LEN, "%s", buff); } else { ret = util_snprintf(error_str, ERR_BUFF_LEN, "unknown error"); } if (ret < 0) FATAL("!snprintf"); } else { /* get rid of new line and carriage return chars */ char *cr = strchr(error_str, '\r'); if (cr) *cr = '\0'; char *nl = strchr(error_str, '\n'); if (nl) *nl = '\0'; } return error_str; } pmdk-1.11.1/src/librpmem/rpmem.h0000664000000000000000000000124314123364546015125 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem.h -- internal definitions for librpmem */ #include "alloc.h" #include "fault_injection.h" #define RPMEM_LOG_PREFIX "librpmem" #define RPMEM_LOG_LEVEL_VAR "RPMEM_LOG_LEVEL" #define RPMEM_LOG_FILE_VAR "RPMEM_LOG_FILE" #if FAULT_INJECTION void rpmem_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at); int rpmem_fault_injection_enabled(void); #else static inline void rpmem_inject_fault_at(enum pmem_allocation_type type, int nth, const char *at) { abort(); } static inline int rpmem_fault_injection_enabled(void) { return 0; } #endif pmdk-1.11.1/src/freebsd/0000775000000000000000000000000014123364546013437 5ustar rootrootpmdk-1.11.1/src/freebsd/README0000664000000000000000000000115714123364546014323 0ustar rootrootPersistent Memory Development Kit This is src/freebsd/README. This directory contains FreeBSD-specific files for the Persistent Memory Development Kit. The subdirectory "include" contains header files that have no equivalents on FreeBSD. Most of these files are empty, which is a cheap trick to avoid preprocessor errors when including non-existing files. Others are redirects for files that are in different locations on FreeBSD. This way we don't need a lot of preprocessor conditionals in all the source code files, although it does require conditionals in the Makefiles (which could be addressed by using autoconf). pmdk-1.11.1/src/freebsd/include/0000775000000000000000000000000014123364546015062 5ustar rootrootpmdk-1.11.1/src/freebsd/include/sys/0000775000000000000000000000000014123364546015700 5ustar rootrootpmdk-1.11.1/src/freebsd/include/sys/sysmacros.h0000664000000000000000000000021314123364546020070 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2017-2020, Intel Corporation */ /* * sys/sysmacros.h -- Empty file redirect */ pmdk-1.11.1/src/freebsd/include/endian.h0000664000000000000000000000025514123364546016473 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2017-2020, Intel Corporation */ /* * endian.h -- redirect for FreeBSD */ #include pmdk-1.11.1/src/freebsd/include/features.h0000664000000000000000000000020614123364546017047 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2017-2020, Intel Corporation */ /* * features.h -- Empty file redirect */ pmdk-1.11.1/src/freebsd/include/linux/0000775000000000000000000000000014123364546016221 5ustar rootrootpmdk-1.11.1/src/freebsd/include/linux/kdev_t.h0000664000000000000000000000021214123364546017641 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2017-2020, Intel Corporation */ /* * linux/kdev_t.h -- Empty file redirect */ pmdk-1.11.1/src/freebsd/include/linux/limits.h0000664000000000000000000000021214123364546017666 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2017-2020, Intel Corporation */ /* * linux/limits.h -- Empty file redirect */ pmdk-1.11.1/src/test/0000775000000000000000000000000014123364546013004 5ustar rootrootpmdk-1.11.1/src/test/signal_handle/0000775000000000000000000000000014123364546015574 5ustar rootrootpmdk-1.11.1/src/test/signal_handle/out0w.log.match0000664000000000000000000000050714123364546020452 0ustar rootrootsignal_handle$(nW)TEST0w: START: signal_handle $(nW)signal_handle$(nW) s a a i v Testing SIGSEGV... signal_handler_2: $(*) Testing SIGABRT... signal_handler_1: $(*) Testing SIGABRT... signal_handler_1: $(*) Testing SIGILL... signal_handler_2: $(*) Testing SIGABRT... signal_handler_3: $(*) signal_handle$(nW)TEST0w: DONE pmdk-1.11.1/src/test/signal_handle/signal_handle.c0000664000000000000000000000476514123364546020544 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * signal_handle.c -- unit test for signal_handle * * * operations are: 's', 'a', 'a', 'i', 'v' * s: testing SIGSEGV with signal_handler_2 * a: testing SIGABRT with signal_handler_1 * a: testing second occurrence of SIGABRT with signal_handler_1 * i: testing SIGILL with signal_handler_2 * v: testing third occurrence of SIGABRT with other signal_handler_3 * */ #include "unittest.h" ut_jmp_buf_t Jmp; static void signal_handler_1(int sig) { UT_OUT("\tsignal_handler_1: %s", os_strsignal(sig)); ut_siglongjmp(Jmp); } static void signal_handler_2(int sig) { UT_OUT("\tsignal_handler_2: %s", os_strsignal(sig)); ut_siglongjmp(Jmp); } static void signal_handler_3(int sig) { UT_OUT("\tsignal_handler_3: %s", os_strsignal(sig)); ut_siglongjmp(Jmp); } int main(int argc, char *argv[]) { START(argc, argv, "signal_handle"); if (argc < 2) UT_FATAL("usage: %s op:s|a|a|i|v", argv[0]); struct sigaction v1, v2, v3; sigemptyset(&v1.sa_mask); v1.sa_flags = 0; v1.sa_handler = signal_handler_1; sigemptyset(&v2.sa_mask); v2.sa_flags = 0; v2.sa_handler = signal_handler_2; SIGACTION(SIGSEGV, &v2, NULL); SIGACTION(SIGABRT, &v1, NULL); SIGACTION(SIGABRT, &v2, NULL); SIGACTION(SIGABRT, &v1, NULL); SIGACTION(SIGILL, &v2, NULL); for (int arg = 1; arg < argc; arg++) { if (strchr("sabiv", argv[arg][0]) == NULL || argv[arg][1] != '\0') UT_FATAL("op must be one of: s, a, a, i, v"); switch (argv[arg][0]) { case 's': UT_OUT("Testing SIGSEGV..."); if (!ut_sigsetjmp(Jmp)) { if (!raise(SIGSEGV)) { UT_OUT("\t SIGSEGV occurrence"); } else { UT_OUT("\t Issue with SIGSEGV raise"); } } break; case 'a': UT_OUT("Testing SIGABRT..."); if (!ut_sigsetjmp(Jmp)) { if (!raise(SIGABRT)) { UT_OUT("\t SIGABRT occurrence"); } else { UT_OUT("\t Issue with SIGABRT raise"); } } break; case 'i': UT_OUT("Testing SIGILL..."); if (!ut_sigsetjmp(Jmp)) { if (!raise(SIGILL)) { UT_OUT("\t SIGILL occurrence"); } else { UT_OUT("\t Issue with SIGILL raise"); } } break; case 'v': if (!ut_sigsetjmp(Jmp)) { sigemptyset(&v3.sa_mask); v3.sa_flags = 0; v3.sa_handler = signal_handler_3; UT_OUT("Testing SIGABRT..."); SIGACTION(SIGABRT, &v3, NULL); if (!raise(SIGABRT)) { UT_OUT("\t SIGABRT occurrence"); } else { UT_OUT("\t Issue with SIGABRT raise"); } } break; } } DONE(NULL); } pmdk-1.11.1/src/test/signal_handle/signal_handle.vcxproj0000664000000000000000000000642314123364546022006 0ustar rootroot Debug x64 Release x64 {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {AE9E908D-BAEC-491F-9914-436B3CE35E94} Win32Proj signal_handle 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/signal_handle/signal_handle.vcxproj.filters0000664000000000000000000000156014123364546023452 0ustar rootroot Tests Files Match Files {69f676d7-e653-4644-892c-be4e71754264} {00ea252a-e40d-4b35-8ac5-7d8ea7d8b365} {9fa92886-a9ee-412f-bb0a-ce241dc6deaf} Source Files pmdk-1.11.1/src/test/signal_handle/TEST0w.PS10000664000000000000000000000053014123364546017145 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/signal_handle/TEST0w.PS1 -- unit test for signal_handle # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup expect_normal_exit $Env:EXE_DIR\signal_handle$Env:EXESUFFIX s a a i v check pass pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/0000775000000000000000000000000014123364546016771 5ustar rootrootpmdk-1.11.1/src/test/obj_pmalloc_rand_mt/TEST1.PS10000664000000000000000000000060714123364546020161 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pmalloc_rand_mt/TEST1 -- multithreaded allocator test # . ..\unittest\unittest.ps1 require_fs_type pmem require_test_type medium setup require_free_space 3G $Env:PMEM_IS_PMEM_FORCE=1 expect_normal_exit $Env:EXE_DIR\obj_pmalloc_rand_mt$Env:EXESUFFIX $DIR\testfile 8 1000 260000 1234 pass pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/obj_pmalloc_rand_mt.vcxproj.filters0000664000000000000000000000155314123364546026046 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Source Files Test Files pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/obj_pmalloc_rand_mt.c0000664000000000000000000000440414123364546023124 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2020, Intel Corporation */ /* * obj_pmalloc_mt.c -- multithreaded test of allocator */ #include #include "file.h" #include "rand.h" #include "unittest.h" #define RRAND(seed, max, min) (rnd64_r(&(seed)) % ((max) - (min)) + (min)) static size_t object_size; static unsigned nobjects; static unsigned iterations = 1000000; static unsigned seed; static void * test_worker(void *arg) { PMEMobjpool *pop = arg; PMEMoid *objects = ZALLOC(sizeof(PMEMoid) * nobjects); unsigned fill = 0; int ret; rng_t myseed; randomize_r(&myseed, seed); for (unsigned i = 0; i < iterations; ++i) { unsigned fill_ratio = (fill * 100) / nobjects; unsigned pos = RRAND(myseed, nobjects, 0); size_t size = RRAND(myseed, object_size, 64); if (RRAND(myseed, 100, 0) < fill_ratio) { if (!OID_IS_NULL(objects[pos])) { pmemobj_free(&objects[pos]); objects[pos] = OID_NULL; fill--; } } else { if (OID_IS_NULL(objects[pos])) { ret = pmemobj_alloc(pop, &objects[pos], size, 0, NULL, NULL); UT_ASSERTeq(ret, 0); fill++; } } } FREE(objects); return NULL; } int main(int argc, char *argv[]) { START(argc, argv, "obj_pmalloc_rand_mt"); if (argc < 5 || argc > 7) UT_FATAL("usage: %s [file] " "[threads #] [objects #] [object size] " "[iterations (def: 1000000)] [seed (def: time)]", argv[0]); unsigned nthreads = ATOU(argv[2]); nobjects = ATOU(argv[3]); object_size = ATOUL(argv[4]); if (argc > 5) iterations = ATOU(argv[5]); if (argc > 6) seed = ATOU(argv[6]); else seed = 0; PMEMobjpool *pop; int exists = util_file_exists(argv[1]); if (exists < 0) UT_FATAL("!util_file_exists"); if (!exists) { pop = pmemobj_create(argv[1], "TEST", (PMEMOBJ_MIN_POOL * 10) + (nthreads * nobjects * object_size), 0666); if (pop == NULL) UT_FATAL("!pmemobj_create"); } else { pop = pmemobj_open(argv[1], "TEST"); if (pop == NULL) UT_FATAL("!pmemobj_open"); } os_thread_t *threads = MALLOC(sizeof(os_thread_t) * nthreads); for (unsigned i = 0; i < nthreads; ++i) { THREAD_CREATE(&threads[i], NULL, test_worker, pop); } for (unsigned i = 0; i < nthreads; ++i) { THREAD_JOIN(&threads[i], NULL); } FREE(threads); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/TEST00000775000000000000000000000071314123364546017557 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_pmalloc_rand_mt/TEST0 -- multithreaded allocator test # . ../unittest/unittest.sh require_valgrind 3.10 require_fs_type pmem require_test_type long configure_valgrind helgrind force-enable setup require_free_space 3G PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_rand_mt$EXESUFFIX $DIR/testfile 8 1000 260000 10000 1234 pass pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/Makefile0000664000000000000000000000042614123364546020433 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_pmalloc_rand_mt/Makefile -- build obj_pmalloc_rand_mt unit test # TARGET = obj_pmalloc_rand_mt OBJS = obj_pmalloc_rand_mt.o LIBPMEMOBJ=y LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/.gitignore0000664000000000000000000000002414123364546020755 0ustar rootrootobj_pmalloc_rand_mt pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/obj_pmalloc_rand_mt.vcxproj0000664000000000000000000000672714123364546024407 0ustar rootroot Debug x64 Release x64 {D140560D-FDEC-4D3D-8F58-BF5FD5E4DAA1} Win32Proj obj_pmalloc_rand_mt 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_pmalloc_rand_mt/TEST10000775000000000000000000000061014123364546017554 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_pmalloc_rand_mt/TEST1 -- multithreaded allocator test # . ../unittest/unittest.sh require_fs_type pmem require_test_type medium setup require_free_space 3G PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_rand_mt$EXESUFFIX $DIR/testfile 8 1000 260000 1234 pass pmdk-1.11.1/src/test/obj_first_next/0000775000000000000000000000000014123364546016023 5ustar rootrootpmdk-1.11.1/src/test/obj_first_next/TEST1.PS10000664000000000000000000000071414123364546017212 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_first_next/TEST1 -- unit test for POBJ_FIRST macro # # Returns first object on the proper list # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_first_next$Env:EXESUFFIX $DIR\testfile ` a:0:1 a:0:0 a:1:1 a:0:2 a:1:2 P:0 P:1 ` f:0 f:1 r:0:0 r:1:0 P:0 P:1 ` f:0 f:1 a:0:3 a:1:3 P:0 P:1 ` f:0 f:1 check pass pmdk-1.11.1/src/test/obj_first_next/obj_first_next.c0000664000000000000000000001401214123364546021204 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * obj_first_next.c -- unit tests for POBJ_FIRST macro */ #include #include "libpmemobj.h" #include "unittest.h" #define LAYOUT_NAME "obj_first_next" TOID_DECLARE(struct type, 0); TOID_DECLARE(struct type_sec, 1); struct type { int id; }; struct type_sec { int id; }; static PMEMobjpool *pop; typedef void (*fn_op)(int id); typedef void (*fn_void)(); #define FATAL_USAGE()\ UT_FATAL("usage: obj_first_next [Parfn]") /* * get_item_type -- get nth item from list */ static TOID(struct type) get_item_type(int n) { TOID(struct type) item; POBJ_FOREACH_TYPE(pop, item) { if (n == 0) return item; n--; } return TOID_NULL(struct type); } /* * get_item_type_sec -- get nth item from list */ static TOID(struct type_sec) get_item_type_sec(int n) { TOID(struct type_sec) item; POBJ_FOREACH_TYPE(pop, item) { if (n == 0) return item; n--; } return TOID_NULL(struct type_sec); } /* * do_print_type -- print list elements from type collection */ static void do_print_type(void) { TOID(struct type) item; UT_OUT("type:"); POBJ_FOREACH_TYPE(pop, item) { UT_OUT("id = %d", D_RO(item)->id); } } /* * do_print_type_sec -- print list elements from type_sec collection */ static void do_print_type_sec(void) { TOID(struct type_sec) item; UT_OUT("type_sec:"); POBJ_FOREACH_TYPE(pop, item) { UT_OUT("id = %d", D_RO(item)->id); } } static fn_void do_print[] = {do_print_type, do_print_type_sec}; /* * type_constructor -- constructor which sets the item's id to * new value */ static int type_constructor(PMEMobjpool *pop, void *ptr, void *arg) { int id = *(int *)arg; struct type *item = (struct type *)ptr; item->id = id; UT_OUT("constructor(id = %d)", id); pmemobj_persist(pop, item, sizeof(*item)); return 0; } /* * type_sec_constructor -- constructor which sets the item's id to * new value */ static int type_sec_constructor(PMEMobjpool *pop, void *ptr, void *arg) { int id = *(int *)arg; struct type_sec *item = (struct type_sec *)ptr; item->id = id; UT_OUT("constructor(id = %d)", id); pmemobj_persist(pop, item, sizeof(*item)); return 0; } /* * do_alloc_type -- allocates new element to type collection */ static void do_alloc_type(int id) { TOID(struct type) item; POBJ_NEW(pop, &item, struct type, type_constructor, &id); if (TOID_IS_NULL(item)) UT_FATAL("POBJ_NEW"); } /* * do_alloc_type_sec -- allocates new element to type_sec collection */ static void do_alloc_type_sec(int id) { TOID(struct type_sec) item; POBJ_NEW(pop, &item, struct type_sec, type_sec_constructor, &id); if (TOID_IS_NULL(item)) UT_FATAL("POBJ_NEW"); } static fn_op do_alloc[] = {do_alloc_type, do_alloc_type_sec}; /* * do_free_type -- remove and free element from type collection */ static void do_free_type(int n) { TOID(struct type) item; if (TOID_IS_NULL(POBJ_FIRST(pop, struct type))) return; item = get_item_type(n); UT_ASSERT(!TOID_IS_NULL(item)); POBJ_FREE(&item); } /* * do_free_type_sec -- remove and free element from type_sec collection */ static void do_free_type_sec(int n) { TOID(struct type_sec) item; if (TOID_IS_NULL(POBJ_FIRST(pop, struct type_sec))) return; item = get_item_type_sec(n); UT_ASSERT(!TOID_IS_NULL(item)); POBJ_FREE(&item); } static fn_op do_free[] = {do_free_type, do_free_type_sec}; /* * do_first_type -- prints id of first object in type collection */ static void do_first_type(void) { TOID(struct type) first = POBJ_FIRST(pop, struct type); UT_OUT("first id = %d", D_RO(first)->id); } /* * do_first_type_sec -- prints id of first object in type_sec collection */ static void do_first_type_sec(void) { TOID(struct type_sec) first = POBJ_FIRST(pop, struct type_sec); UT_OUT("first id = %d", D_RO(first)->id); } static fn_void do_first[] = {do_first_type, do_first_type_sec}; /* * do_next_type -- finds next element from type collection */ static void do_next_type(int n) { TOID(struct type) item; if (TOID_IS_NULL(POBJ_FIRST(pop, struct type))) return; item = get_item_type(n); UT_ASSERT(!TOID_IS_NULL(item)); item = POBJ_NEXT(item); UT_OUT("next id = %d", D_RO(item)->id); } /* * do_next_type_sec -- finds next element from type_sec collection */ static void do_next_type_sec(int n) { TOID(struct type_sec) item; if (TOID_IS_NULL(POBJ_FIRST(pop, struct type_sec))) return; item = get_item_type_sec(n); UT_ASSERT(!TOID_IS_NULL(item)); item = POBJ_NEXT(item); UT_OUT("next id = %d", D_RO(item)->id); } static fn_op do_next[] = {do_next_type, do_next_type_sec}; /* * do_cleanup -- de-initialization function */ static void do_cleanup(void) { PMEMoid oid, oid_tmp; POBJ_FOREACH_SAFE(pop, oid, oid_tmp) pmemobj_free(&oid); } static void test_internal_object_mask(PMEMobjpool *pop) { /* allocate root object */ PMEMoid root = pmemobj_root(pop, sizeof(struct type)); TX_BEGIN(pop) { /* trigger creation of a range cache */ pmemobj_tx_add_range(root, 0, 8); } TX_END PMEMoid oid; pmemobj_alloc(pop, &oid, sizeof(struct type), 0, NULL, NULL); UT_ASSERT(!OID_IS_NULL(oid)); /* verify that there's no root object nor range cache anywhere */ for (PMEMoid iter = pmemobj_first(pop); !OID_IS_NULL(iter); iter = pmemobj_next(iter)) { UT_ASSERT(OID_EQUALS(iter, oid)); } } int main(int argc, char *argv[]) { START(argc, argv, "obj_first_next"); if (argc < 2) FATAL_USAGE(); const char *path = argv[1]; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); for (int i = 2; i < argc; i++) { int list_num; int id; char type; if (sscanf(argv[i], "%c:%d:%d", &type, &list_num, &id) == EOF) UT_FATAL("!sscanf"); switch (type) { case 'P': do_print[list_num](); break; case 'a': do_alloc[list_num](id); break; case 'r': do_free[list_num](id); break; case 'f': do_first[list_num](); break; case 'n': do_next[list_num](id); break; default: FATAL_USAGE(); } } do_cleanup(); test_internal_object_mask(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_first_next/obj_first_next.vcxproj0000664000000000000000000000731414123364546022464 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {BABC6427-E533-4DCF-91E3-B5B2ED253F46} Win32Proj obj_first_next 10.0.17134.0 Application true v140 Application false v140 NotUsing CompileAsCpp NotUsing CompileAsCpp pmdk-1.11.1/src/test/obj_first_next/TEST00000775000000000000000000000074714123364546016620 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_first_next/TEST0 -- unit test for POBJ_NEXT macro # # Returns next element with proper type number # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_first_next$EXESUFFIX $DIR/testfile\ a:0:0 a:0:1 a:1:1 a:0:2 a:1:2 a:0:3 a:1:3 P:0 P:1\ n:0:2 n:1:1 r:0:0 r:1:0 P:0 P:1\ n:0:0 n:1:0 a:0:4 a:1:4 P:0 P:1\ n:0:1 n:1:1 check pass pmdk-1.11.1/src/test/obj_first_next/Makefile0000664000000000000000000000036314123364546017465 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_first_next/Makefile -- build obj_first_next unit test # TARGET = obj_first_next OBJS = obj_first_next.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_first_next/out0.log.match0000664000000000000000000000131214123364546020505 0ustar rootrootobj_first_next$(nW)TEST0: START: obj_first_next $(nW)obj_first_next$(nW) $(nW)testfile a:0:0 a:0:1 a:1:1 a:0:2 a:1:2 a:0:3 a:1:3 P:0 P:1 n:0:2 n:1:1 r:0:0 r:1:0 P:0 P:1 n:0:0 n:1:0 a:0:4 a:1:4 P:0 P:1 n:0:1 n:1:1 constructor(id = 0) constructor(id = 1) constructor(id = 1) constructor(id = 2) constructor(id = 2) constructor(id = 3) constructor(id = 3) type: id = 0 id = 1 id = 2 id = 3 type_sec: id = 1 id = 2 id = 3 next id = 3 next id = 3 type: id = 1 id = 2 id = 3 type_sec: id = 2 id = 3 next id = 2 next id = 3 constructor(id = 4) constructor(id = 4) type: id = $(nW) id = $(nW) id = $(nW) id = $(nW) type_sec: id = $(nW) id = $(nW) id = $(nW) next id = $(nW) next id = $(nW) obj_first_next$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_first_next/TEST0.PS10000664000000000000000000000066614123364546017217 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_first_next/TEST0 -- unit test for POBJ_NEXT macro # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_first_next$Env:EXESUFFIX $DIR\testfile ` a:0:0 a:0:1 a:1:1 a:0:2 a:1:2 a:0:3 a:1:3 P:0 P:1 ` n:0:2 n:1:1 r:0:0 r:1:0 P:0 P:1 ` n:0:0 n:1:0 a:0:4 a:1:4 P:0 P:1 ` n:0:1 n:1:1 check pass pmdk-1.11.1/src/test/obj_first_next/obj_first_next.vcxproj.filters0000664000000000000000000000224414123364546024130 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {410b2da7-b0a0-4cde-9074-fe5a2223083e} match {e0bdbab6-d3b6-4139-8bf0-5f4b9de0df8b} ps1 Source Files Match Files Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_first_next/.gitignore0000664000000000000000000000001714123364546020011 0ustar rootrootobj_first_next pmdk-1.11.1/src/test/obj_first_next/README0000664000000000000000000000165514123364546016712 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_first_next/README. This directory contains a unit test for POBJ_NEXT and POBJ_FIRST macros. Syntax: $ obj_first_next .. Operations: - P: - print all objects from in normal order - a:: - allocate a new object with type number equal to and set to id using constructor - r:: - remove object on internal list of objects with type number equal to - n:: - return id of + 1 object on internal list of objects with type_number equal to - f: - return id of first object on internal list of objects with type_number equal to : - 0 - objects with type number equal to 0 - 1 - objects with type number equal to 1 pmdk-1.11.1/src/test/obj_first_next/TEST10000775000000000000000000000071314123364546016612 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_first_next/TEST1 -- unit test for POBJ_FIRST macro # # Returns first object on the proper list # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_first_next$EXESUFFIX $DIR/testfile\ a:0:1 a:0:0 a:1:1 a:0:2 a:1:2 P:0 P:1\ f:0 f:1 r:0:0 r:1:0 P:0 P:1\ f:0 f:1 a:0:3 a:1:3 P:0 P:1\ f:0 f:1 check pass pmdk-1.11.1/src/test/obj_first_next/out1.log.match0000664000000000000000000000113614123364546020512 0ustar rootrootobj_first_next$(nW)TEST1: START: obj_first_next $(nW)obj_first_next$(nW) $(nW)testfile a:0:1 a:0:0 a:1:1 a:0:2 a:1:2 P:0 P:1 f:0 f:1 r:0:0 r:1:0 P:0 P:1 f:0 f:1 a:0:3 a:1:3 P:0 P:1 f:0 f:1 constructor(id = 1) constructor(id = 0) constructor(id = 1) constructor(id = 2) constructor(id = 2) type: id = 1 id = 0 id = 2 type_sec: id = 1 id = 2 first id = 1 first id = 1 type: id = 0 id = 2 type_sec: id = 2 first id = 0 first id = 2 constructor(id = 3) constructor(id = 3) type: id = $(nW) id = $(nW) id = $(nW) type_sec: id = $(nW) id = $(nW) first id = $(nW) first id = $(nW) obj_first_next$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmreorder_simple/0000775000000000000000000000000014123364546016354 5ustar rootrootpmdk-1.11.1/src/test/pmreorder_simple/pmreorder5.conf0000664000000000000000000000021014123364546021300 0ustar rootroot{ "pmem_memset_persist":"NoReorderNoCheck", "PMREORDER_MARKER_CHANGE":"ReorderFull", "PMREORDER_MARKER_UNUSED":"ReorderFull" } pmdk-1.11.1/src/test/pmreorder_simple/pmreorder0.log.match0000664000000000000000000002313614123364546022236 0ustar rootrootWARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) pmdk-1.11.1/src/test/pmreorder_simple/pmreorder2.conf0000664000000000000000000000006414123364546021304 0ustar rootroot{ "PMREORDER_MARKER_CHANGE":"NoReorderDoCheck" } pmdk-1.11.1/src/test/pmreorder_simple/pmreorder3.log.match0000664000000000000000000000136714123364546022243 0ustar rootrootWARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) WARNING:pmreorder:File $(nW)/testfile inconsistent WARNING:pmreorder:Call trace: Store [0]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [1]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) Store [2]: by 0x$(nW): write_inconsistent (pmreorder_simple.c:$(N)) by 0x$(nW): main (pmreorder_simple.c:$(N)) pmdk-1.11.1/src/test/pmreorder_simple/pmreorder_simple.c0000664000000000000000000000640714123364546022077 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * pmreorder_simple.c -- a simple unit test for store reordering * * usage: pmreorder_simple g|b|c|m file * g - write data in a consistent manner * b - write data in a possibly inconsistent manner * c - check data consistency * m - write data to the pool in a consistent way, * but at the beginning logs some inconsistent values * * See README file for more details. */ #include "unittest.h" #include "util.h" #include "valgrind_internal.h" /* * The struct three_field is inconsistent if flag is set and the fields have * different values. */ struct three_field { int first_field; int second_field; int third_field; int flag; }; /* * write_consistent -- (internal) write data in a consistent manner */ static void write_consistent(struct three_field *structp) { structp->first_field = 1; structp->second_field = 1; structp->third_field = 1; pmem_persist(&structp->first_field, sizeof(int) * 3); structp->flag = 1; pmem_persist(&structp->flag, sizeof(structp->flag)); } /* * write_inconsistent -- (internal) write data in an inconsistent manner. */ static void write_inconsistent(struct three_field *structp) { structp->flag = 1; structp->first_field = 1; structp->second_field = 1; structp->third_field = 1; pmem_persist(structp, sizeof(*structp)); } /* * check_consistency -- (internal) check struct three_field consistency */ static int check_consistency(struct three_field *structp) { int consistent = 0; if (structp->flag) consistent = (structp->first_field != structp->second_field) || (structp->first_field != structp->third_field); return consistent; } int main(int argc, char *argv[]) { START(argc, argv, "pmreorder_simple"); util_init(); if ((argc != 3) || (strchr("gbcm", argv[1][0]) == NULL) || argv[1][1] != '\0') UT_FATAL("usage: %s g|b|c|m file", argv[0]); int fd = OPEN(argv[2], O_RDWR); size_t size; /* mmap and register in valgrind pmemcheck */ void *map = pmem_map_file(argv[2], 0, 0, 0, &size, NULL); UT_ASSERTne(map, NULL); struct three_field *structp = map; char opt = argv[1][0]; /* clear the struct to get a consistent start state for writing */ if (strchr("gb", opt)) pmem_memset_persist(structp, 0, sizeof(*structp)); else if (strchr("m", opt)) { /* set test values to log an inconsistent start state */ pmem_memset_persist(&structp->flag, 1, sizeof(int)); pmem_memset_persist(&structp->first_field, 0, sizeof(int) * 2); pmem_memset_persist(&structp->third_field, 1, sizeof(int)); /* clear the struct to get back a consistent start state */ pmem_memset_persist(structp, 0, sizeof(*structp)); } /* verify that DEFAULT_REORDER restores default engine */ VALGRIND_EMIT_LOG("PMREORDER_MARKER_CHANGE.BEGIN"); switch (opt) { case 'g': write_consistent(structp); break; case 'b': write_inconsistent(structp); break; case 'm': write_consistent(structp); break; case 'c': return check_consistency(structp); default: UT_FATAL("Unrecognized option %c", opt); } VALGRIND_EMIT_LOG("PMREORDER_MARKER_CHANGE.END"); /* check if undefined marker will not cause an issue */ VALGRIND_EMIT_LOG("PMREORDER_MARKER_UNDEFINED.BEGIN"); VALGRIND_EMIT_LOG("PMREORDER_MARKER_UNDEFINED.END"); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmreorder_simple/TEST30000775000000000000000000000146214123364546017147 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST3 -- unit test for the reordering script # Tests negative case using accumulative reorder engine for section marked # as the most critical and full reorder engine for other parts of the code. # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN b $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_failure ReorderFull pmreorder3.conf "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_simple/pmreorder3.conf0000664000000000000000000000006714123364546021310 0ustar rootroot{ "PMREORDER_MARKER_CHANGE":"ReorderAccumulative" } pmdk-1.11.1/src/test/pmreorder_simple/TEST00000775000000000000000000000173414123364546017146 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST0 -- unit test for the reordering script # Tests negative case using full reorder engine for section marked as the most # critical and no_reorder_no_checker reorder engine for other parts of the # code. # This test also checks behavior for markers unused in program # but defined by user in the config file. # . ../unittest/unittest.sh # it doesn't make sense to run in local directory require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN b $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_failure NoReorderNoCheck pmreorder0.conf "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_simple/Makefile0000664000000000000000000000045414123364546020017 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/Makefile -- build pmreorder_simple # unit test # TARGET = pmreorder_simple OBJS = pmreorder_simple.o LIBPMEM=y # included for VALGRIND_EMIT_LOG LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/pmreorder_simple/TEST50000775000000000000000000000161014123364546017144 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST5 -- unit test for the reordering script # Tests positive case using full reorder engine for section marked as the most # critical and additionally enables pmreorder logs in libpmem library to test # disabling reordering of API functions # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup export PMREORDER_EMIT_LOG=1 # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN m $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success ReorderFull pmreorder$UNITTEST_NUM.conf "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_simple/TEST40000775000000000000000000000145414123364546017151 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST4 -- unit test for the reordering script # Tests positive case using partial reorder engine for section marked as # the most critical and full reorder engine for other parts of the code. # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN g $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success ReorderFull pmreorder4.conf "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_simple/.gitignore0000664000000000000000000000002114123364546020335 0ustar rootrootpmreorder_simple pmdk-1.11.1/src/test/pmreorder_simple/pmreorder0.conf0000664000000000000000000000013314123364546021277 0ustar rootroot{ "PMREORDER_MARKER_CHANGE":"ReorderFull", "PMREORDER_MARKER_UNUSED":"ReorderFull" } pmdk-1.11.1/src/test/pmreorder_simple/README0000664000000000000000000000162714123364546017242 0ustar rootrootThis is src/test/pmreorder_simple/README. This directory contains a unit test for pmreorder script. SYNOPSIS: pmreorder_simple g|b|c|m file DESCRIPTION: pmreorder_simple is the unit test for verifying the functionality of pmreorder script. OPTIONS: file is '$DIR/testfile' for all tests. b: write data to the pool in an inconsistent way g: write data to the pool in a consistent way m: write data to the pool in a consistent way, but at the beginning logs some inconsistent values c: check pool consistency The pool contains three int fields and a "written" flag. If the flag is set, all three fields have to have the same value to be consistent. When ran with 'b' all fields are written at the same time, with respect to the persistence barrier. When run with 'g' the three ints are written first and the flag is written last. The consistency check returns non-zero if the flag is set and the ints differ. pmdk-1.11.1/src/test/pmreorder_simple/TEST10000775000000000000000000000157714123364546017154 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST1 -- unit test for the reordering script # Tests positive case using full reorder engine for section marked as the most # critical and no_reorder_do_check reorder engine for other parts of the code. # This test also checks cli markers parser. # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN g $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success NoReorderDoCheck "PMREORDER_MARKER_CHANGE=ReorderFull" "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_simple/pmreorder4.conf0000664000000000000000000000006214123364546021304 0ustar rootroot{ "PMREORDER_MARKER_CHANGE":"ReorderPartial" } pmdk-1.11.1/src/test/pmreorder_simple/TEST20000775000000000000000000000152014123364546017141 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmreorder_simple/TEST2 -- unit test for the reordering script # Tests negative case using no_reorder_do_check reorder engine for section # marked as the most critical and no_reorder_no_checker reorder engine # for other parts of the code. # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup # create holey file truncate -s 4M $DIR/testfile BIN="./pmreorder_simple$EXESUFFIX" PMEMCHECK_CMD="$BIN b $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success NoReorderNoCheck pmreorder2.conf "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmem2_map_from_existing/0000775000000000000000000000000014123364546017616 5ustar rootrootpmdk-1.11.1/src/test/pmem2_map_from_existing/pmem2_map_from_existing.c0000664000000000000000000001037714123364546024604 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmem2_map_from_existing.c -- pmem2_map_from_existing unittests */ #include #include "fault_injection.h" #include "unittest.h" #include "ut_pmem2_utils.h" /* * test_two_same_mappings - try to create two the same mappings */ static int test_two_same_mappings(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map *map1 = NULL; struct pmem2_map *map2 = NULL; struct pmem2_source *src; int fd = OPEN(argv[0], O_RDWR); int ret = pmem2_source_from_fd(&src, fd); UT_ASSERTeq(ret, 0); ret = pmem2_map_from_existing(&map1, src, (void *)0xFFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map1, NULL); ret = pmem2_map_from_existing(&map2, src, (void *)0xFFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_EXISTS); UT_ASSERTeq(map2, NULL); pmem2_map_delete(&map1); CLOSE(fd); return 1; } /* * test_mapping_overlap_bottom - try to map which overlap * bottom part of existing mapping */ static int test_mapping_overlap_bottom(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map *map1 = NULL; struct pmem2_map *map2 = NULL; struct pmem2_source *src; int fd = OPEN(argv[0], O_RDWR); int ret = pmem2_source_from_fd(&src, fd); UT_ASSERTeq(ret, 0); ret = pmem2_map_from_existing(&map1, src, (void *)0xFFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map1, NULL); ret = pmem2_map_from_existing(&map2, src, (void *)0xFFF0, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_EXISTS); UT_ASSERTeq(map2, NULL); pmem2_map_delete(&map1); CLOSE(fd); return 1; } /* * test_mapping_overlap_upper - try to map which overlap * upper part of existing mapping */ static int test_mapping_overlap_upper(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map *map1 = NULL; struct pmem2_map *map2 = NULL; struct pmem2_source *src; int fd = OPEN(argv[0], O_RDWR); int ret = pmem2_source_from_fd(&src, fd); UT_ASSERTeq(ret, 0); ret = pmem2_map_from_existing(&map1, src, (void *)0x0FFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map1, NULL); ret = pmem2_map_from_existing(&map2, src, (void *)(0x0FFFF + 0x1), 0xFFFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_EXISTS); UT_ASSERTeq(map2, NULL); pmem2_map_delete(&map1); CLOSE(fd); return 1; } /* * test_map_allocation_enomem - inject enomem in to allocation of map object */ static int test_map_allocation_enomem(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map *map = NULL; struct pmem2_source *src; if (!core_fault_injection_enabled()) { return 1; } int fd = OPEN(argv[0], O_RDWR); int ret = pmem2_source_from_fd(&src, fd); UT_ASSERTeq(ret, 0); core_inject_fault_at(PMEM_MALLOC, 1, "pmem2_malloc"); ret = pmem2_map_from_existing(&map, src, (void *)0x0FFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(map, NULL); CLOSE(fd); return 1; } /* * test_register_mapping_enomem - inject enomem during adding map to ravl */ static int test_register_mapping_enomem(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map *map = NULL; struct pmem2_source *src; if (!core_fault_injection_enabled()) { return 1; } int fd = OPEN(argv[0], O_RDWR); int ret = pmem2_source_from_fd(&src, fd); UT_ASSERTeq(ret, 0); core_inject_fault_at(PMEM_MALLOC, 1, "ravl_new_node"); ret = pmem2_map_from_existing(&map, src, (void *)0x0FFFF, 0xFF, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(map, NULL); CLOSE(fd); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_two_same_mappings), TEST_CASE(test_mapping_overlap_bottom), TEST_CASE(test_mapping_overlap_upper), TEST_CASE(test_map_allocation_enomem), TEST_CASE(test_register_mapping_enomem), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_map_from_existing"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } #ifdef _MSC_VER MSVC_CONSTR(libpmem2_init) MSVC_DESTR(libpmem2_fini) #endif pmdk-1.11.1/src/test/pmem2_map_from_existing/Makefile0000664000000000000000000000061214123364546021255 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # # src/test/pmem2_map_from_existing/Makefile -- build pmem2_map unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_map_from_existing OBJS += pmem2_map_from_existing.o\ ut_pmem2_utils.o\ ut_pmem2_source.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_map_from_existing/TESTS.py0000664000000000000000000000212214123364546021067 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020-2021, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class Pmem2_from_existing(t.Test): test_type = t.Short def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') ctx.exec('pmem2_map_from_existing', self.test_case, filepath) class TEST0(Pmem2_from_existing): """try to create two the same mappings""" test_case = "test_two_same_mappings" class TEST1(Pmem2_from_existing): """try to map which overlap bottom part of existing mapping""" test_case = "test_mapping_overlap_bottom" class TEST2(Pmem2_from_existing): """try to map which overlap upper part of existing mapping""" test_case = "test_mapping_overlap_upper" class TEST3(Pmem2_from_existing): """inject enomem in to allocation of map object""" test_case = "test_map_allocation_enomem" class TEST4(Pmem2_from_existing): """inject enomem during adding map to ravl""" test_case = "test_register_mapping_enomem" pmdk-1.11.1/src/test/pmem2_map_from_existing/.gitignore0000664000000000000000000000003014123364546021577 0ustar rootrootpmem2_map_from_existing pmdk-1.11.1/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj0000664000000000000000000001344414123364546026053 0ustar rootroot Debug x64 Release x64 {E660218B-3B2D-4378-A2CD-78B865764CF1} pmem2_map_from_existing 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj.filters0000664000000000000000000000725214123364546027522 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {4557bbd3-f8c2-4d53-821f-ec79100e2b50} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Test Scripts pmdk-1.11.1/src/test/ex_libpmemobj/0000775000000000000000000000000014123364546015620 5ustar rootrootpmdk-1.11.1/src/test/ex_libpmemobj/out18.log.match0000664000000000000000000000000014123364546020364 0ustar rootrootpmdk-1.11.1/src/test/ex_libpmemobj/TEST180000775000000000000000000000064014123364546016476 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST18 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/data_store skiplist $DIR/testfile1 5 > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST7.PS10000664000000000000000000000076414123364546017022 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST7 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup @" Hello! "@| &$Env:EXAMPLES_DIR\ex_pmemobj_writer $DIR\testfile1 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_reader $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST230000775000000000000000000000067614123364546016503 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST23 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli rtree $DIR/testfile1 666 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST220000775000000000000000000000067614123364546016502 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST22 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli btree $DIR/testfile1 444 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST1.PS10000664000000000000000000000166114123364546017011 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST1 -- unit test for libpmemobj examples # . ../unittest/unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 i 1234 foo > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 i 4321 bar >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 i 1 Hello >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 i 2 World! >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 p >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_btree $DIR\testfile1 f 4321 >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST5.PS10000664000000000000000000000061414123364546017012 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST5 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_data_store btree $DIR\testfile1 5 > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST160000775000000000000000000000174614123364546016504 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST16 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug require_fs_type pmem require_pkg ncurses require_tty setup EX_PATH=../../examples/libpmemobj/pminvaders INPUT=$DIR/input.txt dd if=/dev/zero bs=1k count=4 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n oooo >> $INPUT dd if=/dev/zero bs=1k count=4 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n ppppppp >> $INPUT dd if=/dev/zero bs=1k count=4 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n ooo >> $INPUT dd if=/dev/zero bs=1k count=4 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n q >> $INPUT if [ -t 1 -a -z "$NOTTY" ] then expect_normal_exit $EX_PATH/pminvaders2 $DIR/testfile1 < $INPUT else expect_normal_exit $EX_PATH/pminvaders2 $DIR/testfile1 >/dev/null 2>/dev/null < $INPUT fi pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST22.PS10000664000000000000000000000065714123364546017100 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST22 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli btree $DIR\testfile1 444 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST240000775000000000000000000000067714123364546016505 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST24 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli rbtree $DIR/testfile1 444 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST9.PS10000664000000000000000000000100414123364546017010 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST9 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup @" Hello! "@| &$Env:EXAMPLES_DIR\ex_pmemobj_tx_type_writer $DIR\testfile1 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_tx_type_reader $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out10.log.match0000664000000000000000000000042014123364546020362 0ustar rootrootnblocks: 143360 write: 0:Hello write: 13:World! write: 20:foo write: 30:bar read: 13 World! read: 0 Hello read: 30 bar read: 20 foo read: 1 zero: 20 zero: 30 read: 13 World! read: 0 Hello read: 30 read: 20 read: 1 error: 13 read: 13 write: 13:rewrite read: 13 rewrite pmdk-1.11.1/src/test/ex_libpmemobj/TEST170000775000000000000000000000200514123364546016472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST17 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_build_type debug nondebug require_test_type medium setup EX_PATH=../../examples/libpmemobj expect_normal_exit $EX_PATH/lists $DIR/testfile1 1 foo 100 > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 2 bar 200 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 3 foo 300 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 1 bar 400 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 1 foo print >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 2 bar print >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 3 foo print >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/lists $DIR/testfile1 1 bar print >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST25.PS10000664000000000000000000000100614123364546017070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ex_libpmemobj/TEST25 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_buffons_needle_problem $DIR\testfile 100 > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_buffons_needle_problem $DIR\testfile >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST30000775000000000000000000000070214123364546016407 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST3 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli hashmap_tx $DIR/testfile1 444 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST90000775000000000000000000000100314123364546016410 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST9 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/string_store_tx_type expect_normal_exit $EX_PATH/writer $DIR/testfile1 > out$UNITTEST_NUM.log 2>&1 << EOF Hello! EOF expect_normal_exit $EX_PATH/reader $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST120000775000000000000000000000117614123364546016475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST12 -- unit test for libpmemobj examples # EX_PATH=../../examples/libpmemobj/pmemlog . ../unittest/unittest.sh # This test allocates 90M object. Flushing 90M under pmemcheck # makes this test run forever... configure_valgrind pmemcheck force-disable $EX_PATH require_test_type medium require_build_type debug nondebug setup expect_normal_exit $EX_PATH/obj_pmemlog_simple c $DIR/testfile1 \ n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r \ > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST13.PS10000664000000000000000000000072614123364546017075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST13 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_build_type debug nondebug require_test_type medium require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_obj_pmemlog_minimal c $DIR\testfile1 ` n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r ` > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out21.log.match0000664000000000000000000000011314123364546020363 0ustar rootrootseed: 666 count: 2 $(N) $(N) count: 7 $(N) $(N) $(N) $(N) $(N) $(N) $(N) pmdk-1.11.1/src/test/ex_libpmemobj/TEST130000775000000000000000000000075214123364546016475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST13 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/pmemlog expect_normal_exit $EX_PATH/obj_pmemlog_minimal c $DIR/testfile1 \ n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r \ > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST00000775000000000000000000000105714123364546016410 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST0 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug # Valgrind interprets msync as a read and hence reports a race require_fs_type pmem setup EX_PATH=../../examples/libpmemobj expect_normal_exit $EX_PATH/pi $DIR/testfile1 c 2 20 > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/pi $DIR/testfile1 p >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST250000775000000000000000000000077214123364546016502 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ex_libpmemobj/TEST25 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj expect_normal_exit $EX_PATH/buffons_needle_problem $DIR/testfile 100 > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/buffons_needle_problem $DIR/testfile >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST19.PS10000664000000000000000000000071014123364546017074 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST19 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup @" i 1234 i 4321 c 1234 r 1234 c 4321 r 4321 c 4321 q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli skiplist $DIR\testfile1 555 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST18.PS10000664000000000000000000000062014123364546017073 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST18 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_data_store skiplist $DIR\testfile1 5 > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/Makefile0000664000000000000000000000207614123364546017265 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/Makefile -- build ex_libpmemobj unittest # all: $(EXAMPLES) $(MAKE) -C $(EX_LIBPMEMOBJ) include ../Makefile.inc NCURSES := $(call check_package, ncurses) EXAMPLES=$(EX_LIBPMEMOBJ)/pi \ $(EX_LIBPMEMOBJ)/btree \ $(EX_LIBPMEMOBJ)/map/mapcli \ $(EX_LIBPMEMOBJ)/map/data_store \ $(EX_LIBPMEMOBJ)/string_store/writer \ $(EX_LIBPMEMOBJ)/string_store/reader \ $(EX_LIBPMEMOBJ)/string_store_tx/writer \ $(EX_LIBPMEMOBJ)/string_store_tx/reader \ $(EX_LIBPMEMOBJ)/string_store_tx_type/writer \ $(EX_LIBPMEMOBJ)/string_store_tx_type/reader \ $(EX_LIBPMEMOBJ)/pmemblk/obj_pmemblk \ $(EX_LIBPMEMOBJ)/pmemlog/obj_pmemlog \ $(EX_LIBPMEMOBJ)/pmemlog/obj_pmemlog_minimal \ $(EX_LIBPMEMOBJ)/pmemlog/obj_pmemlog_simple \ $(EX_LIBPMEMOBJ)/pmemlog/obj_pmemlog_macros ifeq ($(NCURSES),y) EXAMPLES += $(EX_LIBPMEMOBJ)/pminvaders/pminvaders else $(info NOTE: Skipping pminvaders test because ncurses is missing \ -- see src/examples/libpmemobj/pminvaders/README for details.) endif pmdk-1.11.1/src/test/ex_libpmemobj/TEST10w.PS10000664000000000000000000000103714123364546017255 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST10 -- unit test for libpmemobj examples # . ../unittest/unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_obj_pmemblk c $DIR\testfile1 512 ` n w:0:Hello w:13:World! w:20:foo w:30:bar ` r:13 r:0 r:30 r:20 r:1 ` z:20 z:30 ` r:13 r:0 r:30 r:20 r:1 ` e:13 r:13 w:13:rewrite r:13 ` > out$Env:UNITTEST_NUM.log 2>$null check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST3.PS10000664000000000000000000000066314123364546017014 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST3 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli hashmap_tx $DIR\testfile1 444 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST14.PS10000664000000000000000000000072514123364546017075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST14 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_build_type debug nondebug require_test_type medium require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_obj_pmemlog_macros c $DIR\testfile1 ` n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r ` > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST2.PS10000664000000000000000000000066714123364546017017 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST2 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli hashmap_atomic $DIR\testfile1 555 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST50000775000000000000000000000063414123364546016415 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST5 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/data_store btree $DIR/testfile1 5 > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out7.log.match0000664000000000000000000000000714123364546020311 0ustar rootrootHello! pmdk-1.11.1/src/test/ex_libpmemobj/TEST6.PS10000664000000000000000000000061514123364546017014 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST6 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_data_store rbtree $DIR\testfile1 5 > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST40000775000000000000000000000063414123364546016414 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST4 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/data_store ctree $DIR/testfile1 5 > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/ex_libpmemobj.vcxproj.filters0000664000000000000000000000775114123364546023532 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/ex_libpmemobj/TEST70000775000000000000000000000077314123364546016423 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST7 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/string_store expect_normal_exit $EX_PATH/writer $DIR/testfile1 > out$UNITTEST_NUM.log 2>&1 << EOF Hello! EOF expect_normal_exit $EX_PATH/reader $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST23.PS10000664000000000000000000000065714123364546017101 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST23 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli rtree $DIR\testfile1 444 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/out0.log.match0000664000000000000000000000002114123364546020276 0ustar rootrootpi: 3.0916238067 pmdk-1.11.1/src/test/ex_libpmemobj/TEST24.PS10000664000000000000000000000066014123364546017074 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST24 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli rbtree $DIR\testfile1 444 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST210000775000000000000000000000070314123364546016470 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST21 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli hashmap_rp $DIR/testfile1 666 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/out9.log.match0000664000000000000000000000000714123364546020313 0ustar rootrootHello! pmdk-1.11.1/src/test/ex_libpmemobj/TEST0.PS10000664000000000000000000000075014123364546017006 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST0 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_pi $DIR\testfile1 c 2 20 > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_pi $DIR\testfile1 p >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST17.PS10000664000000000000000000000220014123364546017066 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST17 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 1 foo 100 > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 2 bar 200 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 3 foo 300 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 1 bar 400 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 1 foo print >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 2 bar print >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 3 foo print >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_lists $DIR\testfile1 1 bar print >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out14.log.match0000664000000000000000000000043314123364546020372 0ustar rootrootnbytes: 0 offset: 0 append: Hello append: World! nbytes: 0 offset: 11 walk log contains: Hello log contains: World! rewind nbytes: 0 offset: 0 appendv: Hello:World!:bar:foo nbytes: 0 offset: 17 walk log contains: Hello log contains: World! log contains: bar log contains: foo rewind pmdk-1.11.1/src/test/ex_libpmemobj/out17.log.match0000664000000000000000000000002014123364546020365 0ustar rootroot100 200 300 400 pmdk-1.11.1/src/test/ex_libpmemobj/TEST190000775000000000000000000000073414123364546016503 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST19 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli skiplist $DIR/testfile1 555 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 c 1234 r 1234 c 4321 r 4321 c 4321 q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST12.PS10000664000000000000000000000072514123364546017073 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST12 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_build_type debug nondebug require_test_type medium require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_obj_pmemlog_simple c $DIR\testfile1 ` n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r ` > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out10w.log.match0000664000000000000000000000042014123364546020551 0ustar rootrootnblocks: 143360 write: 0:Hello write: 13:World! write: 20:foo write: 30:bar read: 13 World! read: 0 Hello read: 30 bar read: 20 foo read: 1 zero: 20 zero: 30 read: 13 World! read: 0 Hello read: 30 read: 20 read: 1 error: 13 read: 13 write: 13:rewrite read: 13 rewrite pmdk-1.11.1/src/test/ex_libpmemobj/README0000664000000000000000000000032114123364546016474 0ustar rootrootPersistent Memory Development Kit This is src/test/ex_libpmemobj/README. This directory contains unit tests for libpmemobj examples. The unit tests utilizes examples from src/examples/libpmemobj directory. pmdk-1.11.1/src/test/ex_libpmemobj/TEST21.PS10000664000000000000000000000066414123364546017075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST21 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup echo @" i 1234 i 4321 p n 5 p q "@ | &$Env:EXAMPLES_DIR\ex_pmemobj_mapcli hashmap_rp $DIR\testfile1 666 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST150000775000000000000000000000174414123364546016501 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST15 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug require_fs_type pmem require_pkg ncurses require_tty setup EX_PATH=../../examples/libpmemobj/pminvaders INPUT=$DIR/input.txt dd if=/dev/zero bs=1k count=2 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n oooo >> $INPUT dd if=/dev/zero bs=1k count=2 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n ppppppp >> $INPUT dd if=/dev/zero bs=1k count=2 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n ooo >> $INPUT dd if=/dev/zero bs=1k count=2 2>>prep$UNITTEST_NUM.log | tr '\0' ' ' >> $INPUT echo -n q >> $INPUT if [ -t 1 -a -z "$NOTTY" ] then expect_normal_exit $EX_PATH/pminvaders $DIR/testfile1 < $INPUT else expect_normal_exit $EX_PATH/pminvaders $DIR/testfile1 >/dev/null 2>/dev/null < $INPUT fi pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST140000775000000000000000000000075114123364546016475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST14 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/pmemlog expect_normal_exit $EX_PATH/obj_pmemlog_macros c $DIR/testfile1 \ n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r \ > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST60000775000000000000000000000063514123364546016417 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST6 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/data_store rbtree $DIR/testfile1 5 > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST10000775000000000000000000000150514123364546016407 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST1 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj expect_normal_exit $EX_PATH/btree $DIR/testfile1 i 1234 foo > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/btree $DIR/testfile1 i 4321 bar >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/btree $DIR/testfile1 i 1 Hello >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/btree $DIR/testfile1 i 2 World! >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/btree $DIR/testfile1 p >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/btree $DIR/testfile1 f 4321 >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST4.PS10000664000000000000000000000061414123364546017011 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST4 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_data_store ctree $DIR\testfile1 5 > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out11.log.match0000664000000000000000000000043314123364546020367 0ustar rootrootnbytes: 0 offset: 0 append: Hello append: World! nbytes: 0 offset: 11 walk log contains: Hello log contains: World! rewind nbytes: 0 offset: 0 appendv: Hello:World!:bar:foo nbytes: 0 offset: 17 walk log contains: Hello log contains: World! log contains: bar log contains: foo rewind pmdk-1.11.1/src/test/ex_libpmemobj/out6.log.match0000664000000000000000000000000014123364546020301 0ustar rootrootpmdk-1.11.1/src/test/ex_libpmemobj/TEST80000775000000000000000000000077614123364546016427 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST8 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/string_store_tx expect_normal_exit $EX_PATH/writer $DIR/testfile1 > out$UNITTEST_NUM.log 2>&1 << EOF Hello! EOF expect_normal_exit $EX_PATH/reader $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/ex_libpmemobj.vcxproj0000664000000000000000000001625414123364546022061 0ustar rootroot Debug x64 Release x64 {0fb8f0fd-276c-413b-97a8-67abe0c9043b} {2cd7408e-2f60-43c3-aceb-c7d58cdd8462} {5b2b9c0d-1b6d-4357-8307-6de1ee0a41a3} {bb248bac-6e1b-433c-a254-75140a273ab5} {11d76fbc-dfaa-4b31-9db0-206e171e3f94} {8c42ca7c-1543-4f1b-a55f-28cd419c7d35} {60206d22-e132-4695-8486-10beca32c5cc} {06877fed-15ba-421f-85c9-1a964fb97446} {0056b0b6-cb3e-4f0e-b6dc-48d59cb8e235} {5db2e259-0d19-4a89-b8ec-b2912f39924d} {0bfd78aa-fd94-4db1-8495-8f5cc06d8f03} {59d7a9cd-9912-40e4-96e1-8a873f777f62} {74d655d5-f661-4887-a1eb-5a6222af5fca} {F63FB47F-1DCE-48E5-9CBD-F3E0A354472B} ex_libpmemobj 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/ex_libpmemobj/out13.log.match0000664000000000000000000000043114123364546020367 0ustar rootrootnbytes: 0 offset: 0 append: Hello append: World! nbytes: 0 offset: 0 walk log contains: Hello log contains: World! rewind nbytes: 0 offset: 0 appendv: Hello:World!:bar:foo nbytes: 0 offset: 0 walk log contains: Hello log contains: World! log contains: bar log contains: foo rewind pmdk-1.11.1/src/test/ex_libpmemobj/TEST8.PS10000664000000000000000000000077214123364546017022 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST8 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup @" Hello! "@| &$Env:EXAMPLES_DIR\ex_pmemobj_tx_writer $DIR\testfile1 > out$Env:UNITTEST_NUM.log 2>&1 check_exit_code expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_tx_reader $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out1.log.match0000664000000000000000000000004714123364546020307 0ustar rootroot1 Hello 2 World! 1234 foo 4321 bar bar pmdk-1.11.1/src/test/ex_libpmemobj/TEST100000775000000000000000000000110214123364546016460 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST10 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/pmemblk expect_normal_exit $EX_PATH/obj_pmemblk c $DIR/testfile1 512 \ n w:0:Hello w:13:World! w:20:foo w:30:bar \ r:13 r:0 r:30 r:20 r:1 \ z:20 z:30 \ r:13 r:0 r:30 r:20 r:1 \ e:13 r:13 w:13:rewrite r:13 \ > out$UNITTEST_NUM.log 2>err$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST20000775000000000000000000000070614123364546016412 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST2 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/map expect_normal_exit $EX_PATH/mapcli hashmap_atomic $DIR/testfile1 555 > out$UNITTEST_NUM.log 2>&1 << EOF i 1234 i 4321 p n 5 p q EOF check pass pmdk-1.11.1/src/test/ex_libpmemobj/TEST11.PS10000664000000000000000000000071614123364546017072 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST11 -- unit test for libpmemobj examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemobj_obj_pmemlog c $DIR\testfile1 ` n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r ` > out$Env:UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/ex_libpmemobj/out5.log.match0000664000000000000000000000000014123364546020300 0ustar rootrootpmdk-1.11.1/src/test/ex_libpmemobj/out3.log.match0000664000000000000000000000011314123364546020303 0ustar rootrootseed: 444 count: 2 $(N) $(N) count: 7 $(N) $(N) $(N) $(N) $(N) $(N) $(N) pmdk-1.11.1/src/test/ex_libpmemobj/out4.log.match0000664000000000000000000000000014123364546020277 0ustar rootrootpmdk-1.11.1/src/test/ex_libpmemobj/out8.log.match0000664000000000000000000000000714123364546020312 0ustar rootrootHello! pmdk-1.11.1/src/test/ex_libpmemobj/err10.log.match0000664000000000000000000000005014123364546020342 0ustar rootrootpmemblk_read failed: Input/output error pmdk-1.11.1/src/test/ex_libpmemobj/out2.log.match0000664000000000000000000000011314123364546020302 0ustar rootrootseed: 555 count: 2 $(N) $(N) count: 7 $(N) $(N) $(N) $(N) $(N) $(N) $(N) pmdk-1.11.1/src/test/ex_libpmemobj/out12.log.match0000664000000000000000000000037314123364546020373 0ustar rootrootnbytes: 94371824 offset: 0 append: Hello append: World! nbytes: 94371824 offset: 11 walk log contains: HelloWorld! rewind nbytes: 94371824 offset: 0 appendv: Hello:World!:bar:foo nbytes: 94371824 offset: 17 walk log contains: HelloWorld!barfoo rewind pmdk-1.11.1/src/test/ex_libpmemobj/out19.log.match0000664000000000000000000000002014123364546020367 0ustar rootrootseed: 555 1 1 0 pmdk-1.11.1/src/test/ex_libpmemobj/TEST110000775000000000000000000000074214123364546016472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/ex_libpmemobj/TEST11 -- unit test for libpmemobj examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemobj/pmemlog expect_normal_exit $EX_PATH/obj_pmemlog c $DIR/testfile1 \ n t a:Hello a:World! n t w r n t v:Hello:World!:bar:foo n t w r \ > out$UNITTEST_NUM.log 2>&1 check pass pmdk-1.11.1/src/test/pmempool_transform/0000775000000000000000000000000014123364546016727 5ustar rootrootpmdk-1.11.1/src/test/pmempool_transform/out18.log.match0000664000000000000000000000543114123364546021510 0ustar rootrootpoolset_in PMEMPOOLSET AUTO $(nW) AUTO $(nW) REPLICA $(nW) $(nW)part00 1G $(nW)part01 poolset_out PMEMPOOLSET OPTION SINGLEHDR AUTO $(nW) AUTO $(nW) REPLICA $(nW) $(nW)part00 1G $(nW)part01 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Replica 1 - local, 2 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST180000775000000000000000000000571714123364546017617 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST18 -- test for transform with SINGLEHDR option # # removing the SINGLEHDR option # case: two replicas: # 1. two 4KB-aligned device daxes # 2. three file-based parts # revert transformation hdrs->nohdrs (TEST14) # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_4KB $SIZE_4KB require_max_devdax_size 0 $PMEMOBJ_MAX_ALLOC_SIZE # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup # test requires at least (size of device DAX #0 + 1G) of free space in $DIR DAX_SIZE[0]=$(get_devdax_size 0) SIZE_1G=$(convert_to_bytes 1G) require_free_space $(( DAX_SIZE[0] + SIZE_1G )) dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ 1G:$DIR/part01:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ 1G:$DIR/part01:x OFFSET=${DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Transform poolset back expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_OUT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[1]} >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part01 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST2w.PS10000664000000000000000000000400014123364546020276 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST2 -- test for checking pmempool transform in dry-run # mode; pmem/issues#250 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile0:x ` 20M:$DIR\testfile1:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile0:x ` 20M:$DIR\testfile1:x ` R ` 20M:$DIR\testfile2:x ` 20M:$DIR\testfile3:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 22M srcp 0 TestOK111 srcp 20M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Run transform in dry-run mode expect_normal_exit $PMEMPOOL transform -d $POOLSET_IN $POOLSET_OUT >> $LOG cat $LOG >> $LOG_TEMP # Check if stored data can be read expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR\testfile0 >> $LOG_TEMP dump_pool_info $DIR\testfile1 >> $LOG_TEMP # Make sure no other parts were created check_no_files $DIR\testfile2 $DIR\testfile3 mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST230000775000000000000000000000406014123364546017601 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST23 -- test for transforming poolsets with SINGLEHDR option # # case: dry run for adding the SINGLEHDR option # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Dry run for transforming the poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform -d $POOLSET_IN $POOLSET_OUT \ >> $LOG_TEMP # Check if not transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part01 >> $LOG_TEMP dump_pool_info $DIR/part02 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST220000775000000000000000000000537214123364546017607 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST22 -- test for transforming poolset with SINGLEHDR option # # case: adding a second device-dax-based replica with different alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_4KB $SIZE_4KB $SIZE_2MB $SIZE_2MB require_max_devdax_size 0 $PMEMOBJ_MAX_ALLOC_SIZE # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup dax_device_zero LOG=out${UNITTEST_NUM}.log ERR_LOG=err${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP rm -f $ERR_LOG && touch $ERR_LOG LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Make sure the total size of devices 2/3 is not smaller than devices 0/1. # If this is the case, swap devices. SIZE1=$(($(get_devdax_size 0) + $(get_devdax_size 1))) SIZE2=$(($(get_devdax_size 2) + $(get_devdax_size 3))) if [ $SIZE1 -gt $SIZE2 ]; then TMP=${DEVICE_DAX_PATH[0]} DEVICE_DAX_PATH[0]=${DEVICE_DAX_PATH[2]} DEVICE_DAX_PATH[2]=$TMP TMP=${DEVICE_DAX_PATH[1]} DEVICE_DAX_PATH[1]=${DEVICE_DAX_PATH[3]} DEVICE_DAX_PATH[3]=$TMP fi # Create poolset files create_poolset $POOLSET_IN \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[2]}:x \ AUTO:${DEVICE_DAX_PATH[3]}:x \ R \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x DAX_SIZE[0]=$(get_devdax_size 0) OFFSET=${DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if data is still correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[2]} >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out15.log.match0000664000000000000000000000340714123364546021506 0ustar rootrootpoolset_in PMEMPOOLSET AUTO $(nW) AUTO $(nW) poolset_out PMEMPOOLSET OPTION SINGLEHDR AUTO $(nW) AUTO $(nW) pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST1.PS10000664000000000000000000000403714123364546020120 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST1 -- test for checking pmempool transform; # adding a replica # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x ` R ` 10M:$DIR\testfile5:x ` 20M:$DIR\testfile6:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 22M srcp 0 TestOK111 srcp 20M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Transform poolset $FLAGS = "0" expect_normal_exit $PMEMPOOL transform $POOLSET_IN $POOLSET_OUT $FLAGS >> $LOG cat $LOG >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT >> $LOG_TEMP # Check metadata by pmempool info for ($i=0; $i -lt 7; $i++) { dump_pool_info "$DIR\testfile$i" >> $LOG_TEMP } mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST160000775000000000000000000000476214123364546017614 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST16 -- test for transforming poolset with SINGLEHDR option # # case: adding a device-dax-based replica with 2MB alignment to a poolset with # SINGLEHDR option # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_2MB $SIZE_2MB require_max_devdax_size 0 $PMEMOBJ_MAX_ALLOC_SIZE # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup DAX_SIZE[0]=$(get_devdax_size 0) DAX_SIZE[1]=$(get_devdax_size 1) require_free_space $(( DAX_SIZE[0] + DAX_SIZE[1] )) dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ O SINGLEHDR \ ${DAX_SIZE[0]}:$DIR/part00:x \ ${DAX_SIZE[1]}:$DIR/part01:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ ${DAX_SIZE[1]}:$DIR/part01:x OFFSET=${DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out24.log.match0000664000000000000000000000362014123364546021503 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 poolset_out PMEMPOOLSET OPTION SINGLEHDR 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 pr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out5w.log.match0000664000000000000000000000537414123364546021621 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 20M $(nW)testfile02 REPLICA 60M $(nW)testfile10 poolset_out PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 20M $(nW)testfile02 REPLICA 90M $(nW)testfile10 pr(52428800): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) part 2: path : $(nW)testfile02 type : regular file size : $(nW) Replica 1 - local, 1 part(s): part 0: path : $(nW)testfile10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST240000775000000000000000000000414314123364546017604 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST24 -- test for transforming poolsets with SINGLEHDR option # # case: dry run for removing the SINGLEHDR option # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Transform the poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Dry run for transforming the poolset back expect_normal_exit $PMEMPOOL$EXESUFFIX transform -d $POOLSET_OUT $POOLSET_IN \ >> $LOG_TEMP # Check if not transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/err12.log.match0000664000000000000000000000017014123364546021456 0ustar rootrooterror: Invalid argument error: failed to transform $(nW)poolset.2 -> $(nW)poolset.3: parsing destination poolset failed pmdk-1.11.1/src/test/pmempool_transform/out4w.log.match0000664000000000000000000000633114123364546021612 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 REPLICA 15M $(nW)part10 15M $(nW)part11 poolset_out1 PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 poolset_out2 PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 REPLICA 15M $(nW)part10 15M $(nW)part11 20M $(nW)part12 pr(26214400): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) Replica 1 - local, 3 part(s): part 0: path : $(nW)part10 type : regular file size : $(nW) part 1: path : $(nW)part11 type : regular file size : $(nW) part 2: path : $(nW)part12 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part11 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part12 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out3w.log.match0000664000000000000000000000270714123364546021614 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 poolset_out PMEMPOOLSET 20M $(nW)testfile00 REPLICA 20M $(nW)testfile10 1M $(nW)testfile11 pr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK111 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out10.log.match0000664000000000000000000000221514123364546021475 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 poolset_out PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile01 20M $(nW)testfile21 error: Invalid argument error: failed to transform $(nW)poolset.in -> $(nW)poolset.out: some part file's path is used multiple times Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : 0x0 pmdk-1.11.1/src/test/pmempool_transform/out16.log.match0000664000000000000000000000421114123364546021501 0ustar rootrootpoolset_in PMEMPOOLSET OPTION SINGLEHDR $(nW) $(nW)part00 $(nW) $(nW)part01 poolset_out PMEMPOOLSET OPTION SINGLEHDR AUTO $(nW) AUTO $(nW) REPLICA $(nW) $(nW)part00 $(nW) $(nW)part01 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : 2097152 part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Replica 1 - local, 2 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST170000775000000000000000000000452214123364546017607 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST17 -- test for transform with SINGLEHDR option # # removing the SINGLEHDR option # case: single file-based replica with three parts # revert transformation hdrs->nohdrs (TEST13) # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Transform poolset back expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_OUT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part01 >> $LOG_TEMP dump_pool_info $DIR/part02 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST30000775000000000000000000000370114123364546017520 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST3 -- test for checking pmempool transform; # pmem/issues#252 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile00:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile00:x \ R \ 20M:$DIR/testfile10:x \ 1M:$DIR/testfile11:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 15M srcp 0 TestOK111 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_abnormal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>&1 # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR/testfile00 >> $LOG_TEMP # Make sure no other parts were created check_no_files $DIR/testfile10 $DIR/testfile11 mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST90000775000000000000000000000414114123364546017525 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST9 -- test for checking pmempool transform; # remove master replica as dax device, # another dax device as the second replica # . ../unittest/unittest.sh require_test_type medium require_dax_devices 2 require_fs_type any setup dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out HDR_LEN=4096 # Create poolset files create_poolset $POOLSET_IN \ AUTO:${DEVICE_DAX_PATH[0]}:x \ r \ AUTO:${DEVICE_DAX_PATH[1]}:x create_poolset $POOLSET_OUT \ AUTO:${DEVICE_DAX_PATH[1]}:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 1M srcp 0 TestOK111 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[1]} >> $LOG_TEMP # Check if dax device's header is cleaned expect_normal_exit $CMPMAP$EXESUFFIX -z -l $HDR_LEN ${DEVICE_DAX_PATH[0]} mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out23.log.match0000664000000000000000000000433114123364546021502 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 poolset_out PMEMPOOLSET OPTION SINGLEHDR 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 pr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST120000775000000000000000000000506214123364546017602 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST12 -- test for transform with SINGLEHDR option # # removing the SINGLEHDR option # case: a single replica with two 2MB-aligned device daxes - should fail # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_2MB $SIZE_2MB require_max_devdax_size 0 $PMEMOBJ_MAX_ALLOC_SIZE # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup DAX_SIZE[0]=$(get_devdax_size 0) SIZE_512M=$(convert_to_bytes 512M) require_free_space $(( DAX_SIZE[0] + SIZE_512M )) dax_device_zero LOG=out${UNITTEST_NUM}.log ERR_LOG=err${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_1=$DIR/poolset.1 POOLSET_2=$DIR/poolset.2 POOLSET_3=$DIR/poolset.3 # Create poolset files create_poolset $POOLSET_1 \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ 512M:$DIR/part01:x create_poolset $POOLSET_2 \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ create_poolset $POOLSET_3 \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ OFFSET=${DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_1 \ >> $LOG_TEMP # Remove the second replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_1 $POOLSET_2 >> \ $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_2 >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_2 >> \ $LOG_TEMP # Make an attempt to transform the poolset expect_abnormal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_2 $POOLSET_3 2> $ERR_LOG > /dev/null # Check if data is still correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_2 >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_2 >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/pmempool_transform.vcxproj.filters0000664000000000000000000000341114123364546025735 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/pmempool_transform/out21.log.match0000664000000000000000000000322014123364546021474 0ustar rootrootpr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part10 type : regular file size : $(nW) part 1: path : $(nW)part11 type : regular file size : $(nW) part 2: path : $(nW)part12 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST130000775000000000000000000000374714123364546017613 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST13 -- test for transform with SINGLEHDR option # # adding the SINGLEHDR option # case: single file-based replica with three parts # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST200000775000000000000000000000360614123364546017603 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST20 -- test for transforming poolset with SINGLEHDR option # # case: adding a replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 40M:$DIR/part10:x \ 11M:$DIR/part11:x \ 10M:$DIR/part12:x \ R \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part10 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST00000775000000000000000000000361314123364546017517 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST0 -- test for checking pmempool transform; # removing replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x \ R \ 10M:$DIR/testfile5:x \ 20M:$DIR/testfile6:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 22M srcp 0 TestOK111 srcp 20M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info for i in `seq 0 4` do dump_pool_info $DIR/testfile$i >> $LOG_TEMP done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/Makefile0000664000000000000000000000032514123364546020367 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/pmempool_transform/Makefile -- build pmempool transform test # USE_PMEMOBJCLI=y USE_DDMAP=y include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_transform/TEST10w.PS10000664000000000000000000000243514123364546020367 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST10 -- test for checking pmempool transform; # pmem/issues#285 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x ` r ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile21:x # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo "" >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Try to transform poolset expect_abnormal_exit $PMEMPOOL transform ` $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>$null # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST50000775000000000000000000000424214123364546017523 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST5 -- test for checking pmempool transform; # pmem/issues#262 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ R \ 60M:$DIR/testfile10:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ R \ 90M:$DIR/abc/testfile10:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 50M srcp 0 TestOK111 srcp 25M TestOK222 srcp 45M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 25M 9 srpr 45M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Try to transform the poolset expect_abnormal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>&1 # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR/testfile00 >> $LOG_TEMP dump_pool_info $DIR/testfile01 >> $LOG_TEMP dump_pool_info $DIR/testfile02 >> $LOG_TEMP dump_pool_info $DIR/testfile10 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out7.log.match0000664000000000000000000000330214123364546021421 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 poolset_out PMEMPOOLSET 20M $(nW)part00 REPLICA AUTO $(nW) pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK111 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) Replica 1 - local, 1 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x$(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST40000775000000000000000000000512414123364546017522 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST4 -- test for checking pmempool transform; # pmem/issues#261 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT1=$DIR/poolset.out1 POOLSET_OUT2=$DIR/poolset.out2 # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ r \ 15M:$DIR/part10:x \ 15M:$DIR/part11:x create_poolset $POOLSET_OUT1 \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x create_poolset $POOLSET_OUT2 \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ r \ 15M:$DIR/part10:x \ 15M:$DIR/part11:x \ 20M:$DIR/part12:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 25M srcp 0 TestOK111 srcp 21M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 21M 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out1 >> $LOG_TEMP cat $POOLSET_OUT1 >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out2 >> $LOG_TEMP cat $POOLSET_OUT2 >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset - remove the smaller replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT1 >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT1 >> \ $LOG_TEMP # Transform poolset - add a larger replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_OUT1 $POOLSET_OUT2 >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT2 >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT2 >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part01 >> $LOG_TEMP dump_pool_info $DIR/part10 >> $LOG_TEMP dump_pool_info $DIR/part11 >> $LOG_TEMP dump_pool_info $DIR/part12 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST70000775000000000000000000000403114123364546017521 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST7 -- test for checking pmempool transform; # add replica with dax device # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 require_fs_type any setup dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out HDR_LEN=4096 # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x create_poolset $POOLSET_OUT \ 20M:$DIR/part00:x \ r \ AUTO:${DEVICE_DAX_PATH[0]}:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 1M srcp 0 TestOK111 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Clean the dax devices expect_normal_exit $DDMAP$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -n $HDR_LEN -b 1 # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out2w.log.match0000664000000000000000000000306114123364546021605 0ustar rootrootpr(23068672): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile0 type : regular file size : $(nW) part 1: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out0.log.match0000664000000000000000000000343414123364546021420 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Part file: path : $(nW)testfile0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile2 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile3 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile4 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST210000775000000000000000000000354014123364546017601 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST21 -- test for transforming poolset with SINGLEHDR option # # case: removing a replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x \ R \ 40M:$DIR/part10:x \ 11M:$DIR/part11:x \ 10M:$DIR/part12:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ 40M:$DIR/part10:x \ 11M:$DIR/part11:x \ 10M:$DIR/part12:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part10 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out9.log.match0000664000000000000000000000270514123364546021431 0ustar rootrootpoolset_in PMEMPOOLSET AUTO $(nW) REPLICA AUTO $(nW) poolset_out PMEMPOOLSET AUTO $(nW) pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK111 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x$(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x$(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST0.PS10000664000000000000000000000377214123364546020124 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST0 -- test for checking pmempool transform; # removing replica # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x ` R ` 10M:$DIR\testfile5:x ` 20M:$DIR\testfile6:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 22M srcp 0 TestOK111 srcp 20M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL transform $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT >> $LOG_TEMP # Check metadata by pmempool info for ($i=0; $i -lt 5; $i++) { dump_pool_info "$DIR\testfile$i" >> $LOG_TEMP } mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out14.log.match0000664000000000000000000000421414123364546021502 0ustar rootrootpoolset_in PMEMPOOLSET AUTO $(nW) AUTO $(nW) REPLICA $(nW) $(nW)part00 1G $(nW)part01 poolset_out PMEMPOOLSET OPTION SINGLEHDR AUTO $(nW) AUTO $(nW) REPLICA $(nW) $(nW)part00 1G $(nW)part01 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(nW) Replica 1 - local, 2 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out17.log.match0000664000000000000000000000436714123364546021516 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 poolset_out PMEMPOOLSET OPTION SINGLEHDR 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 pr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST190000775000000000000000000000630514123364546017612 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST19 -- test for transform with SINGLEHDR option # # removing the SINGLEHDR option # case: two replicas larger than the pool size, able to embrace new headers # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_1=$DIR/poolset.1 POOLSET_2=$DIR/poolset.2 POOLSET_3=$DIR/poolset.3 POOLSET_4=$DIR/poolset.4 POOLSET_5=$DIR/poolset.5 # Create poolset files create_poolset $POOLSET_1 \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x create_poolset $POOLSET_2 \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x \ R \ 20M:$DIR/part10:x \ 20M:$DIR/part11:x \ 20M:$DIR/part12:x \ 10M:$DIR/part13:x create_poolset $POOLSET_3 \ O SINGLEHDR \ 20M:$DIR/part10:x \ 20M:$DIR/part11:x \ 20M:$DIR/part12:x \ 10M:$DIR/part13:x create_poolset $POOLSET_4 \ O SINGLEHDR \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x \ 10M:$DIR/part03:x \ R \ 20M:$DIR/part10:x \ 20M:$DIR/part11:x \ 20M:$DIR/part12:x \ 10M:$DIR/part13:x create_poolset $POOLSET_5 \ 20M:$DIR/part00:x \ 20M:$DIR/part01:x \ 20M:$DIR/part02:x \ 10M:$DIR/part03:x \ R \ 20M:$DIR/part10:x \ 20M:$DIR/part11:x \ 20M:$DIR/part12:x \ 10M:$DIR/part13:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 45M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 srpr 40M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_1 \ >> $LOG_TEMP # Transform poolset - add a second, larger, replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_1 $POOLSET_2 >> \ $LOG_TEMP # Transform poolset - remove the first replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_2 $POOLSET_3 >> \ $LOG_TEMP # Transform poolset - add a second larger replica expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_3 $POOLSET_4 >> \ $LOG_TEMP # Write some data into the pool, hitting all the part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_4 >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_4 >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_4 $POOLSET_5 >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_5 >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_5 >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP dump_pool_info $DIR/part01 >> $LOG_TEMP dump_pool_info $DIR/part02 >> $LOG_TEMP dump_pool_info $DIR/part03 >> $LOG_TEMP dump_pool_info $DIR/part10 >> $LOG_TEMP dump_pool_info $DIR/part11 >> $LOG_TEMP dump_pool_info $DIR/part12 >> $LOG_TEMP dump_pool_info $DIR/part13 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out10w.log.match0000664000000000000000000000173114123364546021666 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 poolset_out PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile01 20M $(nW)testfile21 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : 0x0 pmdk-1.11.1/src/test/pmempool_transform/README0000664000000000000000000000030214123364546017602 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_transform/README. This directory contains unit tests for pmempool transform. The tests check if adding and deleting replicas works. pmdk-1.11.1/src/test/pmempool_transform/TEST3w.PS10000664000000000000000000000403014123364546020302 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST3 -- test for checking pmempool transform; # pmem/issues#252 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile00:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile00:x ` R ` 20M:$DIR\testfile10:x ` 1M:$DIR\testfile11:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 15M srcp 0 TestOK111 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo "" >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Transform poolset expect_abnormal_exit $PMEMPOOL transform ` $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>$null # Check if correctly read expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR\testfile00 >> $LOG_TEMP # Make sure no other parts were created check_no_files $DIR\testfile10 $DIR\testfile11 mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out20.log.match0000664000000000000000000000420614123364546021500 0ustar rootrootpr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part10 type : regular file size : $(nW) part 1: path : $(nW)part11 type : regular file size : $(nW) part 2: path : $(nW)part12 type : regular file size : $(nW) Replica 1 - local, 3 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST150000775000000000000000000000512714123364546017607 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST15 -- test for transform with SINGLEHDR option # # removing the SINGLEHDR option # case: single replica with two 4KB-aligned device daxes # revert transformation hdrs->nohdrs (TEST11) # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_4KB $SIZE_4KB # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup OFFSET=$(get_devdax_size 0) ROOT_SIZE=$[OFFSET + 8192] MAX_SIZE=$[PMEMOBJ_MAX_ALLOC_SIZE - 8192] require_max_devdax_size 0 $MAX_SIZE dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Transform poolset back expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_OUT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[1]} >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST140000775000000000000000000000513214123364546017602 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST14 -- test for transform with SINGLEHDR option # # adding the SINGLEHDR option # case: two replicas: # 1. two 4KB-aligned device daxes # 2. three file-based parts # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_4KB $SIZE_4KB require_max_devdax_size 0 $PMEMOBJ_MAX_ALLOC_SIZE # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup # test requires at least (size of device DAX #0 + 1G) of free space in $DIR DAX_SIZE[0]=$(get_devdax_size 0) SIZE_1G=$(convert_to_bytes 1G) require_free_space $(( DAX_SIZE[0] + SIZE_1G )) dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ 1G:$DIR/part01:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x \ R \ ${DAX_SIZE[0]}:$DIR/part00:x \ 1G:$DIR/part01:x OFFSET=${DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST60000775000000000000000000000315714123364546017530 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST6 -- test for checking pmempool transform; # pmem/issues#274 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT1=$DIR/poolset.out1 POOLSET_OUT2=$DIR/poolset.out2 # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x create_poolset $POOLSET_OUT1 \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x \ R \ 20M:$DIR/testfile10:x \ 20M:$DIR/testfile11:x create_poolset $POOLSET_OUT2 \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x \ R \ 20M:$DIR/testfile20:x \ 20M:$DIR/testfile21:x # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out1 >> $LOG_TEMP cat $POOLSET_OUT1 >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out2 >> $LOG_TEMP cat $POOLSET_OUT2 >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT1 >> $LOG_TEMP # Try to transform poolset again expect_abnormal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT2 >> $LOG_TEMP 2>&1 # Check metadata by pmempool info dump_pool_info $POOLSET_OUT1 >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST6w.PS10000664000000000000000000000325714123364546020317 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST6 -- test for checking pmempool transform; # pmem/issues#274 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT1 = "$DIR\poolset.out1" $POOLSET_OUT2 = "$DIR\poolset.out2" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x create_poolset $POOLSET_OUT1 ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x ` R ` 20M:$DIR\testfile10:x ` 20M:$DIR\testfile11:x create_poolset $POOLSET_OUT2 ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x ` R ` 20M:$DIR\testfile20:x ` 20M:$DIR\testfile21:x # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out1 >> $LOG_TEMP cat $POOLSET_OUT1 >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out2 >> $LOG_TEMP cat $POOLSET_OUT2 >> $LOG_TEMP echo "" >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL transform $POOLSET_IN $POOLSET_OUT1 >> $LOG_TEMP # Try to transform poolset again expect_abnormal_exit $PMEMPOOL transform ` $POOLSET_IN $POOLSET_OUT2 >> $LOG_TEMP 2>$null # Check metadata by pmempool info dump_pool_info $POOLSET_OUT1 >> $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST10000775000000000000000000000365314123364546017524 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST1 -- test for checking pmempool transform; # adding a replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x \ R \ 10M:$DIR/testfile5:x \ 20M:$DIR/testfile6:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 22M srcp 0 TestOK111 srcp 20M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset FLAGS=0 expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT $FLAGS >> $LOG cat $LOG >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info for i in `seq 0 6` do dump_pool_info $DIR/testfile$i >> $LOG_TEMP done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/pmempool_transform.vcxproj0000664000000000000000000001024314123364546024267 0ustar rootroot Debug x64 Release x64 {7dc3b3dd-73ed-4602-9af3-8d7053620dea} {26166DF1-3C94-44AF-9075-BA31DCD2F6BB} pmempool_transform 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/pmempool_transform/TEST4.PS10000664000000000000000000000520114123364546020115 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST4 -- test for checking pmempool transform; # pmem/issues#261 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT1 = "$DIR\poolset.out1" $POOLSET_OUT2 = "$DIR\poolset.out2" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\part00:x ` 20M:$DIR\part01:x ` r ` 15M:$DIR\part10:x ` 15M:$DIR\part11:x create_poolset $POOLSET_OUT1 ` 20M:$DIR\part00:x ` 20M:$DIR\part01:x create_poolset $POOLSET_OUT2 ` 20M:$DIR\part00:x ` 20M:$DIR\part01:x ` r ` 15M:$DIR\part10:x ` 15M:$DIR\part11:x ` 20M:$DIR\part12:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 25M srcp 0 TestOK111 srcp 21M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 21M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out1 >> $LOG_TEMP cat $POOLSET_OUT1 >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out2 >> $LOG_TEMP cat $POOLSET_OUT2 >> $LOG_TEMP echo "" >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Transform poolset - remove the smaller replica expect_normal_exit $PMEMPOOL transform $POOLSET_IN $POOLSET_OUT1 >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT1 >> $LOG_TEMP # Transform poolset - add a larger replica expect_normal_exit $PMEMPOOL transform $POOLSET_OUT1 $POOLSET_OUT2 >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT2 >> $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT2 >> $LOG_TEMP dump_pool_info $DIR\part00 >> $LOG_TEMP dump_pool_info $DIR\part01 >> $LOG_TEMP dump_pool_info $DIR\part10 >> $LOG_TEMP dump_pool_info $DIR\part11 >> $LOG_TEMP dump_pool_info $DIR\part12 >> $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out11.log.match0000664000000000000000000000327414123364546021504 0ustar rootrootpoolset_in PMEMPOOLSET AUTO $(nW) AUTO $(nW) poolset_out PMEMPOOLSET OPTION SINGLEHDR AUTO $(nW) AUTO $(nW) pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out6.log.match0000664000000000000000000000301414123364546021420 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 poolset_out1 PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile10 20M $(nW)testfile11 poolset_out2 PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile20 20M $(nW)testfile21 error: Invalid argument error: failed to transform $(nW)poolset.in -> $(nW)poolset.out2: source poolset health check failed Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) Replica 1 - local, 2 part(s): part 0: path : $(nW)testfile10 type : regular file size : $(nW) part 1: path : $(nW)estfile11 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : 0x0 pmdk-1.11.1/src/test/pmempool_transform/TEST80000775000000000000000000000406614123364546017532 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST8 -- test for checking pmempool transform; # remove replica with dax device, # regular file as the master replica # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 require_fs_type any setup dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out HDR_LEN=4096 # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/part00:x \ r \ AUTO:${DEVICE_DAX_PATH[0]}:x create_poolset $POOLSET_OUT \ 20M:$DIR/part00:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 1M srcp 0 TestOK111 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP # Check if correctly read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info $DIR/part00 >> $LOG_TEMP # Check if dax device's header is cleaned expect_normal_exit $CMPMAP$EXESUFFIX -z -l $HDR_LEN ${DEVICE_DAX_PATH[0]} mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out13.log.match0000664000000000000000000000362014123364546021501 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 poolset_out PMEMPOOLSET OPTION SINGLEHDR 20M $(nW)part00 20M $(nW)part01 20M $(nW)part02 pr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out22.log.match0000664000000000000000000000402114123364546021475 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Replica 1 - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out6w.log.match0000664000000000000000000000254114123364546021613 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 poolset_out1 PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile10 20M $(nW)testfile11 poolset_out2 PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 REPLICA 20M $(nW)testfile20 20M $(nW)testfile21 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) Replica 1 - local, 2 part(s): part 0: path : $(nW)testfile10 type : regular file size : $(nW) part 1: path : $(nW)estfile11 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : 0x0 pmdk-1.11.1/src/test/pmempool_transform/TEST5w.PS10000664000000000000000000000441014123364546020306 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST5 -- test for checking pmempool transform; # pmem/issues#262 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` R ` 60M:$DIR\testfile10:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile00:x ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` R ` 90M:$DIR\abc\testfile10:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 50M srcp 0 TestOK111 srcp 25M TestOK222 srcp 45M TestOK333 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 25M 9 srpr 45M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo "" >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo "" >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Try to transform the poolset expect_abnormal_exit $PMEMPOOL transform ` $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>$null # Check if correctly read expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN >> $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR\testfile00 >> $LOG_TEMP dump_pool_info $DIR\testfile01 >> $LOG_TEMP dump_pool_info $DIR\testfile02 >> $LOG_TEMP dump_pool_info $DIR\testfile10 >> $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out1.log.match0000664000000000000000000000472614123364546021426 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Part file: path : $(nW)testfile0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile2 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile3 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile4 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile5 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile6 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST100000775000000000000000000000237414123364546017603 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST10 -- test for checking pmempool transform; # pmem/issues#285 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile00:x \ 20M:$DIR/testfile01:x \ r \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile21:x # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Try to transform poolset expect_abnormal_exit $PMEMPOOL$EXESUFFIX transform \ $POOLSET_IN $POOLSET_OUT >> $LOG_TEMP 2>&1 # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/TEST20000775000000000000000000000366114123364546017524 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_transform/TEST2 -- test for checking pmempool transform in dry-run # mode; pmem/issues#250 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile0:x \ 20M:$DIR/testfile1:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile0:x \ 20M:$DIR/testfile1:x \ R \ 20M:$DIR/testfile2:x \ 20M:$DIR/testfile3:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 22M srcp 0 TestOK111 srcp 20M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Run transform in dry-run mode expect_normal_exit $PMEMPOOL$EXESUFFIX transform -d \ $POOLSET_IN $POOLSET_OUT>> $LOG cat $LOG >> $LOG_TEMP # Check if stored data can be read expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_IN >> $LOG_TEMP dump_pool_info $DIR/testfile0 >> $LOG_TEMP dump_pool_info $DIR/testfile1 >> $LOG_TEMP # Make sure no other parts were created check_no_files $DIR/testfile2 $DIR/testfile3 mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/pmempool_transform/out5.log.match0000664000000000000000000000572614123364546021433 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 20M $(nW)testfile02 REPLICA 60M $(nW)testfile10 poolset_out PMEMPOOLSET 20M $(nW)testfile00 20M $(nW)testfile01 20M $(nW)testfile02 REPLICA 90M $(nW)testfile10 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 error: No such file or directory error: failed to transform $(nW)/poolset.in -> $(nW)/poolset.out: directory $(nW) for part 0 in replica 1 does not exist or is not accessible TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 3 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) part 1: path : $(nW)testfile01 type : regular file size : $(nW) part 2: path : $(nW)testfile02 type : regular file size : $(nW) Replica 1 - local, 1 part(s): part 0: path : $(nW)testfile10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out3.log.match0000664000000000000000000000322514123364546021421 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)testfile00 poolset_out PMEMPOOLSET 20M $(nW)testfile00 REPLICA 20M $(nW)testfile10 1M $(nW)testfile11 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 error: Invalid argument error: failed to transform $(nW)poolset.in -> $(nW)poolset.out: part sizes check failed TestOK111 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out4.log.match0000664000000000000000000000640414123364546021424 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 REPLICA 15M $(nW)part10 15M $(nW)part11 poolset_out1 PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 poolset_out2 PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 REPLICA 15M $(nW)part10 15M $(nW)part11 20M $(nW)part12 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) Replica 1 - local, 3 part(s): part 0: path : $(nW)part10 type : regular file size : $(nW) part 1: path : $(nW)part11 type : regular file size : $(nW) part 2: path : $(nW)part12 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) $(OPT)Lanes offset : 0x2000 $(OPX)Lanes offset : 0x20000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part11 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part12 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out8.log.match0000664000000000000000000000263514123364546021432 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 REPLICA AUTO $(nW) poolset_out PMEMPOOLSET 20M $(nW)part00 pr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK111 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x$(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x$(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out2.log.match0000664000000000000000000000305414123364546021420 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW)testfile0 type : regular file size : $(nW) part 1: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)testfile0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)testfile1 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out12.log.match0000664000000000000000000000311614123364546021500 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK111 TestOK222 Poolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(nW) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform/out19.log.match0000664000000000000000000001050014123364546021502 0ustar rootrootpr($(nW)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 TestOK111 TestOK222 TestOK333 Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 4 part(s): part 0: path : $(nW)part00 type : regular file size : $(nW) part 1: path : $(nW)part01 type : regular file size : $(nW) part 2: path : $(nW)part02 type : regular file size : $(nW) part 3: path : $(nW)part03 type : regular file size : $(nW) Replica 1 - local, 4 part(s): part 0: path : $(nW)part10 type : regular file size : $(nW) part 1: path : $(nW)part11 type : regular file size : $(nW) part 2: path : $(nW)part12 type : regular file size : $(nW) part 3: path : $(nW)part13 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part01 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part02 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part03 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part10 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part11 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part12 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW)part13 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/pmempool_transform/TEST110000775000000000000000000000441314123364546017600 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # pmempool_transform/TEST11 -- test for transform with SINGLEHDR option # # adding the SINGLEHDR option # case: single replica with two 4KB-aligned device daxes # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments $SIZE_4KB $SIZE_4KB # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup OFFSET=$(get_devdax_size 0) ROOT_SIZE=$[OFFSET + 1024] MAX_SIZE=$[PMEMOBJ_MAX_ALLOC_SIZE - 1024] require_max_devdax_size 0 $MAX_SIZE dax_device_zero LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x create_poolset $POOLSET_OUT \ O SINGLEHDR \ AUTO:${DEVICE_DAX_PATH[0]}:x \ AUTO:${DEVICE_DAX_PATH[1]}:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr $ROOT_SIZE srcp 0 TestOK111 srcp $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr $OFFSET 9 EOF # Log poolset structures echo poolset_in >> $LOG_TEMP cat $POOLSET_IN >> $LOG_TEMP echo >> $LOG_TEMP echo poolset_out >> $LOG_TEMP cat $POOLSET_OUT >> $LOG_TEMP echo >> $LOG_TEMP # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT obj $POOLSET_IN \ >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset expect_normal_exit $PMEMPOOL$EXESUFFIX transform $POOLSET_IN $POOLSET_OUT >> \ $LOG_TEMP # Check if correctly transformed expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info dump_pool_info $POOLSET_OUT >> $LOG_TEMP dump_pool_info ${DEVICE_DAX_PATH[0]} >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/obj_list_insert/0000775000000000000000000000000014123364546016175 5ustar rootrootpmdk-1.11.1/src/test/obj_list_insert/TEST1.PS10000664000000000000000000000072614123364546017367 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST1 -- unit test for list_insert # # Adding item to list before the first element # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup create_holey_file 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_list$Env:EXESUFFIX $DIR\testfile ` i:1:0 P:2 R:2 ` i:1:0 P:2 R:2 ` i:1:0 P:2 R:2 ` i:1:0 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/TEST30000775000000000000000000000074314123364546016771 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST3 -- unit test for list_insert # # Adding item to list before the last element # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup create_holey_file 1M $DIR/testfile expect_normal_exit ../obj_list/obj_list$EXESUFFIX $DIR/testfile\ i:1:-1 P:2 R:2\ i:1:-1 P:2 R:2\ i:1:-1 P:2 R:2\ i:1:-1 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/obj_list_insert.vcxproj.filters0000664000000000000000000000237014123364546024454 0ustar rootroot {206aa34c-7454-4c8e-8335-8a4ccea7f9a0} {79b34e3f-e12b-4802-8b86-dacacf1f6594} Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/obj_list_insert/TEST00000775000000000000000000000073714123364546016771 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST0 -- unit test for list_insert # # Adding item to list after the first element # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup create_holey_file 1M $DIR/testfile expect_normal_exit ../obj_list/obj_list$EXESUFFIX $DIR/testfile\ i:0:0 P:2 R:2\ i:0:0 P:2 R:2\ i:0:0 P:2 R:2\ i:0:0 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/Makefile0000664000000000000000000000027614123364546017642 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/obj_list_insert/Makefile -- build obj_list_insert unittest # include ../obj_list/Makefile.inc pmdk-1.11.1/src/test/obj_list_insert/TEST3.PS10000664000000000000000000000073114123364546017365 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST3 -- unit test for list_insert # # Adding item to list before the last element # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup create_holey_file 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_list$Env:EXESUFFIX $DIR\testfile ` i:1:-1 P:2 R:2 ` i:1:-1 P:2 R:2 ` i:1:-1 P:2 R:2 ` i:1:-1 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/TEST2.PS10000664000000000000000000000073014123364546017363 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST2 -- unit test for list_insert # # Adding item to list after the last element # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup create_holey_file 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_list$Env:EXESUFFIX $DIR\testfile ` i:0:-1 P:2 R:2 ` i:0:-1 P:2 R:2 ` i:0:-1 P:2 R:2 ` i:0:-1 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/TEST40000775000000000000000000000074414123364546016773 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST4 -- unit test for list_insert # # Adding item to before/after element in the middle # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup create_holey_file 1M $DIR/testfile expect_normal_exit ../obj_list/obj_list$EXESUFFIX $DIR/testfile\ i:0:-1 i:0:-1 i:0:-1 P:2 R:2\ i:0:1 P:2 R:2\ i:1:2 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/out0.log.match0000664000000000000000000000070114123364546020660 0ustar rootrootobj_list_insert$(nW)TEST0: START: obj_list $(nW)obj_list$(nW) $(nW)testfile i:0:0 P:2 R:2 i:0:0 P:2 R:2 i:0:0 P:2 R:2 i:0:0 P:2 R:2 pmalloc(id = 0) list: id = 0 list reverse: id = 0 pmalloc(id = 1) list: id = 0 id = 1 list reverse: id = 1 id = 0 pmalloc(id = 2) list: id = 0 id = 2 id = 1 list reverse: id = 1 id = 2 id = 0 pmalloc(id = 3) list: id = 0 id = 3 id = 2 id = 1 list reverse: id = 1 id = 2 id = 3 id = 0 obj_list_insert$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_list_insert/TEST0.PS10000664000000000000000000000072514123364546017365 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST0 -- unit test for list_insert # # Adding item to list after the first element # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup create_holey_file 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_list$Env:EXESUFFIX $DIR\testfile ` i:0:0 P:2 R:2 ` i:0:0 P:2 R:2 ` i:0:0 P:2 R:2 ` i:0:0 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/README0000664000000000000000000000032614123364546017056 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_list_insert/README. This directory contains unit tests for list_insert() function. The unit tests utilizes an application from src/test/obj_list directory. pmdk-1.11.1/src/test/obj_list_insert/obj_list_insert.vcxproj0000664000000000000000000000622614123364546023011 0ustar rootroot Debug x64 Release x64 {C2C36D03-26EE-4BD8-8FFC-86CFE16C1218} Win32Proj obj_list_insert 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/obj_list_insert/TEST10000775000000000000000000000074014123364546016764 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST1 -- unit test for list_insert # # Adding item to list before the first element # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup create_holey_file 1M $DIR/testfile expect_normal_exit ../obj_list/obj_list$EXESUFFIX $DIR/testfile\ i:1:0 P:2 R:2\ i:1:0 P:2 R:2\ i:1:0 P:2 R:2\ i:1:0 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/TEST4.PS10000664000000000000000000000073114123364546017366 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST4 -- unit test for list_insert # # Adding item to before/after element in the middle # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup create_holey_file 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_list$Env:EXESUFFIX $DIR\testfile ` i:0:-1 i:0:-1 i:0:-1 P:2 R:2 ` i:0:1 P:2 R:2 ` i:1:2 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/out1.log.match0000664000000000000000000000070114123364546020661 0ustar rootrootobj_list_insert$(nW)TEST1: START: obj_list $(nW)obj_list$(nW) $(nW)testfile i:1:0 P:2 R:2 i:1:0 P:2 R:2 i:1:0 P:2 R:2 i:1:0 P:2 R:2 pmalloc(id = 0) list: id = 0 list reverse: id = 0 pmalloc(id = 1) list: id = 1 id = 0 list reverse: id = 0 id = 1 pmalloc(id = 2) list: id = 2 id = 1 id = 0 list reverse: id = 0 id = 1 id = 2 pmalloc(id = 3) list: id = 3 id = 2 id = 1 id = 0 list reverse: id = 0 id = 1 id = 2 id = 3 obj_list_insert$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_list_insert/TEST20000775000000000000000000000074214123364546016767 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_list_insert/TEST2 -- unit test for list_insert # # Adding item to list after the last element # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup create_holey_file 1M $DIR/testfile expect_normal_exit ../obj_list/obj_list$EXESUFFIX $DIR/testfile\ i:0:-1 P:2 R:2\ i:0:-1 P:2 R:2\ i:0:-1 P:2 R:2\ i:0:-1 P:2 R:2 check pass pmdk-1.11.1/src/test/obj_list_insert/out3.log.match0000664000000000000000000000070514123364546020667 0ustar rootrootobj_list_insert$(nW)TEST3: START: obj_list $(nW)obj_list$(nW) $(nW)testfile i:1:-1 P:2 R:2 i:1:-1 P:2 R:2 i:1:-1 P:2 R:2 i:1:-1 P:2 R:2 pmalloc(id = 0) list: id = 0 list reverse: id = 0 pmalloc(id = 1) list: id = 1 id = 0 list reverse: id = 0 id = 1 pmalloc(id = 2) list: id = 1 id = 2 id = 0 list reverse: id = 0 id = 2 id = 1 pmalloc(id = 3) list: id = 1 id = 2 id = 3 id = 0 list reverse: id = 0 id = 3 id = 2 id = 1 obj_list_insert$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_list_insert/out4.log.match0000664000000000000000000000073214123364546020670 0ustar rootrootobj_list_insert$(nW)TEST4: START: obj_list $(nW)obj_list$(nW) $(nW)testfile i:0:-1 i:0:-1 i:0:-1 P:2 R:2 i:0:1 P:2 R:2 i:1:2 P:2 R:2 pmalloc(id = 0) pmalloc(id = 1) pmalloc(id = 2) list: id = 0 id = 1 id = 2 list reverse: id = 2 id = 1 id = 0 pmalloc(id = 3) list: id = 0 id = 1 id = 3 id = 2 list reverse: id = 2 id = 3 id = 1 id = 0 pmalloc(id = 4) list: id = 0 id = 1 id = 4 id = 3 id = 2 list reverse: id = 2 id = 3 id = 4 id = 1 id = 0 obj_list_insert$(nW)TEST4: DONE pmdk-1.11.1/src/test/obj_list_insert/out2.log.match0000664000000000000000000000070514123364546020666 0ustar rootrootobj_list_insert$(nW)TEST2: START: obj_list $(nW)obj_list$(nW) $(nW)testfile i:0:-1 P:2 R:2 i:0:-1 P:2 R:2 i:0:-1 P:2 R:2 i:0:-1 P:2 R:2 pmalloc(id = 0) list: id = 0 list reverse: id = 0 pmalloc(id = 1) list: id = 0 id = 1 list reverse: id = 1 id = 0 pmalloc(id = 2) list: id = 0 id = 1 id = 2 list reverse: id = 2 id = 1 id = 0 pmalloc(id = 3) list: id = 0 id = 1 id = 2 id = 3 list reverse: id = 3 id = 2 id = 1 id = 0 obj_list_insert$(nW)TEST2: DONE pmdk-1.11.1/src/test/pmem_memcpy/0000775000000000000000000000000014123364546015314 5ustar rootrootpmdk-1.11.1/src/test/pmem_memcpy/pmem_memcpy.c0000664000000000000000000001033014123364546017765 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * pmem_memcpy.c -- unit test for doing a memcpy * * usage: pmem_memcpy file destoff srcoff length * */ #include "unittest.h" #include "util_pmem.h" #include "file.h" #include "memcpy_common.h" static void * pmem_memcpy_persist_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memcpy_persist(pmemdest, src, len); } static void * pmem_memcpy_nodrain_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memcpy_nodrain(pmemdest, src, len); } static void do_persist_ddax(const void *ptr, size_t size) { util_persist_auto(1, ptr, size); } static void do_persist(const void *ptr, size_t size) { util_persist_auto(0, ptr, size); } /* * swap_mappings - swap given two mapped regions. * * Try swapping src and dest by unmapping src, mapping a new dest with * the original src address as a hint. If successful, unmap original dest. * Map a new src with the original dest as a hint. */ static void swap_mappings(char **dest, char **src, size_t size, int fd) { char *d = *dest; char *s = *src; char *td, *ts; MUNMAP(*src, size); /* mmap destination using src addr as a hint */ td = MMAP(s, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); MUNMAP(*dest, size); *dest = td; /* mmap src using original destination addr as a hint */ ts = MMAP(d, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); *src = ts; } /* * do_memcpy_variants -- do_memcpy wrapper that tests multiple variants * of memcpy functions */ static void do_memcpy_variants(int fd, char *dest, int dest_off, char *src, int src_off, size_t bytes, size_t mapped_len, const char *file_name, persist_fn p) { do_memcpy(fd, dest, dest_off, src, src_off, bytes, mapped_len, file_name, pmem_memcpy_persist_wrapper, 0, p, NULL, NULL, NULL); do_memcpy(fd, dest, dest_off, src, src_off, bytes, mapped_len, file_name, pmem_memcpy_nodrain_wrapper, 0, p, NULL, NULL, NULL); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memcpy(fd, dest, dest_off, src, src_off, bytes, mapped_len, file_name, pmem_memcpy, Flags[i], p, NULL, NULL, NULL); } } int main(int argc, char *argv[]) { int fd; char *dest; char *src; char *dest_orig; char *src_orig; size_t mapped_len; if (argc != 5) UT_FATAL("usage: %s file srcoff destoff length", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem_memcpy %s %s %s %s %savx %savx512f", argv[2], argv[3], argv[4], thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); int dest_off = atoi(argv[2]); int src_off = atoi(argv[3]); size_t bytes = strtoul(argv[4], NULL, 0); /* src > dst */ dest_orig = dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL); if (dest == NULL) UT_FATAL("!could not map file: %s", argv[1]); src_orig = src = MMAP(dest + mapped_len, mapped_len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); /* * Its very unlikely that src would not be > dest. pmem_map_file * chooses the first unused address >= 1TB, large * enough to hold the give range, and 1GB aligned. If the * addresses did not get swapped to allow src > dst, log error * and allow test to continue. */ if (src <= dest) { swap_mappings(&dest, &src, mapped_len, fd); if (src <= dest) UT_FATAL("cannot map files in memory order"); } enum file_type type = util_fd_get_type(fd); if (type < 0) UT_FATAL("cannot check type of file with fd %d", fd); persist_fn persist; persist = type == TYPE_DEVDAX ? do_persist_ddax : do_persist; memset(dest, 0, (2 * bytes)); persist(dest, 2 * bytes); memset(src, 0, (2 * bytes)); do_memcpy_variants(fd, dest, dest_off, src, src_off, bytes, 0, argv[1], persist); /* dest > src */ swap_mappings(&dest, &src, mapped_len, fd); if (dest <= src) UT_FATAL("cannot map files in memory order"); do_memcpy_variants(fd, dest, dest_off, src, src_off, bytes, 0, argv[1], persist); int ret = pmem_unmap(dest_orig, mapped_len); UT_ASSERTeq(ret, 0); MUNMAP(src_orig, mapped_len); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem_memcpy/Makefile0000664000000000000000000000054614123364546016761 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_memcpy/Makefile -- build pmem_memcpy unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/pmem2_memcpy TARGET = pmem_memcpy OBJS = pmem_memcpy.o\ memcpy_common.o LIBPMEM=y LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -I$(TOP)/src/test/pmem2_memcpy pmdk-1.11.1/src/test/pmem_memcpy/TESTS.py0000664000000000000000000000245014123364546016571 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation from collections import namedtuple import testframework as t TC = namedtuple('TC', ['dest', 'src', 'length']) class PmemMemcpy(t.Test): test_type = t.Short filesize = 4 * t.MiB envs0 = () envs1 = () test_cases = ( # aligned everything TC(dest=0, src=0, length=4096), # unaligned dest TC(dest=7, src=0, length=4096), # unaligned dest, unaligned src TC(dest=7, src=9, length=4096), # aligned dest, unaligned src TC(dest=0, src=9, length=4096) ) def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' for env in self.envs1: ctx.env[env] = '1' for tc in self.test_cases: filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmem_memcpy', filepath, tc.dest, tc.src, tc.length) class TEST0(PmemMemcpy): pass @t.require_architectures('x86_64') class TEST1(PmemMemcpy): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') class TEST2(PmemMemcpy): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) class TEST3(PmemMemcpy): envs1 = ("PMEM_NO_MOVNT",) class TEST4(PmemMemcpy): envs1 = ("PMEM_NO_MOVNT", "PMEM_NO_GENERIC_MEMCPY") pmdk-1.11.1/src/test/pmem_memcpy/.gitignore0000664000000000000000000000001414123364546017277 0ustar rootrootpmem_memcpy pmdk-1.11.1/src/test/pmem_memcpy/README0000664000000000000000000000150514123364546016175 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_memcpy/README. This directory contains a unit test for pmem_memcpy(). SYNOPSIS: pmem_memcpy file destoff srcoff length DESCRIPTION: pmem_memcpy is the unit test for verifying the functionality of memcpy for persistent memory using non-temporal instructions. OPTIONS: file is '$DIR/testfile1' for all tests. destoff: Is number of bytes for destination address offset based on a 64 byte boundary srcoff: Is number of bytes offset for source address based on 64 byte boundary length: Is the length in bytes. Cannot be less than 4. A zero for the dest offset and src offset are valid. In all cases it sets a pattern of Z's and F's in 1/2 of the length specified to be used as the source buffer. It then tests for successful memcpy using a memcmp and a read of the file. pmdk-1.11.1/src/test/pmem_memcpy/pmem_memcpy.vcxproj0000664000000000000000000000756714123364546021260 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {673277EC-D26B-414D-92E3-84EE873316A8} Win32Proj pmem_memcpy 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\test\pmem2_memcpy;%(AdditionalIncludeDirectories) $(SolutionDir)\test\pmem2_memcpy;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem_memcpy/pmem_memcpy.vcxproj.filters0000664000000000000000000000224114123364546022707 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {be9f59bd-3dd9-4c45-8726-809fcdf7520f} ps1 {e2d1d2f8-73d7-4f5e-8004-16934d80c022} Source Files Source Files Test Scripts Header Files pmdk-1.11.1/src/test/pmem_valgr_simple/0000775000000000000000000000000014123364546016506 5ustar rootrootpmdk-1.11.1/src/test/pmem_valgr_simple/pmemcheck0.log.match0000664000000000000000000000474014123364546022325 0ustar rootroot==$(N)== pmemcheck-$(N).$(nW), a simple persistent store checker ==$(N)== Copyright (c) $(N)-$(N), Intel Corporation ==$(N)== Using $(*) ==$(N)== Command: ./pmem_valgr_simple$(nW) $(nW) $(N) $(N) ==$(N)== Parent PID: $(N) ==$(N)== ==$(N)== $(OPT)==$(N)== Number of stores not made persistent: 3 $(OPX)==$(N)== Number of stores not made persistent: 10 ==$(N)== Stores not made persistent properly: ==$(N)== [0] at 0x$(X): main (pmem_valgr_simple.c:$(N)) ==$(N)== Address: 0x$(X) size: 4 state: DIRTY ==$(N)== [1] at 0x$(X): $(nW)memset$(nW) ($(*)) ==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 8 state: DIRTY $(OPX)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY $(OPT)==$(N)== [$(N)] at 0x$(X): $(nW)memset$(nW) ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 1 state: DIRTY ==$(N)== [$(N)] at 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 2 state: FLUSHED $(OPT)==$(N)== Address: 0x$(X) size: 2 state: FENCED ==$(N)== Total memory not made persistent: 14 $(OPT)==$(N)== $(OPT)==$(N)== Number of overwritten stores: 1 $(OPT)==$(N)== Overwritten stores before they were made persistent: $(OPT)==$(N)== [0] at 0x$(X): $(nW)memset ($(*)) $(OPT)==$(N)== by 0x$(X): main (pmem_valgr_simple.c:$(N)) $(OPT)==$(N)== Address: 0x$(X) size: 8 state: DIRTY $(OPT)==$(N)== ERROR SUMMARY: 3 errors $(OPX)==$(N)== ERROR SUMMARY: 10 errors pmdk-1.11.1/src/test/pmem_valgr_simple/TEST00000775000000000000000000000073614123364546017301 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/pmem_valgr_simple/TEST0 -- unit test for pmem_valgr_simple # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem configure_valgrind pmemcheck force-enable export VALGRIND_OPTS="--mult-stores=yes --indiff=20" setup truncate -s 4M $DIR/testfile1 expect_normal_exit ./pmem_valgr_simple$EXESUFFIX\ $DIR/testfile1 60 8 check pass pmdk-1.11.1/src/test/pmem_valgr_simple/Makefile0000664000000000000000000000037414123364546020152 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # src/test/pmem_valgr_simple/Makefile -- build pmem_valgr_simple unit test # TARGET = pmem_valgr_simple OBJS = pmem_valgr_simple.o LIBPMEM=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem_valgr_simple/out0.log.match0000664000000000000000000000017714123364546021200 0ustar rootrootpmem_valgr_simple/TEST0: START: pmem_valgr_simple ./pmem_valgr_simple$(nW) $(nW)/testfile1 60 8 pmem_valgr_simple/TEST0: DONE pmdk-1.11.1/src/test/pmem_valgr_simple/.gitignore0000664000000000000000000000002214123364546020470 0ustar rootrootpmem_valgr_simple pmdk-1.11.1/src/test/pmem_valgr_simple/README0000664000000000000000000000101514123364546017363 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_valgr_simple/README. This directory contains a unit test of simple pmem functions using valgrind. SYNOPSIS: pmem_valgr_simple file DESCRIPTION: pmem_valgr_simple is a sample unit test showing the functionality of the valgrind tool, which can be used for testing applications using persistent memory. OPTIONS: file is $DIR/testfile1 in all cases. The test uses pmem and language primitives to show how to use the pmemcheck tool in more complicated test cases. pmdk-1.11.1/src/test/pmem_valgr_simple/pmem_valgr_simple.c0000664000000000000000000000233014123364546022352 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2016, Intel Corporation */ /* * pmem_valgr_simple.c -- simple unit test using pmemcheck * * usage: pmem_valgr_simple file */ #include "unittest.h" int main(int argc, char *argv[]) { size_t mapped_len; char *dest; int is_pmem; START(argc, argv, "pmem_valgr_simple"); if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); int dest_off = atoi(argv[2]); size_t bytes = strtoul(argv[3], NULL, 0); dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, &is_pmem); if (dest == NULL) UT_FATAL("!Could not mmap %s\n", argv[1]); /* these will not be made persistent */ *(int *)dest = 4; /* this will be made persistent */ uint64_t *tmp64dst = (void *)((uintptr_t)dest + 4096); *tmp64dst = 50; if (is_pmem) { pmem_persist(tmp64dst, sizeof(*tmp64dst)); } else { UT_ASSERTeq(pmem_msync(tmp64dst, sizeof(*tmp64dst)), 0); } uint16_t *tmp16dst = (void *)((uintptr_t)dest + 1024); *tmp16dst = 21; /* will appear as flushed/fenced in valgrind log */ pmem_flush(tmp16dst, sizeof(*tmp16dst)); /* shows strange behavior of memset in some cases */ memset(dest + dest_off, 0, bytes); UT_ASSERTeq(pmem_unmap(dest, mapped_len), 0); DONE(NULL); } pmdk-1.11.1/src/test/test_release.props0000664000000000000000000000254314123364546016554 0ustar rootroot $(SolutionDir)$(Platform)\$(Configuration)\tests\ $(FrameworkSDKdir)bin\$(TargetPlatformVersion)\$(Platform);$(ExecutablePath) PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS4;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ProjectDir);$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\common;$(SolutionDir)\core;$(SolutionDir)\test\unittest Level3 true CompileAsC platform.h true DbgHelp.lib;mincore.lib;%(AdditionalDependencies) Console pmdk-1.11.1/src/test/scope/0000775000000000000000000000000014123364546014115 5ustar rootrootpmdk-1.11.1/src/test/scope/scope.vcxproj0000664000000000000000000000771614123364546016656 0ustar rootroot Debug x64 Release x64 {C0E811E0-8942-4CFD-A817-74D99E9E6577} Win32Proj scope 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Level3 MaxSpeed true true NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true {179beb5a-2c90-44f5-a734-fa756a5e668c} pmdk-1.11.1/src/test/scope/out15.log.match0000664000000000000000000000161114123364546016667 0ustar rootrootpmemset_config_delete$(nW) pmemset_config_new$(nW) pmemset_config_set_event_callback$(nW) pmemset_config_set_required_store_granularity$(nW) pmemset_config_set_reservation$(nW) pmemset_deep_flush$(nW) pmemset_delete$(nW) pmemset_descriptor_part_map$(nW) pmemset_drain$(nW) pmemset_errormsg$(nW) pmemset_first_part_map$(nW) pmemset_flush$(nW) pmemset_get_store_granularity$(nW) pmemset_memcpy$(nW) pmemset_memmove$(nW) pmemset_memset$(nW) pmemset_new$(nW) pmemset_next_part_map$(nW) pmemset_part_delete$(nW) pmemset_part_map$(nW) pmemset_part_map_by_address$(nW) pmemset_part_map_drop$(nW) pmemset_part_new$(nW) pmemset_perror$(nW) pmemset_persist$(nW) pmemset_remove_part_map$(nW) pmemset_remove_range$(nW) pmemset_set_contiguous_part_coalescing$(nW) pmemset_source_delete$(nW) pmemset_source_from_file$(nW) pmemset_source_from_pmem2$(nW) pmemset_source_from_temporary$(nW) pmemset_xsource_from_file$(nW) pmdk-1.11.1/src/test/scope/scope.vcxproj.filters0000664000000000000000000000227114123364546020314 0ustar rootroot {f75855c4-915b-477a-a6ef-d6e89c61cf93} {83997a01-c24d-41c0-8bd6-c87344c1023f} Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Match Files Match Files pmdk-1.11.1/src/test/scope/out10.log.match0000664000000000000000000000062714123364546016670 0ustar rootrootDllMain pmemblk_bsize pmemblk_checkU pmemblk_checkW pmemblk_check_versionU pmemblk_check_versionW pmemblk_close pmemblk_createU pmemblk_createW pmemblk_ctl_execU pmemblk_ctl_execW pmemblk_ctl_getU pmemblk_ctl_getW pmemblk_ctl_setU pmemblk_ctl_setW pmemblk_errormsgU pmemblk_errormsgW pmemblk_nblock pmemblk_openU pmemblk_openW pmemblk_read pmemblk_set_error pmemblk_set_funcs pmemblk_set_zero pmemblk_write pmdk-1.11.1/src/test/scope/out16.log.match0000664000000000000000000000154714123364546016700 0ustar rootrootDllMain pmemset_config_delete pmemset_config_new pmemset_config_set_event_callback pmemset_config_set_required_store_granularity pmemset_config_set_reservation pmemset_deep_flush pmemset_delete pmemset_descriptor_part_map pmemset_drain pmemset_errormsgU pmemset_errormsgW pmemset_first_part_map pmemset_flush pmemset_get_store_granularity pmemset_memcpy pmemset_memmove pmemset_memset pmemset_new pmemset_next_part_map pmemset_part_delete pmemset_part_map pmemset_part_map_by_address pmemset_part_map_drop pmemset_part_new pmemset_perrorU pmemset_perrorW pmemset_persist pmemset_remove_part_map pmemset_remove_range pmemset_set_contiguous_part_coalescing pmemset_source_delete pmemset_source_from_fileU pmemset_source_from_fileW pmemset_source_from_pmem2 pmemset_source_from_temporaryU pmemset_source_from_temporaryW pmemset_xsource_from_fileU pmemset_xsource_from_fileW pmdk-1.11.1/src/test/scope/Makefile0000664000000000000000000000024114123364546015552 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2016, Intel Corporation # # src/test/scope/Makefile -- build scope unit test # include ../Makefile.inc pmdk-1.11.1/src/test/scope/TESTS.py0000775000000000000000000001043414123364546015376 0ustar rootroot#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # src/test/scope/TESTS.py -- scope tests to check libraries symbols # import os import sys import subprocess as sp import futils as ft import testframework as t from testframework import granularity as g def parse_lib(ctx, lib, static=False): if sys.platform.startswith('linux'): return parse_lib_linux(ctx, lib, static) elif sys.platform == 'win32': return parse_lib_win(ctx, lib, static) def parse_lib_linux(ctx, lib, static): if static: arg = '-g' else: arg = '-D' cmd = ['nm', arg, lib] proc = sp.run(cmd, universal_newlines=True, stdout=sp.PIPE, stderr=sp.STDOUT) if proc.returncode != 0: raise ft.Fail('command "{}" failed: {}' .format(' '.join(cmd), proc.stdout)) symbols = [] for line in proc.stdout.splitlines(): try: # penultimate column of 'nm' output must be either # 'T' (defined function) or 'B' (global variable). # Example output lines: # 000000000003fde4 T pmemobj_create # 0000000000000018 B _pobj_cached_pool # U read if line.split()[-2] in 'TB': symbols.append(line.split()[-1] + os.linesep) except IndexError: continue symbols.sort() return ''.join(symbols) def parse_lib_win(ctx, lib, static): dllview = ft.get_test_tool_path(ctx.build, 'dllview') + '.exe' cmd = [dllview, lib] proc = sp.run(cmd, universal_newlines=True, stdout=sp.PIPE, stderr=sp.STDOUT) if proc.returncode != 0: raise ft.Fail('command "{}" failed: {}' .format(' '.join(cmd), proc.stdout)) out = sorted(proc.stdout.splitlines()) return '\n'.join(out) + '\n' @t.require_valgrind_disabled('drd', 'helgrind', 'memcheck', 'pmemcheck') @g.no_testdir() class Common(t.Test): test_type = t.Medium checked_lib = '' def run(self, ctx): static = False if sys.platform == 'win32': lib = '{}.dll'.format(self.checked_lib) elif str(self.ctx.build) in ['debug', 'release']: lib = '{}.so.1'.format(self.checked_lib) else: static = True lib = '{}.a'.format(self.checked_lib) libpath = os.path.join(ft.get_lib_dir(ctx), lib) log = 'out{}.log'.format(self.testnum) out = parse_lib(ctx, libpath, static) with open(os.path.join(self.cwd, log), 'w') as f: f.write(out) @t.windows_exclude class TEST2(Common): """Check scope of libpmem library (*nix)""" checked_lib = 'libpmem' @t.windows_exclude class TEST3(Common): """Check scope of libpmemlog library (*nix)""" checked_lib = 'libpmemlog' @t.windows_exclude class TEST4(Common): """Check scope of libpmemblk library (*nix)""" checked_lib = 'libpmemblk' @t.windows_exclude class TEST5(Common): """Check scope of libpmemobj library (*nix)""" checked_lib = 'libpmemobj' @t.windows_exclude class TEST6(Common): """Check scope of libpmempool library (*nix)""" checked_lib = 'libpmempool' @t.windows_only class TEST8(Common): """Check scope of libpmem library (windows)""" checked_lib = 'libpmem' @t.windows_only class TEST9(Common): """Check scope of libpmemlog library (windows)""" checked_lib = 'libpmemlog' @t.windows_only class TEST10(Common): """Check scope of libpmemblk library (windows)""" checked_lib = 'libpmemblk' @t.windows_only class TEST11(Common): """Check scope of libpmemobj library (windows)""" checked_lib = 'libpmemobj' @t.windows_only class TEST12(Common): """Check scope of libpmempool library (windows)""" checked_lib = 'libpmempool' @t.windows_exclude class TEST13(Common): """Check scope of libpmem2 library (*nix)""" checked_lib = 'libpmem2' @t.windows_only class TEST14(Common): """Check scope of libpmem2 library (windows)""" checked_lib = 'libpmem2' @t.windows_exclude class TEST15(Common): """Check scope of libpmemset library (*nix)""" checked_lib = 'libpmemset' @t.windows_only class TEST16(Common): """Check scope of libpmemset library (windows)""" checked_lib = 'libpmemset' pmdk-1.11.1/src/test/scope/out9.log.match0000664000000000000000000000062214123364546016613 0ustar rootrootDllMain pmemlog_append pmemlog_appendv pmemlog_checkU pmemlog_checkW pmemlog_check_versionU pmemlog_check_versionW pmemlog_close pmemlog_createU pmemlog_createW pmemlog_ctl_execU pmemlog_ctl_execW pmemlog_ctl_getU pmemlog_ctl_getW pmemlog_ctl_setU pmemlog_ctl_setW pmemlog_errormsgU pmemlog_errormsgW pmemlog_nbyte pmemlog_openU pmemlog_openW pmemlog_rewind pmemlog_set_funcs pmemlog_tell pmemlog_walk pmdk-1.11.1/src/test/scope/out14.log.match0000664000000000000000000000232514123364546016671 0ustar rootrootDllMain pmem2_badblock_clear pmem2_badblock_context_delete pmem2_badblock_context_new pmem2_badblock_next pmem2_config_delete pmem2_config_new pmem2_config_set_length pmem2_config_set_offset pmem2_config_set_protection pmem2_config_set_required_store_granularity pmem2_config_set_sharing pmem2_config_set_vm_reservation pmem2_deep_flush pmem2_errormsgU pmem2_errormsgW pmem2_get_drain_fn pmem2_get_flush_fn pmem2_get_memcpy_fn pmem2_get_memmove_fn pmem2_get_memset_fn pmem2_get_persist_fn pmem2_map_delete pmem2_map_from_existing pmem2_map_get_address pmem2_map_get_size pmem2_map_get_store_granularity pmem2_map_new pmem2_perrorU pmem2_perrorW pmem2_source_alignment pmem2_source_delete pmem2_source_device_idU pmem2_source_device_idW pmem2_source_device_usc pmem2_source_from_anon pmem2_source_from_fd pmem2_source_from_handle pmem2_source_get_handle pmem2_source_numa_node pmem2_source_size pmem2_vm_reservation_delete pmem2_vm_reservation_extend pmem2_vm_reservation_get_address pmem2_vm_reservation_get_size pmem2_vm_reservation_map_find pmem2_vm_reservation_map_find_first pmem2_vm_reservation_map_find_last pmem2_vm_reservation_map_find_next pmem2_vm_reservation_map_find_prev pmem2_vm_reservation_new pmem2_vm_reservation_shrink pmdk-1.11.1/src/test/scope/out11.log.match0000664000000000000000000000422214123364546016664 0ustar rootrootDllMain _pobj_debug_notice pmemobj_alloc pmemobj_alloc_usable_size pmemobj_cancel pmemobj_checkU pmemobj_checkW pmemobj_check_versionU pmemobj_check_versionW pmemobj_close pmemobj_cond_broadcast pmemobj_cond_signal pmemobj_cond_timedwait pmemobj_cond_wait pmemobj_cond_zero pmemobj_createU pmemobj_createW pmemobj_ctl_execU pmemobj_ctl_execW pmemobj_ctl_getU pmemobj_ctl_getW pmemobj_ctl_setU pmemobj_ctl_setW pmemobj_defer_free pmemobj_defrag pmemobj_direct pmemobj_drain pmemobj_errormsgU pmemobj_errormsgW pmemobj_first pmemobj_flush pmemobj_free pmemobj_get_user_data pmemobj_list_insert pmemobj_list_insert_new pmemobj_list_move pmemobj_list_remove pmemobj_memcpy pmemobj_memcpy_persist pmemobj_memmove pmemobj_memset pmemobj_memset_persist pmemobj_mutex_lock pmemobj_mutex_timedlock pmemobj_mutex_trylock pmemobj_mutex_unlock pmemobj_mutex_zero pmemobj_next pmemobj_oid pmemobj_openU pmemobj_openW pmemobj_persist pmemobj_pool_by_oid pmemobj_pool_by_ptr pmemobj_publish pmemobj_realloc pmemobj_reserve pmemobj_root pmemobj_root_construct pmemobj_root_size pmemobj_rwlock_rdlock pmemobj_rwlock_timedrdlock pmemobj_rwlock_timedwrlock pmemobj_rwlock_tryrdlock pmemobj_rwlock_trywrlock pmemobj_rwlock_unlock pmemobj_rwlock_wrlock pmemobj_rwlock_zero pmemobj_set_funcs pmemobj_set_user_data pmemobj_set_value pmemobj_strdup pmemobj_tx_abort pmemobj_tx_add_range pmemobj_tx_add_range_direct pmemobj_tx_alloc pmemobj_tx_begin pmemobj_tx_commit pmemobj_tx_end pmemobj_tx_errno pmemobj_tx_free pmemobj_tx_get_failure_behavior pmemobj_tx_get_user_data pmemobj_tx_lock pmemobj_tx_log_append_buffer pmemobj_tx_log_auto_alloc pmemobj_tx_log_intents_max_size pmemobj_tx_log_snapshots_max_size pmemobj_tx_process pmemobj_tx_publish pmemobj_tx_realloc pmemobj_tx_set_failure_behavior pmemobj_tx_set_user_data pmemobj_tx_stage pmemobj_tx_strdup pmemobj_tx_wcsdup pmemobj_tx_xadd_range pmemobj_tx_xadd_range_direct pmemobj_tx_xalloc pmemobj_tx_xfree pmemobj_tx_xlock pmemobj_tx_xlog_append_buffer pmemobj_tx_xpublish pmemobj_tx_xstrdup pmemobj_tx_xwcsdup pmemobj_tx_zalloc pmemobj_tx_zrealloc pmemobj_type_num pmemobj_volatile pmemobj_wcsdup pmemobj_xalloc pmemobj_xreserve pmemobj_zalloc pmemobj_zrealloc pmdk-1.11.1/src/test/scope/out6.log.match0000664000000000000000000000053314123364546016611 0ustar rootrootpmempool_check$(nW) pmempool_check_end$(nW) pmempool_check_init$(nW) pmempool_check_version$(nW) pmempool_errormsg$(nW) $(OPT)pmempool_fault_injection_enabled$(nW) pmempool_feature_disable$(nW) pmempool_feature_enable$(nW) pmempool_feature_query$(nW) $(OPT)pmempool_inject_fault_at$(nW) pmempool_rm$(nW) pmempool_sync$(nW) pmempool_transform$(nW) pmdk-1.11.1/src/test/scope/out13.log.match0000664000000000000000000000254214123364546016671 0ustar rootrootpmem2_badblock_clear$(nW) pmem2_badblock_context_delete$(nW) pmem2_badblock_context_new$(nW) pmem2_badblock_next$(nW) pmem2_config_delete$(nW) pmem2_config_new$(nW) pmem2_config_set_length$(nW) pmem2_config_set_offset$(nW) pmem2_config_set_protection$(nW) pmem2_config_set_required_store_granularity$(nW) pmem2_config_set_sharing$(nW) pmem2_config_set_vm_reservation$(nW) pmem2_deep_flush$(nW) pmem2_errormsg$(nW) pmem2_get_drain_fn$(nW) pmem2_get_flush_fn$(nW) pmem2_get_memcpy_fn$(nW) pmem2_get_memmove_fn$(nW) pmem2_get_memset_fn$(nW) pmem2_get_persist_fn$(nW) pmem2_map_delete$(nW) pmem2_map_from_existing$(nW) pmem2_map_get_address$(nW) pmem2_map_get_size$(nW) pmem2_map_get_store_granularity$(nW) pmem2_map_new$(nW) pmem2_perror$(nW) pmem2_source_alignment$(nW) pmem2_source_delete$(nW) pmem2_source_device_id$(nW) pmem2_source_device_usc$(nW) pmem2_source_from_anon$(nW) pmem2_source_from_fd$(nW) pmem2_source_get_fd$(nW) pmem2_source_numa_node$(nW) pmem2_source_size$(nW) pmem2_vm_reservation_delete$(nW) pmem2_vm_reservation_extend$(nW) pmem2_vm_reservation_get_address$(nW) pmem2_vm_reservation_get_size$(nW) pmem2_vm_reservation_map_find$(nW) pmem2_vm_reservation_map_find_first$(nW) pmem2_vm_reservation_map_find_last$(nW) pmem2_vm_reservation_map_find_next$(nW) pmem2_vm_reservation_map_find_prev$(nW) pmem2_vm_reservation_new$(nW) pmem2_vm_reservation_shrink$(nW) pmdk-1.11.1/src/test/scope/out5.log.match0000664000000000000000000000526014123364546016612 0ustar rootroot_pobj_cache_invalidate$(nW) _pobj_cached_pool$(nW) _pobj_debug_notice$(nW) pmemobj_alloc$(nW) pmemobj_alloc_usable_size$(nW) pmemobj_cancel$(nW) pmemobj_check$(nW) pmemobj_check_version$(nW) pmemobj_close$(nW) pmemobj_cond_broadcast$(nW) pmemobj_cond_signal$(nW) pmemobj_cond_timedwait$(nW) pmemobj_cond_wait$(nW) pmemobj_cond_zero$(nW) pmemobj_create$(nW) pmemobj_ctl_exec$(nW) pmemobj_ctl_get$(nW) pmemobj_ctl_set$(nW) pmemobj_defer_free$(nW) pmemobj_defrag$(nW) pmemobj_direct$(nW) pmemobj_drain$(nW) pmemobj_errormsg$(nW) $(OPT)pmemobj_fault_injection_enabled$(nW) pmemobj_first$(nW) pmemobj_flush$(nW) pmemobj_free$(nW) pmemobj_get_user_data$(nW) $(OPT)pmemobj_inject_fault_at$(nW) pmemobj_list_insert$(nW) pmemobj_list_insert_new$(nW) pmemobj_list_move$(nW) pmemobj_list_remove$(nW) pmemobj_memcpy$(nW) pmemobj_memcpy_persist$(nW) pmemobj_memmove$(nW) pmemobj_memset$(nW) pmemobj_memset_persist$(nW) pmemobj_mutex_lock$(nW) pmemobj_mutex_timedlock$(nW) pmemobj_mutex_trylock$(nW) pmemobj_mutex_unlock$(nW) pmemobj_mutex_zero$(nW) pmemobj_next$(nW) pmemobj_oid$(nW) pmemobj_open$(nW) pmemobj_persist$(nW) pmemobj_pool_by_oid$(nW) pmemobj_pool_by_ptr$(nW) pmemobj_publish$(nW) pmemobj_realloc$(nW) pmemobj_reserve$(nW) pmemobj_root$(nW) pmemobj_root_construct$(nW) pmemobj_root_size$(nW) pmemobj_rwlock_rdlock$(nW) pmemobj_rwlock_timedrdlock$(nW) pmemobj_rwlock_timedwrlock$(nW) pmemobj_rwlock_tryrdlock$(nW) pmemobj_rwlock_trywrlock$(nW) pmemobj_rwlock_unlock$(nW) pmemobj_rwlock_wrlock$(nW) pmemobj_rwlock_zero$(nW) pmemobj_set_funcs$(nW) pmemobj_set_user_data$(nW) pmemobj_set_value$(nW) pmemobj_strdup$(nW) pmemobj_tx_abort$(nW) pmemobj_tx_add_range$(nW) pmemobj_tx_add_range_direct$(nW) pmemobj_tx_alloc$(nW) pmemobj_tx_begin$(nW) pmemobj_tx_commit$(nW) pmemobj_tx_end$(nW) pmemobj_tx_errno$(nW) pmemobj_tx_free$(nW) pmemobj_tx_get_failure_behavior$(nW) pmemobj_tx_get_user_data$(nW) pmemobj_tx_lock$(nW) pmemobj_tx_log_append_buffer$(nW) pmemobj_tx_log_auto_alloc$(nW) pmemobj_tx_log_intents_max_size$(nW) pmemobj_tx_log_snapshots_max_size$(nW) pmemobj_tx_process$(nW) pmemobj_tx_publish$(nW) pmemobj_tx_realloc$(nW) pmemobj_tx_set_failure_behavior$(nW) pmemobj_tx_set_user_data$(nW) pmemobj_tx_stage$(nW) pmemobj_tx_strdup$(nW) pmemobj_tx_wcsdup$(nW) pmemobj_tx_xadd_range$(nW) pmemobj_tx_xadd_range_direct$(nW) pmemobj_tx_xalloc$(nW) pmemobj_tx_xfree$(nW) pmemobj_tx_xlock$(nW) pmemobj_tx_xlog_append_buffer$(nW) pmemobj_tx_xpublish$(nW) pmemobj_tx_xstrdup$(nW) pmemobj_tx_xwcsdup$(nW) pmemobj_tx_zalloc$(nW) pmemobj_tx_zrealloc$(nW) pmemobj_type_num$(nW) pmemobj_volatile$(nW) pmemobj_wcsdup$(nW) pmemobj_xalloc$(nW) pmemobj_xflush$(nW) pmemobj_xpersist$(nW) pmemobj_xreserve$(nW) pmemobj_zalloc$(nW) pmemobj_zrealloc$(nW) pmdk-1.11.1/src/test/scope/out3.log.match0000664000000000000000000000062614123364546016611 0ustar rootrootpmemlog_append$(nW) pmemlog_appendv$(nW) pmemlog_check$(nW) pmemlog_check_version$(nW) pmemlog_close$(nW) pmemlog_create$(nW) pmemlog_ctl_exec$(nW) pmemlog_ctl_get$(nW) pmemlog_ctl_set$(nW) pmemlog_errormsg$(nW) $(OPT)pmemlog_fault_injection_enabled$(nW) $(OPT)pmemlog_inject_fault_at$(nW) pmemlog_nbyte$(nW) pmemlog_open$(nW) pmemlog_rewind$(nW) pmemlog_set_funcs$(nW) pmemlog_tell$(nW) pmemlog_walk$(nW) pmdk-1.11.1/src/test/scope/out4.log.match0000664000000000000000000000063314123364546016610 0ustar rootrootpmemblk_bsize$(nW) pmemblk_check$(nW) pmemblk_check_version$(nW) pmemblk_close$(nW) pmemblk_create$(nW) pmemblk_ctl_exec$(nW) pmemblk_ctl_get$(nW) pmemblk_ctl_set$(nW) pmemblk_errormsg$(nW) $(OPT)pmemblk_fault_injection_enabled$(nW) $(OPT)pmemblk_inject_fault_at$(nW) pmemblk_nblock$(nW) pmemblk_open$(nW) pmemblk_read$(nW) pmemblk_set_error$(nW) pmemblk_set_funcs$(nW) pmemblk_set_zero$(nW) pmemblk_write$(nW) pmdk-1.11.1/src/test/scope/out8.log.match0000664000000000000000000000070414123364546016613 0ustar rootrootDllMain mmap mprotect msync munmap pmem_check_versionU pmem_check_versionW pmem_deep_drain pmem_deep_flush pmem_deep_persist pmem_drain pmem_errormsgU pmem_errormsgW pmem_flush pmem_has_auto_flush pmem_has_hw_drain pmem_is_pmem pmem_map_fileU pmem_map_fileW pmem_memcpy pmem_memcpy_nodrain pmem_memcpy_persist pmem_memmove pmem_memmove_nodrain pmem_memmove_persist pmem_memset pmem_memset_nodrain pmem_memset_persist pmem_msync pmem_persist pmem_unmap pmdk-1.11.1/src/test/scope/out2.log.match0000664000000000000000000000104714123364546016606 0ustar rootrootpmem_check_version$(nW) pmem_deep_drain$(nW) pmem_deep_flush$(nW) pmem_deep_persist$(nW) pmem_drain$(nW) pmem_errormsg$(nW) $(OPT)pmem_fault_injection_enabled$(nW) pmem_flush$(nW) pmem_has_auto_flush$(nW) pmem_has_hw_drain$(nW) $(OPT)pmem_inject_fault_at$(nW) pmem_is_pmem$(nW) pmem_map_file$(nW) pmem_memcpy$(nW) pmem_memcpy_nodrain$(nW) pmem_memcpy_persist$(nW) pmem_memmove$(nW) pmem_memmove_nodrain$(nW) pmem_memmove_persist$(nW) pmem_memset$(nW) pmem_memset_nodrain$(nW) pmem_memset_persist$(nW) pmem_msync$(nW) pmem_persist$(nW) pmem_unmap$(nW) pmdk-1.11.1/src/test/scope/out12.log.match0000664000000000000000000000066114123364546016670 0ustar rootrootDllMain pmempool_checkU pmempool_checkW pmempool_check_end pmempool_check_initU pmempool_check_initW pmempool_check_versionU pmempool_check_versionW pmempool_errormsgU pmempool_errormsgW pmempool_feature_disableU pmempool_feature_disableW pmempool_feature_enableU pmempool_feature_enableW pmempool_feature_queryU pmempool_feature_queryW pmempool_rmU pmempool_rmW pmempool_syncU pmempool_syncW pmempool_transformU pmempool_transformW pmdk-1.11.1/src/test/getopt/0000775000000000000000000000000014123364546014306 5ustar rootrootpmdk-1.11.1/src/test/getopt/getopt.vcxproj0000664000000000000000000000736014123364546017233 0ustar rootroot Debug x64 Release x64 {433F7840-C597-4950-84C9-E4FF7DF6A298} getopt 10.0.17134.0 Application true v140 Application false v140 Disabled $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {9186eac4-2f34-4f17-b940-6585d7869bcd} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/getopt/getopt.vcxproj.filters0000664000000000000000000000240014123364546020670 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2721ff07-d9d0-499c-aa87-1f13d13d9570} {38bac2e4-0303-4387-b23e-19deacd0a753} Source Files Test scripts Test scripts Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/getopt/TEST1.PS10000664000000000000000000000067414123364546015502 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/getopt/TEST1 -- unit test for windows getopt implementation # #$ERR="stderr$Env:UNITTEST_NUM.log" . ../unittest/unittest.ps1 require_test_type medium require_fs_type none setup # #XXX: fix stderror parse on windows (find way to remove PS stderr overlay) #expect_normal_exit $Env:EXE_DIR\getopt$Env:EXESUFFIX -Z --arg_Z -A 2> $ERR # #check pass pmdk-1.11.1/src/test/getopt/getopt.c0000664000000000000000000000415714123364546015763 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * getopt.c -- test for windows getopt() implementation */ #include #include #include #include "unittest.h" /* * long_options -- command line arguments */ static const struct option long_options[] = { { "arg_a", no_argument, NULL, 'a' }, { "arg_b", no_argument, NULL, 'b' }, { "arg_c", no_argument, NULL, 'c' }, { "arg_d", no_argument, NULL, 'd' }, { "arg_e", no_argument, NULL, 'e' }, { "arg_f", no_argument, NULL, 'f' }, { "arg_g", no_argument, NULL, 'g' }, { "arg_h", no_argument, NULL, 'h' }, { "arg_A", required_argument, NULL, 'A' }, { "arg_B", required_argument, NULL, 'B' }, { "arg_C", required_argument, NULL, 'C' }, { "arg_D", required_argument, NULL, 'D' }, { "arg_E", required_argument, NULL, 'E' }, { "arg_F", required_argument, NULL, 'F' }, { "arg_G", required_argument, NULL, 'G' }, { "arg_H", required_argument, NULL, 'H' }, { "arg_1", optional_argument, NULL, '1' }, { "arg_2", optional_argument, NULL, '2' }, { "arg_3", optional_argument, NULL, '3' }, { "arg_4", optional_argument, NULL, '4' }, { "arg_5", optional_argument, NULL, '5' }, { "arg_6", optional_argument, NULL, '6' }, { "arg_7", optional_argument, NULL, '7' }, { "arg_8", optional_argument, NULL, '8' }, { NULL, 0, NULL, 0 }, }; int main(int argc, char *argv[]) { int opt; int option_index; START(argc, argv, "getopt"); while ((opt = getopt_long(argc, argv, "abcdefghA:B:C:D:E:F:G::H1::2::3::4::5::6::7::8::", long_options, &option_index)) != -1) { switch (opt) { case '?': UT_OUT("unknown argument"); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': UT_OUT("arg_%c", opt); break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': UT_OUT("arg_%c=%s", opt, optarg == NULL ? "null": optarg); break; } } while (optind < argc) { UT_OUT("%s", argv[optind++]); } DONE(NULL); } pmdk-1.11.1/src/test/getopt/stderr0.log.match0000664000000000000000000000000014123364546017455 0ustar rootrootpmdk-1.11.1/src/test/getopt/TEST00000775000000000000000000000103714123364546015074 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/getopt/TEST0 -- unit test for windows getopt implementation # . ../unittest/unittest.sh require_test_type medium require_fs_type none ERR=stderr${UNITTEST_NUM}.log setup expect_normal_exit ./getopt$EXESUFFIX nonOption -f -3arg \ -Barg -b --arg_4=a --arg_G -5 -a -A arg --arg_g -d -1 -e nonOption2 --arg_8 \ nonOption3 --arg_6 -E-a --arg_C=arg -a -7arg --arg_c --arg_D arg -h \ --arg_H arg -2 nonOption4 2>$ERR check pass pmdk-1.11.1/src/test/getopt/Makefile0000664000000000000000000000027714123364546015754 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/getopt/Makefile -- getopt unit test # TARGET = getopt OBJS = getopt.o include ../Makefile.inc pmdk-1.11.1/src/test/getopt/out0.log.match0000664000000000000000000000076314123364546017001 0ustar rootrootgetopt$(nW)TEST0: START: getopt $(nW)getopt$(nW) nonOption -f -3arg -Barg -b --arg_4=a --arg_G -5 -a -A arg --arg_g -d -1 -e nonOption2 --arg_8 nonOption3 --arg_6 -E-a --arg_C=arg -a -7arg --arg_c --arg_D arg -h --arg_H arg -2 nonOption4 arg_f arg_3=arg arg_B=arg arg_b arg_4=a arg_G=-5 arg_a arg_A=arg arg_g arg_d arg_1=null arg_e arg_8=null arg_6=null arg_E=-a arg_C=arg arg_a arg_7=arg arg_c arg_D=arg arg_h arg_H=arg arg_2=null nonOption nonOption2 nonOption3 nonOption4 getopt$(nW)TEST0: DONE pmdk-1.11.1/src/test/getopt/TEST0.PS10000664000000000000000000000104314123364546015470 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/getopt/TEST0 -- unit test for windows getopt implementation # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup $ERR="stderr${Env:UNITTEST_NUM}.log" expect_normal_exit $Env:EXE_DIR\getopt$Env:EXESUFFIX nonOption -f -3arg ` -Barg -b --arg_4=a --arg_G -5 -a -A arg --arg_g -d -1 -e nonOption2 --arg_8 ` nonOption3 --arg_6 -E-a --arg_C=arg -a -7arg --arg_c --arg_D arg -h --arg_H ` arg -2 nonOption4 2> $ERR check pass pmdk-1.11.1/src/test/getopt/.gitignore0000664000000000000000000000000714123364546016273 0ustar rootrootgetopt pmdk-1.11.1/src/test/getopt/TEST10000775000000000000000000000055214123364546015076 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/getopt/TEST1 -- unit test for windows getopt implementation # . ../unittest/unittest.sh require_test_type medium require_fs_type none ERR=stderr${UNITTEST_NUM}.log setup expect_normal_exit ./getopt$EXESUFFIX -Z --arg_Z -A 2>$ERR check pass pmdk-1.11.1/src/test/getopt/out1.log.match0000664000000000000000000000020614123364546016772 0ustar rootrootgetopt/TEST1: START: getopt $(nW)getopt$(nW) -Z --arg_Z -A unknown argument unknown argument unknown argument getopt$(nW)TEST1: DONE pmdk-1.11.1/src/test/getopt/stderr1.log.match0000664000000000000000000000021514123364546017466 0ustar rootroot$(nW)getopt$(nW): invalid option -- 'Z' $(nW)getopt$(nW): unrecognized option '--arg_Z' $(nW)getopt$(nW): option requires an argument -- 'A' pmdk-1.11.1/src/test/obj_zones/0000775000000000000000000000000014123364546014774 5ustar rootrootpmdk-1.11.1/src/test/obj_zones/obj_zones.c0000664000000000000000000000522214123364546017131 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_zones.c -- allocates from a very large pool (exceeding 1 zone) * */ #include #include #include "unittest.h" #define LAYOUT_NAME "obj_zones" #define ALLOC_SIZE ((8191 * (256 * 1024)) - 16) /* must evenly divide a zone */ /* * test_create -- allocate all possible objects and log the number. It should * exceed what would be possible on a single zone. * Additionally, free one object so that we can later check that it can be * allocated after the next open. */ static void test_create(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid oid; int n = 0; while (1) { if (pmemobj_alloc(pop, &oid, ALLOC_SIZE, 0, NULL, NULL) != 0) break; n++; } UT_OUT("allocated: %d", n); pmemobj_free(&oid); pmemobj_close(pop); } /* * test_open -- in the open test we should be able to allocate exactly * one object. */ static void test_open(const char *path) { PMEMobjpool *pop; if ((pop = pmemobj_open(path, LAYOUT_NAME)) == NULL) UT_FATAL("!pmemobj_open: %s", path); int ret = pmemobj_alloc(pop, NULL, ALLOC_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, NULL, ALLOC_SIZE, 0, NULL, NULL); UT_ASSERTne(ret, 0); pmemobj_close(pop); } /* * test_malloc_free -- test if alloc until OOM/free/alloc until OOM sequence * produces the same number of allocations for the second alloc loop. */ static void test_malloc_free(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); size_t alloc_size = PMEM_PAGESIZE * 32; size_t max_allocs = 1000000; PMEMoid *oid = MALLOC(sizeof(PMEMoid) * max_allocs); size_t n = 0; while (1) { if (pmemobj_alloc(pop, &oid[n], alloc_size, 0, NULL, NULL) != 0) break; n++; UT_ASSERTne(n, max_allocs); } size_t first_run_allocated = n; for (size_t i = 0; i < n; ++i) { pmemobj_free(&oid[i]); } n = 0; while (1) { if (pmemobj_alloc(pop, &oid[n], alloc_size, 0, NULL, NULL) != 0) break; n++; } UT_ASSERTeq(first_run_allocated, n); pmemobj_close(pop); FREE(oid); } int main(int argc, char *argv[]) { START(argc, argv, "obj_zones"); if (argc != 3) UT_FATAL("usage: %s file-name [open|create]", argv[0]); const char *path = argv[1]; char op = argv[2][0]; if (op == 'c') test_create(path); else if (op == 'o') test_open(path); else if (op == 'f') test_malloc_free(path); else UT_FATAL("invalid operation"); DONE(NULL); } pmdk-1.11.1/src/test/obj_zones/TEST00000775000000000000000000000057014123364546015563 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ../unittest/unittest.sh # too large configure_valgrind force-disable require_test_type medium setup create_holey_file 64G $DIR/testfile1 expect_normal_exit ./obj_zones$EXESUFFIX $DIR/testfile1 c check expect_normal_exit ./obj_zones$EXESUFFIX $DIR/testfile1 o pass pmdk-1.11.1/src/test/obj_zones/Makefile0000664000000000000000000000033114123364546016431 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_zones/Makefile -- build obj_zones test # TARGET = obj_zones OBJS = obj_zones.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_zones/obj_zones.vcxproj.filters0000664000000000000000000000177114123364546022056 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 {b539ef93-f1f6-4c62-b624-1a07e6615e21} match Source Files Match Files Test Files pmdk-1.11.1/src/test/obj_zones/out0.log.match0000664000000000000000000000016414123364546017462 0ustar rootrootobj_zones$(nW)TEST0: START: obj_zones $(nW)obj_zones$(nW) $(nW)testfile1 c allocated: 32 obj_zones$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_zones/TEST0.PS10000664000000000000000000000071214123364546016160 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_zones/TEST0 -- utnit test for allocates # from a very large pool (exceeding 1 zone) # . ..\unittest\unittest.ps1 # too large require_test_type medium setup create_holey_file 64G $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\obj_zones$Env:EXESUFFIX $DIR\testfile1 c check expect_normal_exit $Env:EXE_DIR\obj_zones$Env:EXESUFFIX $DIR\testfile1 o pass pmdk-1.11.1/src/test/obj_zones/.gitignore0000664000000000000000000000001214123364546016755 0ustar rootrootobj_zones pmdk-1.11.1/src/test/obj_zones/TEST10000775000000000000000000000066314123364546015567 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation . ../unittest/unittest.sh # too large configure_valgrind force-disable require_test_type medium # runs too long on debug builds require_build_type nondebug setup require_free_space 64G create_holey_file 64G $DIR/testfile1 PMEM_IS_PMEM_FORCE=1 PMEM_NO_FLUSH=1 expect_normal_exit\ ./obj_zones$EXESUFFIX $DIR/testfile1 f check pass pmdk-1.11.1/src/test/obj_zones/obj_zones.vcxproj0000664000000000000000000000667114123364546020413 0ustar rootroot Debug x64 Release x64 {CF9F4CEA-EC66-4E78-A086-107EB29E0637} Win32Proj obj_zones 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_rm_remote/0000775000000000000000000000000014123364546017374 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_rm_remote/TEST30000775000000000000000000000240414123364546020164 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # # libpmempool_rm_remote/TEST3 -- test for pmempool_rm with remote replica # # Remove pool, do not remove local and remote pool sets. # . ../unittest/unittest.sh require_test_type medium require_nodes 2 require_node_dax_device 0 1 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 create_poolset $DIR/pool.set 8M:${NODE_DIR[1]}pool.1:x \ m ${NODE_ADDR[0]}:remote.set create_poolset $DIR/remote.set AUTO:$(get_node_devdax_path 0 0) copy_files_to_node 0 ${NODE_DIR[0]} $DIR/remote.set copy_files_to_node 1 ${NODE_DIR[1]} $DIR/pool.set expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX -f ${NODE_DIR[1]}pool.set expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set check_files_on_node 0 remote.set check_no_files_on_node 1 pool.1 # Verify that we can create pool on device dax after removing it. expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set pass pmdk-1.11.1/src/test/libpmempool_rm_remote/TEST00000775000000000000000000000217514123364546020166 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # # libpmempool_rm_remote/TEST0 -- test for pmempool_rm with remote replica # # Remove pool, do not remove local and remote pool sets. # . ../unittest/unittest.sh require_test_type medium require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 create_poolset $DIR/pool.set 8M:${NODE_DIR[1]}/pool.1:x \ m ${NODE_ADDR[0]}:remote.set create_poolset $DIR/remote.set 8M:${NODE_DIR[0]}remote.1:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/remote.set copy_files_to_node 1 ${NODE_DIR[1]} $DIR/pool.set rm_files_from_node 0 ${NODE_DIR[0]}remote.1 rm_files_from_node 1 ${NODE_DIR[1]}pool.1 expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set check_files_on_node 0 remote.set check_no_files_on_node 1 pool.1 check_no_files_on_node 0 remote.1 pass pmdk-1.11.1/src/test/libpmempool_rm_remote/Makefile0000664000000000000000000000045214123364546021035 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/libpmempool_rm_remote/Makefile -- unit test for pmempool_rm # with remote replica # SCP_TO_REMOTE_NODES = y SCP_TARGET = libpmempool_rm SCP_SRC_DIR = ../libpmempool_rm include ../libpmempool_rm/Makefile.inc pmdk-1.11.1/src/test/libpmempool_rm_remote/TEST40000775000000000000000000000246014123364546020167 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_rm_remote/TEST4 -- test for pmempool_rm with remote replica # # Remove pool when it is opened # . ../unittest/unittest.sh require_test_type medium require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 create_poolset $DIR/pool.set 8M:${NODE_DIR[1]}pool.1:x \ m ${NODE_ADDR[0]}:remote.set create_poolset $DIR/remote.set 8M:${NODE_DIR[0]}/remote.1:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/remote.set copy_files_to_node 1 ${NODE_DIR[1]} $DIR/pool.set rm_files_from_node 0 ${NODE_DIR[0]}remote.1 rm_files_from_node 1 ${NODE_DIR[1]}pool.1 expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 # without force pmempool_rm should fail expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX -o \ ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 # with force pmempool_rm should also fail expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX -of \ ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 pass pmdk-1.11.1/src/test/libpmempool_rm_remote/config.sh0000664000000000000000000000043514123364546021177 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # libpmempool_rm_remote/config.sh -- test configuration # CONF_GLOBAL_FS_TYPE=any CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/libpmempool_rm_remote/TEST10000775000000000000000000000216114123364546020162 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # # libpmempool_rm_remote/TEST1 -- test for pmempool_rm with remote replica # # Remove pool and local pool set, do not remove remote pool set. # . ../unittest/unittest.sh require_test_type medium require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 create_poolset $DIR/pool.set 8M:${NODE_DIR[1]}pool.1:x \ m ${NODE_ADDR[0]}:remote.set create_poolset $DIR/remote.set 8M:${NODE_DIR[0]}remote.1:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/remote.set copy_files_to_node 1 ${NODE_DIR[1]} $DIR/pool.set rm_files_from_node 0 ${NODE_DIR[0]}remote.1 rm_files_from_node 1 ${NODE_DIR[1]}pool.1 expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX -l ${NODE_DIR[1]}pool.set check_files_on_node 0 remote.set check_no_files_on_node 1 pool.set pool.1 check_no_files_on_node 0 remote.1 pass pmdk-1.11.1/src/test/libpmempool_rm_remote/TEST20000775000000000000000000000211114123364546020156 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # # libpmempool_rm_remote/TEST2 -- test for pmempool_rm with remote replica # # Remove pool, local and remote pool sets. # . ../unittest/unittest.sh require_test_type medium require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 create_poolset $DIR/pool.set 8M:${NODE_DIR[1]}pool.1:x \ m ${NODE_ADDR[0]}:remote.set create_poolset $DIR/remote.set 8M:${NODE_DIR[0]}/remote.1:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/remote.set copy_files_to_node 1 ${NODE_DIR[1]} $DIR/pool.set rm_files_from_node 0 ${NODE_DIR[0]}remote.1 rm_files_from_node 1 ${NODE_DIR[1]}pool.1 expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}pool.set check_files_on_node 1 pool.set pool.1 check_files_on_node 0 remote.set remote.1 expect_normal_exit run_on_node 1 ./libpmempool_rm$EXESUFFIX -l -r ${NODE_DIR[1]}pool.set check_no_files_on_node 1 pool.set pool.1 check_no_files_on_node 0 remote.set remote.1 pass pmdk-1.11.1/src/test/obj_ctl_heap_size/0000775000000000000000000000000014123364546016447 5ustar rootrootpmdk-1.11.1/src/test/obj_ctl_heap_size/TEST1.PS10000664000000000000000000000077314123364546017643 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_heap_size/TEST1 -- unit test for obj_ctl_heap_size() # . ..\unittest\unittest.ps1 require_test_type short require_fs_type any setup create_poolset $DIR\testset1 ` 4G:$DIR\testdir11:d ` O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj --layout obj_ctl_heap_size ` $DIR\testset1 # create pool sets expect_normal_exit $Env:EXE_DIR\obj_ctl_heap_size$Env:EXESUFFIX $DIR\testset1 x pass pmdk-1.11.1/src/test/obj_ctl_heap_size/TEST00000775000000000000000000000070614123364546017237 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any setup RESVSIZE=$((4 * 1024 * 1024 * 1024)) create_poolset $DIR/testset1 $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj --layout obj_ctl_heap_size\ $DIR/testset1 expect_normal_exit ./obj_ctl_heap_size$EXESUFFIX $DIR/testset1 w pass pmdk-1.11.1/src/test/obj_ctl_heap_size/obj_ctl_heap_size.c0000664000000000000000000000273414123364546022264 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * obj_ctl_heap_size.c -- tests for the ctl entry points: heap.size.* */ #include "unittest.h" #define LAYOUT "obj_ctl_heap_size" #define CUSTOM_GRANULARITY ((1 << 20) * 10) #define OBJ_SIZE 1024 int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_heap_size"); if (argc != 3) UT_FATAL("usage: %s poolset [w|x]", argv[0]); const char *path = argv[1]; char t = argv[2][0]; PMEMobjpool *pop; if ((pop = pmemobj_open(path, LAYOUT)) == NULL) UT_FATAL("!pmemobj_open: %s", path); int ret = 0; size_t disable_granularity = 0; ret = pmemobj_ctl_set(pop, "heap.size.granularity", &disable_granularity); UT_ASSERTeq(ret, 0); /* allocate until OOM */ while (pmemobj_alloc(pop, NULL, OBJ_SIZE, 0, NULL, NULL) == 0) ; if (t == 'x') { ssize_t extend_size = CUSTOM_GRANULARITY; ret = pmemobj_ctl_exec(pop, "heap.size.extend", &extend_size); UT_ASSERTeq(ret, 0); } else if (t == 'w') { ssize_t new_granularity = CUSTOM_GRANULARITY; ret = pmemobj_ctl_set(pop, "heap.size.granularity", &new_granularity); UT_ASSERTeq(ret, 0); ssize_t curr_granularity; ret = pmemobj_ctl_get(pop, "heap.size.granularity", &curr_granularity); UT_ASSERTeq(ret, 0); UT_ASSERTeq(new_granularity, curr_granularity); } else { UT_ASSERT(0); } /* should succeed */ ret = pmemobj_alloc(pop, NULL, OBJ_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_ctl_heap_size/obj_ctl_heap_size.vcxproj0000664000000000000000000000622314123364546023532 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {B379539C-E130-460D-AE82-4EBDD1A97845} Win32Proj obj_ctl_config 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/obj_ctl_heap_size/Makefile0000664000000000000000000000037114123364546020110 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_heap_size/Makefile -- build obj_ctl_heap_size test # TARGET = obj_ctl_heap_size OBJS = obj_ctl_heap_size.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_ctl_heap_size/TEST0.PS10000664000000000000000000000077314123364546017642 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_heap_size/TEST0 -- unit test for obj_ctl_heap_size() # . ..\unittest\unittest.ps1 require_test_type short require_fs_type any setup create_poolset $DIR\testset1 ` 4G:$DIR\testdir11:d ` O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj --layout obj_ctl_heap_size ` $DIR\testset1 # create pool sets expect_normal_exit $Env:EXE_DIR\obj_ctl_heap_size$Env:EXESUFFIX $DIR\testset1 w pass pmdk-1.11.1/src/test/obj_ctl_heap_size/obj_ctl_heap_size.vcxproj.filters0000664000000000000000000000153114123364546025176 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {e0bdbab6-d3b6-4139-8bf0-5f4b9de0df8b} ps1 Source Files Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_ctl_heap_size/.gitignore0000664000000000000000000000002214123364546020431 0ustar rootrootobj_ctl_heap_size pmdk-1.11.1/src/test/obj_ctl_heap_size/TEST10000775000000000000000000000070614123364546017240 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any setup RESVSIZE=$((4 * 1024 * 1024 * 1024)) create_poolset $DIR/testset1 $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj --layout obj_ctl_heap_size\ $DIR/testset1 expect_normal_exit ./obj_ctl_heap_size$EXESUFFIX $DIR/testset1 x pass pmdk-1.11.1/src/test/pmemset_deep_flush/0000775000000000000000000000000014123364546016654 5ustar rootrootpmdk-1.11.1/src/test/pmemset_deep_flush/mock_windows.h0000664000000000000000000000023714123364546021532 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2021, Intel Corporation */ #ifndef WRAP_REAL #define pmem2_deep_flush __wrap_pmem2_deep_flush #endif pmdk-1.11.1/src/test/pmemset_deep_flush/pmemset_deep_flush.vcxproj0000664000000000000000000001143714123364546024147 0ustar rootroot Debug x64 Release x64 {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {47E7DAFC-4EDA-4007-BB7B-4BEB6D63C222} Win32Proj pmemset_deep_flush 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) mock_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) mock_windows.h;%(ForcedIncludeFiles) pmdk-1.11.1/src/test/pmemset_deep_flush/Makefile0000664000000000000000000000111614123364546020313 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # # # src/test/pmemset_deep_flush/Makefile -- build for pmemset_deep_flush API unit tests # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmemset vpath %.c $(TOP)/src/libpmem2 vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmemset TARGET = pmemset_deep_flush OBJS += pmemset_deep_flush.o\ ut_pmemset_utils.o LIBPMEMSET=internal-debug LIBPMEM2=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, pmemset_deep_flush.c) pmdk-1.11.1/src/test/pmemset_deep_flush/TESTS.py0000775000000000000000000000151714123364546020137 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class PMEMSET_DEEP_FLUSH(t.Test): test_type = t.Short create_file = True def run(self, ctx): filepath = ctx.create_holey_file(32 * t.MiB, 'testfile1') ctx.exec('pmemset_deep_flush', self.test_case, filepath) class TEST0(PMEMSET_DEEP_FLUSH): """test pmemset_deep_flush on single part map""" test_case = "test_deep_flush_single" class TEST1(PMEMSET_DEEP_FLUSH): """test pmemset_deep_flush on multiple part maps""" test_case = "test_deep_flush_multiple" class TEST2(PMEMSET_DEEP_FLUSH): """test pmemset_deep_flush on multiple part maps with coalescing""" test_case = "test_deep_flush_multiple_coal" pmdk-1.11.1/src/test/pmemset_deep_flush/pmemset_deep_flush.vcxproj.filters0000664000000000000000000000445614123364546025621 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {bfc2182c-11f1-4b3c-8a7c-5570f93e83b6} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Test Scripts pmdk-1.11.1/src/test/pmemset_deep_flush/.gitignore0000664000000000000000000000003114123364546020636 0ustar rootrootpmemset_deep_flush *.old pmdk-1.11.1/src/test/pmemset_deep_flush/pmemset_deep_flush.c0000664000000000000000000001720514123364546022675 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2021, Intel Corporation */ /* * pmemset_persist.c -- pmemset_part unittests */ #include "out.h" #include "unittest.h" #include "ut_pmemset_utils.h" static int pmem2_df_count; FUNC_MOCK(pmem2_deep_flush, int, struct pmem2_map *map, void *ptr, size_t size) FUNC_MOCK_RUN_DEFAULT { pmem2_df_count++; return _FUNC_REAL(pmem2_deep_flush)(map, ptr, size); } FUNC_MOCK_END static void create_config(struct pmemset_config **cfg) { int ret = pmemset_config_new(cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); ret = pmemset_config_set_required_store_granularity(*cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); } /* * test_deep_flush_single - test pmemset_deep_flush combinations with single map */ static int test_deep_flush_single(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_deep_flush_single "); const char *file = argv[0]; struct pmemset_part *part; struct pmemset_source *src; struct pmemset *set; struct pmemset_config *cfg; int ret = pmemset_source_from_file(&src, file); UT_PMEMSET_EXPECT_RETURN(ret, 0); create_config(&cfg); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_new(&part, set, src, 0, 64 * 1024); UT_PMEMSET_EXPECT_RETURN(ret, 0); struct pmemset_part_descriptor desc; ret = pmemset_part_map(&part, NULL, &desc); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(part, NULL); /* flush single part map */ pmemset_deep_flush(set, desc.addr, desc.size); UT_ASSERTeq(pmem2_df_count, 1); pmem2_df_count = 0; /* flush half of a single part map */ pmemset_deep_flush(set, desc.addr, desc.size / 2); UT_ASSERTeq(pmem2_df_count, 1); pmem2_df_count = 0; /* flush half of a single part map and out of map */ pmemset_deep_flush(set, (char *)desc.addr + desc.size / 2, desc.size); UT_ASSERTeq(pmem2_df_count, 1); pmem2_df_count = 0; /* flush out of map */ pmemset_deep_flush(set, (char *)desc.addr - desc.size, desc.size / 2); UT_ASSERTeq(pmem2_df_count, 0); ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_config_delete(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); return 1; } /* * test_deep_flush_multiple_coal - test pmemset_deep_flush * conbinations on multiple part maps with coalescing */ static int test_deep_flush_multiple_coal(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_deep_flush_multiple_coal "); const char *file1 = argv[0]; struct pmemset_part *part; struct pmemset_source *src; struct pmemset *set; struct pmemset_config *cfg; size_t part_size = 64 * 1024; const size_t num_of_parts = 8; struct pmemset_part_descriptor desc; int ret = pmemset_source_from_file(&src, file1); UT_PMEMSET_EXPECT_RETURN(ret, 0); create_config(&cfg); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_set_contiguous_part_coalescing(set, PMEMSET_COALESCING_FULL); UT_PMEMSET_EXPECT_RETURN(ret, 0); for (int i = 0; i < num_of_parts; i++) { ret = pmemset_part_new(&part, set, src, 0, part_size); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_map(&part, NULL, &desc); if (ret == PMEMSET_E_CANNOT_COALESCE_PARTS) goto end; UT_PMEMSET_EXPECT_RETURN(ret, 0); } /* flush all maps */ pmemset_deep_flush(set, desc.addr, desc.size); UT_ASSERTeq(pmem2_df_count, num_of_parts); pmem2_df_count = 0; /* flush a half of all parts */ pmemset_deep_flush(set, (char *)desc.addr + (part_size * (num_of_parts / 2)), desc.size); UT_ASSERTeq(pmem2_df_count, num_of_parts / 2); pmem2_df_count = 0; /* flush tree maps, but start and finish at the middle of them */ pmemset_deep_flush(set, (char *)desc.addr + (part_size / 2), part_size * 2); UT_ASSERTeq(pmem2_df_count, 3); pmem2_df_count = 0; /* * flush one (not first) map, but start and finish are in the middle, * it means flush range is smaller than map */ pmemset_deep_flush(set, (char *)desc.addr + ((part_size * 2) + (part_size / 4)), part_size / 4); UT_ASSERTeq(pmem2_df_count, 1); pmem2_df_count = 0; /* * flush tree maps, but start and finish at the middle of them, * and start is not in the first map */ pmemset_deep_flush(set, (char *)desc.addr + part_size + (part_size / 2), part_size * 2); UT_ASSERTeq(pmem2_df_count, 3); pmem2_df_count = 0; /* flush one map, use whole map size as a range */ pmemset_deep_flush(set, (char *)desc.addr + (part_size * 5), part_size); UT_ASSERTeq(pmem2_df_count, 1); pmem2_df_count = 0; /* * flush two maps, but start at the beginning of fifth and * finish at the middle of the next one */ pmemset_deep_flush(set, (char *)desc.addr + (part_size * 5), part_size + (part_size / 2)); UT_ASSERTeq(pmem2_df_count, 2); pmem2_df_count = 0; /* flush all, but range out of maps */ pmemset_deep_flush(set, (char *)desc.addr, desc.size + part_size); UT_ASSERTeq(pmem2_df_count, num_of_parts); end: ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_config_delete(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); return 1; } /* * test_deep_flush_multiple - test pmemset_deep_flush conbinations on multiple * part maps */ static int test_deep_flush_multiple(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_deep_flush_multiple "); const char *file1 = argv[0]; struct pmemset_part *part; struct pmemset_source *src; struct pmemset *set; struct pmemset_config *cfg; struct pmemset_part_map *first_pmap = NULL; struct pmemset_part_map *second_pmap = NULL; struct pmemset_part_descriptor first_desc; struct pmemset_part_descriptor second_desc; size_t part_size = 64 * 1024; int ret = pmemset_source_from_file(&src, file1); UT_PMEMSET_EXPECT_RETURN(ret, 0); create_config(&cfg); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_new(&part, set, src, 0, part_size); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_map(&part, NULL, NULL); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_new(&part, set, src, 0, part_size); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_map(&part, NULL, NULL); UT_PMEMSET_EXPECT_RETURN(ret, 0); pmemset_first_part_map(set, &first_pmap); UT_ASSERTne(first_pmap, NULL); pmemset_next_part_map(set, first_pmap, &second_pmap); UT_ASSERTne(second_pmap, NULL); first_desc = pmemset_descriptor_part_map(first_pmap); second_desc = pmemset_descriptor_part_map(second_pmap); size_t len = (size_t)((char *)second_desc.addr - (char *)first_desc.addr); size_t range_size = second_desc.size + len; /* flush both maps at once */ pmemset_deep_flush(set, first_desc.addr, range_size); UT_ASSERTeq(pmem2_df_count, 2); ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_config_delete(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_deep_flush_single), TEST_CASE(test_deep_flush_multiple), TEST_CASE(test_deep_flush_multiple_coal), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmemset_deep_flush"); util_init(); out_init("pmemset_deep_flush", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } #ifdef _MSC_VER MSVC_CONSTR(libpmemset_init) MSVC_DESTR(libpmemset_fini) #endif pmdk-1.11.1/src/test/pmem_is_pmem_posix/0000775000000000000000000000000014123364546016675 5ustar rootrootpmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST30000775000000000000000000000127614123364546017473 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST3 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none setup # empty list - all queries should produce 0 expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ t 0x7fff77423000 2147479552\ t 0x7fff77423000 2147483648\ t 0x7fff77423000 8192\ t 0x7fff77423000 4096\ t 0x7fff77424000 2147479552\ t 0x7fff77424000 2147483648\ t 0x7fff77424000 8192\ t 0x7fff77428000 10240\ t 0x7fff77423000 0\ t 0x7fff77424000 0\ t 0x7fff77424000 0xffffffffffffffff\ t 0x7fff77423008 1\ t 0x7fff77423FF0 32 check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST00000775000000000000000000000347014123364546017466 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST0 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_dax_devices 1 setup # two mm entries # # 7fff77423000 2147479552 # start at first mm entry, extends into second: should produce: 1 # 7fff77423000 2147483648 # exactly matches sum of both mm entries: should produce: 1 # 7fff77423000 8192 # start at first mm entry, extends into second: should produce: 1 # 7fff77423000 4096 # entirely encompassed by first mm entry: should produce: 1 # 7fff77424000 2147479552 # exactly matches second mm entry, should produce: 1 # 7fff77424000 2147483648 # extends past second mm entry, should produce: 0 # 7fff77424000 8192 # entirely encompassed by second mm entry: should produce: 1 # 7fff77428000 10240 # subset of second mm entry: should produce: 1 # 7fff77423000 0 # starts at first mm entry: should produce: 1 # 7fff77424000 0 # starts at second mm entry: should produce: 1 # 7fff77424000 0xffffffffffffffff # extends past second mm entry, should produce: 0 # 7fff77423008 1 # entirely encompassed by first mm entry: should produce: 1 # 7fff77423ff0 32 # start at first mm entry, extends into second: should produce: 1 expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ f 0x7fff77423000 4096 MAP_SYNC\ a 0x7fff77423000 4096 MAP_SYNC\ a 0x7fff77424000 2147479552 DEV_DAX ${DEVICE_DAX_PATH[0]}\ \ t 0x7fff77423000 2147479552\ t 0x7fff77423000 2147483648\ t 0x7fff77423000 8192\ t 0x7fff77423000 4096\ t 0x7fff77424000 2147479552\ t 0x7fff77424000 2147483648\ t 0x7fff77424000 8192\ t 0x7fff77428000 10240\ t 0x7fff77423000 0\ t 0x7fff77424000 0\ t 0x7fff77424000 0xffffffffffffffff\ t 0x7fff77423008 1\ t 0x7fff77423FF0 32 check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/Makefile0000664000000000000000000000153614123364546020342 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/pmem_is_pmem_posix/Makefile -- build pmem_is_pmem_posix unit test # include ../../common.inc TOP = ../../.. vpath %.c $(TOP)/src/libpmem vpath %.c $(TOP)/src/libpmem2 vpath %.c $(TOP)/src/libpmem2/$(ARCH) TARGET = pmem_is_pmem_posix OBJS = pmem_is_pmem_posix.o\ libpmem.o\ pmem.o\ pmem_posix.o\ memops_generic.o ifeq ($(ARCH), aarch64) OBJS += init.o endif ifeq ($(ARCH), x86_64) OBJS += init.o cpu.o endif ifeq ($(ARCH), ppc64) include $(TOP)/src/libpmem2/$(ARCH)/sources.inc OBJS += $(LIBPMEM2_ARCH_SOURCE:%.c=%.o) endif LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -DSRCVERSION="" -DDEBUG -DAVX512F_AVAILABLE=0 -DAVX_AVAILABLE=0 -DSSE2_AVAILABLE=0 CFLAGS += -I$(TOP)/src/libpmem CFLAGS += -I$(TOP)/src/libpmem/$(ARCH) CFLAGS += -I$(TOP)/src/libpmem2 pmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST50000775000000000000000000000077414123364546017477 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST5 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_dax_devices 1 setup # test adding/removing ranges to/from map tracking list expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ a 0x000000030000 0x20000 DEV_DAX ${DEVICE_DAX_PATH[0]}\ s 0x000000040000 0x20000\ r 0x000000040000 0x20000\ check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST40000775000000000000000000000267614123364546017501 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST4 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_dax_devices 1 setup # test adding/removing ranges to/from map tracking list expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ a 0x000000010000 0x10000 DEV_DAX ${DEVICE_DAX_PATH[0]}\ t 0x000000010000 0x10000\ t 0x000000020000 0x10000\ t 0x000000030000 0x10000\ t 0x000000040000 0x10000\ t 0x000000010000 0x40000\ a 0x000000020000 0x10000 MAP_SYNC\ t 0x000000010000 0x10000\ t 0x000000020000 0x10000\ t 0x000000030000 0x10000\ t 0x000000040000 0x10000\ t 0x000000010000 0x40000\ a 0x000000030000 0x20000 DEV_DAX ${DEVICE_DAX_PATH[0]}\ t 0x000000010000 0x10000\ t 0x000000020000 0x10000\ t 0x000000030000 0x10000\ t 0x000000040000 0x10000\ t 0x000000010000 0x40000\ s 0x000000020000 0x20000\ r 0x000000020000 0x20000\ t 0x000000010000 0x10000\ t 0x000000020000 0x10000\ t 0x000000030000 0x10000\ t 0x000000040000 0x10000\ t 0x000000010000 0x40000\ r 0x000000010000 0x40000\ t 0x000000010000 0x10000\ t 0x000000020000 0x10000\ t 0x000000030000 0x10000\ t 0x000000040000 0x10000\ t 0x000000010000 0x40000\ a 0x000000030000 0x20000 DEV_DAX ${DEVICE_DAX_PATH[0]}\ a 0x000000020000 0x20000 DEV_DAX ${DEVICE_DAX_PATH[0]}\ t 0x000000030000 0x20000\ t 0x000000020000 0x20000 check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/out0.log.match0000664000000000000000000000121414123364546021360 0ustar rootrootpmem_is_pmem_posix/TEST0: START: pmem_is_pmem_posix ./pmem_is_pmem_posix$(nW) $(*) addr 0x7fff77423000 len 2147479552 is_pmem 1 addr 0x7fff77423000 len 2147483648 is_pmem 1 addr 0x7fff77423000 len 8192 is_pmem 1 addr 0x7fff77423000 len 4096 is_pmem 1 addr 0x7fff77424000 len 2147479552 is_pmem 1 addr 0x7fff77424000 len 2147483648 is_pmem 0 addr 0x7fff77424000 len 8192 is_pmem 1 addr 0x7fff77428000 len 10240 is_pmem 1 addr 0x7fff77423000 len 0 is_pmem 0 addr 0x7fff77424000 len 0 is_pmem 0 addr 0x7fff77424000 len 18446744073709551615 is_pmem 0 addr 0x7fff77423008 len 1 is_pmem 1 addr 0x7fff77423ff0 len 32 is_pmem 1 pmem_is_pmem_posix/TEST0: DONE pmdk-1.11.1/src/test/pmem_is_pmem_posix/.gitignore0000664000000000000000000000002314123364546020660 0ustar rootrootpmem_is_pmem_posix pmdk-1.11.1/src/test/pmem_is_pmem_posix/README0000664000000000000000000000156414123364546017563 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_is_pmem_posix/README. This test is Posix specific. This directory contains a unit test for pmem_is_pmem(). The program in pmem_is_pmem_posix.c takes a list of fake memory regions (an address and a length) and modifies the internal file map tracking list by adding or removing given region, depending on the op argument ('a' - add, 'r' - remove). It arranges for pmem_is_pmem() to use this fake list of file mappings when looking up the range. usage: pmem_is_pmem_posix op addr len [op addr len]... op is one of: 'a' (add), 'r' (remove), 't' (test), 'f' (fault_injection for util_range_register), 's' (fault_injection for util_range_split) addr is interpreted as a hex value, len as a decimal value unless it starts with 0x. If op argument is 't', then addr/len pair is tested against the current list of memory regions. pmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST10000775000000000000000000000321414123364546017463 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST1 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_dax_devices 1 setup # single mm entry - 0x7fff77423000 4096 # # 7fff77423000 2147479552 # extends past mm entry, should produce: 0 # 7fff77423000 2147483648 # extends past mm entry, should produce: 0 # 7fff77423000 8192 # extends past mm entry, should produce: 0 # 7fff77423000 4096 # entirely encompassed by mm entry: should produce: 1 # 7fff77424000 2147479552 # extends past mm entry, should produce: 0 # 7fff77424000 2147483648 # extends past mm entry, should produce: 0 # 7fff77424000 8192 # extends past mm entry, should produce: 0 # 7fff77428000 10240 # extends past mm entry, should produce: 0 # 7fff77423000 0 # starts at mm entry: should produce: 1 # 7fff77424000 0 # starts behind mm entry, should produce: 0 # 7fff77424000 0xffffffffffffffff # starts behind mm entry, should produce: 0 # 7fff77423008 1 # entirely encompassed by first mm entry: should produce: 0 # 7fff77423ff0 32 # start at first mm entry, extends into second: should produce: 0 expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ a 0x7fff77423000 4096 DEV_DAX ${DEVICE_DAX_PATH[0]}\ \ t 0x7fff77423000 2147479552\ t 0x7fff77423000 2147483648\ t 0x7fff77423000 8192\ t 0x7fff77423000 4096\ t 0x7fff77424000 2147479552\ t 0x7fff77424000 2147483648\ t 0x7fff77424000 8192\ t 0x7fff77428000 10240\ t 0x7fff77423000 0\ t 0x7fff77424000 0\ t 0x7fff77424000 0xffffffffffffffff\ t 0x7fff77423008 1\ t 0x7fff77423FF0 32 check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/pmem_is_pmem_posix.c0000664000000000000000000000575314123364546022744 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * pmem_is_pmem_posix.c -- Posix specific unit test for pmem_is_pmem() * * usage: pmem_is_pmem_posix op addr len [op addr len ...] * where op can be: 'a' (add), 'r' (remove), 't' (test), * 'f' (fault_injection for util_range_register), * 's' (fault_injection for util_range_split) */ #include #include "unittest.h" #include "mmap.h" #include "../libpmem/pmem.h" static enum pmem_map_type str2type(char *str) { if (strcmp(str, "DEV_DAX") == 0) return PMEM_DEV_DAX; if (strcmp(str, "MAP_SYNC") == 0) return PMEM_MAP_SYNC; FATAL("unknown type '%s'", str); } static int do_fault_injection_register(void *addr, size_t len, enum pmem_map_type type) { if (!pmem_fault_injection_enabled()) goto end; pmem_inject_fault_at(PMEM_MALLOC, 1, "util_range_register"); int ret = util_range_register(addr, len, "", type); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); end: return 4; } static int do_fault_injection_split(void *addr, size_t len) { if (!pmem_fault_injection_enabled()) goto end; pmem_inject_fault_at(PMEM_MALLOC, 1, "util_range_split"); int ret = util_range_unregister(addr, len); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); end: return 3; } static int range_add(void *addr, size_t len, const char *path, enum pmem_map_type t) { int ret = util_range_register(addr, len, path, t); if (ret != 0) UT_OUT("%s", pmem_errormsg()); return 4; } static int range_add_ddax(void *addr, size_t len, const char *path, enum pmem_map_type t) { range_add(addr, len, path, t); return 5; } static int range_rm(void *addr, size_t len) { int ret = util_range_unregister(addr, len); UT_ASSERTeq(ret, 0); return 3; } static int range_test(void *addr, size_t len) { UT_OUT("addr %p len %zu is_pmem %d", addr, len, pmem_is_pmem(addr, len)); return 3; } int main(int argc, char *argv[]) { START(argc, argv, "pmem_is_pmem_posix"); if (argc < 4) UT_FATAL("usage: %s op addr len type [op addr len type file]", argv[0]); /* insert memory regions to the list */ int i; for (i = 1; i < argc; ) { UT_ASSERT(i + 2 < argc); errno = 0; void *addr = (void *)strtoull(argv[i + 1], NULL, 0); UT_ASSERTeq(errno, 0); size_t len = strtoull(argv[i + 2], NULL, 0); UT_ASSERTeq(errno, 0); switch (argv[i][0]) { case 'a': { enum pmem_map_type t = str2type(argv[i + 3]); /* * If type is DEV_DAX we expect path to ddax * as a third arg. Functions return number of * consumed arguments. */ if (t == PMEM_DEV_DAX) i += range_add_ddax(addr, len, argv[i + 4], t); else i += range_add(addr, len, "", t); break; } case 'r': i += range_rm(addr, len); break; case 't': i += range_test(addr, len); break; case 'f': i += do_fault_injection_register(addr, len, str2type(argv[i + 3])); break; case 's': i += do_fault_injection_split(addr, len); break; default: FATAL("invalid op '%c'", argv[i][0]); } } DONE(NULL); } pmdk-1.11.1/src/test/pmem_is_pmem_posix/out1.log.match0000664000000000000000000000121414123364546021361 0ustar rootrootpmem_is_pmem_posix/TEST1: START: pmem_is_pmem_posix ./pmem_is_pmem_posix$(nW) $(*) addr 0x7fff77423000 len 2147479552 is_pmem 0 addr 0x7fff77423000 len 2147483648 is_pmem 0 addr 0x7fff77423000 len 8192 is_pmem 0 addr 0x7fff77423000 len 4096 is_pmem 1 addr 0x7fff77424000 len 2147479552 is_pmem 0 addr 0x7fff77424000 len 2147483648 is_pmem 0 addr 0x7fff77424000 len 8192 is_pmem 0 addr 0x7fff77428000 len 10240 is_pmem 0 addr 0x7fff77423000 len 0 is_pmem 0 addr 0x7fff77424000 len 0 is_pmem 0 addr 0x7fff77424000 len 18446744073709551615 is_pmem 0 addr 0x7fff77423008 len 1 is_pmem 1 addr 0x7fff77423ff0 len 32 is_pmem 0 pmem_is_pmem_posix/TEST1: DONE pmdk-1.11.1/src/test/pmem_is_pmem_posix/TEST20000775000000000000000000000316714123364546017473 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_is_pmem_posix/TEST2 -- unit test for pmem_is_pmem # . ../unittest/unittest.sh require_test_type medium require_fs_type none setup # single mm entry - 0x7fff77424000 2147479552 # # 7fff77423000 2147479552 # starts before mm entry, should produce: 0 # 7fff77423000 2147483648 # starts before mm entry, should produce: 0 # 7fff77423000 8192 # starts before mm entry, should produce: 0 # 7fff77423000 4096 # starts before mm entry, should produce: 0 # 7fff77424000 2147479552 # exactly matches mm entry, should produce: 1 # 7fff77424000 2147483648 # extends past mm entry, should produce: 0 # 7fff77424000 8192 # entirely encompassed by mm entry: should produce: 1 # 7fff77428000 10240 # subset of mm entry: should produce: 1 # 7fff77423000 0 # starts before mm entry, should produce: 0 # 7fff77424000 0 # starts at mm entry: should produce: 1 # 7fff77424000 0xffffffffffffffff # extends past second mm entry, should produce: 0 # 7fff77423008 1 # entirely encompassed by first mm entry: should produce: 0 # 7fff77423ff0 32 # start at first mm entry, extends into second: should produce: 0 expect_normal_exit ./pmem_is_pmem_posix$EXESUFFIX\ a 0x7fff77424000 2147479552 MAP_SYNC\ \ t 0x7fff77423000 2147479552\ t 0x7fff77423000 2147483648\ t 0x7fff77423000 8192\ t 0x7fff77423000 4096\ t 0x7fff77424000 2147479552\ t 0x7fff77424000 2147483648\ t 0x7fff77424000 8192\ t 0x7fff77428000 10240\ t 0x7fff77423000 0\ t 0x7fff77424000 0\ t 0x7fff77424000 0xffffffffffffffff\ t 0x7fff77423008 1\ t 0x7fff77423FF0 32 check pass pmdk-1.11.1/src/test/pmem_is_pmem_posix/out3.log.match0000664000000000000000000000121414123364546021363 0ustar rootrootpmem_is_pmem_posix/TEST3: START: pmem_is_pmem_posix ./pmem_is_pmem_posix$(nW) $(*) addr 0x7fff77423000 len 2147479552 is_pmem 0 addr 0x7fff77423000 len 2147483648 is_pmem 0 addr 0x7fff77423000 len 8192 is_pmem 0 addr 0x7fff77423000 len 4096 is_pmem 0 addr 0x7fff77424000 len 2147479552 is_pmem 0 addr 0x7fff77424000 len 2147483648 is_pmem 0 addr 0x7fff77424000 len 8192 is_pmem 0 addr 0x7fff77428000 len 10240 is_pmem 0 addr 0x7fff77423000 len 0 is_pmem 0 addr 0x7fff77424000 len 0 is_pmem 0 addr 0x7fff77424000 len 18446744073709551615 is_pmem 0 addr 0x7fff77423008 len 1 is_pmem 0 addr 0x7fff77423ff0 len 32 is_pmem 0 pmem_is_pmem_posix/TEST3: DONE pmdk-1.11.1/src/test/pmem_is_pmem_posix/out4.log.match0000664000000000000000000000215414123364546021370 0ustar rootrootpmem_is_pmem_posix/TEST4: START: pmem_is_pmem_posix ./pmem_is_pmem_posix$(nW) $(*) addr 0x10000 len 65536 is_pmem 1 addr 0x20000 len 65536 is_pmem 0 addr 0x30000 len 65536 is_pmem 0 addr 0x40000 len 65536 is_pmem 0 addr 0x10000 len 262144 is_pmem 0 addr 0x10000 len 65536 is_pmem 1 addr 0x20000 len 65536 is_pmem 1 addr 0x30000 len 65536 is_pmem 0 addr 0x40000 len 65536 is_pmem 0 addr 0x10000 len 262144 is_pmem 0 addr 0x10000 len 65536 is_pmem 1 addr 0x20000 len 65536 is_pmem 1 addr 0x30000 len 65536 is_pmem 1 addr 0x40000 len 65536 is_pmem 1 addr 0x10000 len 262144 is_pmem 1 addr 0x10000 len 65536 is_pmem 1 addr 0x20000 len 65536 is_pmem 0 addr 0x30000 len 65536 is_pmem 0 addr 0x40000 len 65536 is_pmem 1 addr 0x10000 len 262144 is_pmem 0 addr 0x10000 len 65536 is_pmem 0 addr 0x20000 len 65536 is_pmem 0 addr 0x30000 len 65536 is_pmem 0 addr 0x40000 len 65536 is_pmem 0 addr 0x10000 len 262144 is_pmem 0 duplicated persistent memory range; presumably unmapped with munmap() instead of pmem_unmap(): addr 0x20000 len 131072 addr 0x30000 len 131072 is_pmem 1 addr 0x20000 len 131072 is_pmem 0 pmem_is_pmem_posix/TEST4: DONE pmdk-1.11.1/src/test/pmem_is_pmem_posix/out2.log.match0000664000000000000000000000121414123364546021362 0ustar rootrootpmem_is_pmem_posix/TEST2: START: pmem_is_pmem_posix ./pmem_is_pmem_posix$(nW) $(*) addr 0x7fff77423000 len 2147479552 is_pmem 0 addr 0x7fff77423000 len 2147483648 is_pmem 0 addr 0x7fff77423000 len 8192 is_pmem 0 addr 0x7fff77423000 len 4096 is_pmem 0 addr 0x7fff77424000 len 2147479552 is_pmem 1 addr 0x7fff77424000 len 2147483648 is_pmem 0 addr 0x7fff77424000 len 8192 is_pmem 1 addr 0x7fff77428000 len 10240 is_pmem 1 addr 0x7fff77423000 len 0 is_pmem 0 addr 0x7fff77424000 len 0 is_pmem 0 addr 0x7fff77424000 len 18446744073709551615 is_pmem 0 addr 0x7fff77423008 len 1 is_pmem 0 addr 0x7fff77423ff0 len 32 is_pmem 0 pmem_is_pmem_posix/TEST2: DONE pmdk-1.11.1/src/test/win_mmap_dtor/0000775000000000000000000000000014123364546015643 5ustar rootrootpmdk-1.11.1/src/test/win_mmap_dtor/win_mmap_dtor.filters0000664000000000000000000000171014123364546022073 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {6043ccf6-d070-43a3-867f-2aa9612ac158} ps1 {9e75d124-4f98-4b16-ad1d-f62881ec9f30} match Source Files Test Scripts pmdk-1.11.1/src/test/win_mmap_dtor/win_mmap_dtor.vcxproj.filters0000664000000000000000000000112014123364546023560 0ustar rootroot {0da09383-3374-4523-b95d-d943028e8202} Source Files Source Files pmdk-1.11.1/src/test/win_mmap_dtor/win_mmap_dtor.c0000664000000000000000000000336214123364546020652 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * win_mmap_dtor.c -- unit test for windows mmap destructor */ #include "unittest.h" #include "os.h" #include "win_mmap.h" #define KILOBYTE (1 << 10) #define MEGABYTE (1 << 20) unsigned long long Mmap_align; int main(int argc, char *argv[]) { START(argc, argv, "win_mmap_dtor"); if (argc != 2) UT_FATAL("usage: %s path", argv[0]); SYSTEM_INFO si; GetSystemInfo(&si); /* set pagesize for mmap */ Mmap_align = si.dwAllocationGranularity; const char *path = argv[1]; int fd = os_open(path, O_RDWR); UT_ASSERTne(fd, -1); /* * Input file has size equal to 2MB, but the mapping is 3MB. * In this case mmap should map whole file and reserve 1MB * of virtual address space for remaining part of the mapping. */ void *addr = mmap(NULL, 3 * MEGABYTE, PROT_READ, MAP_SHARED, fd, 0); UT_ASSERTne(addr, MAP_FAILED); MEMORY_BASIC_INFORMATION basic_info; SIZE_T bytes_returned; bytes_returned = VirtualQuery(addr, &basic_info, sizeof(basic_info)); UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.RegionSize, 2 * MEGABYTE); UT_ASSERTeq(basic_info.State, MEM_COMMIT); bytes_returned = VirtualQuery((char *)addr + 2 * MEGABYTE, &basic_info, sizeof(basic_info)); UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.RegionSize, MEGABYTE); UT_ASSERTeq(basic_info.State, MEM_RESERVE); win_mmap_fini(); bytes_returned = VirtualQuery((char *)addr + 2 * MEGABYTE, &basic_info, sizeof(basic_info)); UT_ASSERTeq(bytes_returned, sizeof(basic_info)); /* * region size can be bigger than 1MB because there was probably * free space after this mapping */ UT_ASSERTeq(basic_info.State, MEM_FREE); DONE(NULL); } pmdk-1.11.1/src/test/win_mmap_dtor/TEST0.PS10000664000000000000000000000057614123364546017037 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/win_mmap_dtor/TEST0 -- unit test for win_mmap destructor # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\win_mmap_dtor$Env:EXESUFFIX $DIR\testfile1 check_files $DIR\testfile1 pass pmdk-1.11.1/src/test/win_mmap_dtor/win_mmap_dtor.vcxproj0000664000000000000000000000641214123364546022122 0ustar rootroot Debug x64 Release x64 {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {F03DABEE-A03E-4437-BFD3-D012836F2D94} Win32Proj win_mmap_dtor 10.0.17134.0 Application true v140 Application false v140 NotUsing NotUsing pmdk-1.11.1/src/test/pmempool_feature/0000775000000000000000000000000014123364546016347 5ustar rootrootpmdk-1.11.1/src/test/pmempool_feature/pmempool_feature.vcxproj0000664000000000000000000000742614123364546023340 0ustar rootroot Debug x64 Release x64 {7dc3b3dd-73ed-4602-9af3-8d7053620dea} {AF038868-2432-4159-A62F-941F11D12C5D} pmempool_feature 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/pmempool_feature/TEST1.PS10000775000000000000000000000125614123364546017543 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # pmempool_feature/TEST1 -- unit test for CKSUM_2K # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 expect_normal_exit $PMEMPOOL create obj $POOLSET # PMEMPOOL_FEAT_CHCKSUM_2K is enabled by default pmempool_feature_query "CKSUM_2K" # disable PMEMPOOL_FEAT_SHUTDOWN_STATE prior to success $exit_func="expect_abnormal_exit" pmempool_feature_disable "CKSUM_2K" # should fail $exit_func="expect_normal_exit" pmempool_feature_disable "SHUTDOWN_STATE" pmempool_feature_disable "CKSUM_2K" # should succeed pmempool_feature_enable "CKSUM_2K" check pass pmdk-1.11.1/src/test/pmempool_feature/TEST160000775000000000000000000000073114123364546017224 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # pmempool_feature/TEST16 -- unit test for CHECK_BAD_BLOCKS # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind force-disable setup . ./common.sh require_bb_enabled_by_default $PMEMPOOL$EXESUFFIX pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_CHECK_BAD_BLOCKS check pass pmdk-1.11.1/src/test/pmempool_feature/TEST30000775000000000000000000000063714123364546017145 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST3 -- unit test for SINGLEHDR + memcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind memcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SINGLEHDR check pass pmdk-1.11.1/src/test/pmempool_feature/TEST90000775000000000000000000000063014123364546017144 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST9 -- unit test for SINGLEHDR + dax_device # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 1 configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "dax_device" pmempool_feature_test_SINGLEHDR check pass pmdk-1.11.1/src/test/pmempool_feature/TEST120000775000000000000000000000073714123364546017226 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_feature/TEST12 -- unit test for CHECK_BAD_BLOCKS # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind force-disable setup . ./common.sh require_bb_disabled_by_default $PMEMPOOL$EXESUFFIX pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_CHECK_BAD_BLOCKS check pass pmdk-1.11.1/src/test/pmempool_feature/TEST13.PS10000775000000000000000000000111314123364546017616 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST13 -- unit test for CHECK_BAD_BLOCKS # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 expect_normal_exit $PMEMPOOL create obj $POOLSET # PMEMPOOL_FEAT_CHECK_BAD_BLOCKS is disabled by default pmempool_feature_query "CHECK_BAD_BLOCKS" $exit_func="expect_abnormal_exit" pmempool_feature_enable "CHECK_BAD_BLOCKS" # should fail $exit_func="expect_normal_exit" pmempool_feature_disable "CHECK_BAD_BLOCKS" # should succeed check pass pmdk-1.11.1/src/test/pmempool_feature/TEST00000775000000000000000000000057014123364546017136 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST0 -- unit test for SINGLEHDR # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SINGLEHDR check pass pmdk-1.11.1/src/test/pmempool_feature/grep12.log.match0000664000000000000000000000015114123364546021242 0ustar rootrootquery CHECK_BAD_BLOCKS result is 0 query CHECK_BAD_BLOCKS result is 1 query CHECK_BAD_BLOCKS result is 0 pmdk-1.11.1/src/test/pmempool_feature/grep16.log.match0000664000000000000000000000015114123364546021246 0ustar rootrootquery CHECK_BAD_BLOCKS result is 1 query CHECK_BAD_BLOCKS result is 1 query CHECK_BAD_BLOCKS result is 0 pmdk-1.11.1/src/test/pmempool_feature/Makefile0000664000000000000000000000026214123364546020007 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/pmempool_feature/Makefile -- build pmempool feature unittest # include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_feature/grep0.log.match0000664000000000000000000000003414123364546021157 0ustar rootrootquery SINGLEHDR result is 0 pmdk-1.11.1/src/test/pmempool_feature/TEST14.PS10000775000000000000000000000060714123364546017626 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_feature/TEST14 -- unit test for SHUTDOWN_STATE + ctl # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 $Env:PMEMOBJ_CONF += "sds.at_create=0" expect_normal_exit $PMEMPOOL create obj $POOLSET pmempool_feature_query "SHUTDOWN_STATE" check pass pmdk-1.11.1/src/test/pmempool_feature/TEST2.PS10000775000000000000000000000136514123364546017545 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # pmempool_feature/TEST2 -- unit test for SHUTDOWN_STATE # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 expect_normal_exit $PMEMPOOL create obj $POOLSET # PMEMPOOL_FEAT_SHUTDOWN_STATE is enabled by default pmempool_feature_query "SHUTDOWN_STATE" pmempool_feature_disable "SHUTDOWN_STATE" # PMEMPOOL_FEAT_SHUTDOWN_STATE requires PMEMPOOL_FEAT_CHCKSUM_2K pmempool_feature_disable "CKSUM_2K" $exit_func="expect_abnormal_exit" pmempool_feature_enable "SHUTDOWN_STATE" # should fail $exit_func="expect_normal_exit" pmempool_feature_enable "CKSUM_2K" pmempool_feature_enable "SHUTDOWN_STATE" # should succeed check pass pmdk-1.11.1/src/test/pmempool_feature/common.PS10000664000000000000000000000270614123364546020171 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/pmempool_feature/common.ps1 -- common part of pmempool_feature tests # $PART_SIZE = (convert_to_bytes "10M") $PART_SIZE_STR = ${PART_SIZE}.toString() + "B" #10MiB $POOLSET="$DIR\testset" # create poolset create_poolset $POOLSET ` ${PART_SIZE_STR}:$DIR\testfile11:x ${PART_SIZE_STR}:$DIR\testfile12:x ` R ${PART_SIZE_STR}:$DIR\testfile21:x ${PART_SIZE_STR}:$DIR\testfile22:x ` R ${PART_SIZE_STR}:$DIR\testfile31:x $LOG = "grep${Env:UNITTEST_NUM}.log" remove_files $LOG $exit_func="expect_normal_exit" # pmempool_feature_query -- query feature # # usage: pmempool_feature_query function pmempool_feature_query($arg1) { $val=$(expect_normal_exit $PMEMPOOL feature -q $arg1 $POOLSET) echo "query $arg1 result is $val" >> $LOG } # pmempool_feature_enable -- enable feature # # usage: pmempool_feature_enable [no-query] function pmempool_feature_enable($arg1, $arg2) { & $exit_func $PMEMPOOL feature -e $arg1 $POOLSET 2>&1 | Select-String "$arg1" | %{$_.Line} >> $LOG if ( "x$arg2" -ne "xno-query" ){ pmempool_feature_query $arg1 } } # pmempool_feature_disable -- disable feature # # usage: pmempool_feature_disable [no-query] function pmempool_feature_disable($arg1, $arg2) { & $exit_func $PMEMPOOL feature -d $arg1 $POOLSET 2>&1 | Select-String "$arg1" | %{$_.Line} >> $LOG if ( "x$arg2" -ne "xno-query" ){ pmempool_feature_query $arg1 } } pmdk-1.11.1/src/test/pmempool_feature/TEST50000775000000000000000000000071114123364546017140 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST5 -- unit test for SHUTDOWN_STATE + memcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind memcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SHUTDOWN_STATE check pass pmdk-1.11.1/src/test/pmempool_feature/TEST15.PS10000775000000000000000000000060714123364546017627 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # pmempool_feature/TEST15 -- unit test for SHUTDOWN_STATE + ctl # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 $Env:PMEMOBJ_CONF += "sds.at_create=1" expect_normal_exit $PMEMPOOL create obj $POOLSET pmempool_feature_query "SHUTDOWN_STATE" check pass pmdk-1.11.1/src/test/pmempool_feature/TEST40000775000000000000000000000067514123364546017150 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST4 -- unit test for CKSUM_2K + memcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind memcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_CKSUM_2K check pass pmdk-1.11.1/src/test/pmempool_feature/TEST70000775000000000000000000000067714123364546017155 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST7 -- unit test for CKSUM_2K + pmemcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind pmemcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_CKSUM_2K check pass pmdk-1.11.1/src/test/pmempool_feature/grep15.log.match0000664000000000000000000000004114123364546021243 0ustar rootrootquery SHUTDOWN_STATE result is 1 pmdk-1.11.1/src/test/pmempool_feature/TEST0.PS10000775000000000000000000000074714123364546017546 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST0 -- unit test for SINGLEHDR # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 expect_normal_exit $PMEMPOOL create obj $POOLSET $exit_func="expect_abnormal_exit" pmempool_feature_enable "SINGLEHDR" "no-query" # UNSUPPORTED pmempool_feature_disable "SINGLEHDR" "no-query" # UNSUPPORTED pmempool_feature_query "SINGLEHDR" check pass pmdk-1.11.1/src/test/pmempool_feature/common.sh0000664000000000000000000001254114123364546020176 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # src/test/pmempool_feature/common.sh -- common part of pmempool_feature tests # # for feature values please see: pmempool feature help PART_SIZE=$(convert_to_bytes 10M) # define files and directories POOLSET=$DIR/testset TEST_SET_LOCAL=testset_local TEST_SET_REMOTE=testset_remote LOG=grep${UNITTEST_NUM}.log pmempool_exe=$PMEMPOOL$EXESUFFIX exit_func=expect_normal_exit sds_enabled=$(is_ndctl_enabled $pmempool_exe; echo $?) # pmempool_feature_query -- query feature # # usage: pmempool_feature_query [] function pmempool_feature_query() { query_exit_type=${2-normal} query_exit_func=expect_${query_exit_type}_exit val=$($query_exit_func $pmempool_exe feature -q $1 $POOLSET 2>> $LOG) if [ "$query_exit_type" == "normal" ]; then echo "query $1 result is $val" &>> $LOG fi } # pmempool_feature_enable -- enable feature # # usage: pmempool_feature_enable [no-query] function pmempool_feature_enable() { $exit_func $pmempool_exe feature -e $1 $POOLSET &>> $LOG if [ "x$2" != "xno-query" ]; then pmempool_feature_query $1 fi } # pmempool_feature_disable -- disable feature # # usage: pmempool_feature_disable [no-query] function pmempool_feature_disable() { $exit_func $pmempool_exe feature -d $1 $POOLSET '&>>' $LOG if [ "x$2" != "xno-query" ]; then pmempool_feature_query $1 fi } # pmempool_feature_create_poolset -- create poolset # # usage: pmempool_feature_create_poolset function pmempool_feature_create_poolset() { POOLSET_TYPE=$1 case "$1" in "no_dax_device") create_poolset $POOLSET \ $PART_SIZE:$DIR/testfile11:x \ $PART_SIZE:$DIR/testfile12:x \ r \ $PART_SIZE:$DIR/testfile21:x \ $PART_SIZE:$DIR/testfile22:x \ r \ $PART_SIZE:$DIR/testfile31:x ;; "dax_device") create_poolset $POOLSET \ AUTO:$DEVICE_DAX_PATH ;; "remote") create_poolset $DIR/$TEST_SET_LOCAL \ $PART_SIZE:${NODE_DIR[1]}/testfile_local11:x \ $PART_SIZE:${NODE_DIR[1]}/testfile_local12:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE \ $PART_SIZE:${NODE_DIR[0]}/testfile_remote21:x \ $PART_SIZE:${NODE_DIR[0]}/testfile_remote22:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL rm_files_from_node 1 \ ${NODE_DIR[1]}testfile_local11 ${NODE_DIR[1]}testfile_local12 rm_files_from_node 0 \ ${NODE_DIR[0]}testfile_remote21 ${NODE_DIR[0]}testfile_remote22 POOLSET="${NODE_DIR[1]}/$TEST_SET_LOCAL" ;; esac expect_normal_exit $pmempool_exe rm -f $POOLSET # create pool # pmempool create under valgrind pmemcheck takes too long # it is not part of the test so it is run here without valgrind VALGRIND_DISABLED=y expect_normal_exit $pmempool_exe create obj $POOLSET } # pmempool_feature_test_SINGLEHDR -- test SINGLEHDR function pmempool_feature_test_SINGLEHDR() { exit_func=expect_abnormal_exit pmempool_feature_enable "SINGLEHDR" "no-query" # UNSUPPORTED pmempool_feature_disable "SINGLEHDR" "no-query" # UNSUPPORTED exit_func=expect_normal_exit pmempool_feature_query "SINGLEHDR" } # pmempool_feature_test_CKSUM_2K -- test CKSUM_2K function pmempool_feature_test_CKSUM_2K() { # PMEMPOOL_FEAT_CHCKSUM_2K is enabled by default pmempool_feature_query "CKSUM_2K" # SHUTDOWN_STATE is disabled on Linux if PMDK is compiled with old ndctl # enable it to interfere toggling CKSUM_2K if [ $sds_enabled -eq 1 ]; then pmempool_feature_enable SHUTDOWN_STATE "no-query" fi # disable PMEMPOOL_FEAT_SHUTDOWN_STATE prior to success exit_func=expect_abnormal_exit pmempool_feature_disable "CKSUM_2K" # should fail exit_func=expect_normal_exit pmempool_feature_disable "SHUTDOWN_STATE" pmempool_feature_disable "CKSUM_2K" # should succeed pmempool_feature_enable "CKSUM_2K" } # pmempool_feature_test_SHUTDOWN_STATE -- test SHUTDOWN_STATE function pmempool_feature_test_SHUTDOWN_STATE() { pmempool_feature_query "SHUTDOWN_STATE" if [ $sds_enabled -eq 0 ]; then pmempool_feature_disable SHUTDOWN_STATE fi # PMEMPOOL_FEAT_SHUTDOWN_STATE requires PMEMPOOL_FEAT_CHCKSUM_2K pmempool_feature_disable "CKSUM_2K" exit_func=expect_abnormal_exit pmempool_feature_enable "SHUTDOWN_STATE" # should fail exit_func=expect_normal_exit pmempool_feature_enable "CKSUM_2K" pmempool_feature_enable "SHUTDOWN_STATE" # should succeed } # pmempool_feature_test_CHECK_BAD_BLOCKS -- test SHUTDOWN_STATE function pmempool_feature_test_CHECK_BAD_BLOCKS() { # PMEMPOOL_FEAT_CHECK_BAD_BLOCKS is disabled by default pmempool_feature_query "CHECK_BAD_BLOCKS" pmempool_feature_enable "CHECK_BAD_BLOCKS" pmempool_feature_disable "CHECK_BAD_BLOCKS" } # pmempool_feature_remote_init -- initialization remote replics function pmempool_feature_remote_init() { require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 pmempool_exe="run_on_node 1 ../pmempool" } # pmempool_feature_test_remote -- run remote tests function pmempool_feature_test_remote() { # create pool expect_normal_exit $pmempool_exe rm -f $POOLSET expect_normal_exit $pmempool_exe create obj $POOLSET # poolset with remote replicas are not supported exit_func=expect_abnormal_exit pmempool_feature_enable $1 no-query pmempool_feature_disable $1 no-query pmempool_feature_query $1 abnormal } pmdk-1.11.1/src/test/pmempool_feature/TEST150000775000000000000000000000073714123364546017231 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_feature/TEST15 -- unit test for SHUTDOWN_STATE + ctl # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX setup . ./common.sh require_usc_permission $DIR PMEMOBJ_CONF="${PMEMOBJ_CONF}sds.at_create=1" pmempool_feature_create_poolset "no_dax_device" pmempool_feature_query SHUTDOWN_STATE normal check pass pmdk-1.11.1/src/test/pmempool_feature/TEST140000775000000000000000000000070214123364546017220 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_feature/TEST14 -- unit test for SHUTDOWN_STATE + ctl # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX setup . ./common.sh PMEMOBJ_CONF="${PMEMOBJ_CONF}sds.at_create=0" pmempool_feature_create_poolset "no_dax_device" pmempool_feature_query SHUTDOWN_STATE normal check pass pmdk-1.11.1/src/test/pmempool_feature/TEST60000775000000000000000000000064114123364546017143 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST6 -- unit test for SINGLEHDR + pmemcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind pmemcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SINGLEHDR check pass pmdk-1.11.1/src/test/pmempool_feature/TEST10000775000000000000000000000062614123364546017141 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST1 -- unit test for CKSUM_2K # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_CKSUM_2K check pass pmdk-1.11.1/src/test/pmempool_feature/TEST80000775000000000000000000000071314123364546017145 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST8 -- unit test for SHUTDOWN_STATE + pmemcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind pmemcheck force-enable $PMEMPOOL$EXESUFFIX setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SHUTDOWN_STATE check pass pmdk-1.11.1/src/test/pmempool_feature/pmempool_feature.vcxproj.filters0000664000000000000000000000166714123364546025010 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files pmdk-1.11.1/src/test/pmempool_feature/grep13.log.match0000664000000000000000000000015114123364546021243 0ustar rootrootquery CHECK_BAD_BLOCKS result is 0 query CHECK_BAD_BLOCKS result is 0 query CHECK_BAD_BLOCKS result is 0 pmdk-1.11.1/src/test/pmempool_feature/grep1.log.match0000664000000000000000000000021514123364546021161 0ustar rootrootquery CKSUM_2K result is 1 query CKSUM_2K result is 1 query SHUTDOWN_STATE result is 0 query CKSUM_2K result is 0 query CKSUM_2K result is 1 pmdk-1.11.1/src/test/pmempool_feature/grep2.log.match0000664000000000000000000000030014123364546021155 0ustar rootroot$(OPT)query SHUTDOWN_STATE result is 1 query SHUTDOWN_STATE result is 0 query CKSUM_2K result is 0 query SHUTDOWN_STATE result is 0 query CKSUM_2K result is 1 query SHUTDOWN_STATE result is 1 pmdk-1.11.1/src/test/pmempool_feature/TEST100000775000000000000000000000066714123364546017226 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST10 -- unit test for CKSUM_2K + dax_device # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX require_dax_devices 1 configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "dax_device" pmempool_feature_test_CKSUM_2K check pass pmdk-1.11.1/src/test/pmempool_feature/TEST20000775000000000000000000000064214123364546017140 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST2 -- unit test for SHUTDOWN_STATE # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "no_dax_device" pmempool_feature_test_SHUTDOWN_STATE check pass pmdk-1.11.1/src/test/pmempool_feature/grep14.log.match0000664000000000000000000000004114123364546021242 0ustar rootrootquery SHUTDOWN_STATE result is 0 pmdk-1.11.1/src/test/pmempool_feature/TEST110000775000000000000000000000070314123364546017216 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_feature/TEST11 -- unit test for SHUTDOWN_STATE + dax_device # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds $PMEMPOOL$EXESUFFIX require_dax_devices 1 configure_valgrind force-disable setup . ./common.sh pmempool_feature_create_poolset "dax_device" pmempool_feature_test_SHUTDOWN_STATE check pass pmdk-1.11.1/src/test/obj_memcheck_register/0000775000000000000000000000000014123364546017316 5ustar rootrootpmdk-1.11.1/src/test/obj_memcheck_register/TEST00000775000000000000000000000074114123364546020105 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_memcheck_register/TEST0 -- unit test for obj_memcheck_register # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_valgrind 3.12 configure_valgrind memcheck force-enable setup expect_normal_exit ./obj_memcheck_register$EXESUFFIX c $DIR/testfile expect_normal_exit ./obj_memcheck_register$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/obj_memcheck_register/Makefile0000664000000000000000000000041214123364546020753 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_memcheck_register/Makefile -- build obj_memcheck_register test # TARGET = obj_memcheck_register OBJS = obj_memcheck_register.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_memcheck_register/.gitignore0000664000000000000000000000002614123364546021304 0ustar rootrootobj_memcheck_register pmdk-1.11.1/src/test/obj_memcheck_register/obj_memcheck_register.c0000664000000000000000000000230014123364546023767 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * obj_memcheck_register.c - tests that verifies that objects are registered * correctly in memcheck */ #include "unittest.h" static void test_create(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, "register", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid oid = pmemobj_root(pop, 1024); TX_BEGIN(pop) { pmemobj_tx_alloc(1024, 0); pmemobj_tx_add_range(oid, 0, 10); } TX_END pmemobj_close(pop); } static void test_open(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_open(path, "register")) == NULL) UT_FATAL("!pmemobj_open: %s", path); PMEMoid oid = pmemobj_root(pop, 1024); TX_BEGIN(pop) { pmemobj_tx_add_range(oid, 0, 10); } TX_END pmemobj_close(pop); } int main(int argc, char *argv[]) { START(argc, argv, "obj_memcheck_register"); if (argc != 3) UT_FATAL("usage: %s [c|o] file-name", argv[0]); switch (argv[1][0]) { case 'c': test_create(argv[2]); break; case 'o': test_open(argv[2]); break; default: UT_FATAL("usage: %s [c|o] file-name", argv[0]); break; } DONE(NULL); } pmdk-1.11.1/src/test/obj_pool_win/0000775000000000000000000000000014123364546015464 5ustar rootrootpmdk-1.11.1/src/test/obj_pool_win/TEST1.PS10000664000000000000000000000401614123364546016652 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool_win/TEST1 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\obj_pool_win$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool_win/obj_pool_win.vcxproj.filters0000664000000000000000000000202114123364546023223 0ustar rootroot {f459273f-0480-464b-9821-cd0be6ce719c} {9104a19e-81c8-4555-a6f5-573fd73525ba} {79f31ec7-a8e4-417f-9334-932346426333} Source Files Match Files Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_pool_win/out0.log.match0000664000000000000000000000026414123364546020153 0ustar rootrootobj_pool_win$(nW)TEST0: START: obj_pool_win$(nW) $(nW)obj_pool_win$(nW) c $(nW)testfile test$(nW) 20 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool_win$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_pool_win/TEST0.PS10000664000000000000000000000370514123364546016655 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool_win/TEST0 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\obj_pool_win$Env:EXESUFFIX c $DIR\testfile test$Env:SUFFIX 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool_win/obj_pool.vcxproj.filters0000664000000000000000000001142614123364546022357 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 {b539ef93-f1f6-4c62-b624-1a07e6615e21} match Source Files Test Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files pmdk-1.11.1/src/test/obj_pool_win/obj_pool_win.vcxproj0000664000000000000000000000723114123364546021564 0ustar rootroot Debug x64 Release x64 {B775480C-5B32-4F64-B026-47367280EC56} Win32Proj obj_pool 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_pool_win/obj_pool_win.c0000664000000000000000000000365514123364546020321 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * obj_pool.c -- unit test for pmemobj_create() and pmemobj_open() * * usage: obj_pool op path layout [poolsize mode] * * op can be: * c - create * o - open * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #define MB ((size_t)1 << 20) static void pool_create(const wchar_t *path, const wchar_t *layout, size_t poolsize, unsigned mode) { char *upath = ut_toUTF8(path); PMEMobjpool *pop = pmemobj_createW(path, layout, poolsize, mode); if (pop == NULL) UT_OUT("!%s: pmemobj_create", upath); else { os_stat_t stbuf; STATW(path, &stbuf); UT_OUT("%s: file size %zu mode 0%o", upath, stbuf.st_size, stbuf.st_mode & 0777); pmemobj_close(pop); int result = pmemobj_checkW(path, layout); if (result < 0) UT_OUT("!%s: pmemobj_check", upath); else if (result == 0) UT_OUT("%s: pmemobj_check: not consistent", upath); } free(upath); } static void pool_open(const wchar_t *path, const wchar_t *layout) { char *upath = ut_toUTF8(path); PMEMobjpool *pop = pmemobj_openW(path, layout); if (pop == NULL) { UT_OUT("!%s: pmemobj_open", upath); } else { UT_OUT("%s: pmemobj_open: Success", upath); pmemobj_close(pop); } free(upath); } int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "obj_pool_win"); if (argc < 4) UT_FATAL("usage: %s op path layout [poolsize mode]", ut_toUTF8(argv[0])); wchar_t *layout = NULL; size_t poolsize; unsigned mode; if (wcscmp(argv[3], L"EMPTY") == 0) layout = L""; else if (wcscmp(argv[3], L"NULL") != 0) layout = argv[3]; switch (argv[1][0]) { case 'c': poolsize = wcstoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = wcstoul(argv[5], NULL, 8); pool_create(argv[2], layout, poolsize, mode); break; case 'o': pool_open(argv[2], layout); break; default: UT_FATAL("unknown operation"); } DONEW(NULL); } pmdk-1.11.1/src/test/obj_pool_win/out1.log.match0000664000000000000000000000026314123364546020153 0ustar rootrootobj_pool_win$(nW)TEST1: START: obj_pool_win$(nW) $(nW)obj_pool_win$(nW) c $(nW)testfile test$(nW) 0 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool_win$(nW)TEST1: DONE pmdk-1.11.1/src/test/log_pool_win/0000775000000000000000000000000014123364546015473 5ustar rootrootpmdk-1.11.1/src/test/log_pool_win/log_pool_win.c0000664000000000000000000000334114123364546020327 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * log_pool.c -- unit test for pmemlog_create() and pmemlog_open() * * usage: log_pool op path [poolsize mode] * * op can be: * c - create * o - open * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #define MB ((size_t)1 << 20) static void pool_create(const wchar_t *path, size_t poolsize, unsigned mode) { char *upath = ut_toUTF8(path); PMEMlogpool *plp = pmemlog_createW(path, poolsize, mode); if (plp == NULL) UT_OUT("!%s: pmemlog_create", upath); else { os_stat_t stbuf; STATW(path, &stbuf); UT_OUT("%s: file size %zu usable space %zu mode 0%o", upath, stbuf.st_size, pmemlog_nbyte(plp), stbuf.st_mode & 0777); pmemlog_close(plp); int result = pmemlog_checkW(path); if (result < 0) UT_OUT("!%s: pmemlog_check", upath); else if (result == 0) UT_OUT("%s: pmemlog_check: not consistent", upath); } free(upath); } static void pool_open(const wchar_t *path) { char *upath = ut_toUTF8(path); PMEMlogpool *plp = pmemlog_openW(path); if (plp == NULL) UT_OUT("!%s: pmemlog_open", upath); else { UT_OUT("%s: pmemlog_open: Success", upath); pmemlog_close(plp); } free(upath); } int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "log_pool_win"); if (argc < 3) UT_FATAL("usage: %s op path [poolsize mode]", ut_toUTF8(argv[0])); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = wcstoul(argv[3], NULL, 0) * MB; /* in megabytes */ mode = wcstoul(argv[4], NULL, 8); pool_create(argv[2], poolsize, mode); break; case 'o': pool_open(argv[2]); break; default: UT_FATAL("unknown operation"); } DONEW(NULL); } pmdk-1.11.1/src/test/log_pool_win/TEST1.PS10000664000000000000000000000072214123364546016661 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool_win/TEST1 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_holey_file 40M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\log_pool_win$Env:EXESUFFIX c $DIR\testfile 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool_win/log_pool_win.vcxproj.filters0000664000000000000000000000206114123364546023245 0ustar rootroot {23c6f442-37c2-42e0-b742-d395b81b56ca} {3e720f7b-57cd-43dc-9f5e-6bda1ff6778c} {fa0437cc-be2e-47f8-aa2d-6c5874443279} Source Files Test Scripts Test Scripts Match Files Match Files pmdk-1.11.1/src/test/log_pool_win/out0.log.match0000664000000000000000000000026014123364546020156 0ustar rootrootlog_pool$(nW)TEST0: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 20 0600 $(nW)testfile: file size 20971520 usable space 20963328 mode 0600 log_pool$(nW)TEST0: DONE pmdk-1.11.1/src/test/log_pool_win/TEST0.PS10000664000000000000000000000061714123364546016663 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool_win/TEST0 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\log_pool_win$Env:EXESUFFIX c $DIR\testfile 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool_win/log_pool_win.vcxproj0000664000000000000000000000701114123364546021576 0ustar rootroot Debug x64 Release x64 {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {C71DAF3E-9361-4723-93E2-C475D1D0C0D0} Win32Proj log_pool_win 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/log_pool_win/log_pool_win.filters0000664000000000000000000001060314123364546021554 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {e0803b93-70ee-46fd-bc41-8d5af1e0abbd} ps1 {6f9013b1-e713-4763-870b-c5654da397a4} match Source Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/log_pool_win/out1.log.match0000664000000000000000000000025714123364546020165 0ustar rootrootlog_pool$(nW)TEST1: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: file size 41943040 usable space 41934848 mode 0600 log_pool$(nW)TEST1: DONE pmdk-1.11.1/src/test/util_parse_size/0000775000000000000000000000000014123364546016205 5ustar rootrootpmdk-1.11.1/src/test/util_parse_size/TEST00000775000000000000000000000074314123364546016776 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_parse_size/TEST0 -- unit test for util_parse_size. # . ../unittest/unittest.sh require_test_type medium require_fs_type none setup expect_normal_exit ./util_parse_size$EXESUFFIX 11K 11M 11G 11T 11P\ 11KiB 11MiB 11GiB 11TiB 11PiB 11kB 11MB 11GB 11TB 11PB 1234\ 10k 10KB 10mB 10mb 10Mb 10B B 10ki 10KiC KiD\ 10Kiboli 10Kboli 10boli 10KiBoli check pass pmdk-1.11.1/src/test/util_parse_size/Makefile0000664000000000000000000000035114123364546017644 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/util_parse_size/Makefile -- check parsing results # TARGET = util_parse_size OBJS = util_parse_size.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_parse_size/util_parse_size.c0000664000000000000000000000103714123364546021553 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * util_parse_size.c -- unit test for parsing a size */ #include "unittest.h" #include "util.h" #include int main(int argc, char *argv[]) { int ret = 0; uint64_t size = 0; START(argc, argv, "util_parse_size"); for (int arg = 1; arg < argc; ++arg) { ret = util_parse_size(argv[arg], &size); if (ret == 0) { UT_OUT("%s - correct %"PRIu64, argv[arg], size); } else { UT_OUT("%s - incorrect", argv[arg]); } } DONE(NULL); } pmdk-1.11.1/src/test/util_parse_size/out0.log.match0000664000000000000000000000141414123364546020672 0ustar rootrootutil_parse_size$(nW)TEST0: START: util_parse_size $(nW)util_parse_size$(S) 11K - correct 11264 11M - correct 11534336 11G - correct 11811160064 11T - correct 12094627905536 11P - correct 12384898975268864 11KiB - correct 11264 11MiB - correct 11534336 11GiB - correct 11811160064 11TiB - correct 12094627905536 11PiB - correct 12384898975268864 11kB - correct 11000 11MB - correct 11000000 11GB - correct 11000000000 11TB - correct 11000000000000 11PB - correct 11000000000000000 1234 - correct 1234 10k - incorrect 10KB - incorrect 10mB - incorrect 10mb - incorrect 10Mb - incorrect 10B - correct 10 B - incorrect 10ki - incorrect 10KiC - incorrect KiD - incorrect 10Kiboli - incorrect 10Kboli - incorrect 10boli - incorrect 10KiBoli - incorrect util_parse_size$(nW)TEST0: DONE pmdk-1.11.1/src/test/util_parse_size/TEST0.PS10000664000000000000000000000074214123364546017374 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_parse_size/TEST0 -- unit test for util_parse_size. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_parse_size$Env:EXESUFFIX 11K 11M 11G 11T 11P ` 11KiB 11MiB 11GiB 11TiB 11PiB 11kB 11MB 11GB 11TB 11PB 1234 ` 10k 10KB 10mB 10mb 10Mb 10B B 10ki 10KiC KiD ` 10Kiboli 10Kboli 10boli 10KiBoli check pass pmdk-1.11.1/src/test/util_parse_size/.gitignore0000664000000000000000000000002014123364546020165 0ustar rootrootutil_parse_size pmdk-1.11.1/src/test/util_parse_size/util_parse_size.vcxproj.filters0000664000000000000000000000260514123364546024475 0ustar rootroot Source Files Source Files Source Files Test Scripts Match Files Test Scripts Match Files {123c699c-29a6-434e-8584-36f216dcc624} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {3bb361b7-844f-4234-9a67-39f6ae260599} match {2f14a64d-7d7c-4617-ae54-6ec929e6b689} ps1 pmdk-1.11.1/src/test/util_parse_size/util_parse_size.vcxproj0000664000000000000000000000630614123364546023030 0ustar rootroot Debug x64 Release x64 {08B62E36-63D2-4FF1-A605-4BBABAEE73FB} Win32Proj util_parse_size 10.0.17134.0 Application true v140 Application false v140 {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/magic/0000775000000000000000000000000014123364546014064 5ustar rootrootpmdk-1.11.1/src/test/magic/TEST00000775000000000000000000000215214123364546014651 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # # magic/TEST0 -- test for magic file script # . ../unittest/unittest.sh require_test_type medium require_build_type nondebug # There is no point in testing the file command using memcheck # because even if it does report any problems we can't fix it configure_valgrind force-disable require_command file setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log MAGIC=../../../utils/pmdk.magic rm -f $LOG && touch $LOG rm -f $POOL expect_normal_exit $PMEMPOOL create blk 512 $POOL expect_normal_exit file -m $MAGIC $POOL >> $LOG rm -f $POOL expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit file -m $MAGIC $POOL >> $LOG rm -f $POOL expect_normal_exit $PMEMPOOL create obj $POOL expect_normal_exit file -m $MAGIC $POOL >> $LOG rm -f $POOL create_poolset $POOL 32M:file.part1:x 32M:file.part2:x expect_normal_exit file -m $MAGIC $POOL >> $LOG rm -f $POOL create_poolset $POOL 32M:file.part1:x 32M:file.part2:x R 32M:file.rep1:x 32M:file.rep2:x expect_normal_exit file -m $MAGIC $POOL >> $LOG check pass pmdk-1.11.1/src/test/magic/Makefile0000664000000000000000000000025114123364546015522 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/magic/Makefile -- build unittest for magic file # include ../Makefile.inc pmdk-1.11.1/src/test/magic/out0.log.match0000664000000000000000000000040514123364546016550 0ustar rootroot$(*): Persistent Memory Pool file, type: BLK, version 0x1 $(*): Persistent Memory Pool file, type: LOG, version 0x1 $(*): Persistent Memory Pool file, type: OBJ, version 0x6 $(*): Persistent Memory Poolset file $(*): Persistent Memory Poolset file with replica pmdk-1.11.1/src/test/magic/README0000664000000000000000000000043114123364546014742 0ustar rootrootPersistent Memory Development Kit This is src/test/magic/README. This directory contains a unit test for PMDK magic file. Magic file contains pattern for identifying PMDK pool file format. This file is read by file(1) command. See file(1) and magic(4) manual pages for details. pmdk-1.11.1/src/test/util_file_create/0000775000000000000000000000000014123364546016303 5ustar rootrootpmdk-1.11.1/src/test/util_file_create/out0w.log.match0000664000000000000000000000042314123364546021156 0ustar rootrootutil_file_create$(nW)TEST0w: START: util_file_create $(nW)util_file_create$(nW) 0x4000 0x4000:$(nW)testdir1 0x4000:$(nW)NUL 0x4000:$(nW)testfile1 $(nW)testdir1: util_file_create: $(*) NUL: $(*) $(nW)testfile1: util_file_create: File exists util_file_create$(nW)TEST0w: DONE pmdk-1.11.1/src/test/util_file_create/TEST1.PS10000664000000000000000000000126214123364546017471 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST1 -- unit test for util_file_create() # # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any require_no_superuser # icacls does have problems with handling long paths in the correct way. require_short_path setup mkdir $DIR\testdir1 > $null # remove write permissions & icacls $DIR/testdir1 /deny ${Env:USERNAME}:W >$null expect_normal_exit $Env:EXE_DIR\util_file_create$Env:EXESUFFIX 0x4000 ` 0x4000:$DIR\testdir1\testfile # grant full permissions so test code can cleanup & icacls $DIR/testdir1 /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/util_file_create/TEST00000775000000000000000000000143614123364546017074 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST0 -- unit test for util_file_create() # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup MIN_POOL=0x4000 truncate -s 32K $DIR/testfile1 mkdir $DIR/testdir1 ln -s $DIR/testfile0 $DIR/testlink1 ln -s $DIR/testfile1 $DIR/testlink2 ln -s $DIR/testdir1 $DIR/testlink3 ln -s /dev/zero $DIR/testlink4 expect_normal_exit ./util_file_create$EXESUFFIX $MIN_POOL \ $MIN_POOL:$DIR/testdir1\ $MIN_POOL:/dev/zero\ $MIN_POOL:$DIR/testlink1\ $MIN_POOL:$DIR/testlink2\ $MIN_POOL:$DIR/testlink3\ $MIN_POOL:$DIR/testlink4\ $MIN_POOL:$DIR/testfile1\ 0x1000:$DIR/testfile2\ $MIN_POOL:$DIR/testfile3 check pass pmdk-1.11.1/src/test/util_file_create/util_file_create.c0000664000000000000000000000147514123364546021755 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2018, Intel Corporation */ /* * util_file_create.c -- unit test for util_file_create() * * usage: util_file_create minlen len:path [len:path]... */ #include "unittest.h" #include "file.h" int main(int argc, char *argv[]) { START(argc, argv, "util_file_create"); if (argc < 3) UT_FATAL("usage: %s minlen len:path...", argv[0]); char *fname; size_t minsize = strtoul(argv[1], &fname, 0); for (int arg = 2; arg < argc; arg++) { size_t size = strtoul(argv[arg], &fname, 0); if (*fname != ':') UT_FATAL("usage: %s minlen len:path...", argv[0]); fname++; int fd; if ((fd = util_file_create(fname, size, minsize)) == -1) UT_OUT("!%s: util_file_create", fname); else { UT_OUT("%s: created", fname); os_close(fd); } } DONE(NULL); } pmdk-1.11.1/src/test/util_file_create/Makefile0000664000000000000000000000037414123364546017747 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2016, Intel Corporation # # src/test/util_file_create/Makefile -- build util_file_create unit test # TARGET = util_file_create OBJS = util_file_create.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_file_create/TEST2.PS10000664000000000000000000000055214123364546017473 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST2 -- unit test for util_file_create() # # . ..\unittest\unittest.ps1 require_fs_type any require_test_type medium setup expect_normal_exit $Env:EXE_DIR\util_file_create$Env:EXESUFFIX 0x4000 ` 0x7FFFFFFFFFFFFFFF:$DIR\testfile check pass pmdk-1.11.1/src/test/util_file_create/util_file_create.vcxproj0000664000000000000000000000675114123364546023230 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {D829DB63-E046-474D-8EA3-43A6659294D8} Win32Proj util_file_create 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/util_file_create/out0.log.match0000664000000000000000000000130414123364546020766 0ustar rootrootutil_file_create/TEST0: START: util_file_create ./util_file_create$(nW) 0x4000 0x4000:$(nW)/testdir1 0x4000:/dev/zero 0x4000:$(nW)/testlink1 0x4000:$(nW)/testlink2 0x4000:$(nW)/testlink3 0x4000:$(nW)/testlink4 0x4000:$(nW)/testfile1 0x1000:$(nW)/testfile2 0x4000:$(nW)/testfile3 $(nW)/testdir1: util_file_create: File exists /dev/zero: util_file_create: File exists $(nW)/testlink1: util_file_create: File exists $(nW)/testlink2: util_file_create: File exists $(nW)/testlink3: util_file_create: File exists $(nW)/testlink4: util_file_create: File exists $(nW)/testfile1: util_file_create: File exists $(nW)/testfile2: util_file_create: Invalid argument $(nW)/testfile3: created util_file_create/TEST0: DONE pmdk-1.11.1/src/test/util_file_create/util_file_create.vcxproj.filters0000664000000000000000000000254014123364546024667 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2d237952-c50b-4d8c-a83f-e28a96d88887} {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd Source Files Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files pmdk-1.11.1/src/test/util_file_create/.gitignore0000664000000000000000000000002114123364546020264 0ustar rootrootutil_file_create pmdk-1.11.1/src/test/util_file_create/README0000664000000000000000000000101514123364546017160 0ustar rootrootPersistent Memory Development Kit This is src/test/util_file_create/README. This directory contains a unit test for util_file_create(). The program in util_file_create.c takes a minimal pool size along with the list of len:path pairs. For example: ./util_file_create minlen len1:path1 This will call util_file_create() on path1 using len1 as pool size. minlen and len are interpreted as a decimal values unless they start with 0x. If len is zero, the file pointed by path must exist. Otherwise, the file is created. pmdk-1.11.1/src/test/util_file_create/TEST10000775000000000000000000000070214123364546017070 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST1 -- unit test for util_file_create() # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_no_superuser setup MIN_POOL=0x4000 mkdir $DIR/testdir1 chmod -w $DIR/testdir1 expect_normal_exit ./util_file_create$EXESUFFIX $MIN_POOL \ $MIN_POOL:$DIR/testdir1/testfile check pass pmdk-1.11.1/src/test/util_file_create/TEST0w.PS10000664000000000000000000000071514123364546017661 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST0 -- unit test for util_file_create() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 32K $DIR\testfile1 mkdir $DIR\testdir1 > $null expect_normal_exit $Env:EXE_DIR\util_file_create$Env:EXESUFFIX 0x4000 ` 0x4000:$DIR\testdir1 ` 0x4000:NUL ` 0x4000:$DIR\testfile1 check pass pmdk-1.11.1/src/test/util_file_create/out1.log.match0000664000000000000000000000033214123364546020767 0ustar rootrootutil_file_create$(nW)TEST1: START: util_file_create $(nW)util_file_create$(nW) 0x4000 0x4000:$(nW)testdir1$(nW)testfile $(nW)testdir1$(nW)testfile: util_file_create: Permission denied util_file_create$(nW)TEST1: DONE pmdk-1.11.1/src/test/util_file_create/TEST20000775000000000000000000000070114123364546017070 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/util_file_create/TEST2 -- unit test for util_file_create() # . ../unittest/unittest.sh require_test_type medium setup # without fallocate this test takes forever require_native_fallocate $DIR/testfile1 MIN_POOL=0x4000 expect_normal_exit ./util_file_create$EXESUFFIX $MIN_POOL \ 0x7FFFFFFFFFFFFFFF:$DIR/testfile check pass pmdk-1.11.1/src/test/util_file_create/out2.log.match0000664000000000000000000000025514123364546020774 0ustar rootrootutil_file_create$(nW)TEST2: START: util_file_create $(nW)util_file_create$(nW) 0x4000 0x7FFFFFFFFFFFFFFF:$(nW)testfile $(nW)testfile: $(*) util_file_create$(nW)TEST2: DONE pmdk-1.11.1/src/test/helgrind-log.supp0000664000000000000000000000141614123364546016272 0ustar rootroot{ Helgrind:Race fun:*mem*cpy ... fun:_IO_file_xsputn@@GLIBC* fun:fputs fun:out_print_func fun:out_common fun:out_log } { Helgrind:Race fun:*memmove fun:_IO_file_xsputn@@GLIBC* fun:fputs fun:out_print_func fun:out_common fun:out_log } { Helgrind:Race fun:*mem*cpy ... fun:_IO_file_xsputn@@GLIBC* fun:fputs fun:out_print_func fun:out_error fun:out_err } { Helgrind:Race fun:*mem*cpy fun:_IO_file_xsputn@@GLIBC* fun:fputs ... fun:ut_out } { Helgrind:Race fun:*memmove fun:_IO_file_xsputn@@GLIBC* fun:fputs ... fun:ut_out } pmdk-1.11.1/src/test/blk_pool/0000775000000000000000000000000014123364546014605 5ustar rootrootpmdk-1.11.1/src/test/blk_pool/TEST20.PS10000664000000000000000000000052514123364546016055 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST20 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST20 non-existing file, bsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST340000775000000000000000000000106714123364546015465 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_pool/TEST34 -- unit test for pmemblk_create # # This test is equivalent of TEST0 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 # # TEST34 non-existing file, poolsize > 0 # expect_normal_exit ./blk_pool$EXESUFFIX f $DIR/testfile 4096 20 0600 expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST7.PS10000664000000000000000000000403714123364546016004 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST7 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 17M 0K $DIR\testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out35.log.match0000664000000000000000000000025614123364546017365 0ustar rootrootblk_pool$(nW)TEST35: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0600 $(nW)testfile: file size 41943040 usable blocks 9935 mode 0600 blk_pool$(nW)TEST35: DONE pmdk-1.11.1/src/test/blk_pool/TEST230000775000000000000000000000376414123364546015471 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST23 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile # # TEST23 existing file, file size >= min required size, bsize == 0 # (empty pool header) # expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST330000775000000000000000000000142614123364546015463 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_pool/TEST33 -- create a pool with the smallest parts # possible # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 # # TEST33 non-existing file, poolsize >= min required size, bsize > min bsize # part size == min part size (pool set) # CMD="$DIR/testset" MIN_PART=$((2 * 1024 * 1024)) # 2MiB for i in {1..9}; do CMD="$CMD $MIN_PART:$DIR/testfile$i:x" done create_poolset $CMD expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 100 0 0640 check_files $DIR/testset $DIR/testfile1 $DIR/testfile2 $DIR/testfile3 \ $DIR/testfile4 $DIR/testfile5 $DIR/testfile6 $DIR/testfile7 $DIR/testfile8 \ $DIR/testfile9 check pass pmdk-1.11.1/src/test/blk_pool/TEST220000775000000000000000000000076414123364546015465 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST22 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST22 existing file, file size < min required size, bsize == 0 # (valid pool header) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 512 20 0640 truncate -s 1M $DIR/testfile expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST15w.PS10000664000000000000000000000411714123364546016251 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST15 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST15 non-existing file, poolsize >= min required size, bsize > min bsize # (pool set) create_poolset $DIR\testset 20M:$DIR\testfile1:x 20M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testset 100 0 0640 check_files $DIR\testset $DIR\testfile1 $DIR\testfile2 check pass pmdk-1.11.1/src/test/blk_pool/out15.log.match0000664000000000000000000000025514123364546017362 0ustar rootrootblk_pool$(nW)TEST15: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 80949 mode 0666 blk_pool$(nW)TEST15: DONE pmdk-1.11.1/src/test/blk_pool/TEST28.PS10000664000000000000000000000071714123364546016070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST28 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST28 existing file, file size >= min required size, bsize == 300 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 300 20 0640 expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 300 check pass pmdk-1.11.1/src/test/blk_pool/TEST1.PS10000664000000000000000000000377014123364546016001 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST1 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 40M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out38.log.match0000664000000000000000000000025014123364546017362 0ustar rootrootblk_pool$(nW)TEST38: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 80592 mode 0666 blk_pool$(nW)TEST38: DONE pmdk-1.11.1/src/test/blk_pool/TEST5.PS10000664000000000000000000000065414123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST5 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST5 non-existing file, poolsize > 0 # path is invalid (directory not exist) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c \nul\testfile 4096 20 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out30.log.match0000664000000000000000000000023714123364546017357 0ustar rootrootblk_pool$(nW)TEST30: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testset 300 $(nW)testset: pmemblk_open: Operation not supported blk_pool$(nW)TEST30: DONE pmdk-1.11.1/src/test/blk_pool/TEST160000775000000000000000000000110314123364546015454 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/blk_pool/TEST16 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST16 non-existing file, poolsize >= min required size, bsize > min bsize # (pool set with replica section) # create_poolset $DIR/testset 20M:$DIR/testfile1:x R 20M:$DIR/testfile2:x expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 100 0 0600 check_files $DIR/testset check_no_files $DIR/testfile1 $DIR/testfile2 check pass pmdk-1.11.1/src/test/blk_pool/TEST22.PS10000664000000000000000000000407614123364546016064 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST22 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST22 existing file, file size < min required size, bsize == 0 # (valid pool header) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 512 20 0640 truncate -s 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/out24.log.match0000664000000000000000000000023314123364546017356 0ustar rootrootblk_pool$(nW)TEST24: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 1024 $(nW)testfile: pmemblk_open: Invalid argument blk_pool$(nW)TEST24: DONE pmdk-1.11.1/src/test/blk_pool/TEST400000775000000000000000000000156614123364546015466 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_pool/TEST40 -- create a pool with the smallest parts # possible # # This test is equivalent of TEST33 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 # # TEST40 non-existing file, poolsize >= min required size, bsize > min bsize # part size == min part size (pool set) # CMD="$DIR/testset" MIN_PART=$((2 * 1024 * 1024)) # 2MiB for i in {1..9}; do CMD="$CMD $MIN_PART:$DIR/testfile$i:x" done create_poolset $CMD expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 100 0 0640 check_files $DIR/testset $DIR/testfile1 $DIR/testfile2 $DIR/testfile3 \ $DIR/testfile4 $DIR/testfile5 $DIR/testfile6 $DIR/testfile7 $DIR/testfile8 \ $DIR/testfile9 check pass pmdk-1.11.1/src/test/blk_pool/TEST240000775000000000000000000000077314123364546015467 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST24 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST24 existing file, file size >= min required size, bsize == 1024 # (bsize doesn't match the value from pool header) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 512 20 0640 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 1024 check pass pmdk-1.11.1/src/test/blk_pool/TEST9.PS10000664000000000000000000000061514123364546016004 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST9 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST9 non-existing file, poolsize < min required size # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 1 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST27.PS10000664000000000000000000000071314123364546016063 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST27 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST27 existing file, file size >= min required size, bsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 512 20 0640 expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/out32.log.match0000664000000000000000000000025314123364546017357 0ustar rootrootblk_pool$(nW)TEST32: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testsetㅓㅹ 300 $(nW)testsetㅓㅹ: pmemblk_open: Operation not supported blk_pool$(nW)TEST32: DONE pmdk-1.11.1/src/test/blk_pool/out10.log.match0000664000000000000000000000024014123364546017347 0ustar rootrootblk_pool$(nW)TEST10: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0640 $(nW)testfile: pmemblk_create: File exists blk_pool$(nW)TEST10: DONE pmdk-1.11.1/src/test/blk_pool/out16.log.match0000664000000000000000000000022514123364546017360 0ustar rootrootblk_pool$(nW)TEST16: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testset 100 0 0600 $(nW)testset: pmemblk_create: $(*) blk_pool$(nW)TEST16: DONE pmdk-1.11.1/src/test/blk_pool/TEST170000775000000000000000000000064714123364546015471 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_pool/TEST17 -- unit test for pmemblk_create with unicode # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/ㅹestㆅile 4096 20 0600 check_files $DIR/ㅹestㆅile check pass pmdk-1.11.1/src/test/blk_pool/out40.log.match0000664000000000000000000000025014123364546017353 0ustar rootrootblk_pool$(nW)TEST40: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 34996 mode 0666 blk_pool$(nW)TEST40: DONE pmdk-1.11.1/src/test/blk_pool/TEST25.PS10000664000000000000000000000140114123364546016054 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST25 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST25 existing file, file size >= min required size, bsize == 0 # (no read permissions) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 512 20 0640 # remove read permissions & icacls $DIR\testfile /deny ${Env:USERNAME}:R >$null expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 # grant full permissions so test code can cleanup & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/blk_pool/TEST30000775000000000000000000000403214123364546015374 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST3 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile chmod 0640 $DIR/testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST10.PS10000664000000000000000000000440214123364546016052 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST10 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # XXX Doesn't change outcome whether we make it WO or not, # same goes for linux test & icacls $DIR\testfile /grant ${Env:USERNAME}:W >$null # # TEST10 existing file, file length >= min required size, poolsize > 0 # (no read permissions) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST380000775000000000000000000000121314123364546015462 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_pool/TEST38 -- unit test for pmemblk_create # # This test is equivalent of TEST15 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 # # TEST38 non-existing file, poolsize >= min required size, bsize > min bsize # (pool set) # create_poolset $DIR/testset 20M:$DIR/testfile1:x 20M:$DIR/testfile2:x expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 100 0 0640 check_files $DIR/testset $DIR/testfile1 $DIR/testfile2 check pass pmdk-1.11.1/src/test/blk_pool/TEST90000775000000000000000000000062414123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST9 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST9 non-existing file, poolsize < min required size # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 1 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out23.log.match0000664000000000000000000000023014123364546017352 0ustar rootrootblk_pool$(nW)TEST23: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Invalid argument blk_pool$(nW)TEST23: DONE pmdk-1.11.1/src/test/blk_pool/TEST120000775000000000000000000000064114123364546015456 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST12 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST12 non-existing file, poolsize >= min required size, bsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 0 20 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST360000775000000000000000000000427614123364546015474 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # Copyright 2019, IBM Corporation # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST36 -- unit test for pmemblk_create # # This test is equivalent of TEST8 for ppc64le platform # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 create_nonzeroed_file 17M 8K $DIR/testfile chmod 0600 $DIR/testfile # # TEST36 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST13.PS10000664000000000000000000000063714123364546016063 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST13 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST13 non-existing file, poolsize >= min required size, bsize < min bsize # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 10 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out26.log.match0000664000000000000000000000023114123364546017356 0ustar rootrootblk_pool$(nW)TEST26: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Permission denied blk_pool$(nW)TEST26: DONE pmdk-1.11.1/src/test/blk_pool/out21.log.match0000664000000000000000000000023014123364546017350 0ustar rootrootblk_pool$(nW)TEST21: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Invalid argument blk_pool$(nW)TEST21: DONE pmdk-1.11.1/src/test/blk_pool/TEST320000775000000000000000000000103114123364546015452 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_pool/TEST32 -- unit test for blk poolsets with unicode # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem setup umask 0 expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile⮸ 300 20 0640 cp $DIR/testfile⮸ $DIR/testfileⰊ create_poolset $DIR/testsetㅓㅹ 20M:$DIR/testfile⮸ R 20M:$DIR/testfileⰊ expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testsetㅓㅹ 300 check pass pmdk-1.11.1/src/test/blk_pool/TEST130000775000000000000000000000066414123364546015464 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST13 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 # # TEST13 non-existing file, poolsize >= min required size, bsize < min bsize # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 10 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST200000775000000000000000000000053214123364546015454 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST20 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST20 non-existing file, bsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST00000775000000000000000000000072614123364546015377 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST0 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit ./blk_pool$EXESUFFIX f $DIR/testfile 4096 20 0600 expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/blk_pool.c0000664000000000000000000000451114123364546016553 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * blk_pool.c -- unit test for pmemblk_create() and pmemblk_open() * * usage: blk_pool op path bsize [poolsize mode] * * op can be: * c - create * o - open * f - do fault injection * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #include "../libpmemblk/blk.h" #define MB ((size_t)1 << 20) static void do_fault_injection(const char *path, size_t bsize, size_t poolsize, unsigned mode) { if (!pmemblk_fault_injection_enabled()) return; pmemblk_inject_fault_at(PMEM_MALLOC, 1, "blk_runtime_init"); PMEMblkpool *pbp = pmemblk_create(path, bsize, poolsize, mode); UT_ASSERTeq(pbp, NULL); UT_ASSERTeq(errno, ENOMEM); } static void pool_create(const char *path, size_t bsize, size_t poolsize, unsigned mode) { PMEMblkpool *pbp = pmemblk_create(path, bsize, poolsize, mode); if (pbp == NULL) UT_OUT("!%s: pmemblk_create", path); else { os_stat_t stbuf; STAT(path, &stbuf); UT_OUT("%s: file size %zu usable blocks %zu mode 0%o", path, stbuf.st_size, pmemblk_nblock(pbp), stbuf.st_mode & 0777); pmemblk_close(pbp); int result = pmemblk_check(path, bsize); if (result < 0) UT_OUT("!%s: pmemblk_check", path); else if (result == 0) UT_OUT("%s: pmemblk_check: not consistent", path); else UT_ASSERTeq(pmemblk_check(path, bsize * 2), -1); } } static void pool_open(const char *path, size_t bsize) { PMEMblkpool *pbp = pmemblk_open(path, bsize); if (pbp == NULL) UT_OUT("!%s: pmemblk_open", path); else { UT_OUT("%s: pmemblk_open: Success", path); pmemblk_close(pbp); } } int main(int argc, char *argv[]) { START(argc, argv, "blk_pool"); if (argc < 4) UT_FATAL("usage: %s op path bsize [poolsize mode]", argv[0]); size_t bsize = strtoul(argv[3], NULL, 0); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = strtoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); pool_create(argv[2], bsize, poolsize, mode); break; case 'o': pool_open(argv[2], bsize); break; case 'f': poolsize = strtoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); do_fault_injection(argv[2], bsize, poolsize, mode); break; default: UT_FATAL("unknown operation"); } DONE(NULL); } pmdk-1.11.1/src/test/blk_pool/out31w.log.match0000664000000000000000000000025714123364546017551 0ustar rootrootblk_pool$(nW)TEST31w: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 39171 mode 0600 blk_pool$(nW)TEST31w: DONE pmdk-1.11.1/src/test/blk_pool/TEST250000775000000000000000000000100714123364546015457 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST25 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST25 existing file, file size >= min required size, bsize == 0 # (no read permissions) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 512 20 0640 chmod -r $DIR/testfile expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/out39.log.match0000664000000000000000000000026714123364546017373 0ustar rootrootblk_pool$(nW)TEST39: START: blk_pool $(nW)blk_pool$(nW) c $(nW)ㅹestㆅile 4096 20 0600 $(nW)ㅹestㆅile: file size 20971520 usable blocks 4820 mode 0600 blk_pool$(nW)TEST39: DONE pmdk-1.11.1/src/test/blk_pool/out15w.log.match0000664000000000000000000000025714123364546017553 0ustar rootrootblk_pool$(nW)TEST15w: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 80830 mode 0600 blk_pool$(nW)TEST15w: DONE pmdk-1.11.1/src/test/blk_pool/TEST31w.PS10000664000000000000000000000510414123364546016244 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST31 -- create a pool with the smallest parts # possible # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST31 non-existing file, poolsize >= min required size, bsize > min bsize # part size == min part size (pool set) $MIN_PART = (2 * 1024 * 1024).toString() + "B" # 2MiB create_poolset $DIR\testset ${MIN_PART}:$DIR\testfile1:x ${MIN_PART}:$DIR\testfile2:x ` ${MIN_PART}:$DIR\testfile3:x ${MIN_PART}:$DIR\testfile4:x ${MIN_PART}:$DIR\testfile5:x ` ${MIN_PART}:$DIR\testfile6:x ${MIN_PART}:$DIR\testfile7:x ${MIN_PART}:$DIR\testfile8:x ` ${MIN_PART}:$DIR\testfile9:x ${MIN_PART}:$DIR\testfile10:x expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testset 100 0 0640 check_files $DIR\testset $DIR\testfile1 $DIR\testfile2 $DIR\testfile3 ` $DIR\testfile4 $DIR\testfile5 $DIR\testfile6 $DIR\testfile7 $DIR\testfile8 ` $DIR\testfile9 $DIR\testfile10 check pass pmdk-1.11.1/src/test/blk_pool/Makefile0000664000000000000000000000035214123364546016245 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/Makefile -- build blk_pool unit test # TARGET = blk_pool OBJS = blk_pool.o LIBPMEMBLK=y USE_PMEMSPOIL=y include ../Makefile.inc pmdk-1.11.1/src/test/blk_pool/TEST3.PS10000664000000000000000000000377014123364546016003 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST3 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST14.PS10000664000000000000000000000071514123364546016061 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST14 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST14 non-existing file, poolsize >= min required size, bsize > min bsize # block size is too large # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile $((64*1024)) 20 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST2.PS10000664000000000000000000000057614123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST2 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST50000775000000000000000000000066414123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST5 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST5 non-existing file, poolsize > 0 # path is invalid (directory not exist) # expect_normal_exit ./blk_pool$EXESUFFIX c /NULL/testfile 4096 20 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out7.log.match0000664000000000000000000000023514123364546017301 0ustar rootrootblk_pool$(nW)TEST7: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0640 $(nW)testfile: pmemblk_create: File exists blk_pool$(nW)TEST7: DONE pmdk-1.11.1/src/test/blk_pool/TEST6.PS10000664000000000000000000000067714123364546016011 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST6 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup touch $DIR\testfile # # TEST6 existing file, file length < min required size, poolsize == 0, # bsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c \NULL\testfile 0 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST40000775000000000000000000000071514123364546015401 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST4 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 touch $DIR/testfile chmod 0640 $DIR/testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out34.log.match0000664000000000000000000000025714123364546017365 0ustar rootrootblk_pool$(nW)TEST34: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0600 $(nW)testfile: file size 20971520 usable blocks 4820 mode 0600 blk_pool$(nW)TEST34: DONE pmdk-1.11.1/src/test/blk_pool/TEST70000775000000000000000000000410114123364546015375 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST7 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_nonzeroed_file 17M 0K $DIR/testfile chmod 0640 $DIR/testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST23.PS10000664000000000000000000000375514123364546016070 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST23 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST23 existing file, file size >= min required size, bsize == 0 # (empty pool header) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/out0.log.match0000664000000000000000000000026214123364546017272 0ustar rootrootblk_pool$(nW)TEST0: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0600 $(nW)testfile: file size 20971520 usable blocks 4850 mode 0600 blk_pool$(nW)TEST0: DONE pmdk-1.11.1/src/test/blk_pool/TEST24.PS10000664000000000000000000000101314123364546016052 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST24 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST24 existing file, file size >= min required size, bsize == 1024 # (bsize doesn't match the value from pool header) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 512 20 0640 expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 1024 check pass pmdk-1.11.1/src/test/blk_pool/out37.log.match0000664000000000000000000000025614123364546017367 0ustar rootrootblk_pool$(nW)TEST37: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testfile 10 20 0600 $(nW)testfile: file size 20971520 usable blocks 40076 mode 0600 blk_pool$(nW)TEST37: DONE pmdk-1.11.1/src/test/blk_pool/out33.log.match0000664000000000000000000000025514123364546017362 0ustar rootrootblk_pool$(nW)TEST33: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testset 100 0 0640 $(nW)testset: file size $(N) usable blocks 36187 mode 0666 blk_pool$(nW)TEST33: DONE pmdk-1.11.1/src/test/blk_pool/TEST210000775000000000000000000000372514123364546015464 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST21 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 1M $DIR/testfile # # TEST21 existing file, file size < min required size, bsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/out25.log.match0000664000000000000000000000023114123364546017355 0ustar rootrootblk_pool$(nW)TEST25: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Permission denied blk_pool$(nW)TEST25: DONE pmdk-1.11.1/src/test/blk_pool/out9.log.match0000664000000000000000000000024214123364546017301 0ustar rootrootblk_pool$(nW)TEST9: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 1 0640 $(nW)testfile: pmemblk_create: Invalid argument blk_pool$(nW)TEST9: DONE pmdk-1.11.1/src/test/blk_pool/TEST30w.PS10000664000000000000000000000542614123364546016252 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST30 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST30 existing file, file size >= min required size, bsize == 300 # (pool set with replica section) # # XXX fix one we figure out windows poolsets and $PMEMSPOIL tool(?) echo "XXX" > out30w.log #expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` # c $DIR\testfile1 300 20 0640 #cp $DIR\testfile1 $DIR\testfile2 #$PMEMSPOIL $DIR\testfile1 pool_hdr.uuid=1111111111111111 \ # pool_hdr.next_part_uuid=1111111111111111 \ # pool_hdr.prev_part_uuid=1111111111111111 \ # pool_hdr.next_repl_uuid=2222222222222222 \ # pool_hdr.prev_repl_uuid=2222222222222222 \ # "pool_hdr.f:checksum_gen" #$PMEMSPOIL $DIR\testfile2 pool_hdr.uuid=2222222222222222 \ # pool_hdr.next_part_uuid=2222222222222222 \ # pool_hdr.prev_part_uuid=2222222222222222 \ # pool_hdr.next_repl_uuid=1111111111111111 \ # pool_hdr.prev_repl_uuid=1111111111111111 \ # "pool_hdr.f:checksum_gen" #create_poolset $DIR\testset 20M:$DIR\testfile1 R 20M:$DIR\testfile2 #expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` # c $DIR\testset 300 check pass pmdk-1.11.1/src/test/blk_pool/TEST0.PS10000664000000000000000000000124014123364546015766 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST0 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # Note: linux test reset default permissions and assures the library # creates a file using the permissions given. The Windows test just # checks that the permissions match. Note that the library's use # of the Windows CRT file functions (_chmod, _stat, etc) limit # permissions to R/W or RO # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out30w.log.match0000664000000000000000000000000414123364546017536 0ustar rootrootXXX pmdk-1.11.1/src/test/blk_pool/out14.log.match0000664000000000000000000000024614123364546017361 0ustar rootrootblk_pool$(nW)TEST14: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 65536 20 0640 $(nW)testfile: pmemblk_create: Invalid argument blk_pool$(nW)TEST14: DONE pmdk-1.11.1/src/test/blk_pool/out36.log.match0000664000000000000000000000023214123364546017360 0ustar rootrootblk_pool$(nW)TEST36: START: blk_pool $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0600 $(nW)testfile: pmemblk_create: File exists blk_pool$(nW)TEST36: DONE pmdk-1.11.1/src/test/blk_pool/TEST26.PS10000664000000000000000000000140314123364546016057 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST26 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST26 existing file, file size >= min required size, bsize == 0 # (no write permissions) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 512 20 0640 # remove write permissions & icacls $DIR\testfile /deny ${Env:USERNAME}:W >$null expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 # grant full permissions so test code can cleanup & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/blk_pool/out17.log.match0000664000000000000000000000027414123364546017365 0ustar rootrootblk_pool$(nW)TEST17: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)ㅹestㆅile 4096 20 0600 $(nW)ㅹestㆅile: file size 20971520 usable blocks 4850 mode 0600 blk_pool$(nW)TEST17: DONE pmdk-1.11.1/src/test/blk_pool/.gitignore0000664000000000000000000000001114123364546016565 0ustar rootrootblk_pool pmdk-1.11.1/src/test/blk_pool/TEST12.PS10000664000000000000000000000063214123364546016055 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST12 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST12 non-existing file, poolsize >= min required size, bsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 0 20 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/README0000664000000000000000000000672414123364546015476 0ustar rootrootPersistent Memory Development Kit This is src/test/blk_pool/README. This directory contains a unit test for pmemblk_create() and pmemblk_open(). The program in blk_pool.c takes: operation, path, bsize, poolsize, mode Operation can be: c - create o - open f - do fault injection "poolsize and "mode" arguments are ignored if operation is "open". For example: ./blk_pool c /my/file 4096 20 0640 This calls pmemblk_create() with the given arguments. Note that poolsize is given in megabytes. Test cases: - pmemblk_create: TEST0 (pass) non-existing file, poolsize >= min required size, bsize >= min blk size, fault_injection == 1 TEST1 (pass) existing file, file length >= min required size, poolsize == 0, bsize >= min blk size TEST2 (fail) non-existing file, poolsize == 0, bsize >= min blk size TEST3 (fail) existing file, file length >= min required size, poolsize != 0, bsize >= min blk size TEST4 (fail) existing file, file length < min required size, poolsize == 0, bsize >= min blk size TEST5 (fail) non-existing file, poolsize >= min required size, bsize >= min blk size path is invalid, directory does not exist TEST6 (fail) existing file, file length >= min required size, poolsize == 0, bsize == 0 TEST7 (fail) existing file, file length >= min required size, poolsize == 0, bsize >= min blk size file contains garbage TEST8 (pass) existing file, file length >= min required size, poolsize == 0, bsize >= min blk size file contains garbage, except for header TEST9 (fail) non-existing file, poolsize < min required size, bsize >= min blk size TEST10 (fail) existing file, file length >= min required size, poolsize == 0, bsize >= min blk size no read permissions TEST11 (fail) existing file, file length >= min required size, poolsize == 0, bsize >= min blk size no write permissions TEST12 (fail) non-existing file, poolsize >= min required size, bsize == 0 TEST13 (pass) non-existing file, poolsize >= min required size, bsize < min blk size TEST14 (fail) non-existing file, poolsize >= min required size, bsize > min blk size block size is too large TEST15 (pass) non-existing file, poolsize >= min required size, bsize < min blk size pool set TEST16 (fail) non-existing file, poolsize >= min required size, bsize < min blk size pool set with replica section - pmemblk_open: TEST20 (fail) non-existing file, bsize == 0 TEST21 (fail) existing file, file length < min required size, bsize == 0 TEST22 (fail) existing file, file length < min required size, bsize == 0 valid pool header TEST23 (fail) existing file, file length >= min required size, bsize == 0 empty pool header TEST24 (fail) existing file, file length >= min required size, bsize == 1024 bsize doesn't match the value from pool header TEST25 (fail) existing file, file length >= min required size, bsize == 0 no read permissions TEST26 (fail) existing file, file length >= min required size, bsize == 0 no write permissions TEST27 (pass) existing file, file length >= min required size, bsize == 0 TEST28 (pass) existing file, file length >= min required size, bsize == 300 bsize matches the value from pool header TEST29 (pass) existing file, file length >= min required size, bsize == 300 bsize matches the value from pool header pool set TEST30 (fail) existing file, file length >= min required size, bsize == 300 bsize matches the value from pool header pool set with replica section - each case outputs: - error, if error happened - resulting file size, nblocks, mode, consistency check results pmdk-1.11.1/src/test/blk_pool/TEST21.PS10000664000000000000000000000371614123364546016063 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST21 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 1M $DIR\testfile # # TEST21 existing file, file size < min required size, bsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/blk_pool.vcxproj0000664000000000000000000001256014123364546020027 0ustar rootroot Debug x64 Release x64 {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {95B683BD-B9DC-400F-9BC0-8F1505F08BF5} Win32Proj blk_pool 10.0.17134.0 Application true v140 Application false v140 true pmdk-1.11.1/src/test/blk_pool/out20.log.match0000664000000000000000000000024114123364546017351 0ustar rootrootblk_pool$(nW)TEST20: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: No such file or directory blk_pool$(nW)TEST20: DONE pmdk-1.11.1/src/test/blk_pool/TEST150000775000000000000000000000105314123364546015457 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/blk_pool/TEST15 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 # # TEST15 non-existing file, poolsize >= min required size, bsize > min bsize # (pool set) # create_poolset $DIR/testset 20M:$DIR/testfile1:x 20M:$DIR/testfile2:x expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 100 0 0640 check_files $DIR/testset $DIR/testfile1 $DIR/testfile2 check pass pmdk-1.11.1/src/test/blk_pool/TEST140000775000000000000000000000072414123364546015462 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST14 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST14 non-existing file, poolsize >= min required size, bsize > min bsize # block size is too large # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile $((64*1024)) 20 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST60000775000000000000000000000073614123364546015406 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST6 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 touch $DIR/testfile chmod 0640 $DIR/testfile # # TEST6 existing file, file length < min required size, poolsize == 0, # bsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 0 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST290000775000000000000000000000102314123364546015461 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/blk_pool/TEST29 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST29 existing file, file size >= min required size, bsize == 300 # (pool set) # create_poolset $DIR/testset 20M:$DIR/testfile1 20M:$DIR/testfile2 expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testset 300 0 0640 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testset 300 check pass pmdk-1.11.1/src/test/blk_pool/out27.log.match0000664000000000000000000000021714123364546017363 0ustar rootrootblk_pool$(nW)TEST27: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Success blk_pool$(nW)TEST27: DONE pmdk-1.11.1/src/test/blk_pool/TEST10000775000000000000000000000405014123364546015372 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST1 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 create_holey_file 40M $DIR/testfile chmod 0600 $DIR/testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST260000775000000000000000000000101014123364546015452 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST26 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST26 existing file, file size >= min required size, bsize == 0 # (no write permissions) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 512 20 0640 chmod -w $DIR/testfile expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST4.PS10000664000000000000000000000065514123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST4 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup Touch $DIR\testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/blk_pool.vcxproj.filters0000664000000000000000000001303014123364546021467 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {05f2a8a8-59fc-4969-8e86-6ee33c321153} match {881544fe-d25d-4cf8-8468-86eeb68ab91e} ps1 Source Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Test Scripts pmdk-1.11.1/src/test/blk_pool/TEST300000775000000000000000000000213514123364546015456 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/blk_pool/TEST30 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST30 existing file, file size >= min required size, bsize == 300 # (pool set with replica section) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile1 300 20 0640 cp $DIR/testfile1 $DIR/testfile2 $PMEMSPOIL $DIR/testfile1 pool_hdr.uuid=1111111111111111 \ pool_hdr.next_part_uuid=1111111111111111 \ pool_hdr.prev_part_uuid=1111111111111111 \ pool_hdr.next_repl_uuid=2222222222222222 \ pool_hdr.prev_repl_uuid=2222222222222222 \ "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile2 pool_hdr.uuid=2222222222222222 \ pool_hdr.next_part_uuid=2222222222222222 \ pool_hdr.prev_part_uuid=2222222222222222 \ pool_hdr.next_repl_uuid=1111111111111111 \ pool_hdr.prev_repl_uuid=1111111111111111 \ "pool_hdr.f:checksum_gen" create_poolset $DIR/testset 20M:$DIR/testfile1 R 20M:$DIR/testfile2 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testset 300 check pass pmdk-1.11.1/src/test/blk_pool/out11.log.match0000664000000000000000000000024014123364546017350 0ustar rootrootblk_pool$(nW)TEST11: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0640 $(nW)testfile: pmemblk_create: File exists blk_pool$(nW)TEST11: DONE pmdk-1.11.1/src/test/blk_pool/out6.log.match0000664000000000000000000000023714123364546017302 0ustar rootrootblk_pool$(nW)TEST6: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 0 0 0640 $(nW)testfile: pmemblk_create: Invalid argument blk_pool$(nW)TEST6: DONE pmdk-1.11.1/src/test/blk_pool/TEST80000775000000000000000000000414214123364546015403 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST8 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup umask 0 create_nonzeroed_file 17M 8K $DIR/testfile chmod 0600 $DIR/testfile # # TEST8 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out13.log.match0000664000000000000000000000026314123364546017357 0ustar rootrootblk_pool$(nW)TEST13: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 10 20 0600 $(nW)testfile: file size 20971520 usable blocks 40315 mode 0600 blk_pool$(nW)TEST13: DONE pmdk-1.11.1/src/test/blk_pool/TEST29.PS10000664000000000000000000000413614123364546016070 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST29 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST29 existing file, file size >= min required size, bsize == 300 # (pool set) # create_poolset $DIR\testset 20M:$DIR\testfile1 20M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testset 300 0 0600 expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` o $DIR\testset 300 check pass pmdk-1.11.1/src/test/blk_pool/TEST370000775000000000000000000000102314123364546015460 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_pool/TEST37 -- unit test for pmemblk_create # # This test is equivalent of TEST13 for ppc64le platform # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 # # TEST37 non-existing file, poolsize >= min required size, bsize < min bsize # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 10 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST8.PS10000664000000000000000000000406214123364546016003 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST8 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 17M 8K $DIR\testfile # # TEST8 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out22.log.match0000664000000000000000000000023014123364546017351 0ustar rootrootblk_pool$(nW)TEST22: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 0 $(nW)testfile: pmemblk_open: Invalid argument blk_pool$(nW)TEST22: DONE pmdk-1.11.1/src/test/blk_pool/TEST350000775000000000000000000000420414123364546015462 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # Copyright 2019, IBM Corporation # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST35 -- unit test for pmemblk_create # # This test is equivalent of TEST1 for ppc64le platform # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 create_holey_file 40M $DIR/testfile chmod 0600 $DIR/testfile # # TEST35 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out28.log.match0000664000000000000000000000022114123364546017357 0ustar rootrootblk_pool$(nW)TEST28: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testfile 300 $(nW)testfile: pmemblk_open: Success blk_pool$(nW)TEST28: DONE pmdk-1.11.1/src/test/blk_pool/out1.log.match0000664000000000000000000000026114123364546017272 0ustar rootrootblk_pool$(nW)TEST1: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0600 $(nW)testfile: file size 41943040 usable blocks 9965 mode 0600 blk_pool$(nW)TEST1: DONE pmdk-1.11.1/src/test/blk_pool/TEST270000775000000000000000000000067314123364546015471 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST27 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST27 existing file, file size >= min required size, bsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 512 20 0640 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 0 check pass pmdk-1.11.1/src/test/blk_pool/TEST100000775000000000000000000000412114123364546015451 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST10 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0240 $DIR/testfile # # TEST10 existing file, file length >= min required size, poolsize > 0 # (no read permissions) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST20000775000000000000000000000060514123364546015375 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST2 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 0 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/TEST310000775000000000000000000000073014123364546015456 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_pool/TEST31 -- unit test for pmemblk_open with unicode # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST31 existing file, file size >= min required size, layout matches # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/ㅹestㆅile 4096 20 0640 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/ㅹestㆅile 4096 check pass pmdk-1.11.1/src/test/blk_pool/TEST11.PS10000664000000000000000000000440314123364546016054 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST11 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # XXX Doesn't change outcome whether we make it RO or not, # same goes for linux test & icacls $DIR\testfile /grant ${Env:USERNAME}:R >$null # # TEST11 existing file, file length >= min required size, poolsize > 0 # (no write permissions) # expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testfile 4096 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool/out5.log.match0000664000000000000000000000025414123364546017300 0ustar rootrootblk_pool$(nW)TEST5: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0640 $(nW)testfile: pmemblk_create: No such file or directory blk_pool$(nW)TEST5: DONE pmdk-1.11.1/src/test/blk_pool/out3.log.match0000664000000000000000000000023614123364546017276 0ustar rootrootblk_pool$(nW)TEST3: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 20 0640 $(nW)testfile: pmemblk_create: File exists blk_pool$(nW)TEST3: DONE pmdk-1.11.1/src/test/blk_pool/TEST16.PS10000664000000000000000000000416714123364546016070 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool/TEST16 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST16 non-existing file, poolsize >= min required size, bsize > min bsize # (pool set with replica section) # create_poolset $DIR\testset 20M:$DIR\testfile1:x R 20M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\blk_pool$Env:EXESUFFIX ` c $DIR\testset 100 0 0600 check_files $DIR\testset check_no_files $DIR\testfile1 $DIR\testfile2 check pass pmdk-1.11.1/src/test/blk_pool/out31.log.match0000664000000000000000000000023214123364546017353 0ustar rootrootblk_pool$(nW)TEST31: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)ㅹestㆅile 4096 $(nW)ㅹestㆅile: pmemblk_open: Success blk_pool$(nW)TEST31: DONE pmdk-1.11.1/src/test/blk_pool/out4.log.match0000664000000000000000000000024214123364546017274 0ustar rootrootblk_pool$(nW)TEST4: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0640 $(nW)testfile: pmemblk_create: Invalid argument blk_pool$(nW)TEST4: DONE pmdk-1.11.1/src/test/blk_pool/TEST280000775000000000000000000000067714123364546015476 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool/TEST28 -- unit test for pmemblk_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST28 existing file, file size >= min required size, bsize == 300 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 300 20 0640 expect_normal_exit ./blk_pool$EXESUFFIX o $DIR/testfile 300 check pass pmdk-1.11.1/src/test/blk_pool/TEST390000775000000000000000000000100714123364546015464 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_pool/TEST39 -- unit test for pmemblk_create with unicode # # This test is equivalent of TEST17 for ppc64le platform # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup umask 0 # # TEST39 non-existing file, poolsize > 0 # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/ㅹestㆅile 4096 20 0600 check_files $DIR/ㅹestㆅile check pass pmdk-1.11.1/src/test/blk_pool/out8.log.match0000664000000000000000000000026114123364546017301 0ustar rootrootblk_pool$(nW)TEST8: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0600 $(nW)testfile: file size 17825792 usable blocks 4082 mode 0600 blk_pool$(nW)TEST8: DONE pmdk-1.11.1/src/test/blk_pool/out2.log.match0000664000000000000000000000025314123364546017274 0ustar rootrootblk_pool$(nW)TEST2: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 4096 0 0640 $(nW)testfile: pmemblk_create: No such file or directory blk_pool$(nW)TEST2: DONE pmdk-1.11.1/src/test/blk_pool/out12.log.match0000664000000000000000000000024214123364546017353 0ustar rootrootblk_pool$(nW)TEST12: START: blk_pool$(nW) $(nW)blk_pool$(nW) c $(nW)testfile 0 20 0640 $(nW)testfile: pmemblk_create: Invalid argument blk_pool$(nW)TEST12: DONE pmdk-1.11.1/src/test/blk_pool/TEST110000775000000000000000000000412214123364546015453 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_pool/TEST11 -- unit test for pmemblk_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0440 $DIR/testfile # # TEST11 existing file, file length >= min required size, poolsize > 0 # (no write permissions) # expect_normal_exit ./blk_pool$EXESUFFIX c $DIR/testfile 4096 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/blk_pool/out29.log.match0000664000000000000000000000021714123364546017365 0ustar rootrootblk_pool$(nW)TEST29: START: blk_pool$(nW) $(nW)blk_pool$(nW) o $(nW)testset 300 $(nW)testset: pmemblk_open: Success blk_pool$(nW)TEST29: DONE pmdk-1.11.1/src/test/pmem_map_file_win/0000775000000000000000000000000014123364546016453 5ustar rootrootpmdk-1.11.1/src/test/pmem_map_file_win/TEST1.PS10000664000000000000000000000256414123364546017647 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file_win/TEST1 -- unit test for pmem_map_file_win # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup # # pass the file of zero length expect_normal_exit $Env:EXE_DIR\pmem_map_file_win$Env:EXESUFFIX ` $DIR\testfile1 0 - 0666 1 1 ` $DIR\testfile2 0 C 0666 0 0 ` $DIR\testfile3 4096 C 0666 1 1 ` $DIR\testfile4 0 E 0666 1 1 ` $DIR\testfile5 4096 E 0666 1 1 ` $DIR\testfile6 4096 CE 0666 1 1 ` $DIR\testfile7 4096 CES 0666 1 1 ` $DIR\testfile8 4096 CS 0666 1 1 ` $DIR\testfile9 -1 C 0666 1 1 ` $DIR\testfile10 4096 X 0666 1 1 ` $DIR\testfile11 4096 CX 0666 1 1 ` $DIR\testfile12 0x1FFFFFFFFFFFFFFF CE 0666 1 1 ` $DIR 0 T 0666 1 1 ` $DIR 4096 T 0666 1 1 ` $DIR 4096 TC 0666 1 1 ` $DIR 4096 TE 0666 1 1 ` $DIR 4096 TS 0666 1 1 ` $DIR 4096 TSE 0666 1 1 ` $DIR 4096 TCE 0666 1 1 ` $DIR 4096 TSEC 0666 1 1 ` \nul\nonexistingdir 4096 T 0666 1 1 check_files $DIR\testfile3 ` $DIR\testfile6 ` $DIR\testfile7 ` $DIR\testfile8 check_no_files $DIR\testfile1 ` $DIR\testfile2 ` $DIR\testfile4 ` $DIR\testfile5 ` $DIR\testfile9 ` $DIR\testfile10 ` $DIR\testfile11 ` $DIR\testfile12 check pass pmdk-1.11.1/src/test/pmem_map_file_win/pmem_map_file_win.vcxproj.filters0000664000000000000000000000417014123364546025210 0ustar rootroot {189d0bf0-2f10-40d2-9a97-1c627dede493} {c775678f-276b-4eef-a23a-1e2e5e70e6f2} {1c3585e0-7b64-4460-86ee-dd837e30fecd} {d5932343-5e43-4cca-82a3-cde9c0443952} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts Test Scripts Match Files Match Files Header Files pmdk-1.11.1/src/test/pmem_map_file_win/mocks_windows.h0000664000000000000000000000114314123364546021511 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of libc functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmem * files, when compiled for the purpose of pmem_map_file test. * It would replace default implementation with mocked functions defined * in pmem_map_file.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define os_posix_fallocate __wrap_os_posix_fallocate #define os_ftruncate __wrap_os_ftruncate #endif pmdk-1.11.1/src/test/pmem_map_file_win/out0.log.match0000664000000000000000000000206514123364546021143 0ustar rootrootpmem_map_file_win$(nW)TEST0: START: pmem_map_file_win$(nW) $(nW)pmem_map_file_win$(nW) $(nW)testfile1 0 - 0 1 1 $(nW)testfile1 -1 - 0 1 1 $(nW)testfile1 0 - 0 0 0 $(nW)testfile1 0 X 0 0 0 $(nW)testfile1 0 - 0644 1 1 $(nW)testfile1 1024 - 0 1 1 $(nW)testfile1 0 C 0 1 1 $(nW)testfile1 0 E 0 1 1 $(nW)testfile1 4096 T 0644 1 1 $(nW)testfile1 4096 E 0644 1 1 $(nW)testfile1 0 - 0644 1 1 $(nW)testfile1 0 - 0 1 1 mapped_len 2147483648 unmap successful $(nW)testfile1 -1 - 0 1 1 pmem_map_file: Invalid argument $(nW)testfile1 0 - 0 0 0 unmap successful $(nW)testfile1 0 X 0 0 0 pmem_map_file: Invalid argument $(nW)testfile1 0 - 644 1 1 mapped_len 2147483648 unmap successful $(nW)testfile1 1024 - 0 1 1 pmem_map_file: Invalid argument $(nW)testfile1 0 C 0 1 1 pmem_map_file: Invalid argument $(nW)testfile1 0 E 0 1 1 mapped_len 2147483648 unmap successful $(nW)testfile1 4096 T 644 1 1 pmem_map_file: Invalid argument $(nW)testfile1 4096 E 644 1 1 pmem_map_file: Invalid argument $(nW)testfile1 0 - 644 1 1 mapped_len 2147483648 unmap successful pmem_map_file_win$(nW)TEST0: DONE pmdk-1.11.1/src/test/pmem_map_file_win/TEST0.PS10000664000000000000000000000144014123364546017636 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file_win/TEST0 -- unit test for pmem_map_file_win # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 2G $DIR\testfile1 # expect_normal_exit $Env:EXE_DIR\pmem_map_file_win$Env:EXESUFFIX ` $DIR\testfile1 0 - 0 1 1 ` $DIR\testfile1 -1 - 0 1 1 ` $DIR\testfile1 0 - 0 0 0 ` $DIR\testfile1 0 X 0 0 0 ` $DIR\testfile1 0 - 0644 1 1 ` $DIR\testfile1 1024 - 0 1 1 ` $DIR\testfile1 0 C 0 1 1 ` $DIR\testfile1 0 E 0 1 1 ` $DIR\testfile1 4096 T 0644 1 1 ` $DIR\testfile1 4096 E 0644 1 1 ` $DIR\testfile1 0 - 0644 1 1 check_files $DIR\testfile1 check pass pmdk-1.11.1/src/test/pmem_map_file_win/pmem_map_file_win.c0000664000000000000000000000774714123364546022305 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2019, Intel Corporation */ /* * pmem_map_file_win.c -- unit test for mapping persistent memory for raw access * * usage: pmem_map_file_win file */ #define _GNU_SOURCE #include "unittest.h" #include #define CHECK_BYTES 4096 /* bytes to compare before/after map call */ ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { ut_siglongjmp(Jmp); } #define PMEM_FILE_ALL_FLAGS\ (PMEM_FILE_CREATE|PMEM_FILE_EXCL|PMEM_FILE_SPARSE|PMEM_FILE_TMPFILE) static int device_dax = 0; /* * parse_flags -- parse 'flags' string */ static int parse_flags(const wchar_t *flags_str) { int ret = 0; while (*flags_str != L'\0') { switch (*flags_str) { case L'0': case L'-': /* no flags */ break; case L'T': ret |= PMEM_FILE_TMPFILE; break; case L'S': ret |= PMEM_FILE_SPARSE; break; case L'C': ret |= PMEM_FILE_CREATE; break; case L'E': ret |= PMEM_FILE_EXCL; break; case L'X': /* not supported flag */ ret |= (PMEM_FILE_ALL_FLAGS + 1); break; case L'D': device_dax = 1; break; default: UT_FATAL("unknown flags: %c", *flags_str); } flags_str++; }; return ret; } /* * do_check -- check the mapping */ static void do_check(int fd, void *addr, size_t mlen) { /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char pat[CHECK_BYTES]; char buf[CHECK_BYTES]; /* write some pattern to the file */ memset(pat, 0x5A, CHECK_BYTES); WRITE(fd, pat, CHECK_BYTES); if (memcmp(pat, addr, CHECK_BYTES)) UT_OUT("first %d bytes do not match", CHECK_BYTES); /* fill up mapped region with new pattern */ memset(pat, 0xA5, CHECK_BYTES); memcpy(addr, pat, CHECK_BYTES); UT_ASSERTeq(pmem_msync(addr, CHECK_BYTES), 0); UT_ASSERTeq(pmem_unmap(addr, mlen), 0); if (!ut_sigsetjmp(Jmp)) { /* same memcpy from above should now fail */ memcpy(addr, pat, CHECK_BYTES); } else { UT_OUT("unmap successful"); } LSEEK(fd, (os_off_t)0, SEEK_SET); if (READ(fd, buf, CHECK_BYTES) == CHECK_BYTES) { if (memcmp(pat, buf, CHECK_BYTES)) UT_OUT("first %d bytes do not match", CHECK_BYTES); } } int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "pmem_map_file_win"); int fd; void *addr; size_t mlen; size_t *mlenp; const wchar_t *path; unsigned long long len; int flags; int mode; int is_pmem; int *is_pmemp; int use_mlen; int use_is_pmem; if (argc < 7) UT_FATAL("usage: %s path len flags mode use_mlen " "use_is_pmem ...", ut_toUTF8(argv[0])); for (int i = 1; i + 5 < argc; i += 6) { path = argv[i]; len = wcstoull(argv[i + 1], NULL, 0); flags = parse_flags(argv[i + 2]); mode = wcstol(argv[i + 3], NULL, 8); use_mlen = _wtoi(argv[i + 4]); use_is_pmem = _wtoi(argv[i + 5]); mlen = SIZE_MAX; if (use_mlen) mlenp = &mlen; else mlenp = NULL; if (use_is_pmem) is_pmemp = &is_pmem; else is_pmemp = NULL; char *upath = ut_toUTF8(path); char *uflags = ut_toUTF8(argv[i + 2]); UT_OUT("%s %lld %s %o %d %d", upath, len, uflags, mode, use_mlen, use_is_pmem); free(uflags); free(upath); addr = pmem_map_fileW(path, len, flags, mode, mlenp, is_pmemp); if (addr == NULL) { UT_OUT("!pmem_map_file"); continue; } if (use_mlen) { UT_ASSERTne(mlen, SIZE_MAX); UT_OUT("mapped_len %zu", mlen); } else { mlen = len; } if (addr) { if ((flags & PMEM_FILE_TMPFILE) == 0 && !device_dax) { fd = WOPEN(argv[i], O_RDWR); if (!use_mlen) { os_stat_t stbuf; FSTAT(fd, &stbuf); mlen = stbuf.st_size; } if (fd != -1) { do_check(fd, addr, mlen); (void) CLOSE(fd); } else { UT_OUT("!cannot open file: %s", argv[i]); } } else { UT_ASSERTeq(pmem_unmap(addr, mlen), 0); } } } DONEW(NULL); } /* * Since libpmem is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmem_init) MSVC_DESTR(libpmem_fini) pmdk-1.11.1/src/test/pmem_map_file_win/README0000664000000000000000000000237214123364546017337 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_map_file_win/README. This directory contains a unit test for pmem_map_fileW(). The program in pmem_map_file_win.c takes a path, file length, flags, mode, use_mapped_len and use_is_pmem flags. The accepted flags in 'flags' string are: 'C' - PMEM_FILE_CREATE 'T' - PMEM_FILE_TMPFILE 'E' - PMEM_FILE_EXCL 'S' - PMEM_FILE_SPARSE '-' or '0' - no flag 'X' - not supported flag 'mode' - an an octal number that specifies the file mode Example: $ pmem_map_file_win /mnt/pmem/testfile 4096 CTS 0644 1 1 ... If the file is successfully mapped to memory, and it is not a temporary file, then initially the first 4k of the file is populated with some pattern using write(). The file content is verified after successful mapping with pmem_map_file_win(). Then, the program overwrites the first 4k of the mapped memory region with another pattern, unmaps the file, and verifies its content once again. Since this test unmaps the file with pmem_unmap(), it also tests that function by trying to access the address after it was unmapped and verifying it can't. Finally, the program re-opens the file with read-only access then tries to map the file and prints an error message if pmem_map_file_win() fails (which it should). pmdk-1.11.1/src/test/pmem_map_file_win/mocks_windows.c0000664000000000000000000000154414123364546021511 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * mocks_windows.c -- mocked functions used in pmem_map_file.c * (Windows-specific) */ #include "unittest.h" #define MAX_LEN (4 * 1024 * 1024) /* * posix_fallocate -- interpose on libc posix_fallocate() */ FUNC_MOCK(os_posix_fallocate, int, int fd, os_off_t offset, os_off_t len) FUNC_MOCK_RUN_DEFAULT { UT_OUT("posix_fallocate: off %ju len %ju", offset, len); if (len > MAX_LEN) return ENOSPC; return _FUNC_REAL(os_posix_fallocate)(fd, offset, len); } FUNC_MOCK_END /* * ftruncate -- interpose on libc ftruncate() */ FUNC_MOCK(os_ftruncate, int, int fd, os_off_t len) FUNC_MOCK_RUN_DEFAULT { UT_OUT("ftruncate: len %ju", len); if (len > MAX_LEN) { errno = ENOSPC; return -1; } return _FUNC_REAL(os_ftruncate)(fd, len); } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem_map_file_win/out1.log.match0000664000000000000000000000430514123364546021143 0ustar rootrootpmem_map_file_win$(nW)TEST1: START: pmem_map_file_win$(nW) $(nW)pmem_map_file_win$(nW) $(nW)testfile1 0 - 0666 1 1 $(nW)testfile2 0 C 0666 0 0 $(nW)testfile3 4096 C 0666 1 1 $(nW)testfile4 0 E 0666 1 1 $(nW)testfile5 4096 E 0666 1 1 $(nW)testfile6 4096 CE 0666 1 1 $(nW)testfile7 4096 CES 0666 1 1 $(nW)testfile8 4096 CS 0666 1 1 $(nW)testfile9 -1 C 0666 1 1 $(nW)testfile10 4096 X 0666 1 1 $(nW)testfile11 4096 CX 0666 1 1 $(nW)testfile12 0x1FFFFFFFFFFFFFFF CE 0666 1 1 $(nW) 0 T 0666 1 1 $(nW) 4096 T 0666 1 1 $(nW) 4096 TC 0666 1 1 $(nW) 4096 TE 0666 1 1 $(nW) 4096 TS 0666 1 1 $(nW) 4096 TSE 0666 1 1 $(nW) 4096 TCE 0666 1 1 $(nW) 4096 TSEC 0666 1 1 $(nW)nonexistingdir 4096 T 0666 1 1 $(nW)testfile1 0 - 666 1 1 pmem_map_file: No such file or directory $(nW)testfile2 0 C 666 0 0 pmem_map_file: Invalid argument $(nW)testfile3 4096 C 666 1 1 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 unmap successful $(nW)testfile4 0 E 666 1 1 pmem_map_file: No such file or directory $(nW)testfile5 4096 E 666 1 1 pmem_map_file: Invalid argument $(nW)testfile6 4096 CE 666 1 1 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 unmap successful $(nW)testfile7 4096 CES 666 1 1 ftruncate: len 4096 mapped_len 4096 unmap successful $(nW)testfile8 4096 CS 666 1 1 ftruncate: len 4096 mapped_len 4096 unmap successful $(nW)testfile9 -1 C 666 1 1 pmem_map_file: Invalid argument $(nW)testfile10 4096 X 666 1 1 pmem_map_file: Invalid argument $(nW)testfile11 4096 CX 666 1 1 pmem_map_file: Invalid argument $(nW)testfile12 2305843009213693951 CE 666 1 1 ftruncate: len 2305843009213693951 pmem_map_file: $(*) $(nW) 0 T 666 1 1 pmem_map_file: Invalid argument $(nW) 4096 T 666 1 1 pmem_map_file: Invalid argument $(nW) 4096 TC 666 1 1 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 $(nW) 4096 TE 666 1 1 pmem_map_file: Invalid argument $(nW) 4096 TS 666 1 1 pmem_map_file: Invalid argument $(nW) 4096 TSE 666 1 1 pmem_map_file: Invalid argument $(nW) 4096 TCE 666 1 1 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 $(nW) 4096 TSEC 666 1 1 ftruncate: len 4096 mapped_len 4096 $(nW)nonexistingdir 4096 T 666 1 1 pmem_map_file: Invalid argument pmem_map_file_win$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem_map_file_win/pmem_map_file_win.vcxproj0000664000000000000000000001264714123364546023551 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {5AD07646-5E16-4CEF-B80A-BE5EE4D54FEF} Win32Proj pmem_map_file_win 10.0.17134.0 Application true v140 Application false v140 mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;$(SolutionDir)\libpmem2\x86_64;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;$(SolutionDir)\libpmem2\x86_64;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem_map_file_win/out2.log.match0000664000000000000000000000100214123364546021133 0ustar rootrootpmem_map_file_win$(nW)TEST2: START: pmem_map_file_win$(nW) $(nW)pmem_map_file_win$(nW) $(nW) 0 D 0666 1 1 $(nW) 0 DSC 0666 1 1 $(nW) 0 DT 0666 1 1 $(nW) 0 DCE 0666 1 1 $(nW) 0 DC 0666 1 1 $(nW) 2097152 DC 0666 1 1 $(nW) 0 D 666 1 1 mapped_len $(N) $(nW) 0 DSC 666 1 1 mapped_len $(N) $(nW) 0 DT 666 1 1 pmem_map_file: Invalid argument $(nW) 0 DCE 666 1 1 pmem_map_file: Invalid argument $(nW) 0 DC 666 1 1 mapped_len $(N) $(nW) 2097152 DC 666 1 1 pmem_map_file: Invalid argument pmem_map_file_win$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_ctl_stats/0000775000000000000000000000000014123364546015636 5ustar rootrootpmdk-1.11.1/src/test/obj_ctl_stats/obj_ctl_stats.c0000664000000000000000000000634314123364546020642 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2020, Intel Corporation */ /* * obj_ctl_stats.c -- tests for the libpmemobj statistics module */ #include "unittest.h" int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_stats"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop; if ((pop = pmemobj_create(path, "ctl", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); int enabled; int ret = pmemobj_ctl_get(pop, "stats.enabled", &enabled); UT_ASSERTeq(enabled, 0); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, NULL, 1, 0, NULL, NULL); UT_ASSERTeq(ret, 0); size_t allocated; ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); UT_ASSERTeq(allocated, 0); enabled = 1; ret = pmemobj_ctl_set(pop, "stats.enabled", &enabled); UT_ASSERTeq(ret, 0); PMEMoid oid; ret = pmemobj_alloc(pop, &oid, 1, 0, NULL, NULL); UT_ASSERTeq(ret, 0); size_t oid_size = pmemobj_alloc_usable_size(oid) + 16; ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); UT_ASSERTeq(ret, 0); UT_ASSERTeq(allocated, oid_size); size_t run_allocated = 0; ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &run_allocated); UT_ASSERTeq(ret, 0); UT_ASSERT(run_allocated /* 2 allocs */ > allocated /* 1 alloc */); pmemobj_free(&oid); ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); UT_ASSERTeq(ret, 0); UT_ASSERTeq(allocated, 0); ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &run_allocated); UT_ASSERTeq(ret, 0); UT_ASSERT(run_allocated /* 2 allocs */ > allocated /* 1 alloc */); TX_BEGIN(pop) { oid = pmemobj_tx_alloc(1, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END oid_size = pmemobj_alloc_usable_size(oid) + 16; ret = pmemobj_ctl_get(pop, "stats.heap.curr_allocated", &allocated); UT_ASSERTeq(ret, 0); UT_ASSERTeq(allocated, oid_size); enum pobj_stats_enabled enum_enabled; ret = pmemobj_ctl_get(pop, "stats.enabled", &enum_enabled); UT_ASSERTeq(enabled, POBJ_STATS_ENABLED_BOTH); UT_ASSERTeq(ret, 0); run_allocated = 0; ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &run_allocated); UT_ASSERTeq(ret, 0); enum_enabled = POBJ_STATS_ENABLED_PERSISTENT; /* transient disabled */ ret = pmemobj_ctl_set(pop, "stats.enabled", &enum_enabled); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, &oid, 1, 0, NULL, NULL); UT_ASSERTeq(ret, 0); size_t tmp = 0; ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &tmp); UT_ASSERTeq(ret, 0); UT_ASSERTeq(tmp, run_allocated); /* shouldn't change */ /* the deallocated object shouldn't be reflected in rebuilt stats */ pmemobj_free(&oid); pmemobj_close(pop); pop = pmemobj_open(path, "ctl"); UT_ASSERTne(pop, NULL); /* stats are rebuilt lazily, so initially this should be 0 */ tmp = 0; ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &tmp); UT_ASSERTeq(ret, 0); UT_ASSERTeq(tmp, 0); ret = pmemobj_alloc(pop, NULL, 1, 0, NULL, NULL); UT_ASSERTeq(ret, 0); /* after first alloc, the previously allocated object will be found */ tmp = 0; ret = pmemobj_ctl_get(pop, "stats.heap.run_allocated", &tmp); UT_ASSERTeq(ret, 0); UT_ASSERTeq(tmp, run_allocated + oid_size); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_ctl_stats/obj_ctl_stats.vcxproj.filters0000664000000000000000000000140214123364546023551 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Test Files pmdk-1.11.1/src/test/obj_ctl_stats/obj_ctl_stats.vcxproj0000664000000000000000000000663314123364546022115 0ustar rootroot Debug x64 Release x64 {03228F84-4F41-4BCC-8C2D-F329DC87B289} Win32Proj obj_ctl_stats 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_ctl_stats/TEST00000775000000000000000000000036714123364546016431 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any setup expect_normal_exit ./obj_ctl_stats$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_ctl_stats/Makefile0000664000000000000000000000035114123364546017275 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_stats/Makefile -- build obj_ctl_stats test # TARGET = obj_ctl_stats OBJS = obj_ctl_stats.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_ctl_stats/TEST0.PS10000664000000000000000000000051114123364546017017 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_ctl_stats/TEST0 -- unit test for the libpmemobj statistics module # . ..\unittest\unittest.ps1 require_test_type short require_fs_type any setup expect_normal_exit $Env:EXE_DIR\obj_ctl_stats$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_ctl_stats/.gitignore0000664000000000000000000000001614123364546017623 0ustar rootrootobj_ctl_stats pmdk-1.11.1/src/test/obj_ctl_stats/TEST10000775000000000000000000000043414123364546016425 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any configure_valgrind pmemcheck force-enable setup expect_normal_exit ./obj_ctl_stats$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/rpmemd_log/0000775000000000000000000000000014123364546015131 5ustar rootrootpmdk-1.11.1/src/test/rpmemd_log/logfile0.log.match0000664000000000000000000000160614123364546020433 0ustar rootrootERR message on err level ERR message on warn level WARN message on warn level ERR message on notice level WARN message on notice level NOTICE message on notice level ERR message on info level WARN message on info level NOTICE message on info level INFO message on info level ERR message on debug level WARN message on debug level NOTICE message on debug level INFO message on debug level [prefix] ERR message on err level [prefix] ERR message on warn level [prefix] WARN message on warn level [prefix] ERR message on notice level [prefix] WARN message on notice level [prefix] NOTICE message on notice level [prefix] ERR message on info level [prefix] WARN message on info level [prefix] NOTICE message on info level [prefix] INFO message on info level [prefix] ERR message on debug level [prefix] WARN message on debug level [prefix] NOTICE message on debug level [prefix] INFO message on debug level pmdk-1.11.1/src/test/rpmemd_log/stderr2.log.match0000664000000000000000000000005414123364546020313 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_log/syslog2.log.match0000664000000000000000000000005414123364546020330 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_log/stderr0.log.match0000664000000000000000000000160614123364546020315 0ustar rootrootERR message on err level ERR message on warn level WARN message on warn level ERR message on notice level WARN message on notice level NOTICE message on notice level ERR message on info level WARN message on info level NOTICE message on info level INFO message on info level ERR message on debug level WARN message on debug level NOTICE message on debug level INFO message on debug level [prefix] ERR message on err level [prefix] ERR message on warn level [prefix] WARN message on warn level [prefix] ERR message on notice level [prefix] WARN message on notice level [prefix] NOTICE message on notice level [prefix] ERR message on info level [prefix] WARN message on info level [prefix] NOTICE message on info level [prefix] INFO message on info level [prefix] ERR message on debug level [prefix] WARN message on debug level [prefix] NOTICE message on debug level [prefix] INFO message on debug level pmdk-1.11.1/src/test/rpmemd_log/TEST00000775000000000000000000000110714123364546015715 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_log/TEST0 -- unit test for rpmemd_log module # # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_normal_exit ./rpmemd_log\ log stderr stderr$UNITTEST_NUM.log expect_normal_exit ./rpmemd_log\ log file logfile$UNITTEST_NUM.log expect_normal_exit ./rpmemd_log\ log syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_log/Makefile0000664000000000000000000000064514123364546016576 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/rpmemd_log/Makefile -- build rpmemd_log test # TOP = ../../.. vpath %.c $(TOP)/src/tools/rpmemd TARGET = rpmemd_log OBJS = rpmemd_log_test.o rpmemd_log.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -I../../tools/rpmemd LDFLAGS += $(call extract_funcs, rpmemd_log_test.c) pmdk-1.11.1/src/test/rpmemd_log/syslog1.log.match0000664000000000000000000000000614123364546020324 0ustar rootrootfatal pmdk-1.11.1/src/test/rpmemd_log/logfile2.log.match0000664000000000000000000000005414123364546020431 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_log/.gitignore0000664000000000000000000000001314123364546017113 0ustar rootrootrpmemd_log pmdk-1.11.1/src/test/rpmemd_log/README0000664000000000000000000000034114123364546016007 0ustar rootrootPersistent Memory Development Kit This is src/test/rpmemd_log/README. This test is Linux specific. This directory contains a unit test for rpmemd_log module. Usage: $ rpmemd_log fatal|log|assert stderr|file|syslog pmdk-1.11.1/src/test/rpmemd_log/logfile1.log.match0000664000000000000000000000000614123364546020425 0ustar rootrootfatal pmdk-1.11.1/src/test/rpmemd_log/rpmemd_log_test.c0000664000000000000000000001122314123364546020460 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2017, Intel Corporation */ /* * rpmemd_log_test.c -- unit tests for rpmemd_log */ #include #include #include #include "unittest.h" #include "rpmemd_log.h" #define PREFIX "prefix" static FILE *syslog_fh; /* * openlog -- mock for openlog function which logs its usage */ FUNC_MOCK(openlog, void, const char *ident, int option, int facility) FUNC_MOCK_RUN_DEFAULT { UT_OUT("openlog: ident = %s, option = %d, facility = %d", ident, option, facility); } FUNC_MOCK_END /* * closelog -- mock for closelog function which logs its usage */ FUNC_MOCK(closelog, void, void) FUNC_MOCK_RUN_DEFAULT { UT_OUT("closelog"); } FUNC_MOCK_END /* * syslog -- mock for syslog function which redirects message to a file */ FUNC_MOCK(syslog, void, int priority, const char *format, ...) FUNC_MOCK_RUN_DEFAULT { UT_ASSERT(priority == LOG_ERR || priority == LOG_WARNING || priority == LOG_NOTICE || priority == LOG_INFO || priority == LOG_DEBUG); va_list ap; va_start(ap, format); vfprintf(syslog_fh, format, ap); va_end(ap); } FUNC_MOCK_END /* * vsyslog -- mock for vsyslog function which redirects message to a file */ FUNC_MOCK(vsyslog, void, int priority, const char *format, va_list ap) FUNC_MOCK_RUN_DEFAULT { UT_ASSERT(priority == LOG_ERR || priority == LOG_WARNING || priority == LOG_NOTICE || priority == LOG_INFO || priority == LOG_DEBUG); vfprintf(syslog_fh, format, ap); } FUNC_MOCK_END /* * l2s -- level to string */ static const char * l2s(enum rpmemd_log_level level) { return rpmemd_log_level_to_str(level); } /* * test_log_messages -- test log messages on specified level */ static void test_log_messages(enum rpmemd_log_level level) { rpmemd_log_level = level; RPMEMD_LOG(ERR, "ERR message on %s level", l2s(level)); RPMEMD_LOG(WARN, "WARN message on %s level", l2s(level)); RPMEMD_LOG(NOTICE, "NOTICE message on %s level", l2s(level)); RPMEMD_LOG(INFO, "INFO message on %s level", l2s(level)); RPMEMD_DBG("DBG message on %s level", l2s(level)); } /* * test_all_log_messages -- test log messages on all levels, with and without * a prefix. */ static void test_all_log_messages(void) { rpmemd_prefix(NULL); test_log_messages(RPD_LOG_ERR); test_log_messages(RPD_LOG_WARN); test_log_messages(RPD_LOG_NOTICE); test_log_messages(RPD_LOG_INFO); test_log_messages(_RPD_LOG_DBG); rpmemd_prefix("[%s]", PREFIX); test_log_messages(RPD_LOG_ERR); test_log_messages(RPD_LOG_WARN); test_log_messages(RPD_LOG_NOTICE); test_log_messages(RPD_LOG_INFO); test_log_messages(_RPD_LOG_DBG); } #define USAGE() do {\ UT_ERR("usage: %s fatal|log|assert "\ "stderr|file|syslog ", argv[0]);\ } while (0) enum test_log_type { TEST_STDERR, TEST_FILE, TEST_SYSLOG, }; int main(int argc, char *argv[]) { START(argc, argv, "rpmemd_log"); if (argc < 4) { USAGE(); return 1; } const char *log_op = argv[1]; const char *log_type = argv[2]; const char *file = argv[3]; int do_fatal = 0; int do_assert = 0; if (strcmp(log_op, "fatal") == 0) { do_fatal = 1; } else if (strcmp(log_op, "assert") == 0) { do_assert = 1; } else if (strcmp(log_op, "log") == 0) { } else { USAGE(); return 1; } enum test_log_type type; if (strcmp(log_type, "stderr") == 0) { type = TEST_STDERR; } else if (strcmp(log_type, "file") == 0) { type = TEST_FILE; } else if (strcmp(log_type, "syslog") == 0) { type = TEST_SYSLOG; } else { USAGE(); return 1; } int fd_stderr = -1; FILE *stderr_fh = NULL; switch (type) { case TEST_STDERR: /* * Duplicate stdout file descriptor in order to preserve * the file list after redirecting the stdout to a file. */ fd_stderr = dup(2); UT_ASSERTne(fd_stderr, -1); os_close(2); stderr_fh = os_fopen(file, "a"); UT_ASSERTne(stderr_fh, NULL); break; case TEST_SYSLOG: syslog_fh = os_fopen(file, "a"); UT_ASSERTne(syslog_fh, NULL); break; default: break; } int ret; switch (type) { case TEST_STDERR: ret = rpmemd_log_init("rpmemd_log", NULL, 0); UT_ASSERTeq(ret, 0); break; case TEST_SYSLOG: ret = rpmemd_log_init("rpmemd_log", NULL, 1); UT_ASSERTeq(ret, 0); break; case TEST_FILE: ret = rpmemd_log_init("rpmemd_log", file, 0); UT_ASSERTeq(ret, 0); break; } if (do_fatal) { RPMEMD_FATAL("fatal"); } else if (do_assert) { RPMEMD_ASSERT(1); RPMEMD_ASSERT(0); } else { test_all_log_messages(); } rpmemd_log_close(); switch (type) { case TEST_STDERR: /* restore the original stdout file descriptor */ fclose(stderr_fh); UT_ASSERTeq(dup2(fd_stderr, 2), 2); os_close(fd_stderr); break; case TEST_SYSLOG: fclose(syslog_fh); break; default: break; } DONE(NULL); } pmdk-1.11.1/src/test/rpmemd_log/TEST10000775000000000000000000000112314123364546015714 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_log/TEST1 -- unit test for rpmemd_log module # # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ fatal stderr stderr$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ fatal file logfile$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ fatal syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_log/TEST20000775000000000000000000000112614123364546015720 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_log/TEST2 -- unit test for rpmemd_log module # # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ assert stderr stderr$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ assert file logfile$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_log\ assert syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_log/stderr1.log.match0000664000000000000000000000000614123364546020307 0ustar rootrootfatal pmdk-1.11.1/src/test/rpmemd_log/syslog0.log.match0000664000000000000000000000240614123364546020331 0ustar rootrootERR message on err level WARN message on err level NOTICE message on err level INFO message on err level ERR message on warn level WARN message on warn level NOTICE message on warn level INFO message on warn level ERR message on notice level WARN message on notice level NOTICE message on notice level INFO message on notice level ERR message on info level WARN message on info level NOTICE message on info level INFO message on info level ERR message on debug level WARN message on debug level NOTICE message on debug level INFO message on debug level [prefix] ERR message on err level [prefix] WARN message on err level [prefix] NOTICE message on err level [prefix] INFO message on err level [prefix] ERR message on warn level [prefix] WARN message on warn level [prefix] NOTICE message on warn level [prefix] INFO message on warn level [prefix] ERR message on notice level [prefix] WARN message on notice level [prefix] NOTICE message on notice level [prefix] INFO message on notice level [prefix] ERR message on info level [prefix] WARN message on info level [prefix] NOTICE message on info level [prefix] INFO message on info level [prefix] ERR message on debug level [prefix] WARN message on debug level [prefix] NOTICE message on debug level [prefix] INFO message on debug level pmdk-1.11.1/src/test/pmem2_integration/0000775000000000000000000000000014123364546016427 5ustar rootrootpmdk-1.11.1/src/test/pmem2_integration/pmem2_integration.vcxproj0000664000000000000000000001075014123364546023472 0ustar rootroot Debug x64 Release x64 {C7025EE1-57E5-44B9-A4F5-3CB059601FC3} pmem2_integration 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) true true {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_integration/pmem2_integration.c0000664000000000000000000006264714123364546022235 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2021, Intel Corporation */ /* * pmem2_integration.c -- pmem2 integration tests */ #include "libpmem2.h" #include "unittest.h" #include "rand.h" #include "ut_pmem2.h" #include "ut_pmem2_setup_integration.h" #define N_GRANULARITIES 3 /* BYTE, CACHE_LINE, PAGE */ /* * map_invalid -- try to mapping memory with invalid config */ static void map_invalid(struct pmem2_config *cfg, struct pmem2_source *src, int result) { struct pmem2_map *map = (struct pmem2_map *)0x7; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, result); UT_ASSERTeq(map, NULL); } /* * map_valid -- return valid mapped pmem2_map and validate mapped memory length */ static struct pmem2_map * map_valid(struct pmem2_config *cfg, struct pmem2_source *src, size_t size) { struct pmem2_map *map = NULL; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map, NULL); UT_ASSERTeq(pmem2_map_get_size(map), size); return map; } /* * test_reuse_cfg -- map pmem2_map twice using the same pmem2_config */ static int test_reuse_cfg(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_reuse_cfg "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t size; UT_ASSERTeq(pmem2_source_size(src, &size), 0); struct pmem2_map *map1 = map_valid(cfg, src, size); struct pmem2_map *map2 = map_valid(cfg, src, size); /* cleanup after the test */ pmem2_map_delete(&map2); pmem2_map_delete(&map1); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_reuse_cfg_with_diff_fd -- map pmem2_map using the same pmem2_config * with changed file descriptor */ static int test_reuse_cfg_with_diff_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_reuse_cfg_with_diff_fd "); char *file1 = argv[0]; int fd1 = OPEN(file1, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd1, PMEM2_GRANULARITY_PAGE); size_t size1; UT_ASSERTeq(pmem2_source_size(src, &size1), 0); struct pmem2_map *map1 = map_valid(cfg, src, size1); char *file2 = argv[1]; int fd2 = OPEN(file2, O_RDWR); /* set another valid file descriptor in source */ struct pmem2_source *src2; UT_ASSERTeq(pmem2_source_from_fd(&src2, fd2), 0); size_t size2; UT_ASSERTeq(pmem2_source_size(src2, &size2), 0); struct pmem2_map *map2 = map_valid(cfg, src2, size2); /* cleanup after the test */ pmem2_map_delete(&map2); CLOSE(fd2); pmem2_map_delete(&map1); pmem2_config_delete(&cfg); pmem2_source_delete(&src); pmem2_source_delete(&src2); CLOSE(fd1); return 2; } /* * test_register_pmem -- map, use and unmap memory */ static int test_register_pmem(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_register_pmem "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); char *word = "XXXXXXXX"; struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t size; UT_PMEM2_EXPECT_RETURN(pmem2_source_size(src, &size), 0); struct pmem2_map *map = map_valid(cfg, src, size); char *addr = pmem2_map_get_address(map); size_t length = strlen(word); /* write some data in mapped memory without persisting data */ memcpy(addr, word, length); /* cleanup after the test */ pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_use_misc_lens_and_offsets -- test with multiple offsets and lengths */ static int test_use_misc_lens_and_offsets(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_use_misc_lens_and_offsets "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; UT_PMEM2_EXPECT_RETURN(pmem2_source_size(src, &len), 0); struct pmem2_map *map = map_valid(cfg, src, len); char *base = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); rng_t rng; randomize_r(&rng, 13); /* arbitrarily chosen value */ for (size_t i = 0; i < len; i++) base[i] = (char)rnd64_r(&rng); persist_fn(base, len); UT_ASSERTeq(len % Ut_mmap_align, 0); for (size_t l = len; l > 0; l -= Ut_mmap_align) { for (size_t off = 0; off < l; off += Ut_mmap_align) { size_t len2 = l - off; int ret = pmem2_config_set_length(cfg, len2); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_offset(cfg, off); UT_PMEM2_EXPECT_RETURN(ret, 0); struct pmem2_map *map2 = map_valid(cfg, src, len2); char *ptr = pmem2_map_get_address(map2); UT_ASSERTeq(ret = memcmp(base + off, ptr, len2), 0); pmem2_map_delete(&map2); } } pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } struct gran_test_ctx; typedef void(*map_func)(struct pmem2_config *cfg, struct pmem2_source *src, struct gran_test_ctx *ctx); /* * gran_test_ctx -- essential parameters used by granularity test */ struct gran_test_ctx { map_func map_with_expected_gran; enum pmem2_granularity expected_granularity; }; /* * map_with_avail_gran -- map the range with valid granularity, * includes cleanup */ static void map_with_avail_gran(struct pmem2_config *cfg, struct pmem2_source *src, struct gran_test_ctx *ctx) { struct pmem2_map *map; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map, NULL); UT_ASSERTeq(ctx->expected_granularity, pmem2_map_get_store_granularity(map)); /* cleanup after the test */ pmem2_map_delete(&map); } /* * map_with_unavail_gran -- map the range with invalid granularity * (unsuccessful) */ static void map_with_unavail_gran(struct pmem2_config *cfg, struct pmem2_source *src, struct gran_test_ctx *unused) { struct pmem2_map *map; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_GRANULARITY_NOT_SUPPORTED); UT_ERR("%s", pmem2_errormsg()); UT_ASSERTeq(map, NULL); } static const map_func map_with_gran[N_GRANULARITIES][N_GRANULARITIES] = { /* requested granularity / available granularity */ /* -------------------------------------------------------------------- */ /* BYTE CACHE_LINE PAGE */ /* -------------------------------------------------------------------- */ /* BYTE */ {map_with_avail_gran, map_with_unavail_gran, map_with_unavail_gran}, /* CL */ {map_with_avail_gran, map_with_avail_gran, map_with_unavail_gran}, /* PAGE */ {map_with_avail_gran, map_with_avail_gran, map_with_avail_gran}}; static const enum pmem2_granularity gran_id2granularity[N_GRANULARITIES] = { PMEM2_GRANULARITY_BYTE, PMEM2_GRANULARITY_CACHE_LINE, PMEM2_GRANULARITY_PAGE}; /* * str2gran_id -- reads granularity id from the provided string */ static int str2gran_id(const char *in) { int gran = atoi(in); UT_ASSERT(gran >= 0 && gran < N_GRANULARITIES); return gran; } /* * test_granularity -- performs pmem2_map_new with certain expected granularity * in context of certain available granularity */ static int test_granularity(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL( "usage: test_granularity " " "); struct gran_test_ctx ctx; int avail_gran_id = str2gran_id(argv[1]); int req_gran_id = str2gran_id(argv[2]); ctx.expected_granularity = gran_id2granularity[avail_gran_id]; ctx.map_with_expected_gran = map_with_gran[req_gran_id][avail_gran_id]; char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, gran_id2granularity[req_gran_id]); ctx.map_with_expected_gran(cfg, src, &ctx); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 3; } /* * test_len_not_aligned -- try to use unaligned length */ static int test_len_not_aligned(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_len_not_aligned "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len, alignment; int ret = pmem2_source_size(src, &len); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_SOURCE_ALIGNMENT(src, &alignment); UT_ASSERT(len > alignment); size_t aligned_len = ALIGN_DOWN(len, alignment); size_t unaligned_len = aligned_len - 1; ret = pmem2_config_set_length(cfg, unaligned_len); UT_PMEM2_EXPECT_RETURN(ret, 0); map_invalid(cfg, src, PMEM2_E_LENGTH_UNALIGNED); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_len_aligned -- try to use aligned length */ static int test_len_aligned(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_len_aligned "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len, alignment; int ret = pmem2_source_size(src, &len); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_SOURCE_ALIGNMENT(src, &alignment); UT_ASSERT(len > alignment); size_t aligned_len = ALIGN_DOWN(len, alignment); ret = pmem2_config_set_length(cfg, aligned_len); UT_PMEM2_EXPECT_RETURN(ret, 0); struct pmem2_map *map = map_valid(cfg, src, aligned_len); pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_offset_not_aligned -- try to map with unaligned offset */ static int test_offset_not_aligned(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_offset_not_aligned "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len, alignment; int ret = pmem2_source_size(src, &len); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_SOURCE_ALIGNMENT(src, &alignment); /* break the offset */ size_t offset = alignment - 1; ret = pmem2_config_set_offset(cfg, offset); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERT(len > alignment); /* in this case len has to be aligned, only offset will be unaligned */ size_t aligned_len = ALIGN_DOWN(len, alignment); ret = pmem2_config_set_length(cfg, aligned_len - alignment); UT_PMEM2_EXPECT_RETURN(ret, 0); map_invalid(cfg, src, PMEM2_E_OFFSET_UNALIGNED); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_offset_aligned -- try to map with aligned offset */ static int test_offset_aligned(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_offset_aligned "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len, alignment; int ret = pmem2_source_size(src, &len); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_SOURCE_ALIGNMENT(src, &alignment); /* set the aligned offset */ size_t offset = alignment; ret = pmem2_config_set_offset(cfg, offset); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERT(len > alignment * 2); /* set the aligned len */ size_t map_len = ALIGN_DOWN(len / 2, alignment); ret = pmem2_config_set_length(cfg, map_len); UT_PMEM2_EXPECT_RETURN(ret, 0); struct pmem2_map *map = map_valid(cfg, src, map_len); pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_mem_move_cpy_set_with_map_private -- map O_RDONLY file and do * pmem2_[cpy|set|move]_fns with PMEM2_PRIVATE sharing */ static int test_mem_move_cpy_set_with_map_private(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL( "usage: test_mem_move_cpy_set_with_map_private "); char *file = argv[0]; int fd = OPEN(file, O_RDONLY); const char *word1 = "Persistent memory..."; const char *word2 = "Nonpersistent memory"; const char *word3 = "XXXXXXXXXXXXXXXXXXXX"; struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); pmem2_config_set_sharing(cfg, PMEM2_PRIVATE); size_t size = 0; UT_PMEM2_EXPECT_RETURN(pmem2_source_size(src, &size), 0); struct pmem2_map *map = map_valid(cfg, src, size); char *addr = pmem2_map_get_address(map); /* copy initial state */ char *initial_state = MALLOC(size); memcpy(initial_state, addr, size); pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); memcpy_fn(addr, word1, strlen(word1), 0); UT_ASSERTeq(strcmp(addr, word1), 0); memmove_fn(addr, word2, strlen(word2), 0); UT_ASSERTeq(strcmp(addr, word2), 0); memset_fn(addr, 'X', strlen(word3), 0); UT_ASSERTeq(strcmp(addr, word3), 0); /* remap memory, and check that the data has not been saved */ pmem2_map_delete(&map); map = map_valid(cfg, src, size); addr = pmem2_map_get_address(map); UT_ASSERTeq(strcmp(addr, initial_state), 0); /* cleanup after the test */ pmem2_map_delete(&map); FREE(initial_state); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_deep_flush_valid -- perform valid deep_flush for whole map */ static int test_deep_flush_valid(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, len); persist_fn(addr, len); int ret = pmem2_deep_flush(map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 1; } /* * test_deep_flush_e_range_behind -- try deep_flush for range behind a map */ static int test_deep_flush_e_range_behind(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); size_t map_size = pmem2_map_get_size(map); char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, len); persist_fn(addr, len); int ret = pmem2_deep_flush(map, addr + map_size + 1, 64); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_DEEP_FLUSH_RANGE); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 1; } /* * test_deep_flush_e_range_before -- try deep_flush for range before a map */ static int test_deep_flush_e_range_before(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); size_t map_size = pmem2_map_get_size(map); char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, len); persist_fn(addr, len); int ret = pmem2_deep_flush(map, addr - map_size, 64); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_DEEP_FLUSH_RANGE); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 1; } /* * test_deep_flush_slice -- try deep_flush for slice of a map */ static int test_deep_flush_slice(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); size_t map_size = pmem2_map_get_size(map); size_t map_part = map_size / 4; char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, map_part); persist_fn(addr, map_part); int ret = pmem2_deep_flush(map, addr + map_part, map_part); UT_PMEM2_EXPECT_RETURN(ret, 0); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 1; } /* * test_deep_flush_overlap -- try deep_flush for range overlapping map */ static int test_deep_flush_overlap(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); size_t map_size = pmem2_map_get_size(map); char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, len); persist_fn(addr, len); int ret = pmem2_deep_flush(map, addr + 1024, map_size); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_DEEP_FLUSH_RANGE); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 1; } /* * test_unaligned_persist -- try flushing on non-page-aligned addresses */ static int test_unaligned_persist(const struct test_case *tc, int argc, char *argv[]) { char *file = argv[0]; int fd = OPEN(file, O_RDWR); #define FLUSH_OFFSET 256 struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t len; PMEM2_SOURCE_SIZE(src, &len); struct pmem2_map *map = map_valid(cfg, src, len); size_t map_size = pmem2_map_get_size(map); char *addr = pmem2_map_get_address(map); pmem2_persist_fn persist_fn = pmem2_get_persist_fn(map); memset(addr, 0, len); persist_fn(addr + FLUSH_OFFSET, len - FLUSH_OFFSET); int ret = pmem2_deep_flush(map, addr + FLUSH_OFFSET, map_size - FLUSH_OFFSET); UT_PMEM2_EXPECT_RETURN(ret, 0); pmem2_map_delete(&map); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); #undef FLUSH_OFFSET return 1; } /* * test_source_anon -- tests map/config/source functions in combination * with anonymous source. */ static int test_source_anon(enum pmem2_sharing_type sharing, enum pmem2_granularity granularity, size_t source_len, size_t map_len) { int ret = 0; struct pmem2_config *cfg; struct pmem2_source *src; struct pmem2_map *map; struct pmem2_badblock_context *bbctx; UT_PMEM2_EXPECT_RETURN(pmem2_source_from_anon(&src, source_len), 0); UT_PMEM2_EXPECT_RETURN(pmem2_source_device_id(src, NULL, NULL), PMEM2_E_NOSUPP); UT_PMEM2_EXPECT_RETURN(pmem2_source_device_usc(src, NULL), PMEM2_E_NOSUPP); UT_PMEM2_EXPECT_RETURN(pmem2_source_numa_node(src, NULL), PMEM2_E_NOSUPP); UT_PMEM2_EXPECT_RETURN(pmem2_badblock_context_new(&bbctx, src), PMEM2_E_NOSUPP); size_t alignment; UT_PMEM2_EXPECT_RETURN(pmem2_source_alignment(src, &alignment), 0); UT_ASSERT(alignment >= Ut_pagesize); size_t size; UT_PMEM2_EXPECT_RETURN(pmem2_source_size(src, &size), 0); UT_ASSERTeq(size, source_len); PMEM2_CONFIG_NEW(&cfg); UT_PMEM2_EXPECT_RETURN(pmem2_config_set_length(cfg, map_len), 0); /* ignored */ UT_PMEM2_EXPECT_RETURN(pmem2_config_set_offset(cfg, alignment), 0); UT_PMEM2_EXPECT_RETURN(pmem2_config_set_required_store_granularity(cfg, granularity), 0); UT_PMEM2_EXPECT_RETURN(pmem2_config_set_sharing(cfg, sharing), 0); if ((ret = pmem2_map_new(&map, cfg, src)) != 0) goto map_fail; void *addr = pmem2_map_get_address(map); UT_ASSERTne(addr, NULL); UT_ASSERTeq(pmem2_map_get_size(map), map_len ? map_len : source_len); UT_ASSERTeq(pmem2_map_get_store_granularity(map), PMEM2_GRANULARITY_BYTE); UT_PMEM2_EXPECT_RETURN(pmem2_deep_flush(map, addr, alignment), PMEM2_E_NOSUPP); UT_PMEM2_EXPECT_RETURN(pmem2_map_delete(&map), 0); map_fail: PMEM2_CONFIG_DELETE(&cfg); pmem2_source_delete(&src); return ret; } /* * test_source_anon_ok_private -- valid config /w private flag */ static int test_source_anon_private(const struct test_case *tc, int argc, char *argv[]) { int ret = test_source_anon(PMEM2_PRIVATE, PMEM2_GRANULARITY_BYTE, 1 << 30ULL, 1 << 20ULL); UT_ASSERTeq(ret, 0); return 1; } /* * test_source_anon_shared -- valid config /w shared flag */ static int test_source_anon_shared(const struct test_case *tc, int argc, char *argv[]) { int ret = test_source_anon(PMEM2_SHARED, PMEM2_GRANULARITY_BYTE, 1 << 30ULL, 1 << 20ULL); UT_ASSERTeq(ret, 0); return 1; } /* * test_source_anon_page -- valid config /w page granularity */ static int test_source_anon_page(const struct test_case *tc, int argc, char *argv[]) { int ret = test_source_anon(PMEM2_SHARED, PMEM2_GRANULARITY_PAGE, 1 << 30ULL, 1 << 20ULL); UT_ASSERTeq(ret, 0); return 1; } /* * test_source_anon_zero_len -- valid config /w zero (src inherited) map length */ static int test_source_anon_zero_len(const struct test_case *tc, int argc, char *argv[]) { int ret = test_source_anon(PMEM2_SHARED, PMEM2_GRANULARITY_BYTE, 1 << 30ULL, 0); UT_ASSERTeq(ret, 0); return 1; } /* * test_source_anon_too_small -- valid config /w small mapping length */ static int test_source_anon_too_small(const struct test_case *tc, int argc, char *argv[]) { int ret = test_source_anon(PMEM2_SHARED, PMEM2_GRANULARITY_BYTE, 1 << 30ULL, 1 << 10ULL); UT_ASSERTne(ret, 0); return 1; } /* * test_map_from_existing_map -- compare normal map with map_from_existing */ static int test_map_from_existing_map(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: map_from_existing_map "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t size; UT_ASSERTeq(pmem2_source_size(src, &size), 0); struct pmem2_map *map1 = map_valid(cfg, src, size); /* cleanup after the test */ struct pmem2_map *map2; UT_PMEM2_EXPECT_RETURN(pmem2_map_from_existing(&map2, src, pmem2_map_get_address(map1), pmem2_map_get_size(map1), pmem2_map_get_store_granularity(map1)), PMEM2_E_MAP_EXISTS); pmem2_map_delete(&map1); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_map_from_existing -- compare normal map with map_from_existing */ static int test_map_from_existing(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_from_existing "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_source *src; struct pmem2_config *cfg; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t size; UT_ASSERTeq(pmem2_source_size(src, &size), 0); struct pmem2_map *map = map_valid(cfg, src, size); enum pmem2_granularity gran = pmem2_map_get_store_granularity(map); void *persist = pmem2_get_persist_fn(map); void *flush = pmem2_get_flush_fn(map); void *drain = pmem2_get_drain_fn(map); void *memmove = pmem2_get_memmove_fn(map); void *memcpy = pmem2_get_memcpy_fn(map); void *memset = pmem2_get_memset_fn(map); UT_PMEM2_EXPECT_RETURN(pmem2_map_delete(&map), 0); void *addr = FILE_MAP(fd, size); UT_ASSERTeq(pmem2_map_from_existing(&map, src, addr, size, gran), 0); UT_ASSERTeq(pmem2_map_get_address(map), addr); UT_ASSERTeq(pmem2_map_get_size(map), size); UT_ASSERTeq(pmem2_map_get_store_granularity(map), gran); UT_ASSERTeq(pmem2_get_persist_fn(map), persist); UT_ASSERTeq(pmem2_get_flush_fn(map), flush); UT_ASSERTeq(pmem2_get_drain_fn(map), drain); UT_ASSERTeq(pmem2_get_memmove_fn(map), memmove); UT_ASSERTeq(pmem2_get_memcpy_fn(map), memcpy); UT_ASSERTeq(pmem2_get_memset_fn(map), memset); pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } #undef COMPARE_FUNCS /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_reuse_cfg), TEST_CASE(test_reuse_cfg_with_diff_fd), TEST_CASE(test_register_pmem), TEST_CASE(test_use_misc_lens_and_offsets), TEST_CASE(test_granularity), TEST_CASE(test_len_not_aligned), TEST_CASE(test_len_aligned), TEST_CASE(test_offset_not_aligned), TEST_CASE(test_offset_aligned), TEST_CASE(test_mem_move_cpy_set_with_map_private), TEST_CASE(test_deep_flush_valid), TEST_CASE(test_deep_flush_e_range_behind), TEST_CASE(test_deep_flush_e_range_before), TEST_CASE(test_deep_flush_slice), TEST_CASE(test_deep_flush_overlap), TEST_CASE(test_source_anon_private), TEST_CASE(test_source_anon_shared), TEST_CASE(test_source_anon_page), TEST_CASE(test_source_anon_too_small), TEST_CASE(test_source_anon_zero_len), TEST_CASE(test_unaligned_persist), TEST_CASE(test_map_from_existing_map), TEST_CASE(test_map_from_existing) }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_integration"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_integration/pmem2_integration.vcxproj.filters0000664000000000000000000000345014123364546025140 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {4c1dd0a5-269b-43ca-aadb-69c54b295dc2} {92f1ac35-e06e-4934-8606-adae8fb61b52} Source Files Source Files Source Files Source Files Source Files Header Files Header Files Test Scripts Match Files pmdk-1.11.1/src/test/pmem2_integration/Makefile0000664000000000000000000000060514123364546020070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem2_integration/Makefile -- build pmem2_integration test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmem2_integration OBJS = pmem2_integration.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o\ ut_pmem2_setup_integration.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_integration/TESTS.py0000775000000000000000000002010314123364546017702 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation # import testframework as t from testframework import granularity as g class Granularity(str): BYTE = '0' CACHE_LINE = '1' PAGE = '2' class PMEM2_INTEGRATION(t.Test): test_type = t.Medium def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile') ctx.exec('pmem2_integration', self.test_case, filepath) @t.require_devdax(t.DevDax('devdax')) class PMEM2_INTEGRATION_DEV_DAXES(t.Test): test_type = t.Medium def run(self, ctx): dd = ctx.devdaxes.devdax ctx.exec('pmem2_integration', self.test_case, dd.path) class PMEM2_GRANULARITY(t.Test): test_type = t.Medium test_case = 'test_granularity' available_granularity = None requested_granularity = None def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile') ctx.exec('pmem2_integration', self.test_case, filepath, self.available_granularity, self.requested_granularity) class TEST0(PMEM2_INTEGRATION): """map twice using the same config""" test_case = "test_reuse_cfg" class TEST1(PMEM2_INTEGRATION): """map using the same config with changed file descriptor""" test_case = "test_reuse_cfg_with_diff_fd" def run(self, ctx): filepath1 = ctx.create_holey_file(16 * t.MiB, 'testfile1') filepath2 = ctx.create_holey_file(16 * t.MiB, 'testfile2') ctx.exec('pmem2_integration', self.test_case, filepath1, filepath2) @t.require_valgrind_enabled('pmemcheck') class TEST2(PMEM2_INTEGRATION): """check if Valgrind registers data writing on pmem""" test_case = "test_register_pmem" @t.require_valgrind_enabled('pmemcheck') @t.windows_exclude class TEST3(PMEM2_INTEGRATION_DEV_DAXES): """check if Valgrind registers data writing on DevDax""" test_case = "test_register_pmem" class TEST4(PMEM2_INTEGRATION): """create multiple mappings with different offsets and lengths""" test_case = "test_use_misc_lens_and_offsets" def run(self, ctx): filepath = ctx.create_holey_file(1 * t.MiB, 'testfile1') ctx.exec('pmem2_integration', self.test_case, filepath) @g.require_granularity(g.PAGE) class TEST5(PMEM2_GRANULARITY): """test granularity with available page granularity and expected page granularity""" available_granularity = Granularity.PAGE requested_granularity = Granularity.PAGE @g.require_granularity(g.PAGE) class TEST6(PMEM2_GRANULARITY): """test granularity with available page granularity and expected cache line granularity""" available_granularity = Granularity.PAGE requested_granularity = Granularity.CACHE_LINE @g.require_granularity(g.PAGE) class TEST7(PMEM2_GRANULARITY): """test granularity with available page granularity and expected byte granularity""" available_granularity = Granularity.PAGE requested_granularity = Granularity.BYTE @g.require_granularity(g.CACHELINE) class TEST8(PMEM2_GRANULARITY): """test granularity with available cache line granularity and expected page granularity""" available_granularity = Granularity.CACHE_LINE requested_granularity = Granularity.PAGE @g.require_granularity(g.CACHELINE) class TEST9(PMEM2_GRANULARITY): """test granularity with available cache line granularity and expected cache line granularity""" available_granularity = Granularity.CACHE_LINE requested_granularity = Granularity.CACHE_LINE @g.require_granularity(g.CACHELINE) class TEST10(PMEM2_GRANULARITY): """test granularity with available cache line granularity and expected byte granularity""" available_granularity = Granularity.CACHE_LINE requested_granularity = Granularity.BYTE @g.require_granularity(g.BYTE) class TEST11(PMEM2_GRANULARITY): """test granularity with available byte granularity and expected page granularity""" available_granularity = Granularity.BYTE requested_granularity = Granularity.PAGE @g.require_granularity(g.BYTE) class TEST12(PMEM2_GRANULARITY): """test granularity with available byte granularity and expected cache line granularity""" available_granularity = Granularity.BYTE requested_granularity = Granularity.CACHE_LINE @g.require_granularity(g.BYTE) class TEST13(PMEM2_GRANULARITY): """test granularity with available byte granularity and expected byte granularity""" available_granularity = Granularity.BYTE requested_granularity = Granularity.BYTE class TEST14(PMEM2_INTEGRATION): """test not aligned length""" test_case = "test_len_not_aligned" @t.windows_exclude class TEST15(PMEM2_INTEGRATION_DEV_DAXES): """test not aligned length on DevDax""" test_case = "test_len_not_aligned" class TEST16(PMEM2_INTEGRATION): """test aligned length""" test_case = "test_len_aligned" @t.windows_exclude class TEST17(PMEM2_INTEGRATION_DEV_DAXES): """test aligned length on DevDax""" test_case = "test_len_aligned" class TEST18(PMEM2_INTEGRATION): """test unaligned offset""" test_case = "test_offset_not_aligned" @t.windows_exclude class TEST19(PMEM2_INTEGRATION_DEV_DAXES): """test unaligned offset""" test_case = "test_offset_not_aligned" class TEST20(PMEM2_INTEGRATION): """test unaligned offset""" test_case = "test_offset_aligned" @t.windows_exclude class TEST21(PMEM2_INTEGRATION_DEV_DAXES): """test unaligned offset""" test_case = "test_offset_aligned" class TEST22(PMEM2_INTEGRATION): """ map O_RDONLY file and test pmem2_[cpy|set|move]_fns with PMEM2_PRIVATE sharing """ test_case = "test_mem_move_cpy_set_with_map_private" class TEST23(PMEM2_INTEGRATION): """test valid case of pmem2_deep_sflush""" test_case = "test_deep_flush_valid" class TEST24(PMEM2_INTEGRATION): """test deep flush with range out of map""" test_case = "test_deep_flush_e_range_behind" class TEST25(PMEM2_INTEGRATION): """test deep flush with range out of map""" test_case = "test_deep_flush_e_range_before" class TEST26(PMEM2_INTEGRATION): """test deep flush with part of map""" test_case = "test_deep_flush_slice" class TEST27(PMEM2_INTEGRATION): """test deep flush with overlapping part""" test_case = "test_deep_flush_overlap" class TEST28(PMEM2_INTEGRATION): """test for anonymous mappings""" test_case = "test_source_anon_private" class TEST29(PMEM2_INTEGRATION): """test for anonymous mappings""" test_case = "test_source_anon_shared" class TEST30(PMEM2_INTEGRATION): """test for anonymous mappings""" test_case = "test_source_anon_page" class TEST31(PMEM2_INTEGRATION): """test for anonymous mappings""" test_case = "test_source_anon_too_small" class TEST32(PMEM2_INTEGRATION): """test for anonymous mappings""" test_case = "test_source_anon_zero_len" @t.windows_exclude class TEST33(PMEM2_INTEGRATION_DEV_DAXES): """test valid case of pmem2_deep_sflush""" test_case = "test_deep_flush_valid" @t.windows_exclude class TEST34(PMEM2_INTEGRATION_DEV_DAXES): """test deep flush with range out of map""" test_case = "test_deep_flush_e_range_behind" @t.windows_exclude class TEST35(PMEM2_INTEGRATION_DEV_DAXES): """test deep flush with range out of map""" test_case = "test_deep_flush_e_range_before" @t.windows_exclude class TEST36(PMEM2_INTEGRATION_DEV_DAXES): """test deep flush with part of map""" test_case = "test_deep_flush_slice" @t.windows_exclude class TEST37(PMEM2_INTEGRATION_DEV_DAXES): """test deep flush with overlapping part""" test_case = "test_deep_flush_overlap" class TEST38(PMEM2_INTEGRATION): """test for unaligned persists""" test_case = "test_unaligned_persist" class TEST39(PMEM2_INTEGRATION): """compare normal map vs map_from_existing""" test_case = "test_map_from_existing" class TES40(PMEM2_INTEGRATION): """test map_from_existing from pmem2_mapping""" test_case = "test_map_from_existing_map" @t.windows_exclude class TEST41(PMEM2_INTEGRATION_DEV_DAXES): """compare normal map vs map_from_existing on devdax""" test_case = "test_map_from_existing" pmdk-1.11.1/src/test/pmem2_integration/.gitignore0000664000000000000000000000002214123364546020411 0ustar rootrootpmem2_integration pmdk-1.11.1/src/test/pmem2_integration/pmemcheck3.log.match0000664000000000000000000000113514123364546022244 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/pmem2_integration$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 1 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*)memcpy$(*) ==$(*)== by 0x$(*): test_register_pmem (pmem2_integration.c:$(*)) ==$(*)== by 0x$(*): TEST_CASE_PROCESS (unittest.h:$(*)) ==$(*)== by 0x$(*): main (pmem2_integration.c:$(*)) ==$(*)== Address: 0x$(*) size: 8 state: DIRTY ==$(*)== Total memory not made persistent: 8 ==$(*)== ERROR SUMMARY: 1 errors pmdk-1.11.1/src/test/pmem2_integration/pmemcheck2.log.match0000664000000000000000000000113514123364546022243 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/pmem2_integration$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 1 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*)memcpy$(*) ==$(*)== by 0x$(*): test_register_pmem (pmem2_integration.c:$(*)) ==$(*)== by 0x$(*): TEST_CASE_PROCESS (unittest.h:$(*)) ==$(*)== by 0x$(*): main (pmem2_integration.c:$(*)) ==$(*)== Address: 0x$(*) size: 8 state: DIRTY ==$(*)== Total memory not made persistent: 8 ==$(*)== ERROR SUMMARY: 1 errors pmdk-1.11.1/src/test/daxio/0000775000000000000000000000000014123364546014110 5ustar rootrootpmdk-1.11.1/src/test/daxio/TEST30000775000000000000000000000547414123364546014712 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # daxio/TEST3 -- test for daxio utility; exactly the same as TEST0, # but using various size units (KB, KiB, K, B, ...) # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 1 setup # must be done after setup, when daxio path is already known require_binary $DAXIO$EXESUFFIX LOG=out$UNITTEST_NUM.log STDIN_TMP=stdin$UNITTEST_NUM.log DATALOG=data$UNITTEST_NUM.log DATA1=$DIR/data1.bin DATA2=$DIR/data2.bin DATAOUT1=$DIR/data_out1.bin DATAOUT2=$DIR/data_out2.bin # prepare file with test data dd if=/dev/zero bs=1k count=2 2> prep$UNITTEST_NUM.log | tr '\0' 'x' > $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' 'o' >> $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '1' > $DATA2 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '2' >> $DATA2 # fill up Device DAX with some random data (len in hex) expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -l 16KiB < /dev/urandom 2>$LOG" # check if not zeroed expect_abnormal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[0]} &>>$LOG" # zero device (len in dec) expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -l 16K 2>>$LOG" # check if zeroed expect_normal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[0]} &>>$LOG" # write data from files to Device DAX with various offsets/lengths # offset = 0 (default), len = length of input (4K) # 2K * 'x' + 2K * 'o' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA1 -o ${DEVICE_DAX_PATH[0]} 2>>$LOG" # offset = 4K, skip = 2K, len = length of remaining part of input (2K) # 2K * '2' + 2K * '\0' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA2 -o ${DEVICE_DAX_PATH[0]} -k 2KiB -s 4KiB 2>>$LOG" # offset = 8K, skip = 1K, len = 2K # 1K * '1' + 1K * '2' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA2 -o ${DEVICE_DAX_PATH[0]} -k 1K -s 8K -l 2K 2>>$LOG" # offset = 10K # 8 * 'a' echo -n "aaaaaaaa" > $STDIN_TMP expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -s 10K 2>>$LOG < $STDIN_TMP" rm $STDIN_TMP # zero some fragments expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -l 256B 2>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -s 3K -l 128 2>>$LOG" # dump data to file expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o $DATAOUT1 -l 16384 2>>$LOG" # dump data to stdout expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -l 16384 > $DATAOUT2 2>>$LOG" # check content expect_normal_exit "$DDMAP$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -b 1 -n 16384 -r > $DATALOG" expect_normal_exit "$DDMAP$EXESUFFIX -i $DATAOUT1 -b 1 -n 16384 -r >> $DATALOG" expect_normal_exit "$DDMAP$EXESUFFIX -i $DATAOUT2 -b 1 -n 16384 -r >> $DATALOG" check pass pmdk-1.11.1/src/test/daxio/data0.log.match0000664000000000000000000000034114123364546016675 0ustar rootroot256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° 256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° 256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° pmdk-1.11.1/src/test/daxio/TEST00000775000000000000000000000537514123364546014707 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # daxio/TEST0 -- test for daxio utility; basic functionality # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 1 setup # must be done after setup, when daxio path is already known require_binary $DAXIO$EXESUFFIX LOG=out$UNITTEST_NUM.log STDIN_TMP=stdin$UNITTEST_NUM.log DATALOG=data$UNITTEST_NUM.log DATA1=$DIR/data1.bin DATA2=$DIR/data2.bin DATAOUT1=$DIR/data_out1.bin DATAOUT2=$DIR/data_out2.bin # prepare file with test data dd if=/dev/zero bs=1k count=2 2> prep$UNITTEST_NUM.log | tr '\0' 'x' > $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' 'o' >> $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '1' > $DATA2 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '2' >> $DATA2 # fill up Device DAX with some random data (len in hex) expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -l 16384 < /dev/urandom 2>$LOG" # check if not zeroed expect_abnormal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[0]} &>>$LOG" # zero device (len in dec) expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -l 16384 2>>$LOG" # check if zeroed expect_normal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[0]} &>>$LOG" # write data from files to Device DAX with various offsets/lengths # offset = 0 (default), len = length of input (4K) # 2K * 'x' + 2K * 'o' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA1 -o ${DEVICE_DAX_PATH[0]} 2>>$LOG" # offset = 4K, skip = 2K, len = length of remaining part of input (2K) # 2K * '2' + 2K * '\0' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA2 -o ${DEVICE_DAX_PATH[0]} -k 2048 -s 4096 2>>$LOG" # offset = 8K, skip = 1K, len = 2K # 1K * '1' + 1K * '2' expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA2 -o ${DEVICE_DAX_PATH[0]} -k 1024 -s 8192 -l 2048 2>>$LOG" # offset = 10K # 8 * 'a' echo -n "aaaaaaaa" > $STDIN_TMP expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -s 10240 2>>$LOG < $STDIN_TMP" rm $STDIN_TMP # zero some fragments expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -l 256 2>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -s 3072 -l 128 2>>$LOG" # dump data to file expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o $DATAOUT1 -l 16384 2>>$LOG" # dump data to stdout expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -l 16384 > $DATAOUT2 2>>$LOG" # check content expect_normal_exit "$DDMAP$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -b 1 -n 16384 -r > $DATALOG" expect_normal_exit "$DDMAP$EXESUFFIX -i $DATAOUT1 -b 1 -n 16384 -r >> $DATALOG" expect_normal_exit "$DDMAP$EXESUFFIX -i $DATAOUT2 -b 1 -n 16384 -r >> $DATALOG" check pass pmdk-1.11.1/src/test/daxio/Makefile0000664000000000000000000000023414123364546015547 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/daxio/Makefile -- build daxio unittest # include ../Makefile.inc pmdk-1.11.1/src/test/daxio/data2.log.match0000664000000000000000000000012014123364546016672 0ustar rootroot2048 x 2048 o 2048 1 2048 2 8192 ° 1536 x 512 o 1024 ° 1024 1 1024 2 11264 ° pmdk-1.11.1/src/test/daxio/out0.log.match0000664000000000000000000000111414123364546016572 0ustar rootrootdaxio: copied 16384 bytes to device "$(nW)" $(nW) is not zeroed daxio: copied 16384 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 4096 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 2048 bytes to device "$(nW)" daxio: copied 2048 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 8 bytes to device "$(nW)" daxio: copied 256 bytes to device "$(nW)" daxio: copied 128 bytes to device "$(nW)" daxio: copied 16384 bytes to device "$(nW)" daxio: copied 16384 bytes to device "STDOUT" pmdk-1.11.1/src/test/daxio/README0000664000000000000000000000032114123364546014764 0ustar rootrootPersistent Memory Development Kit This is src/test/daxio/README. This directory contains a unit test for 'daxio' utility. The tests in this directory verify the 'daxio' utility features and error handling. pmdk-1.11.1/src/test/daxio/TEST10000775000000000000000000000436114123364546014702 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # daxio/TEST1 -- test for daxio utility; negative scenarios # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 1 setup # must be done after setup, when daxio path is already known require_binary $DAXIO$EXESUFFIX LOG=out$UNITTEST_NUM.log # invalid offset/length expect_abnormal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -k 0x1234abzz &>$LOG" expect_abnormal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -s foo &>>$LOG" expect_abnormal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -l 20xxx &>>$LOG" # zero flag w/o output expect_abnormal_exit "$DAXIO$EXESUFFIX -z &>>$LOG" # no input/output expect_abnormal_exit "$DAXIO$EXESUFFIX -l 100 &>>$LOG" # offset w/o input or output expect_abnormal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -k 100 &>>$LOG" expect_abnormal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -s 100 &>>$LOG" # neither input or output is device dax expect_abnormal_exit "$DAXIO$EXESUFFIX -i /dev/zero -o $DIR/dummy -l 16384 &>>$LOG" # requested size larger than source - no error, but will copy less than requested create_holey_file 4KB $DIR/dummy expect_normal_exit "$DAXIO$EXESUFFIX -i $DIR/dummy -o ${DEVICE_DAX_PATH[0]} -l 8192 &>>$LOG" # offset/length beyond device size DEVSIZE=`$PMEMDETECT -z ${DEVICE_DAX_PATH[0]}` expect_abnormal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o /dev/null -k $(($DEVSIZE + 100)) &>>$LOG" expect_abnormal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -i /dev/zero -s $(($DEVSIZE + 1)) &>>$LOG" # these succeed, but copy less bytes than requested expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -i /dev/zero -l $(($DEVSIZE + 1000)) &>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o /dev/null -k $(($DEVSIZE / 2)) -l $DEVSIZE &>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -i /dev/zero -s $(($DEVSIZE - 100)) -l $DEVSIZE &>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o $DIR/dummy_out -k $(($DEVSIZE - 100)) -l $DEVSIZE &>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -o ${DEVICE_DAX_PATH[0]} -i $DIR/dummy -s $(($DEVSIZE - 100)) -l $DEVSIZE &>>$LOG" check pass pmdk-1.11.1/src/test/daxio/data3.log.match0000664000000000000000000000034114123364546016700 0ustar rootroot256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° 256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° 256 ° 1792 x 1024 o 128 ° 896 o 2048 2 2048 ° 1024 1 1024 2 8 a 6136 ° pmdk-1.11.1/src/test/daxio/out1.log.match0000664000000000000000000000143514123364546016601 0ustar rootrootdaxio: '0x1234abzz' -- invalid input offset daxio: 'foo' -- invalid output offset daxio: '20xxx' -- invalid length daxio: zeroing flag specified but no output file provided daxio: an input file and/or an output file must be provided daxio: skip offset specified but no input file provided daxio: seek offset specified but no output file provided daxio: neither input nor output is device dax daxio: requested size 8192 larger than source daxio: copied 4000 bytes to device "$(nW)" daxio: '$(N)' -- offset beyond device size ($(N)) daxio: '$(N)' -- offset beyond device size ($(N)) daxio: copied $(N) bytes to device "$(nW)" daxio: copied $(N) bytes to device "/dev/null" daxio: copied 100 bytes to device "$(nW)" daxio: copied 100 bytes to device "$(nW)" daxio: copied 100 bytes to device "$(nW)" pmdk-1.11.1/src/test/daxio/TEST20000775000000000000000000000402714123364546014702 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # daxio/TEST2 -- test for daxio utility; move data between two devices . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 2 setup # must be done after setup, when daxio path is already known require_binary $DAXIO$EXESUFFIX LOG=out$UNITTEST_NUM.log DATALOG=data$UNITTEST_NUM.log DATA1=$DIR/data1.bin DATA2=$DIR/data2.bin DATAOUT1=$DIR/data_out1.bin DATAOUT2=$DIR/data_out2.bin # prepare file with test data dd if=/dev/zero bs=1k count=2 2> prep$UNITTEST_NUM.log | tr '\0' 'x' > $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' 'o' >> $DATA1 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '1' > $DATA2 dd if=/dev/zero bs=1k count=2 2>> prep$UNITTEST_NUM.log | tr '\0' '2' >> $DATA2 # zero device (len in dec) expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[0]} -l 16384 2>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -z -o ${DEVICE_DAX_PATH[1]} -l 16384 2>>$LOG" # check if zeroed expect_normal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[0]} &>>$LOG" expect_normal_exit "$CMPMAP$EXESUFFIX -z -l 16384 ${DEVICE_DAX_PATH[1]} &>>$LOG" # write data from files to Device DAX expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA1 -o ${DEVICE_DAX_PATH[0]} 2>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -i $DATA2 -o ${DEVICE_DAX_PATH[0]} -s 4096 2>>$LOG" # move data from one Device DAX to another expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o ${DEVICE_DAX_PATH[1]} -k 512 -s 0 -l 2048 2>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o ${DEVICE_DAX_PATH[1]} -k 5120 -s 3072 -l 2048 2>>$LOG" expect_normal_exit "$DAXIO$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -o ${DEVICE_DAX_PATH[1]} -k 7168 -s 4096 -l 2048 2>>$LOG" # check content expect_normal_exit "$DDMAP$EXESUFFIX -i ${DEVICE_DAX_PATH[0]} -b 1 -n 16384 -r > $DATALOG" expect_normal_exit "$DDMAP$EXESUFFIX -i ${DEVICE_DAX_PATH[1]} -b 1 -n 16384 -r >> $DATALOG" check pass pmdk-1.11.1/src/test/daxio/out3.log.match0000664000000000000000000000111414123364546016575 0ustar rootrootdaxio: copied 16384 bytes to device "$(nW)" $(nW) is not zeroed daxio: copied 16384 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 4096 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 2048 bytes to device "$(nW)" daxio: copied 2048 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 8 bytes to device "$(nW)" daxio: copied 256 bytes to device "$(nW)" daxio: copied 128 bytes to device "$(nW)" daxio: copied 16384 bytes to device "$(nW)" daxio: copied 16384 bytes to device "STDOUT" pmdk-1.11.1/src/test/daxio/out2.log.match0000664000000000000000000000061314123364546016577 0ustar rootrootdaxio: copied 16384 bytes to device "$(nW)" daxio: copied 16384 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 4096 bytes to device "$(nW)" daxio: requested size $(N) larger than source daxio: copied 4096 bytes to device "$(nW)" daxio: copied 2048 bytes to device "$(nW)" daxio: copied 2048 bytes to device "$(nW)" daxio: copied 2048 bytes to device "$(nW)" pmdk-1.11.1/src/test/unicode_api/0000775000000000000000000000000014123364546015263 5ustar rootrootpmdk-1.11.1/src/test/unicode_api/TEST00000775000000000000000000000264114123364546016053 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/test/unicode_api/TEST0 -- unicode C API check # . ../unittest/unittest.sh require_test_type medium require_command bc require_fs_type any # there's no point in testing different builds require_build_type debug require_command clang SRC=../.. HEADERS_DIR=$SRC/include INC_DIR=$SRC/include/libpmemobj EXC_PATT="set_funcs|strdup|rpmem" FAILED=0 DEF_COL=6 function pick_col { require_command bc local ver=$(clang --version | grep version | sed "s/.*clang version \([0-9]*\)\.\([0-9]*\).*/\1*100+\2*10/" | bc) if [ $ver -le 340 ]; then DEF_COL=5 fi } function check_file { local file=$1 local dir=$2 local h_dir=$3 local pat=$4 local funcs=$(clang -Xclang -ast-dump -I$HEADERS_DIR $file -fno-color-diagnostics 2> /dev/null |\ grep "FunctionDecl.*pmem.*char \*" | cut -d " " -f $DEF_COL) for func in $funcs do local good=1 # Not starting at 0 allows set -e to_check="$dir/*.h $h_dir/*.h" if [ -n "${pat:+x}" ] && [[ $func =~ $pat ]]; then continue fi for f in $to_check do let good+=$(grep -c "$func[UW][ ]*(" $f) done if [ $good -ne 3 ]; then echo "Function $func in file $file does not have unicode U/W counterparts" FAILED=1; fi done } setup pick_col for f in $HEADERS_DIR/*.h do check_file $f $INC_DIR $HEADERS_DIR $EXC_PATT done if [ $FAILED -ne 0 ]; then exit 1 fi pass pmdk-1.11.1/src/test/unicode_api/Makefile0000664000000000000000000000027014123364546016722 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/unicode_api/Makefile -- build unittest for unicode api completeness # include ../Makefile.inc pmdk-1.11.1/src/test/unicode_api/README0000664000000000000000000000020714123364546016142 0ustar rootrootPersistent Memory Development Kit This is src/test/unicode_api/README. This directory contains a check for unicode API completeness. pmdk-1.11.1/src/test/pmem2_source_numa/0000775000000000000000000000000014123364546016424 5ustar rootrootpmdk-1.11.1/src/test/pmem2_source_numa/Makefile0000664000000000000000000000075214123364546020070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # # src/test/pmem2_source_numa/Makefile -- build pmem2_source_numa unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_source_numa OBJS +=\ pmem2_source_numa.o\ ut_pmem2_config.o\ ut_pmem2_source.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, pmem2_source_numa.c) pmdk-1.11.1/src/test/pmem2_source_numa/TESTS.py0000664000000000000000000000124014123364546017675 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t @t.require_ndctl @t.windows_exclude class TEST0(t.Test): test_type = t.Short def run(self, ctx): testfile1 = ctx.create_holey_file(2 * t.MiB, 'testfile1') ctx.exec('pmem2_source_numa', 'test_get_numa_node', testfile1, 0) @t.require_ndctl @t.windows_exclude @t.require_devdax(t.DevDax('devdax', alignment=2 * t.MiB)) class TEST1(t.Test): test_type = t.Short def run(self, ctx): dd = ctx.devdaxes.devdax ctx.exec('pmem2_source_numa', 'test_get_numa_node', dd.path, 0) pmdk-1.11.1/src/test/pmem2_source_numa/.gitignore0000664000000000000000000000002214123364546020406 0ustar rootrootpmem2_source_numa pmdk-1.11.1/src/test/pmem2_source_numa/pmem2_source_numa.c0000664000000000000000000000312114123364546022205 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2020, Intel Corporation */ /* * pmem2_source_numa.c -- unit test for getting numa node from source */ #include #include #include "libpmem2.h" #include "unittest.h" #include "ut_pmem2.h" #include "out.h" static int given_numa_node; static int test_get_numa_node(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) { UT_FATAL("usage: test_get_numa_node " "file numa_node"); } char *file = argv[0]; given_numa_node = atoi(argv[1]); int fd = OPEN(file, O_CREAT | O_RDWR, 0666); struct pmem2_source *src; PMEM2_SOURCE_FROM_FD(&src, fd); int numa_node; int ret = pmem2_source_numa_node(src, &numa_node); UT_ASSERTeq(ret, 0); UT_ASSERTeq(numa_node, given_numa_node); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 2; } FUNC_MOCK(pmem2_region_namespace, int, struct ndctl_ctx *ctx, const struct pmem2_source *src, struct ndctl_region **pregion, struct ndctl_namespace **pndns) FUNC_MOCK_RUN_DEFAULT { *pregion = (void *)0x1; return 0; } FUNC_MOCK_END FUNC_MOCK(ndctl_region_get_numa_node, int, const struct ndctl_region *pregion) FUNC_MOCK_RUN_DEFAULT { if (pregion != NULL) { return given_numa_node; } UT_FATAL("region is null"); } FUNC_MOCK_END /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_get_numa_node), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmem2_source_numa"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/unicode_match_script/0000775000000000000000000000000014123364546017172 5ustar rootrootpmdk-1.11.1/src/test/unicode_match_script/TEST00000775000000000000000000000054414123364546017762 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/unicode_match_script/TEST0 -- unicode encoding unit test for match # . ../unittest/unittest.sh require_test_type medium require_fs_type any # there's no point in testing different builds require_build_type debug setup ../match -a pass pmdk-1.11.1/src/test/unicode_match_script/Makefile0000664000000000000000000000030014123364546020623 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/unicode_match_script/Makefile -- build unittest for unicode match # scripts # include ../Makefile.inc pmdk-1.11.1/src/test/unicode_match_script/unicodetest✭✮0000664000000000000000000000074714123364546023602 0ustar rootrootआ इ ई उ ऊ ऋ ऌ অ আ ই ঈ উ ঊ ঋ ঌ এ ঐ ơ Ƣ ƣ Ƥ ƥ Ʀ Ƨ ƨ Ʃ ƪ ƫ Ƭ ƭ Ʈ Ư ư Ʊ Ʋ a̘ ̙ ̚ ̛ ̜ ̝ ̞ ̟ ̠ ̡ ̢ ̣ ̤ ̥ ̦ ̧ ̨ ̩ ̪ ̫ ̬ ̭ ̮ ̯ ̰ ̱ ̲ ̳ ̴ ̵ ̶ ̷ ̸ ̹ ̺ ̻ ̼ ̽ ̾ ̿ ̀ ́ ͂ ̓ ̈́ ͅ ͠ ͡ 奈 懶 癩 羅 蘿螺 裸 邏 樂 洛 烙 珞 落 酪 駱 か が き ぎ く ぐけ げ こ ご さ ざ し じ す ず せ ぜ そ か が き ぎ く ぐ け げ こ ご さ ざ し じ す ず せ ぜ そ ÄÄ pmdk-1.11.1/src/test/unicode_match_script/README0000664000000000000000000000022114123364546020045 0ustar rootrootPersistent Memory Development Kit This is src/test/unicode_match_script/README. This directory contains a unit test for unicode match scripts. pmdk-1.11.1/src/test/unicode_match_script/unicodetest✭✮.match0000664000000000000000000000073614123364546024673 0ustar rootrootआ इ ई उ ऊ ऋ ऌ অ আ ই ঈ উ ঊ ঋ ঌ এ ঐ ơ Ƣ ƣ Ƥ ƥ Ʀ Ƨ ƨ Ʃ ƪ ƫ Ƭ ƭ Ʈ Ư ư Ʊ Ʋ $(nW) ̙ ̚ ̛ ̜ ̝ ̞ ̟ ̠ ̡ ̢ ̣ ̤ ̥ ̦ ̧ ̨ ̩ ̪ ̫ ̬ ̭ ̮ ̯ ̰ ̱ ̲ ̳ ̴ ̵ ̶ ̷ ̸ ̹ ̺ ̻ ̼ ̽ ̾ ̿ ̀ ́ ͂ ̓ ̈́ ͅ ͠ ͡ 奈 懶 癩 羅 $(nW) 裸 邏 樂 洛 烙 珞 落 酪 駱 か が き ぎ く $(nW) げ$(W)$(*) じ す ず せ ぜ そ$(W) か が き ぎ く ぐ け げ こ ご さ ざ し じ す ず せ ぜ そ ÄÄ pmdk-1.11.1/src/test/obj_tx_add_range_direct/0000775000000000000000000000000014123364546017607 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_add_range_direct/TEST00000775000000000000000000000101214123364546020366 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range_direct/TEST0 -- unit test for # pmemobj_tx_add_range_direct # . ../unittest/unittest.sh require_test_type medium # Pmemcheck is disabled here. The next test case (TEST1) will run the same test # under pmemcheck configure_valgrind pmemcheck force-disable configure_valgrind memcheck force-disable setup expect_normal_exit ./obj_tx_add_range_direct$EXESUFFIX $DIR/testfile0 check pass pmdk-1.11.1/src/test/obj_tx_add_range_direct/Makefile0000664000000000000000000000051114123364546021244 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range_direct/Makefile -- build obj_tx_add_range_direct # unit test # TARGET = obj_tx_add_range_direct OBJS = obj_tx_add_range_direct.o LIBPMEMCOMMON=y LIBPMEMOBJ=y include ../Makefile.inc INCS += -I$(TOP)/src/libpmemobj/ pmdk-1.11.1/src/test/obj_tx_add_range_direct/out0.log.match0000664000000000000000000000023414123364546022273 0ustar rootrootobj_tx_add_range_direct$(nW)TEST0: START: obj_tx_add_range_direct $(nW)obj_tx_add_range_direct$(nW) $(nW)testfile0 obj_tx_add_range_direct$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_add_range_direct/TESTS.py0000775000000000000000000000172714123364546021075 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation """ unit tests for pmemobj_tx_add_range_direct and pmemobj_tx_xadd_range_direct """ from os import path import testframework as t @t.require_valgrind_disabled('pmemcheck', 'memcheck') class TEST0(t.Test): test_type = t.Medium def run(self, ctx): testfile = path.join(ctx.testdir, 'testfile0') ctx.exec('obj_tx_add_range_direct', testfile) @t.require_valgrind_enabled('pmemcheck') class TEST1(t.Test): test_type = t.Medium def run(self, ctx): ctx.valgrind.add_opt('--mult-stores=no') testfile = path.join(ctx.testdir, 'testfile1') ctx.exec('obj_tx_add_range_direct', testfile) @t.require_valgrind_enabled('memcheck') @t.require_build('debug') class TEST2(t.Test): test_type = t.Medium def run(self, ctx): testfile = path.join(ctx.testdir, 'testfile2') ctx.exec('obj_tx_add_range_direct', testfile) pmdk-1.11.1/src/test/obj_tx_add_range_direct/TEST0.PS10000664000000000000000000000364014123364546020776 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_add_range_direct/TEST0 -- unit test for # pmemobj_tx_add_range_direct # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit $ENV:EXE_DIR\obj_tx_add_range_direct$Env:EXESUFFIX $DIR\testfile0 check pass pmdk-1.11.1/src/test/obj_tx_add_range_direct/pmemcheck1.log.match0000664000000000000000000000501214123364546023420 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/obj_tx_add_range_direct$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 1 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*): do_tx_xadd_range_no_flush_commit (obj_tx_add_range_direct.c:$(*)) ==$(*)== by 0x$(*): main (obj_tx_add_range_direct.c:$(*)) ==$(*)== Address: 0x$(*) size: 8 state: DIRTY ==$(*)== Total memory not made persistent: 8 ==$(*)== ERROR SUMMARY: 1 errors pmdk-1.11.1/src/test/obj_tx_add_range_direct/.gitignore0000664000000000000000000000003014123364546021570 0ustar rootrootobj_tx_add_range_direct pmdk-1.11.1/src/test/obj_tx_add_range_direct/obj_tx_add_range_direct.c0000664000000000000000000005075714123364546024574 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_tx_add_range_direct.c -- unit test for pmemobj_tx_add_range_direct */ #include #include #include "tx.h" #include "unittest.h" #include "util.h" #include "valgrind_internal.h" #define LAYOUT_NAME "tx_add_range_direct" #define OBJ_SIZE 1024 enum type_number { TYPE_OBJ, TYPE_OBJ_ABORT, }; TOID_DECLARE(struct object, 0); struct object { size_t value; unsigned char data[OBJ_SIZE - sizeof(size_t)]; }; #define VALUE_OFF (offsetof(struct object, value)) #define VALUE_SIZE (sizeof(size_t)) #define DATA_OFF (offsetof(struct object, data)) #define DATA_SIZE (OBJ_SIZE - sizeof(size_t)) #define TEST_VALUE_1 1 #define TEST_VALUE_2 2 /* * do_tx_zalloc -- do tx allocation with specified type number */ static PMEMoid do_tx_zalloc(PMEMobjpool *pop, unsigned type_num) { PMEMoid ret = OID_NULL; TX_BEGIN(pop) { ret = pmemobj_tx_zalloc(sizeof(struct object), type_num); } TX_END return ret; } /* * do_tx_alloc -- do tx allocation and initialize first num bytes */ static PMEMoid do_tx_alloc(PMEMobjpool *pop, uint64_t type_num, uint64_t init_num) { PMEMoid ret = OID_NULL; TX_BEGIN(pop) { ret = pmemobj_tx_alloc(sizeof(struct object), type_num); pmemobj_memset(pop, pmemobj_direct(ret), 0, init_num, 0); } TX_END return ret; } /* * do_tx_add_range_alloc_commit -- call add_range_direct on object allocated * within the same transaction and commit the transaction */ static void do_tx_add_range_alloc_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range_direct(ptr + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj)->data[i], TEST_VALUE_2); } /* * do_tx_add_range_alloc_abort -- call add_range_direct on object allocated * within the same transaction and abort the transaction */ static void do_tx_add_range_alloc_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range_direct(ptr + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_2, DATA_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_OBJ_ABORT)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_add_range_twice_commit -- call add_range_direct one the same area * twice and commit the transaction */ static void do_tx_add_range_twice_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_2); } /* * do_tx_add_range_twice_abort -- call add_range_direct one the same area * twice and abort the transaction */ static void do_tx_add_range_twice_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, 0); } /* * do_tx_add_range_abort_after_nested -- call add_range_direct and * commit the tx */ static void do_tx_add_range_abort_after_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr1 = (char *)pmemobj_direct(obj1.oid); ret = pmemobj_tx_add_range_direct(ptr1 + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { char *ptr2 = (char *)pmemobj_direct(obj2.oid); ret = pmemobj_tx_add_range_direct(ptr2 + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, 0); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], 0); } /* * do_tx_add_range_abort_nested -- call add_range_direct and * commit the tx */ static void do_tx_add_range_abort_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr1 = (char *)pmemobj_direct(obj1.oid); ret = pmemobj_tx_add_range_direct(ptr1 + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { char *ptr2 = (char *)pmemobj_direct(obj2.oid); ret = pmemobj_tx_add_range_direct(ptr2 + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, 0); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], 0); } /* * do_tx_add_range_commit_nested -- call add_range_direct and commit the tx */ static void do_tx_add_range_commit_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr1 = (char *)pmemobj_direct(obj1.oid); ret = pmemobj_tx_add_range_direct(ptr1 + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { char *ptr2 = (char *)pmemobj_direct(obj2.oid); ret = pmemobj_tx_add_range_direct(ptr2 + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, TEST_VALUE_1); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], TEST_VALUE_2); } /* * do_tx_add_range_abort -- call add_range_direct and abort the tx */ static void do_tx_add_range_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, 0); } /* * do_tx_add_range_commit -- call add_range_direct and commit tx */ static void do_tx_add_range_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_flush_commit -- call xadd_range_direct with * POBJ_XADD_NO_FLUSH flag set and commit tx */ static void do_tx_xadd_range_no_flush_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_FLUSH); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; /* let pmemcheck find we didn't flush it */ } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_snapshot_commit -- call xadd_range_direct with * POBJ_XADD_NO_SNAPSHOT flag, commit the transaction */ static void do_tx_xadd_range_no_snapshot_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_SNAPSHOT); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_snapshot_abort -- call xadd_range_direct with * POBJ_XADD_NO_SNAPSHOT flag, modify the value, abort the transaction */ static void do_tx_xadd_range_no_snapshot_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); D_RW(obj)->value = TEST_VALUE_1; TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_SNAPSHOT); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END /* * value added with NO_SNAPSHOT flag should NOT be rolled back * after abort */ UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_2); } /* * do_tx_xadd_range_no_uninit_check -- call xdd_range_direct for * initialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set and commit the * tx */ static void do_tx_xadd_range_no_uninit_check_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_uninit_check -- call xadd_range_direct for * uninitialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set and commit * the tx */ static void do_tx_xadd_range_no_uninit_check_commit_uninit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, 0)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range_direct(ptr + DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_xadd_range_no_uninit_check -- call xadd_range_direct for * partially uninitialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set * only for uninitialized part and commit the tx */ static void do_tx_xadd_range_no_uninit_check_commit_part_uninit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, VALUE_SIZE)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range_direct(ptr + DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_add_range_no_uninit_check -- call add_range_direct for * partially uninitialized memory. */ static void do_tx_add_range_no_uninit_check_commit_no_flag(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, VALUE_SIZE)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_add_range_direct(ptr + VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_add_range_direct(ptr + DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_xadd_range_no_uninit_check_abort -- call pmemobj_tx_range with * POBJ_XADD_ASSUME_INITIALIZED flag, modify the value inside aborted * transaction */ static void do_tx_xadd_range_no_uninit_check_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, 0)); TX_BEGIN(pop) { char *ptr = (char *)pmemobj_direct(obj.oid); ret = pmemobj_tx_xadd_range_direct(ptr + VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range_direct(ptr + DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END } /* * do_tx_commit_and_abort -- use range cache, commit and then abort to make * sure that it won't affect previously modified data. */ static void do_tx_commit_and_abort(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { TX_SET(obj, value, TEST_VALUE_1); /* this will land in cache */ } TX_ONABORT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * test_add_direct_macros -- test TX_ADD_DIRECT, TX_ADD_FIELD_DIRECT and * TX_SET_DIRECT */ static void test_add_direct_macros(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { struct object *o = D_RW(obj); TX_SET_DIRECT(o, value, TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); TX_BEGIN(pop) { struct object *o = D_RW(obj); TX_ADD_DIRECT(o); o->value = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_2); TX_BEGIN(pop) { struct object *o = D_RW(obj); TX_ADD_FIELD_DIRECT(o, value); o->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } #define MAX_CACHED_RANGES 100 /* * test_tx_corruption_bug -- test whether tx_adds for small objects from one * transaction does NOT leak to the next transaction */ static void test_tx_corruption_bug(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); struct object *o = D_RW(obj); unsigned char i; UT_COMPILE_ERROR_ON(1.5 * MAX_CACHED_RANGES > 255); TX_BEGIN(pop) { for (i = 0; i < 1.5 * MAX_CACHED_RANGES; ++i) { TX_ADD_DIRECT(&o->data[i]); o->data[i] = i; } } TX_ONABORT { UT_ASSERT(0); } TX_END for (i = 0; i < 1.5 * MAX_CACHED_RANGES; ++i) UT_ASSERTeq((unsigned char)o->data[i], i); TX_BEGIN(pop) { for (i = 0; i < 0.1 * MAX_CACHED_RANGES; ++i) { TX_ADD_DIRECT(&o->data[i]); o->data[i] = i + 10; } pmemobj_tx_abort(EINVAL); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END for (i = 0; i < 1.5 * MAX_CACHED_RANGES; ++i) UT_ASSERTeq((unsigned char)o->data[i], i); pmemobj_free(&obj.oid); } static void do_tx_add_range_too_large(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); int ret = 0; TX_BEGIN(pop) { ret = pmemobj_tx_add_range_direct(pmemobj_direct(obj.oid), PMEMOBJ_MAX_ALLOC_SIZE + 1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { UT_ASSERTeq(errno, EINVAL); UT_ASSERTeq(ret, 0); } TX_END errno = 0; ret = 0; TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range_direct(pmemobj_direct(obj.oid), PMEMOBJ_MAX_ALLOC_SIZE + 1, POBJ_XADD_NO_ABORT); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_ASSERTeq(ret, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END errno = 0; ret = 0; TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); ret = pmemobj_tx_add_range_direct(pmemobj_direct(obj.oid), PMEMOBJ_MAX_ALLOC_SIZE + 1); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_ASSERTeq(ret, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END errno = 0; ret = 0; TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); ret = pmemobj_tx_xadd_range_direct(pmemobj_direct(obj.oid), PMEMOBJ_MAX_ALLOC_SIZE + 1, 0); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_ASSERTeq(ret, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END errno = 0; } static void do_tx_add_range_lots_of_small_snapshots(PMEMobjpool *pop) { size_t s = TX_DEFAULT_RANGE_CACHE_SIZE * 2; size_t snapshot_s = 8; PMEMoid obj; int ret = pmemobj_zalloc(pop, &obj, s, 0); UT_ASSERTeq(ret, 0); TX_BEGIN(pop) { for (size_t n = 0; n < s; n += snapshot_s) { void *addr = (void *)((size_t)pmemobj_direct(obj) + n); pmemobj_tx_add_range_direct(addr, snapshot_s); } } TX_ONABORT { UT_ASSERT(0); } TX_END } static void do_tx_add_cache_overflowing_range(PMEMobjpool *pop) { /* * This test adds snapshot to the cache, but in way that results in * one of the add_range being split into two caches. */ size_t s = TX_DEFAULT_RANGE_CACHE_SIZE * 2; size_t snapshot_s = TX_DEFAULT_RANGE_CACHE_THRESHOLD - 8; PMEMoid obj; int ret = pmemobj_zalloc(pop, &obj, s, 0); UT_ASSERTeq(ret, 0); TX_BEGIN(pop) { size_t n = 0; while (n != s) { if (n + snapshot_s > s) snapshot_s = s - n; void *addr = (void *)((size_t)pmemobj_direct(obj) + n); pmemobj_tx_add_range_direct(addr, snapshot_s); memset(addr, 0xc, snapshot_s); n += snapshot_s; } pmemobj_tx_abort(0); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(pmemobj_direct(obj), s)); UT_ASSERTne(errno, 0); errno = 0; pmemobj_free(&obj); } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_add_range_direct"); util_init(); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL * 4, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); do_tx_add_range_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_commit_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort_after_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_twice_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_twice_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_alloc_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_alloc_abort(pop); VALGRIND_WRITE_STATS; do_tx_commit_and_abort(pop); VALGRIND_WRITE_STATS; test_add_direct_macros(pop); VALGRIND_WRITE_STATS; test_tx_corruption_bug(pop); VALGRIND_WRITE_STATS; do_tx_add_range_too_large(pop); VALGRIND_WRITE_STATS; do_tx_add_range_lots_of_small_snapshots(pop); VALGRIND_WRITE_STATS; do_tx_add_cache_overflowing_range(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_snapshot_commit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_snapshot_abort(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit_uninit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit_part_uninit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_no_uninit_check_commit_no_flag(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_flush_commit(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_add_range_direct/TEST10000775000000000000000000000074214123364546020400 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range_direct/TEST1 -- unit test for # pmemobj_tx_add_range_direct with valgrind pmemcheck tool # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem configure_valgrind pmemcheck force-enable export VALGRIND_OPTS="--mult-stores=no" setup expect_normal_exit ./obj_tx_add_range_direct$EXESUFFIX $DIR/testfile1 $i check pass pmdk-1.11.1/src/test/obj_tx_add_range_direct/memcheck2.log.match0000664000000000000000000000402614123364546023245 0ustar rootroot==$(*)== Memcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/obj_tx_add_range$(*) ==$(*)== Parent PID: $(*) ==$(*)== **$(*)** Snapshotting uninitialized data in range <0x$(*),0x$(*)> () ==$(*)== Uninitialised byte(s) found during client check request ==$(*)== at $(*): vg_verify_initialized ($(*)) ==$(*)== by $(*): pmemobj_tx_add_snapshot ($(*)) ==$(*)== by $(*): pmemobj_tx_add_common ($(*)) ==$(*)== by $(*): pmemobj_tx_add_range_direct ($(*)) ==$(*)== by $(*): do_tx_add_range_no_uninit_check_commit_no_flag ($(*)obj_tx_add_range_direct$(*)) ==$(*)== by $(*): main ($(*)obj_tx_add_range_direct$(*)) ==$(*)== Address $(*) is 8 bytes inside a block of size $(*) client-defined ==$(*)== at $(*): alloc_prep_block ($(*)) ==$(*)== by $(*): palloc_reservation_create ($(*)) ==$(*)== by $(*): palloc_reserve ($(*)) ==$(*)== by $(*): tx_alloc_common ($(*)) ==$(*)== by $(*): pmemobj_tx_alloc ($(*)) ==$(*)== by $(*): do_tx_alloc ($(*)) ==$(*)== by $(*): do_tx_add_range_no_uninit_check_commit_no_flag ($(*)obj_tx_add_range_direct$(*)) ==$(*)== by $(*): main ($(*)obj_tx_add_range_direct$(*)) ==$(*)== ==$(*)== ==$(*)== HEAP SUMMARY: ==$(*)== in use at exit: $(*) bytes in $(*) blocks ==$(*)== total heap usage: $(*) allocs, $(*) frees, $(*) bytes allocated ==$(*)== $(OPT)==$(*)== All heap blocks were freed -- no leaks are possible $(OPX)==$(*)== LEAK SUMMARY: $(OPT)==$(*)== definitely lost: 0 bytes in 0 blocks $(OPT)==$(*)== indirectly lost: 0 bytes in 0 blocks $(OPT)==$(*)== possibly lost: 0 bytes in 0 blocks $(OPT)==$(*)== still reachable: 0 bytes in 0 blocks $(OPT)==$(*)== suppressed: $(*) bytes in $(*) blocks ==$(*)== $(OPT)==$(*)== For counts of detected and suppressed errors, rerun with: -v ==$(*)== Use --track-origins=yes to see where uninitialised values come from $(OPT)==$(*)== For lists of detected and suppressed errors, rerun with: -s ==$(*)== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: $(*) from $(*)) pmdk-1.11.1/src/test/obj_tx_add_range_direct/out1.log.match0000664000000000000000000000023414123364546022274 0ustar rootrootobj_tx_add_range_direct$(nW)TEST1: START: obj_tx_add_range_direct $(nW)obj_tx_add_range_direct$(nW) $(nW)testfile1 obj_tx_add_range_direct$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_tx_add_range_direct/obj_tx_add_range_direct.vcxproj.filters0000664000000000000000000000201314123364546027472 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {8904faf0-3f37-47b8-9ebf-b65cc577765d} PS1 {8eef4b94-3227-4e2c-9d2c-57b15b596c47} match Source Files Test Scripts Match Files pmdk-1.11.1/src/test/obj_tx_add_range_direct/obj_tx_add_range_direct.vcxproj0000664000000000000000000001041414123364546026027 0ustar rootroot Debug x64 Release x64 {89F947CA-DDEF-4131-8AFB-584ABA4A1302} Win32Proj obj_tx_add_range_direct 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled CompileAsCpp $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) 4200 CompileAsCpp $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) 4200 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/testconfig.ps1.example0000664000000000000000000000534114123364546017233 0ustar rootroot# # src/test/testconfig.ps1 -- configuration for local and remote unit tests # # # 1) *** LOCAL CONFIGURATION *** # # The first part of the file tells the script unittest/unittest.ps1 # which file system locations are to be used for local testing. # # # Appended to PMEM_FS_DIR and NON_PMEM_FS_DIR to test PMDK with file path longer # than 255 characters. Due to limitation of powershell you have to use # UNC prefix (i.e. \\?\c:\tmp) in PMEM_FS_DIR and NON_PMEM_FS_DIR variables. # # $Local:LONGDIR = "LoremipsumdolorsitametconsecteturadipiscingelitVivamuslacinianibhattortordictumsollicitudinNullamvariusvestibulumligulaetegestaselitsemperidMaurisultriciesligulaeuipsumtinciduntluctusMorbimaximusvariusdolorid" #$Env:DIRSUFFIX = "$LONGDIR\$LONGDIR\$LONGDIR\$LONGDIR\$LONGDIR" # # For tests that require true persistent memory, set the path to a directory # on a PMEM-aware file system here. Uncomment this line if there's an # actual persistent memory available on this system. # #$Env:PMEM_FS_DIR = "\mnt\pmem" # # For tests that require true a non-persitent memory aware file system (i.e. # to verify something works on traditional page-cache based memory-mapped # files) set the path to a directory on a normal file system here. # #$Env:NON_PMEM_FS_DIR = "\temp" # # If you don't have real PMEM or PMEM emulation set up, but still want to test # PMEM codepaths uncomment this line. It will set PMEM_IS_PMEM_FORCE to 1 for # tests that require pmem. # #$Env:PMEM_FS_DIR_FORCE_PMEM = "1" # # Overwrite default test type: # check (default), short, medium, long, all # where: check = short + medium; all = short + medium + long # #$Env:TEST_TYPE = "check" # # Overwrite available build types: # debug, nondebug, static-debug, static-nondebug, all (default) # #$Env:TEST_BUILD = "all" # # Overwrite available filesystem types: # pmem, non-pmem, any, none, all (default) # #$Env:TEST_FS = "all" # # Overwrite default timeout # (floating point number with an optional suffix: 's' for seconds (the default), # 'm' for minutes, 'h' for hours or 'd' for days) # #$Env:TEST_TIMEOUT = "60s" # # To display execution time of each test # $Env:TM = "1" # # Test against installed libraries, NOT the one built in tree. # Note that these variable won't affect tests that link statically. You should # disabled them using TEST_BUILD variable. # # $Env:PMDK_LIB_PATH_NONDEBUG = "C:\vcpkg\buildtrees\pmdk\src\1.4.1-0ecc9f7f1f\src\x64\Release" # $Env:PMDK_LIB_PATH_DEBUG = "C:\vcpkg\buildtrees\pmdk\src\1.4.1-0ecc9f7f1f\src\x64\Debug" # # 2) *** REMOTE CONFIGURATION *** # # The second part of the file tells the script unittest/unittest.sh # which remote nodes and their file system locations are to be used # for remote testing. # # XXX - remote capabilities not ported to Windows yet # pmdk-1.11.1/src/test/RUNTESTS0000775000000000000000000004620414123364546014227 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # RUNTESTS -- setup the environment and run each test # # # usage -- print usage message and exit # usage() { [ "$1" ] && echo Error: $1 cat >&2 </dev/null && errmsg="$(tput setaf 1)$errmsg$(tput sgr0)" echo "RUNTESTS: stopping: $RUNTEST_DIR/$RUNTEST_SCRIPT $errmsg, $RUNTEST_PARAMS" >&2 if [ "$keep_going" == "y" ]; then keep_going_exit_code=1 keep_going_skip=y fail_list="$fail_list $RUNTEST_DIR/$RUNTEST_SCRIPT" ((fail_count+=1)) if [ "$CLEAN_FAILED" == "y" ]; then if [[ $CMD_STR == *"RPMEM_PROVIDER"* ]]; then export CLEAN_FAILED_REMOTE=y eval "$CMD_STR" fi dir_rm=$(<$TEMP_LOC) rm -Rf $dir_rm if [ $? -ne 0 ]; then echo -e "Cannot remove directory with data: $dir_rm" fi fi else exit 1 fi } rm -f $TEMP_LOC [ "$verbose_old" != "-1" ] && verbose=$verbose_old return 0 } # # runtest_remote -- add remote persistency parameters and run a test # usage: runtest_remote # runtest_remote() { local params="$RUNTEST_PARAMS" for prov in $1; do for pm in $2; do export RUNTEST_PARAMS="$params RPMEM_PROVIDER=$prov RPMEM_PM=$pm" runtest_local done done } # # load_default_global_test_configuration -- load a default global configuration # load_default_global_test_configuration() { global_req_testtype=all global_req_fstype=all global_req_buildtype=all global_req_provider=none global_req_pmethod=none global_req_rpmem_valgrind=n global_req_timeout='3m' return 0 } # switch_hyphen -- substitute hyphen for underscores switch_hyphen() { echo ${1//-/_} } # # read_global_test_configuration -- read a global configuration from a test # config file and overwrite a global configuration # read_global_test_configuration() { if [ ! -e "config.sh" ]; then return fi # unset all global settings unset CONF_GLOBAL_TEST_TYPE unset CONF_GLOBAL_FS_TYPE unset CONF_GLOBAL_BUILD_TYPE unset CONF_GLOBAL_RPMEM_PROVIDER unset CONF_GLOBAL_RPMEM_PMETHOD unset CONF_GLOBAL_RPMEM_VALGRIND unset CONF_GLOBAL_TIMEOUT # unset all local settings unset CONF_TEST_TYPE unset CONF_FS_TYPE unset CONF_BUILD_TYPE unset CONF_RPMEM_PROVIDER unset CONF_RPMEM_PMETHOD unset CONF_RPMEM_VALGRIND unset CONF_TIMEOUT . config.sh [ -n "$CONF_GLOBAL_TEST_TYPE" ] && global_req_testtype=$CONF_GLOBAL_TEST_TYPE [ -n "$CONF_GLOBAL_FS_TYPE" ] && global_req_fstype=$CONF_GLOBAL_FS_TYPE [ -n "$CONF_GLOBAL_BUILD_TYPE" ] && global_req_buildtype=$CONF_GLOBAL_BUILD_TYPE [ -n "$CONF_GLOBAL_RPMEM_PROVIDER" ] && global_req_provider=$CONF_GLOBAL_RPMEM_PROVIDER [ -n "$CONF_GLOBAL_RPMEM_PMETHOD" ] && global_req_pmethod=$CONF_GLOBAL_RPMEM_PMETHOD [ -n "$CONF_GLOBAL_RPMEM_VALGRIND" ] && global_req_rpmem_valgrind=$CONF_GLOBAL_RPMEM_VALGRIND [ -n "$CONF_GLOBAL_TIMEOUT" ] && global_req_timeout=$CONF_GLOBAL_TIMEOUT return 0 } # # read_test_configuration -- generate a test configuration from a global # configuration and a test configuration read from a test config file # usage: read_test_configuration # read_test_configuration() { req_testtype=$global_req_testtype req_fstype=$global_req_fstype req_buildtype=$global_req_buildtype req_provider=$global_req_provider req_pmethod=$global_req_pmethod req_rpmem_valgrind=$global_req_rpmem_valgrind req_timeout=$global_req_timeout [ -n "${CONF_TEST_TYPE[$1]}" ] && req_testtype=${CONF_TEST_TYPE[$1]} [ -n "${CONF_FS_TYPE[$1]}" ] && req_fstype=${CONF_FS_TYPE[$1]} [ -n "${CONF_BUILD_TYPE[$1]}" ] && req_buildtype=${CONF_BUILD_TYPE[$1]} [ -n "${CONF_RPMEM_PROVIDER[$1]}" ] && req_provider=${CONF_RPMEM_PROVIDER[$1]} [ -n "${CONF_RPMEM_PMETHOD[$1]}" ] && req_pmethod=${CONF_RPMEM_PMETHOD[$1]} [ -n "${CONF_RPMEM_VALGRIND[$1]}" ] && req_rpmem_valgrind=${CONF_RPMEM_VALGRIND[$1]} if [ -n "$runtest_timeout" ]; then req_timeout="$runtest_timeout" else [ -n "${CONF_TIMEOUT[$1]}" ] && req_timeout=${CONF_TIMEOUT[$1]} fi special_params= [ "$req_fstype" == "none" -o "$req_fstype" == "any" ] && \ special_params="req_fs_type=1" return 0 } # # intersection -- return common elements of collection of available and required # values # usage: intersection # intersection() { collection=$1 [ "$collection" == "all" ] && collection=$3 [ "$2" == "all" ] && echo $collection && return for e in $collection; do for r in $2; do [ "$e" == "$r" ] && { subset="$subset $e" } done done echo $subset } # # runtest -- given the test directory name, run tests found inside it # runtest() { [ "$UNITTEST_LOG_LEVEL" ] || UNITTEST_LOG_LEVEL=1 export UNITTEST_LOG_LEVEL [ -f "$1/TEST0" ] || { echo FAIL: $1: test not found. >&2 exit 1 } [ -x "$1/TEST0" ] || { echo FAIL: $1: test not executable. >&2 exit 1 } cd $1 load_default_global_test_configuration read_global_test_configuration runscripts=$testfile if [ "$runscripts" = all ]; then if [ "$testseq" = all ]; then runscripts=`ls -1 TEST* | grep '^TEST[0-9]\+$' | sort -V` else # generate test sequence seqs=(${testseq//,/ }) runscripts= for seq in ${seqs[@]}; do limits=(${seq//-/ }) if [ "${#limits[@]}" -eq "2" ]; then if [ ${limits[0]} -lt ${limits[1]} ]; then nos="$(seq ${limits[0]} ${limits[1]})" else nos="$(seq ${limits[1]} ${limits[0]})" fi else nos=${limits[0]} fi for no in $nos; do runscripts="$runscripts TEST$no" done done fi fi # for each TEST script found... for runscript in $runscripts do UNITTEST_NAME="$1/$runscript" local sid=${runscript#TEST} read_test_configuration $sid local _testtype="$testtype" # unwind check test type to its subtypes [ "$_testtype" == "check" ] && _testtype="short medium" [ "$_testtype" == "all" ] && _testtype="short medium long" ttype=$(intersection "$_testtype" "$req_testtype" "short medium long") [ -z "$ttype" ] && { echo "$UNITTEST_NAME: SKIP test-type $testtype ($req_testtype required)" continue } # collapse test type to check if its valid superset [ "$ttype" == "short medium" ] && ttype="check" [ "$ttype" == "short medium long" ] && ttype="all" # check if output test type is single value ttype_array=($ttype) [ "${#ttype_array[@]}" -gt 1 ] && { echo "$UNITTEST_NAME: multiple test types ($ttype)" exit 1 } [ "$req_rpmem_valgrind" == "y" -a "$RPMEM_VALGRIND_ENABLED" != "y" ] && { echo "$UNITTEST_NAME: SKIP: remote valgrind tests disabled" continue } fss=$(intersection "$fstype" "$req_fstype" "none pmem non-pmem any") builds=$(intersection "$buildtype" "$req_buildtype" "debug nondebug static-debug static-nondebug") provs=$(intersection "$provider" "$req_provider" "verbs sockets") pmeths=$(intersection "$pmethod" "$req_pmethod" "GPSPM APM") # remote tests require both providers and pmethods # local tests require neither providers nor pmethods # anything in between indicates invalid test configuration [ "$req_provider" == "none" -a "$req_pmethod" != "none" ] || [ "$req_provider" != "none" -a "$req_pmethod" == "none" ] && { echo "$UNITTEST_NAME: invalid test configuration" echo "CONF_(GLOBAL_)RPMEM_PROVIDER ($req_provider) and " \ "CONF_(GLOBAL_)RPMEM_PMETHOD ($req_pmethod) have to be set both or neither" exit 1 } # skip remote test if required providers or persistency methods are missing # remote tests have req_provider != "none" [ "$req_provider" != "none" ] && { [ -z "$provs" ] && { echo "$UNITTEST_NAME: SKIP: required providers ($req_provider) are missing" continue } [ -z "$pmeths" ] && { echo "$UNITTEST_NAME: SKIP: required pmethods ($req_pmethod) are missing" continue } } # for each fs-type being tested... for fs in $fss do # don't bother trying when fs-type isn't available... if [ "$fs" == "pmem" ] && [ -z "$PMEM_FS_DIR" ] && [ "$fstype" == "all" ]; then pmem_skip=1 continue fi if [ "$fs" == "non-pmem" ] && [ -z "$NON_PMEM_FS_DIR" ] && [ "$fstype" == "all" ]; then non_pmem_skip=1 continue fi if [ "$fs" == "any" ] && [ -z "$PMEM_FS_DIR" ] && [ -z "$NON_PMEM_FS_DIR" ] && [ "$fstype" == "all" ]; then continue fi # for each build-type being tested... for build in $builds do export RUNTEST_DIR=$1 export RUNTEST_PARAMS="TEST=$ttype FS=$fs BUILD=$build" export RUNTEST_EXTRA="CHECK_TYPE=$checktype CHECK_POOL=$check_pool \ $special_params" export RUNTEST_SCRIPT="$runscript" export RUNTEST_TIMEOUT="$req_timeout" if [ "$KEEP_GOING" == "y" ] && [ "$CLEAN_FAILED" == "y" ]; then # temporary file used for sharing data # between RUNTESTS and tests processes temp_loc=$(mktemp /tmp/data-location.XXXXXXXX) export TEMP_LOC=$temp_loc fi # to not overwrite logs skip other tests from the group # if KEEP_GOING=y and test fail if [ "$keep_going_skip" == "n" ]; then # remote tests have req_provider != "none" if [ "$req_provider" != "none" ]; then runtest_remote "$provs" "$pmeths" else runtest_local fi fi done done keep_going_skip=n done cd .. } [ -f testconfig.sh ] || { cat >&2 </dev/null if [ $? != 0 ]; then unset killopt fi # check if timeout can be run in the foreground timeout --foreground 1s true &>/dev/null if [ $? != 0 ]; then unset use_timeout fi if [ -n "$TRACE" ]; then unset use_timeout fi if [ "$1" ]; then for test in $* do [ -d "$test" ] || echo "RUNTESTS: Test does not exist: $test" [ -f "$test/TEST0" ] && runtest $test done else # no arguments means run them all for testfile0 in */TEST0 do testdir=`dirname $testfile0` if [[ "$skip_dir" =~ "$testdir" ]]; then echo "RUNTESTS: Skipping: $testdir" continue fi runtest $testdir done fi [ "$pmem_skip" ] && echo "SKIPPED fs-type \"pmem\" runs: testconfig.sh doesn't set PMEM_FS_DIR" [ "$non_pmem_skip" ] && echo "SKIPPED fs-type \"non-pmem\" runs: testconfig.sh doesn't set NON_PMEM_FS_DIR" if [ "$fail_count" != "0" ]; then echo "$(tput setaf 1)$fail_count tests failed:$(tput sgr0)" # remove duplicates and print each test name in a new line echo $fail_list | xargs -n1 | uniq exit $keep_going_exit_code else exit 0 fi pmdk-1.11.1/src/test/obj_recovery/0000775000000000000000000000000014123364546015474 5ustar rootrootpmdk-1.11.1/src/test/obj_recovery/diff_post4.log.match0000664000000000000000000000000014123364546021321 0ustar rootrootpmdk-1.11.1/src/test/obj_recovery/TEST7.PS10000664000000000000000000000422514123364546016672 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST7 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type long # XXX: no memcheck for Windows yet, but whatever tool we'll use, it must # be aware we're mocking the system allocator #configure_valgrind memcheck force-enable $Env:PMEMOBJ_VG_CHECK_UNDEF=1 setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c n expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o n pass pmdk-1.11.1/src/test/obj_recovery/TEST1.PS10000664000000000000000000000373514123364546016671 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST1 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c n expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o n check pass pmdk-1.11.1/src/test/obj_recovery/TEST5.PS10000664000000000000000000000432114123364546016665 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST5 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_poolset $DIR\testset 16M:$DIR\testfile1 R 16M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n c f compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_pre$Env:UNITTEST_NUM.log expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n o f compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_post$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/diff_post3.log.match0000664000000000000000000000000014123364546021320 0ustar rootrootpmdk-1.11.1/src/test/obj_recovery/TEST30000775000000000000000000000144114123364546016264 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_recovery/TEST3 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_poolset $DIR/testset 16M:$DIR/testfile1 R 16M:$DIR/testfile2 expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n c s compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_pre$UNITTEST_NUM.log expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n o s compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_post$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/TEST90000775000000000000000000000100414123364546016265 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_recovery/TEST9 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile n c l expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile n o l check pass pmdk-1.11.1/src/test/obj_recovery/TEST00000775000000000000000000000433414123364546016265 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST0 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c s expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o s check pass pmdk-1.11.1/src/test/obj_recovery/Makefile0000664000000000000000000000037314123364546017137 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_recovery/Makefile -- build obj_recovery unit test # TARGET = obj_recovery OBJS = obj_recovery.o LIBPMEMOBJ=y LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_recovery/TEST3.PS10000664000000000000000000000432714123364546016671 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST3 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_poolset $DIR\testset 16M:$DIR\testfile1 R 16M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n c s compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_pre$Env:UNITTEST_NUM.log expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n o s compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_post$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/TEST2.PS10000664000000000000000000000373514123364546016672 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST2 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c f expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o f check pass pmdk-1.11.1/src/test/obj_recovery/TEST50000775000000000000000000000144114123364546016266 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_recovery/TEST5 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_poolset $DIR/testset 16M:$DIR/testfile1 R 16M:$DIR/testfile2 expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n c f compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_pre$UNITTEST_NUM.log expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n o f compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_post$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/TEST6.PS10000664000000000000000000000422514123364546016671 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST6 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type long # XXX: no memcheck for Windows yet, but whatever tool we'll use, it must # be aware we're mocking the system allocator #configure_valgrind memcheck force-enable $Env:PMEMOBJ_VG_CHECK_UNDEF=1 setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c s expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o s pass pmdk-1.11.1/src/test/obj_recovery/TEST40000775000000000000000000000144114123364546016265 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_recovery/TEST4 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_poolset $DIR/testset 16M:$DIR/testfile1 R 16M:$DIR/testfile2 expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n c n compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_pre$UNITTEST_NUM.log expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testset n o n compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff_post$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/TEST70000775000000000000000000000426214123364546016274 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST7 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type long require_no_asan configure_valgrind pmemcheck force-disable configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c n expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o n pass pmdk-1.11.1/src/test/obj_recovery/out0.log.match0000664000000000000000000000016514123364546020163 0ustar rootrootobj_recovery$(nW)TEST0: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testfile y o s obj_recovery$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_recovery/diff_post5.log.match0000664000000000000000000000000014123364546021322 0ustar rootrootpmdk-1.11.1/src/test/obj_recovery/TEST0.PS10000664000000000000000000000373514123364546016670 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST0 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c s expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o s check pass pmdk-1.11.1/src/test/obj_recovery/.gitignore0000664000000000000000000000001514123364546017460 0ustar rootrootobj_recovery pmdk-1.11.1/src/test/obj_recovery/obj_recovery.vcxproj0000664000000000000000000000773114123364546021611 0ustar rootroot Debug x64 Release x64 {2498FCDA-E2CC-43EF-9A35-8CD63F253171} Win32Proj obj_recovery 10.0.17134.0 Application true v140 Application false v140 true Disabled CompileAsCpp MaxSpeed CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_recovery/obj_recovery.c0000664000000000000000000001022414123364546020327 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_recovery.c -- unit test for pool recovery */ #include "unittest.h" #include "valgrind_internal.h" #if VG_PMEMCHECK_ENABLED #define VALGRIND_PMEMCHECK_END_TX VALGRIND_PMC_END_TX #else #define VALGRIND_PMEMCHECK_END_TX #endif POBJ_LAYOUT_BEGIN(recovery); POBJ_LAYOUT_ROOT(recovery, struct root); POBJ_LAYOUT_TOID(recovery, struct foo); POBJ_LAYOUT_END(recovery); #define MB (1 << 20) struct foo { int bar; }; struct root { PMEMmutex lock; TOID(struct foo) foo; char large_data[MB]; }; #define BAR_VALUE 5 int main(int argc, char *argv[]) { START(argc, argv, "obj_recovery"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(recovery) != 1); if (argc != 5) UT_FATAL("usage: %s [file] [lock: y/n] " "[cmd: c/o] [type: n/f/s/l]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; int exists = argv[3][0] == 'o'; enum { TEST_NEW, TEST_FREE, TEST_SET, TEST_LARGE } type; if (argv[4][0] == 'n') type = TEST_NEW; else if (argv[4][0] == 'f') type = TEST_FREE; else if (argv[4][0] == 's') type = TEST_SET; else if (argv[4][0] == 'l') type = TEST_LARGE; else UT_FATAL("invalid type"); if (!exists) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(recovery), 0, S_IWUSR | S_IRUSR)) == NULL) { UT_FATAL("failed to create pool\n"); } } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(recovery))) == NULL) { UT_FATAL("failed to open pool\n"); } } TOID(struct root) root = POBJ_ROOT(pop, struct root); int lock_type = TX_PARAM_NONE; void *lock = NULL; if (argv[2][0] == 'y') { lock_type = TX_PARAM_MUTEX; lock = &D_RW(root)->lock; } if (type == TEST_SET) { if (!exists) { TX_BEGIN_PARAM(pop, lock_type, lock) { TX_ADD(root); TOID(struct foo) f = TX_NEW(struct foo); D_RW(root)->foo = f; D_RW(f)->bar = BAR_VALUE; } TX_END TX_BEGIN_PARAM(pop, lock_type, lock) { TX_ADD_FIELD(D_RW(root)->foo, bar); D_RW(D_RW(root)->foo)->bar = BAR_VALUE * 2; /* * Even though flushes are not required inside * of a transaction, this is done here to * suppress irrelevant pmemcheck issues, because * we exit the program before the data is * flushed, while preserving any real ones. */ pmemobj_persist(pop, &D_RW(D_RW(root)->foo)->bar, sizeof(int)); /* * We also need to cleanup the transaction state * of pmemcheck. */ VALGRIND_PMEMCHECK_END_TX; exit(0); /* simulate a crash */ } TX_END } else { UT_ASSERT(D_RW(D_RW(root)->foo)->bar == BAR_VALUE); } } else if (type == TEST_LARGE) { if (!exists) { TX_BEGIN(pop) { TX_MEMSET(D_RW(root)->large_data, 0xc, MB); pmemobj_persist(pop, D_RW(root)->large_data, MB); VALGRIND_PMEMCHECK_END_TX; exit(0); } TX_END } else { UT_ASSERT(util_is_zeroed(D_RW(root)->large_data, MB)); TX_BEGIN(pop) { /* we should be able to start TX */ TX_MEMSET(D_RW(root)->large_data, 0xc, MB); pmemobj_persist(pop, D_RW(root)->large_data, MB); VALGRIND_PMEMCHECK_END_TX; pmemobj_tx_abort(0); } TX_END } } else if (type == TEST_NEW) { if (!exists) { TX_BEGIN_PARAM(pop, lock_type, lock) { TOID(struct foo) f = TX_NEW(struct foo); TX_SET(root, foo, f); pmemobj_persist(pop, &D_RW(root)->foo, sizeof(PMEMoid)); VALGRIND_PMEMCHECK_END_TX; exit(0); /* simulate a crash */ } TX_END } else { UT_ASSERT(TOID_IS_NULL(D_RW(root)->foo)); } } else { /* TEST_FREE */ if (!exists) { TX_BEGIN_PARAM(pop, lock_type, lock) { TX_ADD(root); TOID(struct foo) f = TX_NEW(struct foo); D_RW(root)->foo = f; D_RW(f)->bar = BAR_VALUE; } TX_END TX_BEGIN_PARAM(pop, lock_type, lock) { TX_ADD(root); TX_FREE(D_RW(root)->foo); D_RW(root)->foo = TOID_NULL(struct foo); pmemobj_persist(pop, &D_RW(root)->foo, sizeof(PMEMoid)); VALGRIND_PMEMCHECK_END_TX; exit(0); /* simulate a crash */ } TX_END } else { UT_ASSERT(!TOID_IS_NULL(D_RW(root)->foo)); } } UT_ASSERT(pmemobj_check(path, POBJ_LAYOUT_NAME(recovery))); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_recovery/TEST60000775000000000000000000000426214123364546016273 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST6 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type long require_no_asan configure_valgrind pmemcheck force-disable configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c s expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o s pass pmdk-1.11.1/src/test/obj_recovery/TEST10000775000000000000000000000433414123364546016266 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST1 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c n expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o n check pass pmdk-1.11.1/src/test/obj_recovery/TEST4.PS10000664000000000000000000000432114123364546016664 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST4 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type medium setup create_poolset $DIR\testset 16M:$DIR\testfile1 R 16M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n c n compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_pre$Env:UNITTEST_NUM.log expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testset n o n compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff_post$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_recovery/TEST80000775000000000000000000000426214123364546016275 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST8 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type long require_no_asan configure_valgrind pmemcheck force-disable configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c f expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o f pass pmdk-1.11.1/src/test/obj_recovery/TEST8.PS10000664000000000000000000000422514123364546016673 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST8 -- unit test for pool recovery # . ..\unittest\unittest.ps1 require_test_type long # XXX: no memcheck for Windows yet, but whatever tool we'll use, it must # be aware we're mocking the system allocator #configure_valgrind memcheck force-enable $Env:PMEMOBJ_VG_CHECK_UNDEF=1 setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y c f expect_normal_exit $Env:EXE_DIR\obj_recovery$Env:EXESUFFIX $DIR\testfile y o f pass pmdk-1.11.1/src/test/obj_recovery/out1.log.match0000664000000000000000000000016514123364546020164 0ustar rootrootobj_recovery$(nW)TEST1: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testfile y o n obj_recovery$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_recovery/obj_recovery.vcxproj.filters0000664000000000000000000000402714123364546023253 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {eb0f0c5c-5282-4823-8322-39b08b516bab} match {88773f0f-f08f-45fd-b773-405591626d4e} PS1 Source Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_recovery/TEST20000775000000000000000000000433414123364546016267 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_recovery/TEST2 -- unit test for pool recovery # . ../unittest/unittest.sh require_test_type medium require_no_asan # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable configure_valgrind pmemcheck force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y c f expect_normal_exit ./obj_recovery$EXESUFFIX $DIR/testfile y o f check pass pmdk-1.11.1/src/test/obj_recovery/out5.log.match0000664000000000000000000000016414123364546020167 0ustar rootrootobj_recovery$(nW)TEST5: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testset n o f obj_recovery$(nW)TEST5: DONE pmdk-1.11.1/src/test/obj_recovery/out3.log.match0000664000000000000000000000016414123364546020165 0ustar rootrootobj_recovery$(nW)TEST3: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testset n o s obj_recovery$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_recovery/out4.log.match0000664000000000000000000000016414123364546020166 0ustar rootrootobj_recovery$(nW)TEST4: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testset n o n obj_recovery$(nW)TEST4: DONE pmdk-1.11.1/src/test/obj_recovery/out2.log.match0000664000000000000000000000016514123364546020165 0ustar rootrootobj_recovery$(nW)TEST2: START: obj_recovery $(nW)obj_recovery$(nW) $(nW)testfile y o f obj_recovery$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_include/0000775000000000000000000000000014123364546015261 5ustar rootrootpmdk-1.11.1/src/test/obj_include/obj_atomic_include.c0000664000000000000000000000026014123364546021234 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_atomic_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_lists_atomic_include.c0000664000000000000000000000027414123364546022457 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_lists_atomic_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_iterator_include.c0000664000000000000000000000026414123364546021615 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_iterator_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_atomic_base_include.c0000664000000000000000000000027214123364546022231 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_atomic_base_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_tx_base_include.c0000664000000000000000000000026214123364546021407 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_tx_base_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_tx_include.c0000664000000000000000000000025014123364546020412 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_tx_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/Makefile0000664000000000000000000000104014123364546016714 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_include/Makefile -- build include tests # TARGET = obj_include OBJS = obj_atomic_base_include.o obj_atomic_include.o \ obj_base_include.o obj_iterator_base_include.o obj_iterator_include.o \ obj_lists_atomic_base_include.o obj_lists_atomic_include.o \ obj_pool_base_include.o obj_pool_include.o obj_thread_include.o \ obj_tx_base_include.o obj_tx_include.o obj_types_include.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_include/obj_base_include.c0000664000000000000000000000033514123364546020675 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_base_include.c -- include test for libpmemobj */ #include int main(int argc, char *argv[]) { return 0; } pmdk-1.11.1/src/test/obj_include/obj_iterator_base_include.c0000664000000000000000000000027614123364546022612 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_iterator_base_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_thread_include.c0000664000000000000000000000026014123364546021227 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_thread_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_pool_base_include.c0000664000000000000000000000026614123364546021731 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_pool_base_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_include.vcxproj0000664000000000000000000000731014123364546021154 0ustar rootroot Debug x64 Release x64 {AB15A115-E429-4123-BEBF-206FBA4CF615} obj_include 10.0.17134.0 Application true v140 Application false v140 Disabled MaxSpeed {f7c6c6b6-4142-4c82-8699-4a9d8183181b} pmdk-1.11.1/src/test/obj_include/.gitignore0000664000000000000000000000001414123364546017244 0ustar rootrootobj_include pmdk-1.11.1/src/test/obj_include/obj_types_include.c0000664000000000000000000000025614123364546021131 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_types_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_lists_atomic_base_include.c0000664000000000000000000000030614123364546023445 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_lists_atomic_base_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/obj_include/obj_include.vcxproj.filters0000664000000000000000000000317114123364546022624 0ustar rootroot {4a1447c8-630b-4665-98c5-87ccd215b237} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files pmdk-1.11.1/src/test/obj_include/obj_pool_include.c0000664000000000000000000000025414123364546020734 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * obj_pool_include.c -- include test for libpmemobj */ #include pmdk-1.11.1/src/test/util_poolset/0000775000000000000000000000000014123364546015526 5ustar rootrootpmdk-1.11.1/src/test/util_poolset/out1w.log.match0000664000000000000000000000172414123364546020407 0ustar rootrootutil_poolset$(nW)TEST1w: START: util_poolset $(nW)util_poolset$(nW) o 4194304 $(nW)testset0 $(nW)testset1 -mo:$(nW)testset2 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset5 $(nW)testset6 $(nW)testset7 -mo:$(nW)testfile82 $(nW)testset8 $(nW)testset9 $(nW)testset10 $(nW)testset11 $(nW)testset0: util_pool_open: No such file or directory $(nW)testset1: util_pool_open: Invalid argument mocked open: $(nW)testset2 $(nW)testset2: util_pool_open: Permission denied $(nW)testset3: util_pool_open: No such file or directory $(nW)testset4: util_pool_open: No such file or directory $(nW)testset5: util_pool_open: Invalid argument $(nW)testset6: util_pool_open: Invalid argument $(nW)testset7: util_pool_open: Invalid argument mocked open: $(nW)testfile82 $(nW)testset8: util_pool_open: Permission denied $(nW)testset9: util_pool_open: Invalid argument $(nW)testset10: util_pool_open: Invalid argument $(nW)testset11: util_pool_open: Invalid argument util_poolset$(nW)TEST1w: DONE pmdk-1.11.1/src/test/util_poolset/TEST2w.PS10000664000000000000000000000650314123364546017107 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST2w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "4" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 4 * 1024 * 1024 # 4MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 4MiB # prepare pool sets create_poolset $DIR\testset1 ${MIN_POOL_STR}:$DIR\testfile11:x ${MIN_POOL_STR}:$DIR\testfile12:x create_poolset $DIR\testset2 ${MIN_POOL_STR}:$DIR\testfile21:x ${MIN_POOL_STR}:$DIR\testfile22:x create_poolset $DIR\testset3 ${MIN_POOL_STR}:$DIR\testfile31:x ${MIN_POOL_STR}:$DIR\testfile32:x create_poolset $DIR\testset4 ${MIN_POOL_STR}:$DIR\testfile41:x ${MIN_POOL_STR}:$DIR\testfile42:x create_poolset $DIR\testset5 ${MIN_POOL_STR}:$DIR\testfile51:x ${MIN_POOL_STR}:$DIR\testfile52:x create_poolset $DIR\testset6 ${MIN_POOL_STR}:$DIR\testfile61:x ${MIN_POOL_STR}:$DIR\testfile62:x create_poolset $DIR\testset7 ${MIN_POOL_STR}:$DIR\testfile71:x ${MIN_POOL_STR}:$DIR\testfile72:x create_poolset $DIR\testset8 ${MIN_POOL_STR}:$DIR\testfile81:x ${MIN_POOL_STR}:$DIR\testfile82:x create_poolset $DIR\testset9 ${MIN_POOL_STR}:$DIR\testfile91:x ${MIN_POOL_STR}:$DIR\testfile92:x create_poolset $DIR\testset10 ${MIN_POOL_STR}:$DIR\testfile101:x ${MIN_POOL_STR}:$DIR\testfile102:x create_poolset $DIR\testset11 ${MIN_POOL_STR}:$DIR\testfile111:x ${MIN_POOL_STR}:$DIR\testfile112:x create_poolset $DIR\testset12 ${MIN_POOL_STR}:$DIR\testfile121:x ${MIN_POOL_STR}:$DIR\testfile122:x # create pool sets expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset1 $DIR\testset2 ` $DIR\testset3 $DIR\testset4 ` $DIR\testset5 $DIR\testset6 ` $DIR\testset7 $DIR\testset8 ` $DIR\testset9 $DIR\testset10 ` $DIR\testset11 $DIR\testset12 # inject some errors &$PMEMSPOIL $DIR\testfile22 pool_hdr.checksum=0 &$PMEMSPOIL $DIR\testfile32 pool_hdr.signature="ERROR" "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile42 pool_hdr.major=99 "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile52 pool_hdr.arch_flags="0000000000000000" "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile62 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile72 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile82 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile91 pool_hdr.poolset_uuid="0123456789012345" "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile101 pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile111 pool_hdr.prev_part_uuid="0123456789012345" ` pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile121 pool_hdr.next_repl_uuid="0123456789012345" "pool_hdr.f:checksum_gen" # now check if pool sets may be opened expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 $DIR\testset2 ` $DIR\testset3 $DIR\testset4 ` $DIR\testset5 $DIR\testset6 ` $DIR\testset7 $DIR\testset8 ` $DIR\testset9 $DIR\testset10 ` $DIR\testset11 $DIR\testset12 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/out0w.log.match0000664000000000000000000000720114123364546020402 0ustar rootrootutil_poolset$(nW)TEST0w: START: util_poolset $(nW)util_poolset$(nW) c 4194304 $(nW)testset0 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset5 $(nW)testset6 -mo:$(nW)testfile72 $(nW)testset7 -mf:1073741824 $(nW)testset8 -mo:$(nW)testfile102 $(nW)testset10 $(nW)testset11 $(nW)testset12 $(nW)testset13 $(nW)testset14 $(nW)testset15 $(nW)testset18 $(nW)testset20 $(nW)testset21 $(nW)testset22 -mo:$(nW)testset23 $(nW)testset23 $(nW)testset24 $(nW)testset25 -mp:6291456 $(nW)testset26 $(nW)testset0: util_pool_create: No such file or directory $(nW)testset1: created: nreps 1 poolsize 4194304 zeroed 1 replica[0]: nparts 1 nhdrs 1 repsize 4194304 is_pmem 0 part[0] path $(nW)testfile11 filesize 4194304 size 4194304 $(nW)testset2: created: nreps 1 poolsize 8323072 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile21 filesize 4194304 size 4194304 part[1] path $(nW)testfile22 filesize 4194304 size 4128768 $(nW)testset3: created: nreps 1 poolsize 8323072 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile31 filesize 4194304 size 4194304 part[1] path $(nW)testfile32 filesize 4194304 size 4128768 $(nW)testset4: util_pool_create: Invalid argument $(nW)testset5: util_pool_create: Invalid argument $(nW)testset6: util_pool_create: No such file or directory mocked open: $(nW)testfile72 $(nW)testset7: util_pool_create: Permission denied mocked fallocate: 1073741824 $(nW)testset8: util_pool_create: No space left on device mocked open: $(nW)testfile102 $(nW)testset10: util_pool_create: Permission denied $(nW)testset11: util_pool_create: Invalid argument $(nW)testset12: util_pool_create: Invalid argument $(nW)testset13: util_pool_create: Invalid argument $(nW)testset14: util_pool_create: Invalid argument $(nW)testset15: util_pool_create: Invalid argument $(nW)testset18: created: nreps 1 poolsize 6225920 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 6225920 is_pmem 0 part[0] path $(nW)subdir1$(nW)testfile181 filesize 3145728 size 3145728 part[1] path $(nW)subdir2$(nW)testfile182 filesize 3145728 size 3080192 $(nW)testset20: util_pool_create: File exists $(nW)testset21: util_pool_create: File exists $(nW)testset22: created: nreps 1 poolsize 8323072 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile221 filesize 4194304 size 4194304 part[1] path $(nW)testfile222 filesize 4194304 size 4128768 mocked open: $(nW)testset23 $(nW)testset23: util_pool_create: Permission denied $(nW)testset24: created: nreps 3 poolsize 8323072 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile241 filesize 4194304 size 4194304 part[1] path $(nW)testfile242 filesize 4194304 size 4128768 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)testfile243 filesize 8388608 size 8388608 replica[2]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile244 filesize 6291456 size 6291456 part[1] path $(nW)testfile245 filesize 2097152 size 2031616 $(nW)testset25: util_pool_create: Invalid argument mocked pmem_is_pmem: 6291456 $(nW)testset26: created: nreps 3 poolsize 6225920 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 6225920 is_pmem 0 part[0] path $(nW)testfile261 filesize 4194304 size 4194304 part[1] path $(nW)testfile262 filesize 2097152 size 2031616 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)testfile263 filesize 8388608 size 8388608 replica[2]: nparts 1 nhdrs 1 repsize 6291456 is_pmem 1 part[0] path $(nW)testfile264 filesize 6291456 size 6291456 util_poolset$(nW)TEST0w: DONE pmdk-1.11.1/src/test/util_poolset/util_poolset.vcxproj.filters0000664000000000000000000001006214123364546023333 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {ddc9f661-883f-425f-a835-1ac9d5a8949a} {cb560619-3b24-4fa0-b698-a785c5666af7} {12d6e366-de81-43aa-a860-c1bc106d91ed} {b945b405-712b-4620-b3d8-70cc9665b46f} Header Files libpmem libpmem Header Files Source Files Source Files libpmem libpmem Source Files libpmem libpmem libpmem libpmem Source Files Source Files Match Files Match Files Match Files Match Files Match Files Match Files Test scripts Test scripts Test scripts Test scripts Test scripts Test scripts Test scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/util_poolset/TEST4w.PS10000664000000000000000000000415314123364546017110 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST4w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "4" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 128 * 1024 * 1024 # 128MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 128MiB $RESVSIZE=4 * 1024 * 1024 * 1024 # 4GiB $RESVSIZE_STR = ${RESVSIZE}.toString() + "B" # 4GiB $REQUIRE_POOL = ${MIN_POOL} * 12 require_free_space "${REQUIRE_POOL}b" create_poolset $DIR\testset1 ` ${RESVSIZE_STR}:$DIR\testdir11:d ` O SINGLEHDR create_poolset $DIR\testset2 ` ${RESVSIZE_STR}:$DIR\testdir21:d ${RESVSIZE_STR}:$DIR\testdir22:d ` O SINGLEHDR create_poolset $DIR\testset3 ` ${RESVSIZE_STR}:$DIR\testdir31:d R ${RESVSIZE_STR}:$DIR\testdir32:d ` O SINGLEHDR create_poolset $DIR\testset4 ` ${RESVSIZE_STR}:$DIR\testdir41:d ${RESVSIZE_STR}:$DIR\testdir42:d ` R ${RESVSIZE_STR}:$DIR\testdir43:d ${RESVSIZE_STR}:$DIR\testdir44:d ` O SINGLEHDR # create pool sets expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX e $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX e $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX e $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/grep0w.log.match0000664000000000000000000000153514123364546020534 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for shutdown state open "$(nW)testset0": No such file or directory size 131072 smaller than 2097152 size 131072 smaller than 2097152 open "$(nW)testfile62": No such file or directory open "$(nW)testfile72": Permission denied posix_fallocate "$(nW)testfile82", 1073741824: No space left on device open "$(nW)testfile102": Permission denied file size does not match config: $(nW)testfile113, 4194304 != 2097152 size 1048576 smaller than 2097152 size 1048576 smaller than 2097152 file size does not match config: $(nW)testfile142, 4194304 != 8388608 file size does not match config: $(nW)testfile152, 4194303 != 4194304 Non-empty file detected Non-empty file detected open "$(nW)testset23": Permission denied reservation pool size 3145728 smaller than 4194304 pmdk-1.11.1/src/test/util_poolset/out5w.log.match0000664000000000000000000000447214123364546020416 0ustar rootrootutil_poolset$(nW)TEST5w: START: util_poolset $(nW)util_poolset$(nW) o 134217728 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset9 $(nW)testset1: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir11$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir11$(nW)000001.pmem filesize $(nW) size $(nW) $(nW)testset2: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir21$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir22$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir21$(nW)000002.pmem filesize $(nW) size $(nW) $(nW)testset3: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir31$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir31$(nW)000001.pmem filesize $(nW) size $(nW) replica[1]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir32$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir32$(nW)000001.pmem filesize $(nW) size $(nW) $(nW)testset4: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir41$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir42$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir41$(nW)000002.pmem filesize $(nW) size $(nW) replica[1]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir43$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir44$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir43$(nW)000002.pmem filesize $(nW) size $(nW) $(nW)testset9: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir91$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir91$(nW)000001.pmem filesize $(nW) size $(nW) replica[1]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir91$(nW)testdir92$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir91$(nW)testdir92$(nW)000001.pmem filesize $(nW) size $(nW) util_poolset$(nW)TEST5w: DONE pmdk-1.11.1/src/test/util_poolset/out4w.log.match0000664000000000000000000000472514123364546020416 0ustar rootrootutil_poolset$(nW)TEST4w: START: util_poolset $(nW)util_poolset$(nW) o 134217728 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset1: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir11$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir11$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir11$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir11$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset2: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir21$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir22$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir21$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir22$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset3: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir31$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir31$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir31$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir31$(nW)000003.pmem filesize $(nW) size $(nW) replica[1]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir32$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir32$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir32$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir32$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset4: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir41$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir42$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir41$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir42$(nW)000003.pmem filesize $(nW) size $(nW) replica[1]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir43$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir44$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir43$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir44$(nW)000003.pmem filesize $(nW) size $(nW) util_poolset$(nW)TEST4w: DONE pmdk-1.11.1/src/test/util_poolset/grep4w.log.match0000664000000000000000000000024014123364546020530 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) pmdk-1.11.1/src/test/util_poolset/out10.log.match0000664000000000000000000000205214123364546020273 0ustar rootrootutil_poolset/TEST10: START: util_poolset ./util_poolset$(nW) o 4194304 $(nW)/testset1 $(nW)/testset2 $(nW)/testset3 $(nW)/testset4 $(nW)/testset5 $(nW)/testset6 $(nW)/testset7 $(nW)/testset8 $(nW)/testset9 $(nW)/testset10 $(nW)/testset11 $(nW)/testset12 $(nW)/testset1: opened: nreps 1 poolsize 8323072 rdonly 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile11 filesize 4194304 size 4194304 part[1] path $(nW)/testfile12 filesize 4194304 size 4128768 $(nW)/testset2: util_pool_open: Invalid argument $(nW)/testset3: util_pool_open: Invalid argument $(nW)/testset4: util_pool_open: Invalid argument $(nW)/testset5: util_pool_open: Invalid argument $(nW)/testset6: util_pool_open: Invalid argument $(nW)/testset7: util_pool_open: Invalid argument $(nW)/testset8: util_pool_open: Invalid argument $(nW)/testset9: util_pool_open: Invalid argument $(nW)/testset10: util_pool_open: Invalid argument $(nW)/testset11: util_pool_open: Invalid argument $(nW)/testset12: util_pool_open: Invalid argument util_poolset/TEST10: DONE pmdk-1.11.1/src/test/util_poolset/TEST30000775000000000000000000000147214123364546016322 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST3 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB MIN_PART=$((2 * 1024 * 1024)) # 2MiB for i in `seq 1 128`; do FILES="$FILES $MIN_PART:$DIR/testfile$i:x " done # prepare pool sets create_poolset $DIR/testset1 $FILES # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL $DIR/testset1 # now check if pool sets may be opened expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL $DIR/testset1 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/TEST90000775000000000000000000001176614123364546016337 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST9 -- unit test for util_pool_create() # # Copy of TEST0 for ppc64le # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem require_ppc64 setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB mkdir -p $DIR/subdir1 mkdir -p $DIR/subdir2 # non-existing files (delete on failure) create_poolset $DIR/testset1 $MIN_POOL:$DIR/testfile11:x # pass create_poolset $DIR/testset2 $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x # pass create_poolset $DIR/testset3 $MIN_POOL:$DIR/testfile31:x \ $MIN_POOL:$DIR/testfile32:z:$MIN_POOL # pass create_poolset $DIR/testset4 1MB:$DIR/testfile41:x \ $MIN_POOL:$DIR/testfile42:x # fail - part1 too small create_poolset $DIR/testset5 $MIN_POOL:$DIR/testfile51:x \ 1MB:$DIR/testfile52:x # fail - part2 too small create_poolset $DIR/testset6 $MIN_POOL:$DIR/testfile61:x \ $MIN_POOL:$DIR/nodir/testfile62:x # fail - part2 non-existing dir create_poolset $DIR/testset7 $MIN_POOL:$DIR/testfile71:x \ $MIN_POOL:/proc/testfile72:x # fail - part2 can't write to dir create_poolset $DIR/testset8 $MIN_POOL:$DIR/testfile81:x \ 1G:$DIR/testfile82:x # fail - part2 no space left # exiting files (do not delete on failure) create_poolset $DIR/testset10 $MIN_POOL:$DIR/testfile101:z \ $MIN_POOL:$DIR/testfile102:z:$MIN_POOL:0444 # fail - part2 read-only create_poolset $DIR/testset11 $MIN_POOL:$DIR/testfile111:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile112:z 1M:$DIR/testfile113:z:$MIN_POOL # fail - part3 too small create_poolset $DIR/testset12 $MIN_POOL:$DIR/testfile121:z:$MIN_POOL \ 195K:$DIR/testfile122:z:195K # fail - part2 too small create_poolset $DIR/testset13 195K:$DIR/testfile131:z:195K \ $MIN_POOL:$DIR/testfile132:z:$MIN_POOL # fail - part2 too small create_poolset $DIR/testset14 $MIN_POOL:$DIR/testfile141:z:$MIN_POOL \ 8M:$DIR/testfile142:z:$MIN_POOL # fail - part2 size doesn't match create_poolset $DIR/testset15 $MIN_POOL:$DIR/testfile151:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile152:z:3M # fail - part2 size doesn't match create_poolset $DIR/testset16 1M:$DIR/testfile161:z:1M \ $MIN_POOL:$DIR/testfile162:z:$MIN_POOL # fail - part1 too small create_poolset $DIR/testset17 2M:$DIR/testfile171:z \ 2M:$DIR/testfile172:z 2M:$DIR/testfile173:z # pass create_poolset $DIR/testset18 2M:$DIR/subdir1/testfile181:z \ 3M:$DIR/subdir2/testfile182:z # pass # mixed (some files exist, some don't) create_poolset $DIR/testset20 $MIN_POOL:$DIR/testfile201:x \ $MIN_POOL:$DIR/testfile202:n # fail - part2 non-zeroed file create_poolset $DIR/testset21 $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x # fail - part2 valid hdr (reuse file from case #2) create_poolset $DIR/testset22 $MIN_POOL:$DIR/testfile221:x \ $MIN_POOL:$DIR/testfile222:h # fail - part2 zeroed hdr (rest is non-zeroed) create_poolset $DIR/testset23 $MIN_POOL:$DIR/testfile231:x \ $MIN_POOL:$DIR/testfile232:z # fail - can't read set file create_poolset $DIR/testset24 $MIN_POOL:$DIR/testfile241:x $MIN_POOL:$DIR/testfile242:x \ r 8M:$DIR/testfile243:x r $MIN_POOL:$DIR/testfile244:x \ $MIN_POOL:$DIR/testfile245:x # pass - replicas create_poolset $DIR/testset25 $MIN_POOL:$DIR/testfile251:z $MIN_POOL:$DIR/testfile252:x \ r 1M:$DIR/testfile253:z # fail - replica too small create_poolset $DIR/testset26 $MIN_POOL:$DIR/testfile261:z 2M:$DIR/testfile262:z \ r 8M:$DIR/testfile263 r 6M:$DIR/testfile264 # pass - pmem/non-pmem expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL \ $DIR/testset0 $DIR/testset1\ $DIR/testset2 $DIR/testset3\ $DIR/testset4 $DIR/testset5\ $DIR/testset6\ -mo:/proc/testfile72 $DIR/testset7\ -mf:$((1024*1024*1024)) $DIR/testset8\ -mo:$DIR/testfile102 $DIR/testset10\ $DIR/testset11\ $DIR/testset12 $DIR/testset13\ $DIR/testset14 $DIR/testset15\ $DIR/testset18\ $DIR/testset20 $DIR/testset21\ $DIR/testset22\ -mo:$DIR/testset23 $DIR/testset23\ $DIR/testset24 $DIR/testset25\ -mp:$((6*1024*1024)) $DIR/testset26 check_files $DIR/testfile11\ $DIR/testfile21 $DIR/testfile22\ $DIR/testfile31 $DIR/testfile32\ $DIR/testfile101 $DIR/testfile102\ $DIR/testfile111 $DIR/testfile112\ $DIR/testfile121 $DIR/testfile122\ $DIR/testfile131 $DIR/testfile132\ $DIR/testfile141 $DIR/testfile142\ $DIR/testfile151 $DIR/testfile152\ $DIR/testfile161 $DIR/testfile162\ $DIR/testfile171 $DIR/testfile172 $DIR/testfile173\ $DIR/subdir1/testfile181 $DIR/subdir2/testfile182\ $DIR/testfile202\ $DIR/testfile221 $DIR/testfile222\ $DIR/testfile232\ $DIR/testfile241 $DIR/testfile242 $DIR/testfile243 $DIR/testfile244 $DIR/testfile245\ $DIR/testfile251 $DIR/testfile253\ $DIR/testfile261 $DIR/testfile262 $DIR/testfile263 $DIR/testfile264 check_no_files $DIR/testfile41 $DIR/testfile42\ $DIR/testfile51 $DIR/testfile52\ $DIR/testfile61\ $DIR/testfile81 $DIR/testfile82\ $DIR/testfile201\ $DIR/testfile231\ $DIR/testfile252 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/mocks_windows.h0000664000000000000000000000133514123364546020567 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of libc functions used in util_poolset * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmem * files, when compiled for the purpose of util_poolset test. * It would replace default implementation with mocked functions defined * in util_poolset.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL_OPEN #define os_open __wrap_os_open #endif #ifndef WRAP_REAL_FALLOCATE #define os_posix_fallocate __wrap_os_posix_fallocate #endif #ifndef WRAP_REAL_PMEM #define pmem_is_pmem __wrap_pmem_is_pmem #endif pmdk-1.11.1/src/test/util_poolset/grep3.log.match0000664000000000000000000000054014123364546020343 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ pmdk-1.11.1/src/test/util_poolset/grep10.log.match0000664000000000000000000000135314123364546020424 0ustar rootrootpid $(N): program: $(nW)/util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ invalid checksum of pool header wrong pool type: "ERRORXX" pool version 99 (library expects 1) invalid reserved values invalid machine value invalid data value invalid machine_class value invalid alignment_desc value wrong architecture flags incompatible feature flags incompatible feature flags incompatible feature flags wrong pool set UUID wrong part UUID wrong part UUID wrong replica UUID pmdk-1.11.1/src/test/util_poolset/mocks.h0000664000000000000000000000033314123364546017012 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2015-2020, Intel Corporation */ #ifndef MOCKS_H #define MOCKS_H extern const char *Open_path; extern os_off_t Fallocate_len; extern size_t Is_pmem_len; #endif pmdk-1.11.1/src/test/util_poolset/TEST00000775000000000000000000001172414123364546016320 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST0 -- unit test for util_pool_create() # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem exclude_ppc64 setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB mkdir -p $DIR/subdir1 mkdir -p $DIR/subdir2 # non-existing files (delete on failure) create_poolset $DIR/testset1 $MIN_POOL:$DIR/testfile11:x # pass create_poolset $DIR/testset2 $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x # pass create_poolset $DIR/testset3 $MIN_POOL:$DIR/testfile31:x \ $MIN_POOL:$DIR/testfile32:z:$MIN_POOL # pass create_poolset $DIR/testset4 1MB:$DIR/testfile41:x \ $MIN_POOL:$DIR/testfile42:x # fail - part1 too small create_poolset $DIR/testset5 $MIN_POOL:$DIR/testfile51:x \ 1MB:$DIR/testfile52:x # fail - part2 too small create_poolset $DIR/testset6 $MIN_POOL:$DIR/testfile61:x \ $MIN_POOL:$DIR/nodir/testfile62:x # fail - part2 non-existing dir create_poolset $DIR/testset7 $MIN_POOL:$DIR/testfile71:x \ $MIN_POOL:/proc/testfile72:x # fail - part2 can't write to dir create_poolset $DIR/testset8 $MIN_POOL:$DIR/testfile81:x \ 1G:$DIR/testfile82:x # fail - part2 no space left # exiting files (do not delete on failure) create_poolset $DIR/testset10 $MIN_POOL:$DIR/testfile101:z \ $MIN_POOL:$DIR/testfile102:z:$MIN_POOL:0444 # fail - part2 read-only create_poolset $DIR/testset11 $MIN_POOL:$DIR/testfile111:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile112:z 1M:$DIR/testfile113:z:$MIN_POOL # fail - part3 too small create_poolset $DIR/testset12 $MIN_POOL:$DIR/testfile121:z:$MIN_POOL \ 12K:$DIR/testfile122:z:12K # fail - part2 too small create_poolset $DIR/testset13 12K:$DIR/testfile131:z:12K \ $MIN_POOL:$DIR/testfile132:z:$MIN_POOL # fail - part2 too small create_poolset $DIR/testset14 $MIN_POOL:$DIR/testfile141:z:$MIN_POOL \ 8M:$DIR/testfile142:z:$MIN_POOL # fail - part2 size doesn't match create_poolset $DIR/testset15 $MIN_POOL:$DIR/testfile151:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile152:z:3M # fail - part2 size doesn't match create_poolset $DIR/testset16 1M:$DIR/testfile161:z:1M \ $MIN_POOL:$DIR/testfile162:z:$MIN_POOL # fail - part1 too small create_poolset $DIR/testset17 2M:$DIR/testfile171:z \ 2M:$DIR/testfile172:z 2M:$DIR/testfile173:z # pass create_poolset $DIR/testset18 2M:$DIR/subdir1/testfile181:z \ 3M:$DIR/subdir2/testfile182:z # pass # mixed (some files exist, some don't) create_poolset $DIR/testset20 $MIN_POOL:$DIR/testfile201:x \ $MIN_POOL:$DIR/testfile202:n # fail - part2 non-zeroed file create_poolset $DIR/testset21 $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x # fail - part2 valid hdr (reuse file from case #2) create_poolset $DIR/testset22 $MIN_POOL:$DIR/testfile221:x \ $MIN_POOL:$DIR/testfile222:h # fail - part2 zeroed hdr (rest is non-zeroed) create_poolset $DIR/testset23 $MIN_POOL:$DIR/testfile231:x \ $MIN_POOL:$DIR/testfile232:z # fail - can't read set file create_poolset $DIR/testset24 $MIN_POOL:$DIR/testfile241:x $MIN_POOL:$DIR/testfile242:x \ r 8M:$DIR/testfile243:x r $MIN_POOL:$DIR/testfile244:x \ $MIN_POOL:$DIR/testfile245:x # pass - replicas create_poolset $DIR/testset25 $MIN_POOL:$DIR/testfile251:z $MIN_POOL:$DIR/testfile252:x \ r 1M:$DIR/testfile253:z # fail - replica too small create_poolset $DIR/testset26 $MIN_POOL:$DIR/testfile261:z 2M:$DIR/testfile262:z \ r 8M:$DIR/testfile263 r 6M:$DIR/testfile264 # pass - pmem/non-pmem expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL \ $DIR/testset0 $DIR/testset1\ $DIR/testset2 $DIR/testset3\ $DIR/testset4 $DIR/testset5\ $DIR/testset6\ -mo:/proc/testfile72 $DIR/testset7\ -mf:$((1024*1024*1024)) $DIR/testset8\ -mo:$DIR/testfile102 $DIR/testset10\ $DIR/testset11\ $DIR/testset12 $DIR/testset13\ $DIR/testset14 $DIR/testset15\ $DIR/testset18\ $DIR/testset20 $DIR/testset21\ $DIR/testset22\ -mo:$DIR/testset23 $DIR/testset23\ $DIR/testset24 $DIR/testset25\ -mp:$((6*1024*1024)) $DIR/testset26 check_files $DIR/testfile11\ $DIR/testfile21 $DIR/testfile22\ $DIR/testfile31 $DIR/testfile32\ $DIR/testfile101 $DIR/testfile102\ $DIR/testfile111 $DIR/testfile112\ $DIR/testfile121 $DIR/testfile122\ $DIR/testfile131 $DIR/testfile132\ $DIR/testfile141 $DIR/testfile142\ $DIR/testfile151 $DIR/testfile152\ $DIR/testfile161 $DIR/testfile162\ $DIR/testfile171 $DIR/testfile172 $DIR/testfile173\ $DIR/subdir1/testfile181 $DIR/subdir2/testfile182\ $DIR/testfile202\ $DIR/testfile221 $DIR/testfile222\ $DIR/testfile232\ $DIR/testfile241 $DIR/testfile242 $DIR/testfile243 $DIR/testfile244 $DIR/testfile245\ $DIR/testfile251 $DIR/testfile253\ $DIR/testfile261 $DIR/testfile262 $DIR/testfile263 $DIR/testfile264 check_no_files $DIR/testfile41 $DIR/testfile42\ $DIR/testfile51 $DIR/testfile52\ $DIR/testfile61\ $DIR/testfile81 $DIR/testfile82\ $DIR/testfile201\ $DIR/testfile231\ $DIR/testfile252 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/Makefile0000664000000000000000000000047414123364546017173 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/Makefile -- build util_poolset unit test # TARGET = util_poolset OBJS = util_poolset.o mocks_posix.o LIBPMEMCOMMON=y USE_PMEMSPOIL=y include ../Makefile.inc LDFLAGS += $(call extract_funcs, mocks_posix.c) pmdk-1.11.1/src/test/util_poolset/grep0.log.match0000664000000000000000000000321414123364546020341 0ustar rootrootpid $(N): program: $(nW)/util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ open "$(nW)/testset0": No such file or directory $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source size 1000000 smaller than 2097152 size 1000000 smaller than 2097152 open "$(nW)/nodir/testfile62": No such file or directory open "/proc/testfile72": Permission denied posix_fallocate "$(nW)/testfile82", 1073741824: No space left on device open "$(nW)/testfile102": Permission denied file size does not match config: $(nW)testfile113, 4194304 != 1048576 size 12288 smaller than 2097152 size 12288 smaller than 2097152 file size does not match config: $(nW)testfile142, 4194304 != 8388608 file size does not match config: $(nW)testfile152, 3145728 != 4194304 Non-empty file detected Non-empty file detected open "$(nW)/testset23": Permission denied reservation pool size 1048576 smaller than 4194304 pmdk-1.11.1/src/test/util_poolset/TEST50000775000000000000000000000375114123364546016326 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST5 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$(((128 + 4) * 1024 * 1024)) MIN_POOL=$((128 * 1024 * 1024)) require_free_space $(( $MIN_POOL * 15 )) export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log # prepare pool sets create_poolset $DIR/testset1\ $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR # pass create_poolset $DIR/testset2\ $RESVSIZE:$DIR/testdir21:d $RESVSIZE:$DIR/testdir22:d\ O SINGLEHDR # pass create_poolset $DIR/testset3\ $RESVSIZE:$DIR/testdir31:d R $RESVSIZE:$DIR/testdir32:d\ O SINGLEHDR # pass create_poolset $DIR/testset4\ $RESVSIZE:$DIR/testdir41:d $RESVSIZE:$DIR/testdir42:d\ R $RESVSIZE:$DIR/testdir43:d $RESVSIZE:$DIR/testdir44:d\ O SINGLEHDR # pass create_poolset $DIR/testset9\ $RESVSIZE:$DIR/testdir91:d R $RESVSIZE:$DIR/testdir91/testdir92:d\ O SINGLEHDR # pass # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 # now check if pool sets may be opened expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 expect_normal_exit ./util_poolset$EXESUFFIX e $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 # this should fail in poolsets with only one directory because this would exceed # the reservation size expect_normal_exit ./util_poolset$EXESUFFIX e $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/testset9 check pass pmdk-1.11.1/src/test/util_poolset/TEST40000775000000000000000000000352314123364546016322 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST4 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$((4 * 1024 * 1024 * 1024)) # 4GiB MIN_POOL=$((128 * 1024 * 1024)) # 128MiB require_free_space $(( $MIN_POOL * 12 )) export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log # prepare pool sets create_poolset $DIR/testset1\ $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR # pass create_poolset $DIR/testset2\ $RESVSIZE:$DIR/testdir21:d $RESVSIZE:$DIR/testdir22:d\ O SINGLEHDR # pass create_poolset $DIR/testset3\ $RESVSIZE:$DIR/testdir31:d R $RESVSIZE:$DIR/testdir32:d\ O SINGLEHDR # pass create_poolset $DIR/testset4\ $RESVSIZE:$DIR/testdir41:d $RESVSIZE:$DIR/testdir42:d\ R $RESVSIZE:$DIR/testdir43:d $RESVSIZE:$DIR/testdir44:d\ O SINGLEHDR # pass # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 # now check if pool sets may be opened expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 expect_normal_exit ./util_poolset$EXESUFFIX f $MIN_POOL\ $DIR/testset4 expect_normal_exit ./util_poolset$EXESUFFIX e $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 expect_normal_exit ./util_poolset$EXESUFFIX e $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 expect_normal_exit ./util_poolset$EXESUFFIX e $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/TEST1w.PS10000664000000000000000000000541514123364546017107 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST1w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium setup $Env:TEST_LOG_LEVEL = "4" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 4 * 1024 * 1024 # 4MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 4MiB create_poolset $DIR\testset1 ${MIN_POOL_STR}:$DIR\testfile11:z:${MIN_POOL_STR} # pass create_poolset $DIR\testset2 ${MIN_POOL_STR}:$DIR\testfile21:x ` ${MIN_POOL_STR}:$DIR\testfile22:x # fail - can't read poolset file create_poolset $DIR\testset3 ${MIN_POOL_STR}:$DIR\testfile31:x ` ${MIN_POOL_STR}:$DIR\testfile32:x # fail - no files create_poolset $DIR\testset4 ${MIN_POOL_STR}:$DIR\testfile41:z:${MIN_POOL_STR} ` ${MIN_POOL_STR}:$DIR\testfile42:x # fail - no second part create_poolset $DIR\testset5 1M:$DIR\testfile51:z:1M ` ${MIN_POOL_STR}:$DIR\testfile52:z:${MIN_POOL_STR} # fail - part1 too small create_poolset $DIR\testset6 ${MIN_POOL_STR}:$DIR\testfile61:z:${MIN_POOL_STR} ` 1M:$DIR\testfile62:z:1M # fail - part2 too small create_poolset $DIR\testset7 2097151B:$DIR\testfile71:z:2097151B ` ${MIN_POOL_STR}:$DIR\testfile72:z:${MIN_POOL_STR} # fail - part1 too small create_poolset $DIR\testset8 ${MIN_POOL_STR}:$DIR\testfile81:z:${MIN_POOL_STR} ` ${MIN_POOL_STR}:$DIR\testfile82:z:${MIN_POOL_STR} # fail - no access permissions create_poolset $DIR\testset9 ${MIN_POOL_STR}:$DIR\testfile91:z:${MIN_POOL_STR} ` 512K:$DIR\testfile92:z:${MIN_POOL_STR} # fail - part2 size doesn't match create_poolset $DIR\testset10 ${MIN_POOL_STR}:$DIR\testfile101:z:4194304B ` ${MIN_POOL_STR}:$DIR\testfile102:z:4194305B # fail - part2 size doesn't match create_poolset $DIR\testset11 2097153B:$DIR\testfile111:z:2097153B ` 2101247B:$DIR\testfile112:z:2101247B 2097152B:$DIR\testfile113:z:2097152B # pass expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset0 $DIR\testset1 ` "-mo:$DIR\testset2" $DIR\testset2 ` $DIR\testset3 $DIR\testset4 ` $DIR\testset5 $DIR\testset6 ` $DIR\testset7 ` "-mo:$DIR\testfile82" $DIR\testset8 ` $DIR\testset9 $DIR\testset10 ` $DIR\testset11 check_files $DIR\testfile11 ` $DIR\testfile51 $DIR\testfile52 ` $DIR\testfile61 $DIR\testfile62 ` $DIR\testfile71 $DIR\testfile72 ` $DIR\testfile81 $DIR\testfile82 ` $DIR\testfile91 $DIR\testfile92 ` $DIR\testfile101 $DIR\testfile102 ` $DIR\testfile111 $DIR\testfile112 $DIR\testfile113 check_no_files $DIR\testfile21 $DIR\testfile22 ` $DIR\testfile31 $DIR\testfile32 ` $DIR\testfile42 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/grep7.log.match0000664000000000000000000000102014123364546020341 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ the NOHDRS poolset option is not supported for local poolsets the NOHDRS poolset option is not supported for local poolsets the NOHDRS poolset option is not supported for local poolsets the NOHDRS poolset option is not supported for local poolsets the NOHDRS poolset option is not supported for local poolsets the NOHDRS poolset option is not supported for local poolsets pmdk-1.11.1/src/test/util_poolset/TEST70000775000000000000000000000260314123364546016323 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST7 -- unit test for util_pool_open() # # case: negative test for local poolsets with the NOHDRS option # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$((4 * 1024 * 1024 * 1024)) # 4GiB MIN_POOL=$((128 * 1024 * 1024)) # 128MiB require_free_space $(( $MIN_POOL * 6 )) export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log # prepare pool sets create_poolset $DIR/testset1 \ $MIN_POOL:$DIR/testfile11:x \ O NOHDRS create_poolset $DIR/testset2 \ $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x \ O NOHDRS create_poolset $DIR/testset3 \ $MIN_POOL:$DIR/testfile31:x \ r \ $MIN_POOL:$DIR/testfile32:x \ O NOHDRS create_poolset $DIR/testset4\ $RESVSIZE:$DIR/testdir41:d\ O NOHDRS create_poolset $DIR/testset5\ $RESVSIZE:$DIR/testdir51:d $RESVSIZE:$DIR/testdir52:d\ O NOHDRS create_poolset $DIR/testset6\ $RESVSIZE:$DIR/testdir61:d R $RESVSIZE:$DIR/testdir62:d\ O NOHDRS # attempt to create the pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset5\ $DIR/testset6 # Extract level 1 messages from the test log $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/out2w.log.match0000664000000000000000000000203314123364546020402 0ustar rootrootutil_poolset$(nW)TEST2w: START: util_poolset $(nW)util_poolset$(nW) o 4194304 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset5 $(nW)testset6 $(nW)testset7 $(nW)testset8 $(nW)testset9 $(nW)testset10 $(nW)testset11 $(nW)testset12 $(nW)testset1: opened: nreps 1 poolsize 8323072 rdonly 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)testfile11 filesize 4194304 size 4194304 part[1] path $(nW)testfile12 filesize 4194304 size 4128768 $(nW)testset2: util_pool_open: Invalid argument $(nW)testset3: util_pool_open: Invalid argument $(nW)testset4: util_pool_open: Invalid argument $(nW)testset5: util_pool_open: Invalid argument $(nW)testset6: util_pool_open: Invalid argument $(nW)testset7: util_pool_open: Invalid argument $(nW)testset8: util_pool_open: Invalid argument $(nW)testset9: util_pool_open: Invalid argument $(nW)testset10: util_pool_open: Invalid argument $(nW)testset11: util_pool_open: Invalid argument $(nW)testset12: util_pool_open: Invalid argument util_poolset$(nW)TEST2w: DONE pmdk-1.11.1/src/test/util_poolset/out0.log.match0000664000000000000000000000726214123364546020222 0ustar rootrootutil_poolset/TEST0: START: util_poolset ./util_poolset$(nW) c 4194304 $(nW)/testset0 $(nW)/testset1 $(nW)/testset2 $(nW)/testset3 $(nW)/testset4 $(nW)/testset5 $(nW)/testset6 -mo:$(nW)/testfile72 $(nW)/testset7 -mf:1073741824 $(nW)/testset8 -mo:$(nW)/testfile102 $(nW)/testset10 $(nW)/testset11 $(nW)/testset12 $(nW)/testset13 $(nW)/testset14 $(nW)/testset15 $(nW)/testset18 $(nW)/testset20 $(nW)/testset21 $(nW)/testset22 -mo:$(nW)/testset23 $(nW)/testset23 $(nW)/testset24 $(nW)/testset25 -mp:6291456 $(nW)/testset26 $(nW)/testset0: util_pool_create: No such file or directory $(nW)/testset1: created: nreps 1 poolsize 4194304 zeroed 1 replica[0]: nparts 1 nhdrs 1 repsize 4194304 is_pmem 0 part[0] path $(nW)/testfile11 filesize 4194304 size 4194304 $(nW)/testset2: created: nreps 1 poolsize 8384512 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile21 filesize 4194304 size 4194304 part[1] path $(nW)/testfile22 filesize 4194304 size 4190208 $(nW)/testset3: created: nreps 1 poolsize 8384512 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile31 filesize 4194304 size 4194304 part[1] path $(nW)/testfile32 filesize 4194304 size 4190208 $(nW)/testset4: util_pool_create: Invalid argument $(nW)/testset5: util_pool_create: Invalid argument $(nW)/testset6: util_pool_create: No such file or directory mocked open: $(nW)/testfile72 $(nW)/testset7: util_pool_create: Permission denied mocked fallocate: 1073741824 $(nW)/testset8: util_pool_create: No space left on device mocked open: $(nW)/testfile102 $(nW)/testset10: util_pool_create: Permission denied $(nW)/testset11: util_pool_create: Invalid argument $(nW)/testset12: util_pool_create: Invalid argument $(nW)/testset13: util_pool_create: Invalid argument $(nW)/testset14: util_pool_create: Invalid argument $(nW)/testset15: util_pool_create: Invalid argument $(nW)/testset18: created: nreps 1 poolsize 5238784 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 5238784 is_pmem 0 part[0] path $(nW)/subdir1/testfile181 filesize 2097152 size 2097152 part[1] path $(nW)/subdir2/testfile182 filesize 3145728 size 3141632 $(nW)/testset20: util_pool_create: File exists $(nW)/testset21: util_pool_create: File exists $(nW)/testset22: created: nreps 1 poolsize 8384512 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile221 filesize 4194304 size 4194304 part[1] path $(nW)/testfile222 filesize 4194304 size 4190208 mocked open: $(nW)/testset23 $(nW)/testset23: util_pool_create: Permission denied $(nW)/testset24: created: nreps 3 poolsize 8384512 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile241 filesize 4194304 size 4194304 part[1] path $(nW)/testfile242 filesize 4194304 size 4190208 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)/testfile243 filesize 8388608 size 8388608 replica[2]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile244 filesize 4194304 size 4194304 part[1] path $(nW)/testfile245 filesize 4194304 size 4190208 $(nW)/testset25: util_pool_create: Invalid argument mocked pmem_is_pmem: 6291456 $(nW)/testset26: created: nreps 3 poolsize 6287360 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 6287360 is_pmem 0 part[0] path $(nW)/testfile261 filesize 4194304 size 4194304 part[1] path $(nW)/testfile262 filesize 2097152 size 2093056 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)/testfile263 filesize 8388608 size 8388608 replica[2]: nparts 1 nhdrs 1 repsize 6291456 is_pmem 1 part[0] path $(nW)/testfile264 filesize 6291456 size 6291456 util_poolset/TEST0: DONE pmdk-1.11.1/src/test/util_poolset/out9.log.match0000664000000000000000000000726214123364546020233 0ustar rootrootutil_poolset/TEST9: START: util_poolset ./util_poolset$(nW) c 4194304 $(nW)/testset0 $(nW)/testset1 $(nW)/testset2 $(nW)/testset3 $(nW)/testset4 $(nW)/testset5 $(nW)/testset6 -mo:$(nW)/testfile72 $(nW)/testset7 -mf:1073741824 $(nW)/testset8 -mo:$(nW)/testfile102 $(nW)/testset10 $(nW)/testset11 $(nW)/testset12 $(nW)/testset13 $(nW)/testset14 $(nW)/testset15 $(nW)/testset18 $(nW)/testset20 $(nW)/testset21 $(nW)/testset22 -mo:$(nW)/testset23 $(nW)/testset23 $(nW)/testset24 $(nW)/testset25 -mp:6291456 $(nW)/testset26 $(nW)/testset0: util_pool_create: No such file or directory $(nW)/testset1: created: nreps 1 poolsize 4194304 zeroed 1 replica[0]: nparts 1 nhdrs 1 repsize 4194304 is_pmem 0 part[0] path $(nW)/testfile11 filesize 4194304 size 4194304 $(nW)/testset2: created: nreps 1 poolsize 8323072 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile21 filesize 4194304 size 4194304 part[1] path $(nW)/testfile22 filesize 4194304 size 4128768 $(nW)/testset3: created: nreps 1 poolsize 8323072 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile31 filesize 4194304 size 4194304 part[1] path $(nW)/testfile32 filesize 4194304 size 4128768 $(nW)/testset4: util_pool_create: Invalid argument $(nW)/testset5: util_pool_create: Invalid argument $(nW)/testset6: util_pool_create: No such file or directory mocked open: $(nW)/testfile72 $(nW)/testset7: util_pool_create: Permission denied mocked fallocate: 1073741824 $(nW)/testset8: util_pool_create: No space left on device mocked open: $(nW)/testfile102 $(nW)/testset10: util_pool_create: Permission denied $(nW)/testset11: util_pool_create: Invalid argument $(nW)/testset12: util_pool_create: Invalid argument $(nW)/testset13: util_pool_create: Invalid argument $(nW)/testset14: util_pool_create: Invalid argument $(nW)/testset15: util_pool_create: Invalid argument $(nW)/testset18: created: nreps 1 poolsize 5177344 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 5177344 is_pmem 0 part[0] path $(nW)/subdir1/testfile181 filesize 2097152 size 2097152 part[1] path $(nW)/subdir2/testfile182 filesize 3145728 size 3080192 $(nW)/testset20: util_pool_create: File exists $(nW)/testset21: util_pool_create: File exists $(nW)/testset22: created: nreps 1 poolsize 8323072 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile221 filesize 4194304 size 4194304 part[1] path $(nW)/testfile222 filesize 4194304 size 4128768 mocked open: $(nW)/testset23 $(nW)/testset23: util_pool_create: Permission denied $(nW)/testset24: created: nreps 3 poolsize 8323072 zeroed 1 replica[0]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile241 filesize 4194304 size 4194304 part[1] path $(nW)/testfile242 filesize 4194304 size 4128768 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)/testfile243 filesize 8388608 size 8388608 replica[2]: nparts 2 nhdrs 2 repsize 8323072 is_pmem 0 part[0] path $(nW)/testfile244 filesize 4194304 size 4194304 part[1] path $(nW)/testfile245 filesize 4194304 size 4128768 $(nW)/testset25: util_pool_create: Invalid argument mocked pmem_is_pmem: 6291456 $(nW)/testset26: created: nreps 3 poolsize 6225920 zeroed 0 replica[0]: nparts 2 nhdrs 2 repsize 6225920 is_pmem 0 part[0] path $(nW)/testfile261 filesize 4194304 size 4194304 part[1] path $(nW)/testfile262 filesize 2097152 size 2031616 replica[1]: nparts 1 nhdrs 1 repsize 8388608 is_pmem 0 part[0] path $(nW)/testfile263 filesize 8388608 size 8388608 replica[2]: nparts 1 nhdrs 1 repsize 6291456 is_pmem 1 part[0] path $(nW)/testfile264 filesize 6291456 size 6291456 util_poolset/TEST9: DONE pmdk-1.11.1/src/test/util_poolset/grep9.log.match0000664000000000000000000000321614123364546020354 0ustar rootrootpid $(N): program: $(nW)/util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ open "$(nW)/testset0": No such file or directory $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source $(OPT)Cannot read device usc - ndctl is not available $(OPT)Unsafe shutdown count is not supported for this source size 1000000 smaller than 2097152 size 1000000 smaller than 2097152 open "$(nW)/nodir/testfile62": No such file or directory open "/proc/testfile72": Permission denied posix_fallocate "$(nW)/testfile82", 1073741824: No space left on device open "$(nW)/testfile102": Permission denied file size does not match config: $(nW)testfile113, 4194304 != 1048576 size 199680 smaller than 2097152 size 199680 smaller than 2097152 file size does not match config: $(nW)testfile142, 4194304 != 8388608 file size does not match config: $(nW)testfile152, 3145728 != 4194304 Non-empty file detected Non-empty file detected open "$(nW)/testset23": Permission denied reservation pool size 1048576 smaller than 4194304 pmdk-1.11.1/src/test/util_poolset/grep4.log.match0000664000000000000000000000054014123364546020344 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ pmdk-1.11.1/src/test/util_poolset/.gitignore0000664000000000000000000000001514123364546017512 0ustar rootrootutil_poolset pmdk-1.11.1/src/test/util_poolset/grep3w.log.match0000664000000000000000000000017314123364546020534 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for shutdown state pmdk-1.11.1/src/test/util_poolset/README0000664000000000000000000000111214123364546016401 0ustar rootrootPersistent Memory Development Kit This is src/test/util_poolset/README. This directory contains a unit test for util_pool_create() and util_pool_open(). The program in util_poolset.c takes a command, minimal pool size along with the list of poolset file paths. The 'command' could be: c - util_poolset_create() o - util_poolset_open() For example: ./util_poolset c minlen path1 This will call util_pool_create() on path1 using minlen as minimal pool size and hdrsize as pool header size. minlen and hdrsize are interpreted as a decimal values unless they start with 0x. pmdk-1.11.1/src/test/util_poolset/TEST3w.PS10000664000000000000000000000163014123364546017104 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST3w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "4" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 4 * 1024 * 1024 # 4MiB $MIN_PART = (2 * 1024 * 1024).toString() + "B" # 2MiB $FILES = @() for ($p = 1; $p -le 128; $p++) { $FILES += "${MIN_PART}:$DIR\testfile${p}:x" } # prepare pool sets create_poolset $DIR\testset1 @FILES # create pool sets expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset1 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/TEST60000775000000000000000000000277714123364546016336 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST6 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$((260 * 1024 * 1024)) # 264MiB (base part + 2 extends) MIN_POOL=$((128 * 1024 * 1024)) # 128MiB require_free_space $(( $MIN_POOL * 8 )) export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log # prepare pool sets create_poolset $DIR/testset2\ $RESVSIZE:$DIR/testdir21:d $RESVSIZE:$DIR/testfile22 create_poolset $DIR/testset3\ $RESVSIZE:$DIR/testdir31:d R $RESVSIZE:$DIR/testfile32 create_poolset $DIR/testset4\ $RESVSIZE:$DIR/testdir41:d $RESVSIZE:$DIR/testdir42:d\ R $RESVSIZE:$DIR/testdir43:d $RESVSIZE:$DIR/testfile44 create_poolset $DIR/testset6\ $RESVSIZE:$DIR/testdir61:d $RESVSIZE:$DIR/testfile62\ O SINGLEHDR create_poolset $DIR/testset7\ $RESVSIZE:$DIR/testdir71:d R $RESVSIZE:$DIR/testfile72\ O SINGLEHDR create_poolset $DIR/testset8\ $RESVSIZE:$DIR/testdir81:d $RESVSIZE:$DIR/testdir82:d\ R $RESVSIZE:$DIR/testdir83:d $RESVSIZE:$DIR/testfile84\ O SINGLEHDR create_poolset $DIR/testset9\ $RESVSIZE:$DIR/testdir91 $RESVSIZE:$DIR/testfile92:d\ O SINGLEHDR # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset6\ $DIR/testset7\ $DIR/testset8\ $DIR/testset9 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/TEST6w.PS10000664000000000000000000000351414123364546017112 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST6w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "6" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 128 * 1024 * 1024 # 4MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 128MiB $RESVSIZE=260 * 1024 * 1024 # 260 MiB $RESVSIZE_STR = ${RESVSIZE}.toString() + "B" # 260 MiB $REQUIRE_POOL = ${MIN_POOL} * 8 require_free_space "${REQUIRE_POOL}b" # prepare pool sets create_poolset $DIR\testset2 ` ${RESVSIZE_STR}:$DIR\testdir21:d ${RESVSIZE_STR}:$DIR\testfile22 create_poolset $DIR\testset3 ` ${RESVSIZE_STR}:$DIR\testdir31:d R ${RESVSIZE_STR}:$DIR\testfile32 create_poolset $DIR\testset4 ` ${RESVSIZE_STR}:$DIR\testdir41:d ${RESVSIZE_STR}:$DIR\testdir42:d ` R ${RESVSIZE_STR}:$DIR\testdir43:d ${RESVSIZE_STR}:$DIR\testfile44 create_poolset $DIR\testset6 ` ${RESVSIZE_STR}:$DIR\testdir61:d ${RESVSIZE_STR}:$DIR\testfile62 ` O SINGLEHDR create_poolset $DIR\testset7 ` ${RESVSIZE_STR}:$DIR\testdir71:d R ${RESVSIZE_STR}:$DIR\testfile72 ` O SINGLEHDR create_poolset $DIR\testset8 ` ${RESVSIZE_STR}:$DIR\testdir81:d ${RESVSIZE_STR}:$DIR\testdir82:d ` R ${RESVSIZE_STR}:$DIR\testdir83:d ${RESVSIZE_STR}:$DIR\testfile84 ` O SINGLEHDR create_poolset $DIR\testset9 ` ${RESVSIZE_STR}:$DIR\testdir91 ${RESVSIZE_STR}:$DIR\testfile92:d ` O SINGLEHDR # create pool sets expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset6 ` $DIR\testset7 ` $DIR\testset8 ` $DIR\testset9 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/grep6.log.match0000664000000000000000000000120614123364546020346 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set pmdk-1.11.1/src/test/util_poolset/TEST10000775000000000000000000000462514123364546016323 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST1 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB create_poolset $DIR/testset1 $MIN_POOL:$DIR/testfile11:z:$MIN_POOL # pass create_poolset $DIR/testset2 $MIN_POOL:$DIR/testfile21:x \ $MIN_POOL:$DIR/testfile22:x # fail - can't read poolset file create_poolset $DIR/testset3 $MIN_POOL:$DIR/testfile31:x \ $MIN_POOL:$DIR/testfile32:x # fail - no files create_poolset $DIR/testset4 $MIN_POOL:$DIR/testfile41:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile42:x # fail - no second part create_poolset $DIR/testset5 1M:$DIR/testfile51:z:1M \ $MIN_POOL:$DIR/testfile52:z:$MIN_POOL # fail - part1 too small create_poolset $DIR/testset6 $MIN_POOL:$DIR/testfile61:z:$MIN_POOL \ 1M:$DIR/testfile62:z:1M # fail - part2 too small create_poolset $DIR/testset7 2097151:$DIR/testfile71:z:2097151 \ $MIN_POOL:$DIR/testfile72:z:$MIN_POOL # fail - part1 too small create_poolset $DIR/testset8 $MIN_POOL:$DIR/testfile81:z:$MIN_POOL \ $MIN_POOL:$DIR/testfile82:z:$MIN_POOL # fail - no access permissions create_poolset $DIR/testset9 $MIN_POOL:$DIR/testfile91:z:$MIN_POOL \ 64K:$DIR/testfile92:z:$MIN_POOL # fail - part2 size doesn't match create_poolset $DIR/testset10 $MIN_POOL:$DIR/testfile101:z:4194304 \ $MIN_POOL:$DIR/testfile102:z:4194303 # fail - part2 size doesn't match create_poolset $DIR/testset11 2097153:$DIR/testfile111:z:2097153 \ 2101247:$DIR/testfile112:z:2101247 2097152:$DIR/testfile113:z:2097152 # pass expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL \ $DIR/testset0 $DIR/testset1\ -mo:$DIR/testset2 $DIR/testset2\ $DIR/testset3 $DIR/testset4\ $DIR/testset5 $DIR/testset6\ $DIR/testset7\ -mo:$DIR/testfile82 $DIR/testset8\ $DIR/testset9 $DIR/testset10\ $DIR/testset11 check_files $DIR/testfile11\ $DIR/testfile51 $DIR/testfile52\ $DIR/testfile61 $DIR/testfile62\ $DIR/testfile71 $DIR/testfile72\ $DIR/testfile81 $DIR/testfile82\ $DIR/testfile91 $DIR/testfile92\ $DIR/testfile101 $DIR/testfile102\ $DIR/testfile111 $DIR/testfile112 $DIR/testfile113 check_no_files $DIR/testfile21 $DIR/testfile22\ $DIR/testfile31 $DIR/testfile32\ $DIR/testfile42 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/grep5.log.match0000664000000000000000000000054014123364546020345 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ pmdk-1.11.1/src/test/util_poolset/util_poolset.c0000664000000000000000000001241614123364546020420 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * util_poolset.c -- unit test for util_pool_create() / util_pool_open() * * usage: util_poolset cmd minlen hdrsize [mockopts] setfile ... */ #include #include "unittest.h" #include "pmemcommon.h" #include "set.h" #include #include "mocks.h" #include "fault_injection.h" #define LOG_PREFIX "ut" #define LOG_LEVEL_VAR "TEST_LOG_LEVEL" #define LOG_FILE_VAR "TEST_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #define SIG "PMEMXXX" #define MIN_PART ((size_t)(1024 * 1024 * 2)) /* 2 MiB */ #define TEST_FORMAT_INCOMPAT_DEFAULT POOL_FEAT_CKSUM_2K #define TEST_FORMAT_INCOMPAT_CHECK POOL_FEAT_INCOMPAT_VALID static size_t Extend_size = MIN_PART * 2; const char *Open_path = ""; os_off_t Fallocate_len = -1; size_t Is_pmem_len = 0; /* * poolset_info -- (internal) dumps poolset info and checks its integrity * * Performs the following checks: * - part_size[i] == rounddown(file_size - pool_hdr_size, Mmap_align) * - replica_size == sum(part_size) * - pool_size == min(replica_size) */ static void poolset_info(const char *fname, struct pool_set *set, int o) { if (o) UT_OUT("%s: opened: nreps %d poolsize %zu rdonly %d", fname, set->nreplicas, set->poolsize, set->rdonly); else UT_OUT("%s: created: nreps %d poolsize %zu zeroed %d", fname, set->nreplicas, set->poolsize, set->zeroed); size_t poolsize = SIZE_MAX; for (unsigned r = 0; r < set->nreplicas; r++) { struct pool_replica *rep = set->replica[r]; size_t repsize = 0; UT_OUT(" replica[%d]: nparts %d nhdrs %d repsize %zu " "is_pmem %d", r, rep->nparts, rep->nhdrs, rep->repsize, rep->is_pmem); for (unsigned i = 0; i < rep->nparts; i++) { struct pool_set_part *part = &rep->part[i]; UT_OUT(" part[%d] path %s filesize %zu size %zu", i, part->path, part->filesize, part->size); size_t partsize = (part->filesize & ~(Ut_mmap_align - 1)); repsize += partsize; if (i > 0 && (set->options & OPTION_SINGLEHDR) == 0) UT_ASSERTeq(part->size, partsize - Ut_mmap_align); /* XXX */ } repsize -= (rep->nhdrs - 1) * Ut_mmap_align; UT_ASSERTeq(rep->repsize, repsize); UT_ASSERT(rep->resvsize >= repsize); if (rep->repsize < poolsize) poolsize = rep->repsize; } UT_ASSERTeq(set->poolsize, poolsize); } /* * mock_options -- (internal) parse mock options and enable mocked functions */ static int mock_options(const char *arg) { /* reset to defaults */ Open_path = ""; Fallocate_len = -1; Is_pmem_len = 0; if (arg[0] != '-' || arg[1] != 'm') return 0; switch (arg[2]) { case 'n': /* do nothing */ break; case 'o': /* open */ Open_path = &arg[4]; break; case 'f': /* fallocate */ Fallocate_len = ATOLL(&arg[4]); break; case 'p': /* is_pmem */ Is_pmem_len = ATOULL(&arg[4]); break; default: UT_FATAL("unknown mock option: %c", arg[2]); } return 1; } int main(int argc, char *argv[]) { START(argc, argv, "util_poolset"); common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); if (argc < 3) UT_FATAL("usage: %s cmd minsize [mockopts] " "setfile ...", argv[0]); char *fname; struct pool_set *set; int ret; size_t minsize = strtoul(argv[2], &fname, 0); for (int arg = 3; arg < argc; arg++) { arg += mock_options(argv[arg]); fname = argv[arg]; struct pool_attr attr; memset(&attr, 0, sizeof(attr)); memcpy(attr.signature, SIG, sizeof(SIG)); attr.major = 1; switch (argv[1][0]) { case 'c': attr.features.incompat = TEST_FORMAT_INCOMPAT_DEFAULT; ret = util_pool_create(&set, fname, 0, minsize, MIN_PART, &attr, NULL, REPLICAS_ENABLED); if (ret == -1) UT_OUT("!%s: util_pool_create", fname); else { /* * XXX: On Windows pool files are created with * R/W permissions, so no need for chmod(). */ #ifndef _WIN32 util_poolset_chmod(set, S_IWUSR | S_IRUSR); #endif poolset_info(fname, set, 0); util_poolset_close(set, DO_NOT_DELETE_PARTS); } break; case 'o': attr.features.incompat = TEST_FORMAT_INCOMPAT_CHECK; ret = util_pool_open(&set, fname, MIN_PART, &attr, NULL, NULL, 0 /* flags */); if (ret == -1) UT_OUT("!%s: util_pool_open", fname); else { poolset_info(fname, set, 1); util_poolset_close(set, DO_NOT_DELETE_PARTS); } break; case 'e': attr.features.incompat = TEST_FORMAT_INCOMPAT_CHECK; ret = util_pool_open(&set, fname, MIN_PART, &attr, NULL, NULL, 0 /* flags */); UT_ASSERTeq(ret, 0); size_t esize = Extend_size; void *nptr = util_pool_extend(set, &esize, MIN_PART); if (nptr == NULL) UT_OUT("!%s: util_pool_extend", fname); else { poolset_info(fname, set, 1); } util_poolset_close(set, DO_NOT_DELETE_PARTS); break; case 'f': if (!core_fault_injection_enabled()) break; attr.features.incompat = TEST_FORMAT_INCOMPAT_CHECK; ret = util_pool_open(&set, fname, MIN_PART, &attr, NULL, NULL, 0 /* flags */); UT_ASSERTeq(ret, 0); size_t fsize = Extend_size; core_inject_fault_at(PMEM_MALLOC, 2, "util_poolset_append_new_part"); void *fnptr = util_pool_extend(set, &fsize, MIN_PART); UT_ASSERTeq(fnptr, NULL); UT_ASSERTeq(errno, ENOMEM); util_poolset_close(set, DO_NOT_DELETE_PARTS); break; } } common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/util_poolset/out6.log.match0000664000000000000000000000105514123364546020222 0ustar rootrootutil_poolset$(nW)TEST6: START: util_poolset $(nW)util_poolset$(nW) c 134217728 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset6 $(nW)testset7 $(nW)testset8 $(nW)testset9 $(nW)testset2: util_pool_create: Invalid argument $(nW)testset3: util_pool_create: Invalid argument $(nW)testset4: util_pool_create: Invalid argument $(nW)testset6: util_pool_create: Invalid argument $(nW)testset7: util_pool_create: Invalid argument $(nW)testset8: util_pool_create: Invalid argument $(nW)testset9: util_pool_create: Invalid argument util_poolset$(nW)TEST6: DONE pmdk-1.11.1/src/test/util_poolset/TEST80000775000000000000000000000232214123364546016322 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/util_poolset/TEST8 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$(((128 + 4) * 1024 * 1024)) MIN_POOL=$((128 * 1024 * 1024)) export TEST_LOG_LEVEL=8 export TEST_LOG_FILE=./test$UNITTEST_NUM.log # prepare pool sets create_poolset $DIR/testset1\ $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR # pass create_poolset $DIR/testset2\ $RESVSIZE:$DIR/testdir21:d $RESVSIZE:$DIR/testdir22:d\ O SINGLEHDR # pass create_poolset $DIR/testset3\ $RESVSIZE:$DIR/testdir31:d R $RESVSIZE:$DIR/testdir32:d\ O SINGLEHDR # pass create_poolset $DIR/testset4\ $RESVSIZE:$DIR/testdir41:d $RESVSIZE:$DIR/testdir42:d\ R $RESVSIZE:$DIR/testdir43:d $RESVSIZE:$DIR/testdir44:d\ O SINGLEHDR # pass create_poolset $DIR/testset9\ $RESVSIZE:$DIR/testdir91:d R $RESVSIZE:$DIR/testdir91/testdir92:d\ O SINGLEHDR # pass # should fail to open expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL\ $DIR/testset1\ $DIR/testset2\ $DIR/testset3\ $DIR/testset4\ $DIR/testset9 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/mocks_windows.c0000664000000000000000000000322614123364546020563 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.c -- mocked functions used in util_poolset.c */ #include "pmem.h" #include "util.h" #include "unittest.h" extern const char *Open_path; extern os_off_t Fallocate_len; extern size_t Is_pmem_len; /* * os_open -- open mock * * due to differences in function mocking on linux we are wrapping os_open * but on linux we just wrap open syscall */ FUNC_MOCK(os_open, int, const char *path, int flags, ...) FUNC_MOCK_RUN_DEFAULT { if (strcmp(Open_path, path) == 0) { UT_OUT("mocked open: %s", path); errno = EACCES; return -1; } va_list ap; va_start(ap, flags); int mode = va_arg(ap, int); va_end(ap); return _FUNC_REAL(os_open)(path, flags, mode); } FUNC_MOCK_END /* * posix_fallocate -- posix_fallocate mock */ FUNC_MOCK(os_posix_fallocate, int, int fd, os_off_t offset, os_off_t len) FUNC_MOCK_RUN_DEFAULT { if (Fallocate_len == len) { UT_OUT("mocked fallocate: %ju", len); return ENOSPC; } return _FUNC_REAL(os_posix_fallocate)(fd, offset, len); } FUNC_MOCK_END /* * pmem_is_pmem -- pmem_is_pmem mock */ FUNC_MOCK(pmem_is_pmem, int, const void *addr, size_t len) FUNC_MOCK_RUN_DEFAULT { if (Is_pmem_len == len) { UT_OUT("mocked pmem_is_pmem: %zu", len); return 1; } return _FUNC_REAL(pmem_is_pmem)(addr, len); } FUNC_MOCK_END /* * On Windows libpmem is statically linked to util_poolset test, but we * don't want its ctor to initialize 'out' module. */ /* * libpmem_init -- load-time initialization for libpmem * * Called automatically by the run-time loader. */ CONSTRUCTOR(libpmem_init) void libpmem_init(void) { pmem_init(); } pmdk-1.11.1/src/test/util_poolset/grep1w.log.match0000664000000000000000000000157714123364546020543 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for shutdown state open "$(nW)testset0": No such file or directory invalid major version (0) open "$(nW)testset2": Permission denied open "$(nW)testfile31": No such file or directory $(OPT)cannot open the part -- "$(nW)testfile31": No such file or directory open "$(nW)testfile32": No such file or directory $(OPT)cannot open the part -- "$(nW)testfile32": No such file or directory open "$(nW)testfile31": No such file or directory open "$(nW)testfile42": No such file or directory size 1048576 smaller than 2097152 size 1048576 smaller than 2097152 size 2097151 smaller than 2097152 open "$(nW)testfile82": Permission denied file size does not match config: $(nW)testfile92, 4194304 != 524288 file size does not match config: $(nW)testfile102, 4194305 != 4194304 invalid major version (0) pmdk-1.11.1/src/test/util_poolset/TEST0w.PS10000664000000000000000000001316614123364546017110 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST0w -- unit test for util_pool_create() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "4" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 4 * 1024 * 1024 # 4MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 4MiB mkdir $DIR\subdir1 -Force > $null mkdir $DIR\subdir2 -Force > $null # non-existing files (delete on failure) create_poolset $DIR\testset1 ${MIN_POOL_STR}:$DIR\testfile11:x # pass create_poolset $DIR\testset2 ${MIN_POOL_STR}:$DIR\testfile21:x ` ${MIN_POOL_STR}:$DIR\testfile22:x # pass create_poolset $DIR\testset3 ${MIN_POOL_STR}:$DIR\testfile31:x ` ${MIN_POOL_STR}:$DIR\testfile32:z:${MIN_POOL_STR} # pass create_poolset $DIR\testset4 128K:$DIR\testfile41:x ` ${MIN_POOL_STR}:$DIR\testfile42:x # fail - part1 too small create_poolset $DIR\testset5 ${MIN_POOL_STR}:$DIR\testfile51:x ` 128K:$DIR\testfile52:x # fail - part2 too small create_poolset $DIR\testset6 ${MIN_POOL_STR}:$DIR\testfile61:x ` ${MIN_POOL_STR}:$DIR\nodir\testfile62:x # fail - part2 non-existing dir create_poolset $DIR\testset7 ${MIN_POOL_STR}:$DIR\testfile71:x ` ${MIN_POOL_STR}:\dummy\testfile72:x # fail - part2 can't write to dir create_poolset $DIR\testset8 ${MIN_POOL_STR}:$DIR\testfile81:x ` 1G:$DIR\testfile82:x # fail - part2 no space left # exiting files (do not delete on failure) create_poolset $DIR\testset10 ${MIN_POOL_STR}:$DIR\testfile101:z ` ${MIN_POOL_STR}:$DIR\testfile102:z:${MIN_POOL_STR}:0400 # fail - part2 read-only create_poolset $DIR\testset11 ${MIN_POOL_STR}:$DIR\testfile111:z:${MIN_POOL_STR} ` ${MIN_POOL_STR}:$DIR\testfile112:z 2M:$DIR\testfile113:z:${MIN_POOL_STR} # fail - part3 too small create_poolset $DIR\testset12 ${MIN_POOL_STR}:$DIR\testfile121:z:${MIN_POOL_STR} ` 1M:$DIR\testfile122:z:1M # fail - part2 too small create_poolset $DIR\testset13 1M:$DIR\testfile131:z:1M ` ${MIN_POOL_STR}:$DIR\testfile132:z:${MIN_POOL_STR} # fail - part2 too small create_poolset $DIR\testset14 ${MIN_POOL_STR}:$DIR\testfile141:z:${MIN_POOL_STR} ` 8M:$DIR\testfile142:z:${MIN_POOL_STR} # fail - part2 size doesn't match create_poolset $DIR\testset15 ${MIN_POOL_STR}:$DIR\testfile151:z:4194304B ` ${MIN_POOL_STR}:$DIR\testfile152:z:4194303B # fail - part2 size doesn't match create_poolset $DIR\testset16 4194303B:$DIR\testfile161:z:4194304B ` ${MIN_POOL_STR}:$DIR\testfile162:z:${MIN_POOL_STR} # fail - part1 too small create_poolset $DIR\testset17 262145B:$DIR\testfile171:z ` 266239B:$DIR\testfile172:z 266240B:$DIR\testfile173:z # pass create_poolset $DIR\testset18 3M:$DIR\subdir1\testfile181:z ` 3M:$DIR\subdir2\testfile182:z # pass # mixed (some files exist, some don't) create_poolset $DIR\testset20 ${MIN_POOL_STR}:$DIR\testfile201:x ` ${MIN_POOL_STR}:$DIR\testfile202:n # fail - part2 non-zeroed file create_poolset $DIR\testset21 ${MIN_POOL_STR}:$DIR\testfile21:x ` ${MIN_POOL_STR}:$DIR\testfile22:x # fail - part2 valid hdr (reuse file from case #2) create_poolset $DIR\testset22 ${MIN_POOL_STR}:$DIR\testfile221:x ` ${MIN_POOL_STR}:$DIR\testfile222:h # fail - part2 zeroed hdr (rest is non-zeroed) create_poolset $DIR\testset23 ${MIN_POOL_STR}:$DIR\testfile231:x ` ${MIN_POOL_STR}:$DIR\testfile232:z # fail - can't read set file create_poolset $DIR\testset24 ${MIN_POOL_STR}:$DIR\testfile241:x ${MIN_POOL_STR}:$DIR\testfile242:x ` r 8M:$DIR\testfile243:x ` r 6M:$DIR\testfile244:x 2M:$DIR\testfile245:x # pass - replicas create_poolset $DIR\testset25 ${MIN_POOL_STR}:$DIR\testfile251:z ${MIN_POOL_STR}:$DIR\testfile252:x ` r 3M:$DIR\testfile253:z # fail - replica too small create_poolset $DIR\testset26 ${MIN_POOL_STR}:$DIR\testfile261:z 2M:$DIR\testfile262:z ` r 8M:$DIR\testfile263 r 6M:$DIR\testfile264 # pass - pmem\non-pmem $_1GB = 1024 * 1024 * 1024 $_6MB = 6 * 1024 * 1024 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset0 $DIR\testset1 ` $DIR\testset2 $DIR\testset3 ` $DIR\testset4 $DIR\testset5 ` $DIR\testset6 ` "-mo:\dummy\testfile72" $DIR\testset7 ` "-mf:$_1GB" $DIR\testset8 ` "-mo:$DIR\testfile102" $DIR\testset10 ` $DIR\testset11 ` $DIR\testset12 $DIR\testset13 ` $DIR\testset14 $DIR\testset15 ` $DIR\testset18 ` $DIR\testset20 $DIR\testset21 ` $DIR\testset22 ` "-mo:$DIR\testset23" $DIR\testset23 ` $DIR\testset24 $DIR\testset25 ` "-mp:$_6MB" $DIR\testset26 check_files $DIR\testfile11 ` $DIR\testfile21 $DIR\testfile22 ` $DIR\testfile31 $DIR\testfile32 ` $DIR\testfile101 $DIR\testfile102 ` $DIR\testfile111 $DIR\testfile112 ` $DIR\testfile121 $DIR\testfile122 ` $DIR\testfile131 $DIR\testfile132 ` $DIR\testfile141 $DIR\testfile142 ` $DIR\testfile151 $DIR\testfile152 ` $DIR\testfile161 $DIR\testfile162 ` $DIR\testfile171 $DIR\testfile172 $DIR\testfile173 ` $DIR\subdir1\testfile181 $DIR\subdir2\testfile182 ` $DIR\testfile202 ` $DIR\testfile221 $DIR\testfile222 ` $DIR\testfile232 ` $DIR\testfile241 $DIR\testfile242 $DIR\testfile243 $DIR\testfile244 $DIR\testfile245 ` $DIR\testfile251 $DIR\testfile253 ` $DIR\testfile261 $DIR\testfile262 $DIR\testfile263 $DIR\testfile264 check_no_files $DIR\testfile41 $DIR\testfile42 ` $DIR\testfile51 $DIR\testfile52 ` $DIR\testfile61 ` $DIR\testfile81 $DIR\testfile82 ` $DIR\testfile201 ` $DIR\testfile231 ` $DIR\testfile252 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/out6w.log.match0000664000000000000000000000105714123364546020413 0ustar rootrootutil_poolset$(nW)TEST6w: START: util_poolset $(nW)util_poolset$(nW) c 134217728 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset6 $(nW)testset7 $(nW)testset8 $(nW)testset9 $(nW)testset2: util_pool_create: Invalid argument $(nW)testset3: util_pool_create: Invalid argument $(nW)testset4: util_pool_create: Invalid argument $(nW)testset6: util_pool_create: Invalid argument $(nW)testset7: util_pool_create: Invalid argument $(nW)testset8: util_pool_create: Invalid argument $(nW)testset9: util_pool_create: Invalid argument util_poolset$(nW)TEST6w: DONE pmdk-1.11.1/src/test/util_poolset/TEST5w.PS10000664000000000000000000000450414123364546017111 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_poolset/TEST5w -- unit test for util_pool_open() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup $Env:TEST_LOG_LEVEL = "5" $Env:TEST_LOG_FILE = "test$Env:UNITTEST_NUM.log" $MIN_POOL = 128 * 1024 * 1024 # 128MiB $MIN_POOL_STR = ${MIN_POOL}.toString() + "B" # 128MiB $RESVSIZE=(128 + 4) * 1024 * 1024 # initial part + extension $RESVSIZE_STR = ${RESVSIZE}.toString() + "B" # initial part + extension $REQUIRE_POOL = ${MIN_POOL} * 15 require_free_space "${REQUIRE_POOL}b" create_poolset $DIR\testset1 ` ${RESVSIZE_STR}:$DIR\testdir11:d ` O SINGLEHDR create_poolset $DIR\testset2 ` ${RESVSIZE_STR}:$DIR\testdir21:d ${RESVSIZE_STR}:$DIR\testdir22:d ` O SINGLEHDR create_poolset $DIR\testset3 ` ${RESVSIZE_STR}:$DIR\testdir31:d R ${RESVSIZE_STR}:$DIR\testdir32:d ` O SINGLEHDR create_poolset $DIR\testset4 ` ${RESVSIZE_STR}:$DIR\testdir41:d ${RESVSIZE_STR}:$DIR\testdir42:d ` R ${RESVSIZE_STR}:$DIR\testdir43:d ${RESVSIZE_STR}:$DIR\testdir44:d ` O SINGLEHDR create_poolset $DIR\testset9 ` ${RESVSIZE}:$DIR\testdir91:d R ${RESVSIZE}:$DIR\testdir91\testdir92:d ` O SINGLEHDR # pass # create pool sets expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX c $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset9 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset9 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX e $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset9 # this should fail in poolsets with only one directory because this would exceed # the reservation size expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX e $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset9 expect_normal_exit $Env:EXE_DIR\util_poolset$Env:EXESUFFIX o $MIN_POOL ` $DIR\testset1 ` $DIR\testset2 ` $DIR\testset3 ` $DIR\testset4 ` $DIR\testset9 sls -Path $Env:TEST_LOG_FILE -Pattern "<1>" | ` %{[string]$_ -replace '^.* len ',"" -replace '^.*][ ]*',''} ` > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/grep1.log.match0000664000000000000000000000214114123364546020340 0ustar rootrootpid $(N): program: $(nW)/util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ open "$(nW)/testset0": No such file or directory invalid major version (0) open "$(nW)/testset2": Permission denied open "$(nW)/testfile31": No such file or directory cannot open the part -- "$(nW)/testfile31": No such file or directory open "$(nW)/testfile32": No such file or directory cannot open the part -- "$(nW)/testfile32": No such file or directory open "$(nW)/testfile31": No such file or directory open "$(nW)/testfile42": No such file or directory size 1048576 smaller than 2097152 size 1048576 smaller than 2097152 size 2097151 smaller than 2097152 open "$(nW)/testfile82": Permission denied file size does not match config: $(nW)testfile92, 4194304 != 65536 file size does not match config: $(nW)testfile102, 4194303 != 4194304 invalid major version (0) pmdk-1.11.1/src/test/util_poolset/out1.log.match0000664000000000000000000000174314123364546020221 0ustar rootrootutil_poolset/TEST1: START: util_poolset ./util_poolset$(nW) o 4194304 $(nW)/testset0 $(nW)/testset1 -mo:$(nW)/testset2 $(nW)/testset2 $(nW)/testset3 $(nW)/testset4 $(nW)/testset5 $(nW)/testset6 $(nW)/testset7 -mo:$(nW)/testfile82 $(nW)/testset8 $(nW)/testset9 $(nW)/testset10 $(nW)/testset11 $(nW)/testset0: util_pool_open: No such file or directory $(nW)/testset1: util_pool_open: Invalid argument mocked open: $(nW)/testset2 $(nW)/testset2: util_pool_open: Permission denied $(nW)/testset3: util_pool_open: No such file or directory $(nW)/testset4: util_pool_open: No such file or directory $(nW)/testset5: util_pool_open: Invalid argument $(nW)/testset6: util_pool_open: Invalid argument $(nW)/testset7: util_pool_open: Invalid argument mocked open: $(nW)/testfile82 $(nW)/testset8: util_pool_open: Permission denied $(nW)/testset9: util_pool_open: Invalid argument $(nW)/testset10: util_pool_open: Invalid argument $(nW)/testset11: util_pool_open: Invalid argument util_poolset/TEST1: DONE pmdk-1.11.1/src/test/util_poolset/grep2.log.match0000664000000000000000000000135314123364546020345 0ustar rootrootpid $(N): program: $(nW)/util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for Valgrind pmemcheck $(OPT)compiled with support for Valgrind helgrind $(OPT)compiled with support for Valgrind memcheck $(OPT)compiled with support for Valgrind drd $(OPT)compiled with support for shutdown state $(OPT)compiled with libndctl 63+ invalid checksum of pool header wrong pool type: "ERRORXX" pool version 99 (library expects 1) invalid reserved values invalid machine value invalid data value invalid machine_class value invalid alignment_desc value wrong architecture flags incompatible feature flags incompatible feature flags incompatible feature flags wrong pool set UUID wrong part UUID wrong part UUID wrong replica UUID pmdk-1.11.1/src/test/util_poolset/grep6w.log.match0000664000000000000000000000137214123364546020541 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set cannot mix directories and files in a set pmdk-1.11.1/src/test/util_poolset/TEST100000775000000000000000000000605014123364546016375 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST10 -- unit test for util_pool_open() # # Copy of TEST2 for ppc64le # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem require_ppc64 setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB # prepare pool sets create_poolset $DIR/testset1 $MIN_POOL:$DIR/testfile11:x $MIN_POOL:$DIR/testfile12:x create_poolset $DIR/testset2 $MIN_POOL:$DIR/testfile21:x $MIN_POOL:$DIR/testfile22:x create_poolset $DIR/testset3 $MIN_POOL:$DIR/testfile31:x $MIN_POOL:$DIR/testfile32:x create_poolset $DIR/testset4 $MIN_POOL:$DIR/testfile41:x $MIN_POOL:$DIR/testfile42:x create_poolset $DIR/testset5 $MIN_POOL:$DIR/testfile51:x $MIN_POOL:$DIR/testfile52:x create_poolset $DIR/testset6 $MIN_POOL:$DIR/testfile61:x $MIN_POOL:$DIR/testfile62:x create_poolset $DIR/testset7 $MIN_POOL:$DIR/testfile71:x $MIN_POOL:$DIR/testfile72:x create_poolset $DIR/testset8 $MIN_POOL:$DIR/testfile81:x $MIN_POOL:$DIR/testfile82:x create_poolset $DIR/testset9 $MIN_POOL:$DIR/testfile91:x $MIN_POOL:$DIR/testfile92:x create_poolset $DIR/testset10 $MIN_POOL:$DIR/testfile101:x $MIN_POOL:$DIR/testfile102:x create_poolset $DIR/testset11 $MIN_POOL:$DIR/testfile111:x $MIN_POOL:$DIR/testfile112:x create_poolset $DIR/testset12 $MIN_POOL:$DIR/testfile121:x $MIN_POOL:$DIR/testfile122:x # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL \ $DIR/testset1 $DIR/testset2\ $DIR/testset3 $DIR/testset4\ $DIR/testset5 $DIR/testset6\ $DIR/testset7 $DIR/testset8\ $DIR/testset9 $DIR/testset10\ $DIR/testset11 $DIR/testset12 # inject some errors $PMEMSPOIL $DIR/testfile22 pool_hdr.checksum=0 $PMEMSPOIL $DIR/testfile32 pool_hdr.signature="ERROR" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile42 pool_hdr.major=99 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile52 pool_hdr.arch_flags="0000000000000000" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile62 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile72 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile82 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile91 pool_hdr.poolset_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile101 pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile111 pool_hdr.prev_part_uuid="0123456789012345" \ pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile121 pool_hdr.next_repl_uuid="0123456789012345" "pool_hdr.f:checksum_gen" # now check if pool sets may be opened expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL $MIN_PART\ $DIR/testset1 $DIR/testset2\ $DIR/testset3 $DIR/testset4\ $DIR/testset5 $DIR/testset6\ $DIR/testset7 $DIR/testset8\ $DIR/testset9 $DIR/testset10\ $DIR/testset11 $DIR/testset12 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/TEST20000775000000000000000000000601114123364546016313 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_poolset/TEST2 -- unit test for util_pool_open() # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem exclude_ppc64 setup export TEST_LOG_LEVEL=4 export TEST_LOG_FILE=./test$UNITTEST_NUM.log MIN_POOL=$((4 * 1024 * 1024)) # 4MiB # prepare pool sets create_poolset $DIR/testset1 $MIN_POOL:$DIR/testfile11:x $MIN_POOL:$DIR/testfile12:x create_poolset $DIR/testset2 $MIN_POOL:$DIR/testfile21:x $MIN_POOL:$DIR/testfile22:x create_poolset $DIR/testset3 $MIN_POOL:$DIR/testfile31:x $MIN_POOL:$DIR/testfile32:x create_poolset $DIR/testset4 $MIN_POOL:$DIR/testfile41:x $MIN_POOL:$DIR/testfile42:x create_poolset $DIR/testset5 $MIN_POOL:$DIR/testfile51:x $MIN_POOL:$DIR/testfile52:x create_poolset $DIR/testset6 $MIN_POOL:$DIR/testfile61:x $MIN_POOL:$DIR/testfile62:x create_poolset $DIR/testset7 $MIN_POOL:$DIR/testfile71:x $MIN_POOL:$DIR/testfile72:x create_poolset $DIR/testset8 $MIN_POOL:$DIR/testfile81:x $MIN_POOL:$DIR/testfile82:x create_poolset $DIR/testset9 $MIN_POOL:$DIR/testfile91:x $MIN_POOL:$DIR/testfile92:x create_poolset $DIR/testset10 $MIN_POOL:$DIR/testfile101:x $MIN_POOL:$DIR/testfile102:x create_poolset $DIR/testset11 $MIN_POOL:$DIR/testfile111:x $MIN_POOL:$DIR/testfile112:x create_poolset $DIR/testset12 $MIN_POOL:$DIR/testfile121:x $MIN_POOL:$DIR/testfile122:x # create pool sets expect_normal_exit ./util_poolset$EXESUFFIX c $MIN_POOL \ $DIR/testset1 $DIR/testset2\ $DIR/testset3 $DIR/testset4\ $DIR/testset5 $DIR/testset6\ $DIR/testset7 $DIR/testset8\ $DIR/testset9 $DIR/testset10\ $DIR/testset11 $DIR/testset12 # inject some errors $PMEMSPOIL $DIR/testfile22 pool_hdr.checksum=0 $PMEMSPOIL $DIR/testfile32 pool_hdr.signature="ERROR" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile42 pool_hdr.major=99 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile52 pool_hdr.arch_flags="0000000000000000" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile62 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile72 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile82 pool_hdr.features.compat=0x12345678 "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile91 pool_hdr.poolset_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile101 pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile111 pool_hdr.prev_part_uuid="0123456789012345" \ pool_hdr.next_part_uuid="0123456789012345" "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile121 pool_hdr.next_repl_uuid="0123456789012345" "pool_hdr.f:checksum_gen" # now check if pool sets may be opened expect_normal_exit ./util_poolset$EXESUFFIX o $MIN_POOL $MIN_PART\ $DIR/testset1 $DIR/testset2\ $DIR/testset3 $DIR/testset4\ $DIR/testset5 $DIR/testset6\ $DIR/testset7 $DIR/testset8\ $DIR/testset9 $DIR/testset10\ $DIR/testset11 $DIR/testset12 $GREP "<1>" $TEST_LOG_FILE | sed -e "s/^.*\][ ]*//g" > ./grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_poolset/out5.log.match0000664000000000000000000000447014123364546020225 0ustar rootrootutil_poolset$(nW)TEST5: START: util_poolset $(nW)util_poolset$(nW) o 134217728 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset9 $(nW)testset1: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir11$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir11$(nW)000001.pmem filesize $(nW) size $(nW) $(nW)testset2: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir21$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir22$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir21$(nW)000002.pmem filesize $(nW) size $(nW) $(nW)testset3: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir31$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir31$(nW)000001.pmem filesize $(nW) size $(nW) replica[1]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir32$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir32$(nW)000001.pmem filesize $(nW) size $(nW) $(nW)testset4: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir41$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir42$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir41$(nW)000002.pmem filesize $(nW) size $(nW) replica[1]: nparts 3 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir43$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir44$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir43$(nW)000002.pmem filesize $(nW) size $(nW) $(nW)testset9: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir91$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir91$(nW)000001.pmem filesize $(nW) size $(nW) replica[1]: nparts 2 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir91$(nW)testdir92$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir91$(nW)testdir92$(nW)000001.pmem filesize $(nW) size $(nW) util_poolset$(nW)TEST5: DONE pmdk-1.11.1/src/test/util_poolset/grep2w.log.match0000664000000000000000000000100514123364546020526 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) $(OPT)compiled with support for shutdown state invalid checksum of pool header wrong pool type: "ERRORXX" pool version 99 (library expects 1) invalid reserved values invalid machine value invalid data value invalid machine_class value invalid alignment_desc value wrong architecture flags incompatible feature flags incompatible feature flags incompatible feature flags wrong pool set UUID wrong part UUID wrong part UUID wrong replica UUID pmdk-1.11.1/src/test/util_poolset/mocks_posix.c0000664000000000000000000000227414123364546020235 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * mocks_posix.c -- mocked functions used in util_poolset.c (Posix version) */ #include "unittest.h" extern const char *Open_path; extern os_off_t Fallocate_len; extern size_t Is_pmem_len; /* * open -- open mock */ FUNC_MOCK(open, int, const char *path, int flags, ...) FUNC_MOCK_RUN_DEFAULT { if (strcmp(Open_path, path) == 0) { UT_OUT("mocked open: %s", path); errno = EACCES; return -1; } va_list ap; va_start(ap, flags); int mode = va_arg(ap, int); va_end(ap); return _FUNC_REAL(open)(path, flags, mode); } FUNC_MOCK_END /* * posix_fallocate -- posix_fallocate mock */ FUNC_MOCK(posix_fallocate, int, int fd, os_off_t offset, off_t len) FUNC_MOCK_RUN_DEFAULT { if (Fallocate_len == len) { UT_OUT("mocked fallocate: %ju", len); return ENOSPC; } return _FUNC_REAL(posix_fallocate)(fd, offset, len); } FUNC_MOCK_END /* * pmem_is_pmem -- pmem_is_pmem mock */ FUNC_MOCK(pmem_is_pmem, int, const void *addr, size_t len) FUNC_MOCK_RUN_DEFAULT { if (Is_pmem_len == len) { UT_OUT("mocked pmem_is_pmem: %zu", len); return 1; } return _FUNC_REAL(pmem_is_pmem)(addr, len); } FUNC_MOCK_END pmdk-1.11.1/src/test/util_poolset/out4.log.match0000664000000000000000000000472314123364546020225 0ustar rootrootutil_poolset$(nW)TEST4: START: util_poolset $(nW)util_poolset$(nW) o 134217728 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset1: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir11$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir11$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir11$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir11$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset2: opened: nreps 1 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir21$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir22$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir21$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir22$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset3: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir31$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir31$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir31$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir31$(nW)000003.pmem filesize $(nW) size $(nW) replica[1]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir32$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir32$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir32$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir32$(nW)000003.pmem filesize $(nW) size $(nW) $(nW)testset4: opened: nreps 2 poolsize $(nW) rdonly 0 replica[0]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir41$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir42$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir41$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir42$(nW)000003.pmem filesize $(nW) size $(nW) replica[1]: nparts 4 nhdrs 1 repsize $(nW) is_pmem $(nW) part[0] path $(nW)testdir43$(nW)000000.pmem filesize $(nW) size $(nW) part[1] path $(nW)testdir44$(nW)000001.pmem filesize $(nW) size $(nW) part[2] path $(nW)testdir43$(nW)000002.pmem filesize $(nW) size $(nW) part[3] path $(nW)testdir44$(nW)000003.pmem filesize $(nW) size $(nW) util_poolset$(nW)TEST4: DONE pmdk-1.11.1/src/test/util_poolset/grep5w.log.match0000664000000000000000000000024014123364546020531 0ustar rootrootpid $(N): program: $(nW)util_poolset$(nW) ut version 1.0 src version: $(nW) pmdk-1.11.1/src/test/util_poolset/out8.log.match0000664000000000000000000000071514123364546020226 0ustar rootrootutil_poolset$(nW)TEST8: START: util_poolset ./util_poolset$(nW) o 134217728 $(nW)testset1 $(nW)testset2 $(nW)testset3 $(nW)testset4 $(nW)testset9 $(nW)testset1: util_pool_open: No such file or directory $(nW)testset2: util_pool_open: No such file or directory $(nW)testset3: util_pool_open: No such file or directory $(nW)testset4: util_pool_open: No such file or directory $(nW)testset9: util_pool_open: No such file or directory util_poolset$(nW)TEST8: DONE pmdk-1.11.1/src/test/util_poolset/out2.log.match0000664000000000000000000000205014123364546020212 0ustar rootrootutil_poolset/TEST2: START: util_poolset ./util_poolset$(nW) o 4194304 $(nW)/testset1 $(nW)/testset2 $(nW)/testset3 $(nW)/testset4 $(nW)/testset5 $(nW)/testset6 $(nW)/testset7 $(nW)/testset8 $(nW)/testset9 $(nW)/testset10 $(nW)/testset11 $(nW)/testset12 $(nW)/testset1: opened: nreps 1 poolsize 8384512 rdonly 0 replica[0]: nparts 2 nhdrs 2 repsize 8384512 is_pmem 0 part[0] path $(nW)/testfile11 filesize 4194304 size 4194304 part[1] path $(nW)/testfile12 filesize 4194304 size 4190208 $(nW)/testset2: util_pool_open: Invalid argument $(nW)/testset3: util_pool_open: Invalid argument $(nW)/testset4: util_pool_open: Invalid argument $(nW)/testset5: util_pool_open: Invalid argument $(nW)/testset6: util_pool_open: Invalid argument $(nW)/testset7: util_pool_open: Invalid argument $(nW)/testset8: util_pool_open: Invalid argument $(nW)/testset9: util_pool_open: Invalid argument $(nW)/testset10: util_pool_open: Invalid argument $(nW)/testset11: util_pool_open: Invalid argument $(nW)/testset12: util_pool_open: Invalid argument util_poolset/TEST2: DONE pmdk-1.11.1/src/test/util_poolset/grep7.log.ignore0000664000000000000000000000004314123364546020534 0ustar rootrootcompiled with support for Valgrind pmdk-1.11.1/src/test/util_poolset/util_poolset.vcxproj0000664000000000000000000001450214123364546021667 0ustar rootroot Debug x64 Release x64 {6F06A19B-0921-4B71-A3A5-B350B5FFEADB} Win32Proj util_poolset 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) {ce3f2dfb-8470-4802-ad37-21caf6cb2681} WRAP_REAL_PMEM;%(PreprocessorDefinitions) WRAP_REAL_PMEM;%(PreprocessorDefinitions) _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL_OPEN;WRAP_REAL_PMEM;WRAP_REAL_FALLOCATE NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL_OPEN;WRAP_REAL_PMEM;WRAP_REAL_FALLOCATE WRAP_REAL_PMEM;%(PreprocessorDefinitions) WRAP_REAL_PMEM;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/obj_fragmentation/0000775000000000000000000000000014123364546016474 5ustar rootrootpmdk-1.11.1/src/test/obj_fragmentation/obj_fragmentation.vcxproj0000664000000000000000000000674514123364546023615 0ustar rootroot Debug x64 Release x64 {60EF55C7-8399-4543-B5B2-3AE2C532C67E} Win32Proj obj_fragmentation 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_fragmentation/TEST1.PS10000664000000000000000000000054214123364546017662 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_fragmentation/TEST1 -- unit test measures average # heap fragmentation. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit ` $Env:EXE_DIR\obj_fragmentation$Env:EXESUFFIX 4096 ` $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_fragmentation/obj_fragmentation.vcxproj.filters0000664000000000000000000000164014123364546025251 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Test Files Test Files Test Files pmdk-1.11.1/src/test/obj_fragmentation/obj_fragmentation.c0000664000000000000000000000310714123364546022331 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * obj_fragmentation.c -- measures average heap fragmentation * * A pretty simplistic test that measures internal fragmentation of the * allocator for the given size. */ #include #include "unittest.h" #define LAYOUT_NAME "obj_fragmentation" #define OBJECT_OVERHEAD 64 /* account for the header added to each object */ #define MAX_OVERALL_OVERHEAD 0.10f /* * For the best accuracy fragmentation should be measured for one full zone * because the metadata is preallocated. For reasonable test duration a smaller * size must be used. */ #define DEFAULT_FILE_SIZE ((size_t)(1ULL << 28)) /* 256 megabytes */ int main(int argc, char *argv[]) { START(argc, argv, "obj_fragmentation"); if (argc < 3) UT_FATAL("usage: %s allocsize filename [filesize]", argv[0]); size_t file_size; if (argc == 4) file_size = ATOUL(argv[3]); else file_size = DEFAULT_FILE_SIZE; size_t alloc_size = ATOUL(argv[1]); const char *path = argv[2]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, file_size, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create: %s", path); size_t allocated = 0; int err = 0; do { PMEMoid oid; err = pmemobj_alloc(pop, &oid, alloc_size, 0, NULL, NULL); if (err == 0) allocated += pmemobj_alloc_usable_size(oid) + OBJECT_OVERHEAD; } while (err == 0); float allocated_pct = ((float)allocated / file_size); float overhead_pct = 1.f - allocated_pct; UT_ASSERT(overhead_pct <= MAX_OVERALL_OVERHEAD); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_fragmentation/TEST00000775000000000000000000000040714123364546017262 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_fs_type pmem setup expect_normal_exit ./obj_fragmentation$EXESUFFIX 1024 \ $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_fragmentation/Makefile0000664000000000000000000000037114123364546020135 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_fragmentation/Makefile -- build obj_fragmentation test # TARGET = obj_fragmentation OBJS = obj_fragmentation.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_fragmentation/TEST2.PS10000664000000000000000000000054214123364546017663 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_fragmentation/TEST2 -- unit test measures average # heap fragmentation. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit ` $Env:EXE_DIR\obj_fragmentation$Env:EXESUFFIX 7654 ` $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_fragmentation/TEST0.PS10000664000000000000000000000053714123364546017665 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_fragmentation/TEST0 -- unit test measures average # heap fragmentation. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit $Env:EXE_DIR\obj_fragmentation$Env:EXESUFFIX 1024 ` $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_fragmentation/.gitignore0000664000000000000000000000002214123364546020456 0ustar rootrootobj_fragmentation pmdk-1.11.1/src/test/obj_fragmentation/TEST10000775000000000000000000000041114123364546017256 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_fs_type pmem setup expect_normal_exit\ ./obj_fragmentation$EXESUFFIX 4096 \ $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_fragmentation/TEST20000775000000000000000000000041114123364546017257 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_fs_type pmem setup expect_normal_exit\ ./obj_fragmentation$EXESUFFIX 7654 \ $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_out_of_memory/0000775000000000000000000000000014123364546016521 5ustar rootrootpmdk-1.11.1/src/test/obj_out_of_memory/TEST1.PS10000664000000000000000000000401514123364546017706 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ..\unittest\unittest.ps1 require_test_type medium setup $Env:PMEM_IS_PMEM_FORCE=1 $Env:PMEMOBJ_LOG_LEVEL=1 create_poolset $DIR\testset1 8M:$DIR\testfile1 R 8M:$DIR\testfile2 expect_normal_exit ` $Env:EXE_DIR\obj_out_of_memory$Env:EXESUFFIX 1024 $DIR\testset1 compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_out_of_memory/obj_out_of_memory.vcxproj0000664000000000000000000000725414123364546023663 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {70EE1D40-0C65-4985-8EFC-BD40EE3A89B2} Win32Proj obj_out_of_memory 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/obj_out_of_memory/TEST00000775000000000000000000000415014123364546017306 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 create_holey_file 8M $DIR/testfile1 create_holey_file 16M $DIR/testfile2 create_poolset $DIR/testset1 8M:$DIR/testfile11:x create_poolset $DIR/testset2 8M:$DIR/testfile21:x 8M:$DIR/testfile22:x expect_normal_exit\ ./obj_out_of_memory$EXESUFFIX 1024 \ $DIR/testfile1 \ $DIR/testfile2 \ $DIR/testset1 \ $DIR/testset2 check pass pmdk-1.11.1/src/test/obj_out_of_memory/obj_out_of_memory.c0000664000000000000000000000333314123364546022404 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * obj_out_of_memory.c -- allocate objects until OOM */ #include #include "unittest.h" #define LAYOUT_NAME "out_of_memory" struct cargs { size_t size; }; static int test_constructor(PMEMobjpool *pop, void *addr, void *args) { struct cargs *a = args; pmemobj_memset_persist(pop, addr, rand() % 256, a->size / 2); return 0; } static void test_alloc(PMEMobjpool *pop, size_t size) { unsigned long cnt = 0; while (1) { struct cargs args = { size }; if (pmemobj_alloc(pop, NULL, size, 0, test_constructor, &args) != 0) break; cnt++; } UT_OUT("size: %zu allocs: %lu", size, cnt); } static void test_free(PMEMobjpool *pop) { PMEMoid oid; PMEMoid next; POBJ_FOREACH_SAFE(pop, oid, next) pmemobj_free(&oid); } int main(int argc, char *argv[]) { START(argc, argv, "obj_out_of_memory"); if (argc < 3) UT_FATAL("usage: %s size filename ...", argv[0]); size_t size = ATOUL(argv[1]); for (int i = 2; i < argc; i++) { const char *path = argv[i]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create: %s", path); test_alloc(pop, size); pmemobj_close(pop); UT_ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1); /* * To prevent subsequent opens from receiving exactly the same * volatile memory addresses a dummy malloc has to be made. * This can expose issues in which traces of previous volatile * state are leftover in the persistent pool. */ void *heap_touch = MALLOC(1); UT_ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL); test_free(pop); pmemobj_close(pop); FREE(heap_touch); } DONE(NULL); } pmdk-1.11.1/src/test/obj_out_of_memory/Makefile0000664000000000000000000000037114123364546020162 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_out_of_memory/Makefile -- build obj_out_of_memory test # TARGET = obj_out_of_memory OBJS = obj_out_of_memory.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_out_of_memory/TEST2.PS10000664000000000000000000000374514123364546017720 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ..\unittest\unittest.ps1 # this is the long version of the test require_test_type long setup $Env:PMEM_IS_PMEM_FORCE=1 $Env:PMEMOBJ_LOG_LEVEL=1 create_poolset $DIR\testset1 2G:$DIR\testfile1 # allocate 32 kilobyte blocks so that runs are used expect_normal_exit ` $Env:EXE_DIR\obj_out_of_memory$Env:EXESUFFIX 32768 $DIR\testset1 pass pmdk-1.11.1/src/test/obj_out_of_memory/out0.log.match0000664000000000000000000000042614123364546021210 0ustar rootrootobj_out_of_memory$(nW)TEST0: START: obj_out_of_memory $(nW)obj_out_of_memory$(nW) 1024 $(nW)testfile1 $(nW)testfile2 $(nW)testset1 $(nW)testset2 size: 1024 allocs: 4080 size: 1024 allocs: 11760 size: 1024 allocs: 4080 size: 1024 allocs: 11760 obj_out_of_memory$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_out_of_memory/TEST0.PS10000664000000000000000000000413214123364546017705 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ..\unittest\unittest.ps1 require_test_type medium setup $Env:PMEM_IS_PMEM_FORCE=1 $Env:PMEMOBJ_LOG_LEVEL=1 create_holey_file 8M $DIR\testfile1 create_holey_file 16M $DIR\testfile2 create_poolset $DIR\testset1 8M:$DIR\testfile11:x create_poolset $DIR\testset2 8M:$DIR\testfile21:x 8M:$DIR\testfile22:x expect_normal_exit ` $Env:EXE_DIR\obj_out_of_memory$Env:EXESUFFIX 1024 ` $DIR\testfile1 ` $DIR\testfile2 ` $DIR\testset1 ` $DIR\testset2 pass pmdk-1.11.1/src/test/obj_out_of_memory/.gitignore0000664000000000000000000000002214123364546020503 0ustar rootrootobj_out_of_memory pmdk-1.11.1/src/test/obj_out_of_memory/TEST10000775000000000000000000000072414123364546017312 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 create_poolset $DIR/testset1 8M:$DIR/testfile1 R 8M:$DIR/testfile2 expect_normal_exit\ ./obj_out_of_memory$EXESUFFIX 1024 $DIR/testset1 compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_out_of_memory/obj_out_of_memory.vcxproj.filters0000664000000000000000000000302414123364546025321 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93e0c482-c24a-4989-9d88-88c977830384} match {c01d120f-0cb1-4d38-8eab-0fb965a987e4} ps1 Source Files Test Scripts Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_out_of_memory/diff1.log.match0000664000000000000000000000000014123364546021276 0ustar rootrootpmdk-1.11.1/src/test/obj_out_of_memory/out1.log.match0000664000000000000000000000024014123364546021203 0ustar rootrootobj_out_of_memory$(nW)TEST1: START: obj_out_of_memory $(nW)obj_out_of_memory$(nW) 1024 $(nW)testset1 size: 1024 allocs: 4080 obj_out_of_memory$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_out_of_memory/TEST20000775000000000000000000000061114123364546017306 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type long setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 create_poolset $DIR/testset1 2G:$DIR/testfile1 # allocate 32 kilobyte blocks so that runs are used expect_normal_exit\ ./obj_out_of_memory$EXESUFFIX 32768 $DIR/testset1 pass pmdk-1.11.1/src/test/traces/0000775000000000000000000000000014123364546014265 5ustar rootrootpmdk-1.11.1/src/test/traces/traces.vcxproj.filters0000664000000000000000000000400314123364546020627 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {dac6c718-f0f8-43a0-ba38-bd72ab98e456} ps1 {822d02f2-ed7a-4f61-9773-b579384486f5} match Source Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/traces/TEST1.PS10000664000000000000000000000434214123364546015455 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST1 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = "0" # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/TEST5.PS10000664000000000000000000000434114123364546015460 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST5 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = "4" # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/traces.vcxproj0000664000000000000000000000741114123364546017166 0ustar rootroot Debug x64 Release x64 {CA4BBB24-D33E-42E2-A495-F10D80DE8C1D} Win32Proj traces 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/traces/redir_stderr3.log.match0000664000000000000000000000057614123364546020646 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*)Log level NONE $(*)Log level ERROR $(*)Log level WARNING pmdk-1.11.1/src/test/traces/custom_file0.log.match0000664000000000000000000000065714123364546020464 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*) $(*)Log level NONE $(*)Log level ERROR $(*)Log level WARNING $(*)Log level INFO $(*)Log level DEBUG $(*) pmdk-1.11.1/src/test/traces/TEST30000775000000000000000000000055714123364546015064 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST3 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=2 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/TEST00000775000000000000000000000111214123364546015045 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST0 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup shopt -u failglob rm -f ./custom_file.log-* shopt -s failglob export UT_LOG_LEVEL=4 export UT_LOG_FILE=./custom_file.log- expect_normal_exit ./traces$EXESUFFIX # check results [ -s ./custom_file.log-* ] || { fatal "error: ./custom_file.log-PID not found" } mv ./custom_file.log-* custom_file$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/redir_stderr4.log.match0000664000000000000000000000063314123364546020641 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*) $(*)Log level NONE $(*)Log level ERROR $(*)Log level WARNING $(*)Log level INFO $(*) pmdk-1.11.1/src/test/traces/Makefile0000664000000000000000000000042414123364546015725 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2016, Intel Corporation # # src/test/traces/Makefile -- build traces unit test # TARGET = traces OBJS = traces.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -DDEBUG pmdk-1.11.1/src/test/traces/redir_stderr6.log.match0000664000000000000000000000110514123364546020636 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*) : <0> [traces.c:$(*) main]$(W)Log level NONE : <1> [traces.c:$(*) main]$(W)Log level ERROR : <2> [traces.c:$(*) main]$(W)Log level WARNING : <3> [traces.c:$(*) main]$(W)Log level INFO : <4> [traces.c:$(*) main]$(W)Log level DEBUG $(*) pmdk-1.11.1/src/test/traces/TEST3.PS10000664000000000000000000000434114123364546015456 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST3 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = "2" # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/TEST2.PS10000664000000000000000000000433714123364546015462 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST2 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = 1 # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/TEST50000775000000000000000000000055714123364546015066 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST5 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=4 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/TEST6.PS10000664000000000000000000000434114123364546015461 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST6 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = "4" # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/TEST40000775000000000000000000000055714123364546015065 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST4 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=3 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/TEST0.PS10000664000000000000000000000420514123364546015452 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST0 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup rm -Force .\custom_file.log-* $Env:UT_LOG_LEVEL = "4" $Env:UT_LOG_FILE = ".\custom_file.log-" expect_normal_exit $Env:EXE_DIR\traces$Env:EXESUFFIX # check results if (-not (Test-Path .\custom_file.log-*)) { echo "error: .\custom_file.log-PID not found" exit 1 } mv -Force .\custom_file.log-* custom_file$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/.gitignore0000664000000000000000000000003114123364546016247 0ustar rootroottraces custom_file.log-* pmdk-1.11.1/src/test/traces/redir_stderr5.log.match0000664000000000000000000000065714123364546020650 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*) $(*)Log level NONE $(*)Log level ERROR $(*)Log level WARNING $(*)Log level INFO $(*)Log level DEBUG $(*) pmdk-1.11.1/src/test/traces/redir_stderr2.log.match0000664000000000000000000000055014123364546020635 0ustar rootroot$(*) $(*) $(*) $(OPT)$(*) compiled with support for Valgrind pmemcheck $(OPT)$(*) compiled with support for Valgrind helgrind $(OPT)$(*) compiled with support for Valgrind memcheck $(OPT)$(*) compiled with support for Valgrind drd $(OPT)$(*) compiled with support for shutdown state $(OPT)$(*) compiled with libndctl 63+ $(*)Log level NONE $(*)Log level ERROR pmdk-1.11.1/src/test/traces/TEST60000775000000000000000000000055714123364546015067 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST6 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=4 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/TEST10000775000000000000000000000055714123364546015062 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST1 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=0 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/traces/TEST4.PS10000664000000000000000000000434114123364546015457 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\traces\TEST4 -- unit test for traces # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:UT_LOG_LEVEL = "3" # NOTE: Any test that need to redirect stderr could follow the below syntax: # 1. primarily to avoid powershell converting the error strings to exception # objects # 2. as a side benefit this will leave the error file in ASCII, so you can # avoid a conversion from UNICODE to ASCII expect_normal_exit "cmd /c $Env:EXE_DIR\traces$Env:EXESUFFIX 2```>redir_stderr$Env:UNITTEST_NUM.log" check pass pmdk-1.11.1/src/test/traces/traces.c0000664000000000000000000000133014123364546015707 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * traces.c -- unit test for traces */ #define LOG_PREFIX "ut" #define LOG_LEVEL_VAR "UT_LOG_LEVEL" #define LOG_FILE_VAR "UT_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #include #include #include "pmemcommon.h" #include "unittest.h" int main(int argc, char *argv[]) { START(argc, argv, "traces"); /* Execute test */ common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); LOG(0, "Log level NONE"); LOG(1, "Log level ERROR"); LOG(2, "Log level WARNING"); LOG(3, "Log level INFO"); LOG(4, "Log level DEBUG"); /* Cleanup */ common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/traces/redir_stderr1.log.match0000664000000000000000000000002314123364546020627 0ustar rootroot$(*)Log level NONE pmdk-1.11.1/src/test/traces/TEST20000775000000000000000000000055714123364546015063 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/traces/TEST2 -- unit test for traces # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug setup export UT_LOG_LEVEL=1 expect_normal_exit ./traces$EXESUFFIX 2>redir_stderr$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/libpmempool_feature/0000775000000000000000000000000014123364546017036 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_feature/libpmempool_feature.vcxproj.filters0000664000000000000000000000245114123364546026156 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {0d34316a-f8ec-4b25-ae70-41c75318bc7f} {55ac52b5-5cc6-44e4-87b2-8d243a23ff71} Source Files Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files pmdk-1.11.1/src/test/libpmempool_feature/TEST2w.PS10000664000000000000000000000142414123364546020414 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # libpmempool_feature/TEST2 -- unit test for PMEMPOOL_FEAT_SHUTDOWN_STATE # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.ps1 expect_normal_exit $PMEMPOOL create obj $POOL # PMEMPOOL_FEAT_SHUTDOWN_STATE is enabled by default libpmempool_feature_query "SHUTDOWN_STATE" libpmempool_feature_disable "SHUTDOWN_STATE" # PMEMPOOL_FEAT_SHUTDOWN_STATE requires PMEMPOOL_FEAT_CHCKSUM_2K libpmempool_feature_disable "CKSUM_2K" $exit_func="expect_abnormal_exit" libpmempool_feature_enable "SHUTDOWN_STATE" # should fail $exit_func="expect_normal_exit" libpmempool_feature_enable "CKSUM_2K" libpmempool_feature_enable "SHUTDOWN_STATE" # should succeed check pass pmdk-1.11.1/src/test/libpmempool_feature/TEST1.PS10000664000000000000000000000146014123364546020224 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # libpmempool_feature/TEST1 -- unit test for PMEMPOOL_FEAT_CHCKSUM_2K # . ..\unittest\unittest.ps1 require_test_type medium # we are matching pmempool logs which are available only in debug version require_build_type debug require_fs_type any setup . .\common.ps1 expect_normal_exit $PMEMPOOL create obj $POOL # PMEMPOOL_FEAT_CHCKSUM_2K is enabled by default libpmempool_feature_query "CKSUM_2K" # disable PMEMPOOL_FEAT_SHUTDOWN_STATE prior to success $exit_func="expect_abnormal_exit" libpmempool_feature_disable "CKSUM_2K" # should fail $exit_func="expect_normal_exit" libpmempool_feature_disable "SHUTDOWN_STATE" libpmempool_feature_disable "CKSUM_2K" # should succeed libpmempool_feature_enable "CKSUM_2K" check pass pmdk-1.11.1/src/test/libpmempool_feature/TEST30000775000000000000000000000256714123364546017640 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # libpmempool_feature/TEST3 -- unit test for invalid features # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup . ./common.sh # test single file pool with invalid compat features expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL expect_normal_exit $PMEMSPOIL -v $POOL \ pool_hdr.features.compat=0xfe \ "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal CKSUM_2K # test multipart poolset with invalid incompat features in one of its part POOLSET=$DIR/testset POOL=$POOLSET TARGET_PART1=$DIR/testfile23 TARGET_PART2=$DIR/testfile11 PART_SIZE=$(convert_to_bytes 10M) create_poolset $POOLSET \ $PART_SIZE:$TARGET_PART2:x \ $PART_SIZE:$DIR/testfile12:x \ r \ $PART_SIZE:$DIR/testfile21:x \ $PART_SIZE:$DIR/testfile22:x \ $PART_SIZE:$TARGET_PART1:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOLSET expect_normal_exit $PMEMSPOIL -v $TARGET_PART1 \ pool_hdr.features.incompat=0xfe \ "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal CKSUM_2K # test invalid rocompat features in first of its part expect_normal_exit $PMEMSPOIL -v $TARGET_PART2 \ pool_hdr.features.ro_compat=0xfe \ "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal CKSUM_2K check pass pmdk-1.11.1/src/test/libpmempool_feature/grep3.log.match0000664000000000000000000000220414123364546021652 0ustar rootroot$(*)pool.obj: spoil: pool_hdr.features.compat=0xfe $(*)pool.obj: spoil: pool_hdr.f:checksum_gen : <1> [feature.c:$(N) features_check] invalid features detected: {compat 0xfe, incompat 0x0, ro_compat 0x0} : <1> [feature.c:$(N) poolset_open] invalid features - replica #0 part #0 $(*)testfile23: spoil: pool_hdr.features.incompat=0xfe $(*)testfile23: spoil: pool_hdr.f:checksum_gen $(OPT): <1> [feature.c:$(N) features_check] features mismatch detected: {compat 0x0, incompat 0xfe, ro_compat 0x0} != {compat 0x0, incompat 0x$(N), ro_compat 0x0} $(OPT): <1> [feature.c:$(N) features_check] features mismatch detected: {compat 0x1, incompat 0xfe, ro_compat 0x0} != {compat 0x1, incompat 0x$(N), ro_compat 0x0} : <1> [feature.c:$(N) poolset_open] invalid features - replica #1 part #2 $(*)testfile11: spoil: pool_hdr.features.ro_compat=0xfe $(*)testfile11: spoil: pool_hdr.f:checksum_gen : <1> [feature.c:$(N) features_check] invalid features detected: {compat 0x0, incompat 0x0, ro_compat 0xfe} : <1> [feature.c:$(N) poolset_open] invalid features - replica #0 part #0 pmdk-1.11.1/src/test/libpmempool_feature/TEST00000775000000000000000000000101514123364546017620 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # libpmempool_feature/TEST0 -- unit test for PMEMPOOL_FEAT_SINGLEHDR # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup . ./common.sh expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL exit_func=expect_abnormal_exit libpmempool_feature_enable SINGLEHDR no-query # UNSUPPORTED libpmempool_feature_disable SINGLEHDR no-query # UNSUPPORTED libpmempool_feature_query SINGLEHDR check pass pmdk-1.11.1/src/test/libpmempool_feature/Makefile0000664000000000000000000000042714123364546020501 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/libpmempool_feature/Makefile -- build libpmempool_feature unittest # TARGET = libpmempool_feature OBJS = libpmempool_feature.o LIBPMEMPOOL=y LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_feature/TEST3.PS10000664000000000000000000000266414123364546020235 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # libpmempool_feature/TEST3 -- unit test for invalid features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup . .\common.ps1 # test single file pool with invalid compat features expect_normal_exit $PMEMPOOL create obj $POOL expect_normal_exit $PMEMSPOIL -v $POOL ` pool_hdr.features.compat=0xfe ` "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal "CKSUM_2K" # test multipart poolset with invalid incompat features in one of its part $POOLSET="$DIR\testset" $POOL=$POOLSET $TARGET_PART1="$DIR\testfile23" $TARGET_PART2="$DIR\testfile11" $PART_SIZE = (convert_to_bytes "10M") $PART_SIZE_STR = ${PART_SIZE}.toString() + "B" #10MiB create_poolset $POOLSET ` ${PART_SIZE_STR}:${TARGET_PART2}:x ${PART_SIZE_STR}:$DIR\testfile12:x ` R ${PART_SIZE_STR}:$DIR\testfile21:x ${PART_SIZE_STR}:$DIR\testfile22:x ` ${PART_SIZE_STR}:${TARGET_PART1}:x expect_normal_exit $PMEMPOOL create obj $POOLSET expect_normal_exit $PMEMSPOIL -v $TARGET_PART1 ` pool_hdr.features.incompat=0xfe ` "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal "CKSUM_2K" # test invalid rocompat features in first of its part expect_normal_exit $PMEMSPOIL -v $TARGET_PART2 ` pool_hdr.features.ro_compat=0xfe ` "pool_hdr.f:checksum_gen" >> $LOG libpmempool_feature_query_abnormal "CKSUM_2K" check pass pmdk-1.11.1/src/test/libpmempool_feature/grep0.log.match0000664000000000000000000000037214123364546021653 0ustar rootroot$(OPT): <1> [feature.c:$(N) unsupported_feature] unsupported feature: SINGLEHDR $(OPT): <1> [feature.c:$(N) unsupported_feature] unsupported feature: SINGLEHDR query SINGLEHDR result is 0 pmempool info: SINGLEHDR is NOT set pmdk-1.11.1/src/test/libpmempool_feature/common.PS10000664000000000000000000000505214123364546020655 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/libpmempool_feature/common.ps1 -- common part of libpmempool_feature tests # $POOL = "$DIR\pool.obj" $OUT = "out${Env:UNITTEST_NUM}.log" $LOG = "grep${Env:UNITTEST_NUM}.log" remove_files $LOG $QUERY_PATTERN="query" $ERROR_PATTERN="<1> \[feature.c:.*\]" $exit_func="expect_normal_exit" # libpmempool_feature_query_abnormal -- query feature with expected # abnormal result # # usage: libpmempool_feature_query_abnormal function libpmempool_feature_query_abnormal($arg1) { # query feature expect_abnormal_exit $Env:EXE_DIR\libpmempool_feature$Env:EXESUFFIX $POOL q $arg1 cat $OUT | Select-String "$QUERY_PATTERN" | %{$_.Line} >> $LOG if ( Test-Path $Env:PMEMPOOL_LOG_FILE ) { cat $Env:PMEMPOOL_LOG_FILE | Select-String "$ERROR_PATTERN" | %{$_.Line} >> $LOG } } # libpmempool_feature_query -- query feature # # usage: libpmempool_feature_query function libpmempool_feature_query($arg1) { # query feature expect_normal_exit $Env:EXE_DIR\libpmempool_feature$Env:EXESUFFIX $POOL q $arg1 cat $OUT | Select-String "$QUERY_PATTERN" | %{$_.Line} >> $LOG # verify query by pmempool info $count=(expect_normal_exit $PMEMPOOL info $POOL | Select-String "$arg1").length if ( "$count" -eq "0" ){ echo "pmempool info: $arg1 is NOT set" >> $LOG }else{ echo "pmempool info: $arg1 is set" >> $LOG } # check if pool is still valid expect_normal_exit $PMEMPOOL check $POOL | out-null } # libpmempool_feature_enable -- enable feature # # usage: libpmempool_feature_enable [no-query] function libpmempool_feature_enable($arg1, $arg2) { & $exit_func $Env:EXE_DIR\libpmempool_feature$Env:EXESUFFIX $POOL e $arg1 2>&1 ` | Select-String "$arg1" | %{$_.Line} >> $LOG if ( "$exit_func" -eq "expect_abnormal_exit" ) { if ( Test-Path $Env:PMEMPOOL_LOG_FILE ) { cat $Env:PMEMPOOL_LOG_FILE | Select-String "$ERROR_PATTERN" | %{$_.Line} >> $LOG } } if ( "$arg2" -ne "no-query" ){ libpmempool_feature_query $arg1 } } # libpmempool_feature_disable -- disable feature # # usage: libpmempool_feature_disable [no-query] function libpmempool_feature_disable($arg1, $arg2) { & $exit_func $Env:EXE_DIR\libpmempool_feature$Env:EXESUFFIX $POOL d $arg1 2>&1 ` | Select-String "$arg1" | %{$_.Line} >> $LOG if ( "$exit_func" -eq "expect_abnormal_exit" ) { cat $Env:PMEMPOOL_LOG_FILE | Select-String "$ERROR_PATTERN" | %{$_.Line} >> $LOG } if ( "$arg2" -ne "no-query" ){ libpmempool_feature_query $arg1 } } pmdk-1.11.1/src/test/libpmempool_feature/libpmempool_feature.vcxproj0000664000000000000000000001065114123364546024510 0ustar rootroot Debug x64 Release x64 {6F776280-B383-4DCE-8F42-9670164D038D} Win32Proj libpmempool_feature 10.0.17134.0 Application true v140 Application false v140 true false $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) true $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {1baa1617-93ae-4196-8a1a-bd492fb18aef} {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {9186eac4-2f34-4f17-b940-6585d7869bcd} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_feature/TEST0.PS10000664000000000000000000000114614123364546020224 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # libpmempool_feature/TEST0 -- unit test for PMEMPOOL_FEAT_SINGLEHDR # . ..\unittest\unittest.ps1 require_test_type medium # we are matching pmempool logs which are available only in debug version require_build_type debug require_fs_type any setup . .\common.PS1 expect_normal_exit $PMEMPOOL create obj $POOL $exit_func="expect_abnormal_exit" libpmempool_feature_enable "SINGLEHDR" "no-query" # UNSUPPORTED libpmempool_feature_disable "SINGLEHDR" "no-query" # UNSUPPORTED libpmempool_feature_query "SINGLEHDR" check pass pmdk-1.11.1/src/test/libpmempool_feature/.gitignore0000664000000000000000000000002414123364546021022 0ustar rootrootlibpmempool_feature pmdk-1.11.1/src/test/libpmempool_feature/common.sh0000664000000000000000000000444414123364546020670 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/libpmempool_feature/common.sh -- common part of libpmempool_feature tests # POOL=$DIR/pool.obj OUT=out${UNITTEST_NUM}.log LOG=grep${UNITTEST_NUM}.log QUERY_PATTERN="query" ERROR_PATTERN="<1> \\[feature.c:.*\\]" exit_func=expect_normal_exit sds_enabled=$(is_ndctl_enabled ./libpmempool_feature$EXESUFFIX; echo $?) # libpmempool_feature_query_abnormal -- query feature with expected # abnormal result # # usage: libpmempool_feature_query_abnormal function libpmempool_feature_query_abnormal() { # query feature expect_abnormal_exit ./libpmempool_feature$EXESUFFIX $POOL q $1 if [ -f "$PMEMPOOL_LOG_FILE" ]; then cat $PMEMPOOL_LOG_FILE | grep "$ERROR_PATTERN" >> $LOG fi } # libpmempool_feature_query -- query feature # # usage: libpmempool_feature_query function libpmempool_feature_query() { # query feature expect_normal_exit ./libpmempool_feature$EXESUFFIX $POOL q $1 cat $OUT | grep "$QUERY_PATTERN" >> $LOG # verify query with pmempool info set +e count=$(expect_normal_exit $PMEMPOOL$EXESUFFIX info $POOL | grep -c "$1") set -e if [ "$count" = "0" ]; then echo "pmempool info: $1 is NOT set" >> $LOG else echo "pmempool info: $1 is set" >> $LOG fi # check if pool is still valid expect_normal_exit $PMEMPOOL$EXESUFFIX check $POOL >> /dev/null } # libpmempool_feature_enable -- enable feature # # usage: libpmempool_feature_enable [no-query] function libpmempool_feature_enable() { $exit_func ./libpmempool_feature$EXESUFFIX $POOL e $1 if [ "$exit_func" == "expect_abnormal_exit" ]; then if [ -f "$PMEMPOOL_LOG_FILE" ]; then cat $PMEMPOOL_LOG_FILE | grep "$ERROR_PATTERN" >> $LOG fi fi if [ "x$2" != "xno-query" ]; then libpmempool_feature_query $1 fi } # libpmempool_feature_disable -- disable feature # # usage: libpmempool_feature_disable [no-query] function libpmempool_feature_disable() { $exit_func ./libpmempool_feature$EXESUFFIX $POOL d $1 if [ "$exit_func" == "expect_abnormal_exit" ]; then if [ -f "$PMEMPOOL_LOG_FILE" ]; then cat $PMEMPOOL_LOG_FILE | grep "$ERROR_PATTERN" >> $LOG fi fi if [ "x$2" != "xno-query" ]; then libpmempool_feature_query $1 fi } pmdk-1.11.1/src/test/libpmempool_feature/TEST10000775000000000000000000000165614123364546017634 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # libpmempool_feature/TEST1 -- unit test for PMEMPOOL_FEAT_CHCKSUM_2K # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds ./libpmempool_feature$EXESUFFIX setup . ./common.sh require_usc_permission $DIR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL # PMEMPOOL_FEAT_CHCKSUM_2K is enabled by default libpmempool_feature_query CKSUM_2K # SHUTDOWN_STATE is disabled by default on Linux # enable it to interfere toggling CKSUM_2K libpmempool_feature_enable SHUTDOWN_STATE no-query # disable PMEMPOOL_FEAT_SHUTDOWN_STATE prior to success exit_func=expect_abnormal_exit libpmempool_feature_disable CKSUM_2K # should fail exit_func=expect_normal_exit libpmempool_feature_disable SHUTDOWN_STATE libpmempool_feature_disable CKSUM_2K # should succeed libpmempool_feature_enable CKSUM_2K check pass pmdk-1.11.1/src/test/libpmempool_feature/grep1.log.match0000664000000000000000000000065414123364546021657 0ustar rootrootquery CKSUM_2K result is 1 pmempool info: CKSUM_2K is set $(OPT): <1> [feature.c:$(N) require_other_feature_is] disable SHUTDOWN_STATE prior to disabling CKSUM_2K query CKSUM_2K result is 1 pmempool info: CKSUM_2K is set query SHUTDOWN_STATE result is 0 pmempool info: SHUTDOWN_STATE is NOT set query CKSUM_2K result is 0 pmempool info: CKSUM_2K is NOT set query CKSUM_2K result is 1 pmempool info: CKSUM_2K is set pmdk-1.11.1/src/test/libpmempool_feature/libpmempool_feature.c0000664000000000000000000000312614123364546023236 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * libpmempool_feature -- pmempool_feature_(enable|disable|query) test * */ #include #include #include #include "libpmempool.h" #include "pool_hdr.h" #include "unittest.h" #define EMPTY_FLAGS 0 /* * print_usage -- print usage of program */ static void print_usage(const char *name) { UT_OUT("usage: %s (e|d|q) ", name); UT_OUT("feature-name: SINGLEHDR, CKSUM_2K, SHUTDOWN_STATE"); } /* * str2pmempool_feature -- convert feature name to pmempool_feature enum */ static enum pmempool_feature str2pmempool_feature(const char *app, const char *str) { uint32_t fval = util_str2pmempool_feature(str); if (fval == UINT32_MAX) { print_usage(app); UT_FATAL("unknown feature: %s", str); } return (enum pmempool_feature)fval; } int main(int argc, char *argv[]) { START(argc, argv, "libpmempool_feature"); if (argc < 4) { print_usage(argv[0]); UT_FATAL("insufficient number of arguments: %d", argc - 1); } const char *path = argv[1]; char cmd = argv[2][0]; enum pmempool_feature feature = str2pmempool_feature(argv[0], argv[3]); int ret; switch (cmd) { case 'e': return pmempool_feature_enable(path, feature, EMPTY_FLAGS); case 'd': return pmempool_feature_disable(path, feature, EMPTY_FLAGS); case 'q': ret = pmempool_feature_query(path, feature, EMPTY_FLAGS); if (ret < 0) return 1; UT_OUT("query %s result is %d", argv[3], ret); return 0; default: print_usage(argv[0]); UT_FATAL("unknown command: %c", cmd); } DONE(NULL); } pmdk-1.11.1/src/test/libpmempool_feature/grep2.log.match0000664000000000000000000000070614123364546021656 0ustar rootrootquery SHUTDOWN_STATE result is 0 pmempool info: SHUTDOWN_STATE is NOT set query CKSUM_2K result is 0 pmempool info: CKSUM_2K is NOT set $(OPT): <1> [feature.c:$(N) require_other_feature_is] enable CKSUM_2K prior to enabling SHUTDOWN_STATE query SHUTDOWN_STATE result is 0 pmempool info: SHUTDOWN_STATE is NOT set query CKSUM_2K result is 1 pmempool info: CKSUM_2K is set query SHUTDOWN_STATE result is 1 pmempool info: SHUTDOWN_STATE is set pmdk-1.11.1/src/test/libpmempool_feature/TEST20000775000000000000000000000164614123364546017634 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # libpmempool_feature/TEST2 -- unit test for PMEMPOOL_FEAT_SHUTDOWN_STATE # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_sds ./libpmempool_feature$EXESUFFIX setup . ./common.sh require_usc_permission $DIR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL # SHUTDOWN_STATE is disabled on Linux if PMDK is compiled with old ndctl if [ $sds_enabled -eq 1 ]; then libpmempool_feature_query SHUTDOWN_STATE else libpmempool_feature_disable SHUTDOWN_STATE fi # PMEMPOOL_FEAT_SHUTDOWN_STATE requires PMEMPOOL_FEAT_CHCKSUM_2K libpmempool_feature_disable CKSUM_2K exit_func=expect_abnormal_exit libpmempool_feature_enable SHUTDOWN_STATE # should fail exit_func=expect_normal_exit libpmempool_feature_enable CKSUM_2K libpmempool_feature_enable SHUTDOWN_STATE # should succeed check pass pmdk-1.11.1/src/test/libpmempool_feature/grep2w.log.match0000664000000000000000000000101414123364546022036 0ustar rootrootquery SHUTDOWN_STATE result is 1 pmempool info: SHUTDOWN_STATE is set query SHUTDOWN_STATE result is 0 pmempool info: SHUTDOWN_STATE is NOT set query CKSUM_2K result is 0 pmempool info: CKSUM_2K is NOT set $(OPT): <1> [feature.c:$(N) require_other_feature_is] enable CKSUM_2K prior to enabling SHUTDOWN_STATE query SHUTDOWN_STATE result is 0 pmempool info: SHUTDOWN_STATE is NOT set query CKSUM_2K result is 1 pmempool info: CKSUM_2K is set query SHUTDOWN_STATE result is 1 pmempool info: SHUTDOWN_STATE is set pmdk-1.11.1/src/test/pmem2_deep_flush/0000775000000000000000000000000014123364546016222 5ustar rootrootpmdk-1.11.1/src/test/pmem2_deep_flush/pmem2_deep_flush.vcxproj.filters0000664000000000000000000000344714123364546024534 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {bfc2182c-11f1-4b3c-8a7c-5570f93e83b6} {475ae9b2-a2dd-4f13-83b9-df6c8eaf0c4d} Test Scripts Source Files Libpmem2 Libpmem2 Libpmem2 Libpmem2 Source Files Source Files Header Files pmdk-1.11.1/src/test/pmem2_deep_flush/pmem2_deep_flush.c0000664000000000000000000002146614123364546021615 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_deep_flush.c -- unit test for pmem_deep_flush() * * usage: pmem2_deep_flush file deep_persist_size offset * * pmem2_deep_flush depending on the mapping granularity is performed using one * of the following paths: * - page: NOP * - cache: pmem2_deep_flush_dax * - byte: pmem2_persist_cpu_cache + pmem2_deep_flush_dax * * Where pmem2_deep_flush_dax: * - pmem2_get_type_from_stat is used to determine a file type * - for regular files performs pmem2_flush_file_buffers_os OR * - for Device DAX: * - is looking for Device DAX region (pmem2_get_region_id) * - is constructing the region deep flush file paths * - opens deep_flush file (os_open) * - reads deep_flush file (read) * - performs a write to it (write) * * Where pmem2_persist_cpu_cache performs: * - flush (replaced by mock_flush) AND * - drain (replaced by mock_drain) * * Additionally, for the sake of this test, the following functions are * replaced: * - pmem2_get_type_from_stat (to control perceived file type) * - pmem2_flush_file_buffers_os (for counting calls) * - pmem2_get_region_id (to prevent reading sysfs in search for non * existing Device DAXes) * or mocked: * - os_open (to prevent opening non existing * /sys/bus/nd/devices/region[0-9]+/deep_flush files) * - write (for counting writes to non-existing * /sys/bus/nd/devices/region[0-9]+/deep_flush files) * * NOTE: In normal usage the persist function precedes any call to * pmem2_deep_flush. This test aims to validate the pmem2_deep_flush * function and so the persist function is omitted. */ #include "source.h" #ifndef _WIN32 #include #endif #include "mmap.h" #include "persist.h" #include "pmem2_arch.h" #include "pmem2_utils.h" #include "ut_pmem2_utils.h" #include "region_namespace.h" #include "unittest.h" static int n_file_buffs_flushes = 0; static int n_fences = 0; static int n_flushes = 0; static int n_writes = 0; static int n_reads = 0; static enum pmem2_file_type *ftype_value; static int read_invalid = 0; static int deep_flush_not_needed = 0; #ifndef _WIN32 #define MOCK_FD 999 #define MOCK_REG_ID 888 #define MOCK_BUS_DEVICE_PATH "/sys/bus/nd/devices/region888/deep_flush" #define MOCK_DEV_ID 777UL /* * pmem2_get_region_id -- redefine libpmem2 function */ int pmem2_get_region_id(const struct pmem2_source *src, unsigned *region_id) { *region_id = MOCK_REG_ID; return 0; } /* * os_open -- os_open mock */ FUNC_MOCK(os_open, int, const char *path, int flags, ...) FUNC_MOCK_RUN_DEFAULT { if (strcmp(path, MOCK_BUS_DEVICE_PATH) == 0) return MOCK_FD; va_list ap; va_start(ap, flags); int mode = va_arg(ap, int); va_end(ap); return _FUNC_REAL(os_open)(path, flags, mode); } FUNC_MOCK_END /* * write -- write mock */ FUNC_MOCK(write, int, int fd, const void *buffer, size_t count) FUNC_MOCK_RUN_DEFAULT { UT_ASSERTeq(*(char *)buffer, '1'); UT_ASSERTeq(count, 1); UT_ASSERTeq(fd, MOCK_FD); ++n_writes; return 1; } FUNC_MOCK_END /* * read -- read mock */ FUNC_MOCK(read, int, int fd, void *buffer, size_t nbytes) FUNC_MOCK_RUN_DEFAULT { UT_ASSERTeq(nbytes, 2); UT_ASSERTeq(fd, MOCK_FD); UT_OUT("mocked read, fd %d", fd); char pattern[2] = {'1', '\n'}; int ret = sizeof(pattern); if (deep_flush_not_needed) pattern[0] = '0'; if (read_invalid) { ret = 0; goto end; } memcpy(buffer, pattern, sizeof(pattern)); end: ++n_reads; return ret; } FUNC_MOCK_END #endif /* not _WIN32 */ /* * mock_flush -- count flush calls in the test */ static void mock_flush(const void *addr, size_t len) { ++n_flushes; } /* * mock_drain -- count drain calls in the test */ static void mock_drain(void) { ++n_fences; } /* * pmem2_arch_init -- attach flush and drain functions replacements */ void pmem2_arch_init(struct pmem2_arch_info *info) { info->flush = mock_flush; info->fence = mock_drain; } /* * pmem2_map_find -- redefine libpmem2 function, redefinition is needed * for a proper compilation of the test. NOTE: this function is not used * in the test. */ struct pmem2_map * pmem2_map_find(const void *addr, size_t len) { UT_ASSERT(0); return NULL; } /* * pmem2_flush_file_buffers_os -- redefine libpmem2 function */ int pmem2_flush_file_buffers_os(struct pmem2_map *map, const void *addr, size_t len, int autorestart) { ++n_file_buffs_flushes; return 0; } /* * map_init -- fill pmem2_map in minimal scope */ static void map_init(struct pmem2_map *map) { const size_t length = 8 * MEGABYTE; map->content_length = length; /* * The test needs to allocate more memory because some test cases * validate behavior with address beyond mapping. */ map->addr = MALLOC(2 * length); #ifndef _WIN32 map->source.type = PMEM2_SOURCE_FD; /* mocked device ID for device DAX */ map->source.value.st_rdev = MOCK_DEV_ID; #else map->source.type = PMEM2_SOURCE_HANDLE; #endif ftype_value = &map->source.value.ftype; } /* * counters_check_n_reset -- check numbers of uses of deep-flushing elements * and reset them */ static void counters_check_n_reset(int msynces, int flushes, int fences, int writes, int reads) { UT_ASSERTeq(n_file_buffs_flushes, msynces); UT_ASSERTeq(n_flushes, flushes); UT_ASSERTeq(n_fences, fences); UT_ASSERTeq(n_writes, writes); UT_ASSERTeq(n_reads, reads); n_file_buffs_flushes = 0; n_flushes = 0; n_fences = 0; n_writes = 0; n_reads = 0; read_invalid = 0; deep_flush_not_needed = 0; } /* * test_deep_flush_func -- test pmem2_deep_flush for all granularity options */ static int test_deep_flush_func(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map map; map_init(&map); *ftype_value = PMEM2_FTYPE_REG; void *addr = map.addr; size_t len = map.content_length; map.effective_granularity = PMEM2_GRANULARITY_PAGE; pmem2_set_flush_fns(&map); int ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 0, 0, 0, 0); map.effective_granularity = PMEM2_GRANULARITY_CACHE_LINE; pmem2_set_flush_fns(&map); ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(1, 0, 0, 0, 0); map.effective_granularity = PMEM2_GRANULARITY_BYTE; pmem2_set_flush_fns(&map); ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(1, 0, 0, 0, 0); FREE(map.addr); return 0; } /* * test_deep_flush_func_devdax -- test pmem2_deep_flush with mocked DAX devices */ static int test_deep_flush_func_devdax(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map map; map_init(&map); void *addr = map.addr; size_t len = map.content_length; *ftype_value = PMEM2_FTYPE_DEVDAX; map.effective_granularity = PMEM2_GRANULARITY_CACHE_LINE; pmem2_set_flush_fns(&map); int ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 1, 1); deep_flush_not_needed = 1; ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 0, 1); read_invalid = 1; ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 0, 1); map.effective_granularity = PMEM2_GRANULARITY_BYTE; pmem2_set_flush_fns(&map); ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 1, 1); deep_flush_not_needed = 1; ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 0, 1); read_invalid = 1; ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, 0); counters_check_n_reset(0, 1, 1, 0, 1); FREE(map.addr); return 0; } /* * test_deep_flush_range_beyond_mapping -- test pmem2_deep_flush with * the address that goes beyond mapping */ static int test_deep_flush_range_beyond_mapping(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map map; map_init(&map); /* set address completely beyond mapping */ void *addr = (void *)((uintptr_t)map.addr + map.content_length); size_t len = map.content_length; int ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_DEEP_FLUSH_RANGE); /* * set address in the middle of mapping, which makes range partially * beyond mapping */ addr = (void *)((uintptr_t)map.addr + map.content_length / 2); ret = pmem2_deep_flush(&map, addr, len); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_DEEP_FLUSH_RANGE); FREE(map.addr); return 0; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_deep_flush_func), TEST_CASE(test_deep_flush_func_devdax), TEST_CASE(test_deep_flush_range_beyond_mapping), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_deep_flush"); pmem2_persist_init(); util_init(); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_deep_flush/Makefile0000664000000000000000000000101114123364546017653 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_deep_flush/Makefile -- build pmem2_deep_flush test # TOP = ../../.. vpath %.c $(TOP)/src/libpmem2 vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_deep_flush LIBPMEMCORE=internal-debug OBJS += pmem2_deep_flush.o\ deep_flush.o\ deep_flush_linux.o\ memops_generic.o\ persist.o\ errormsg.o\ ut_pmem2_utils.o include ../Makefile.inc LDFLAGS += $(call extract_funcs, pmem2_deep_flush.c) pmdk-1.11.1/src/test/pmem2_deep_flush/TESTS.py0000775000000000000000000000130614123364546017501 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t from testframework import granularity as g @g.no_testdir() class PMEM2_DEEP_FLUSH(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem2_deep_flush', self.test_case) class TEST0(PMEM2_DEEP_FLUSH): """test pmem2_deep_flush""" test_case = "test_deep_flush_func" @t.linux_only class TEST1(PMEM2_DEEP_FLUSH): """test pmem2_deep_flush with mocked DAX devices""" test_case = "test_deep_flush_func_devdax" class TEST2(PMEM2_DEEP_FLUSH): """test pmem2_deep_flush with range beyond mapping""" test_case = "test_deep_flush_range_beyond_mapping" pmdk-1.11.1/src/test/pmem2_deep_flush/.gitignore0000664000000000000000000000002114123364546020203 0ustar rootrootpmem2_deep_flush pmdk-1.11.1/src/test/pmem2_deep_flush/pmem2_deep_flush.vcxproj0000664000000000000000000001027614123364546023063 0ustar rootroot Debug x64 Release x64 {F7508935-C65A-4521-88E3-76AB24F2978D} pmem2_deep_flush 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) true true {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmemspoil/0000775000000000000000000000000014123364546015011 5ustar rootrootpmdk-1.11.1/src/test/pmemspoil/pmemspoil.vcxproj.filters0000664000000000000000000000116014123364546022100 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Test Scripts pmdk-1.11.1/src/test/pmemspoil/TEST00000775000000000000000000000212714123364546015600 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # # pmemspoil/TEST0 -- test for pmemspoil # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem require_build_type nondebug setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG POOLSET=$DIR/pool.set POOL1=$DIR/pool.part1 POOL2=$DIR/pool.part2 POOL3=$DIR/pool.part3 REPL1=$DIR/pool.rep.part1 REPL2=$DIR/pool.rep.part2 REPL3=$DIR/pool.rep.part3 POOLS="$POOL1 $POOL2 $POOL3 $REPL1 $REPL2 $REPL3" rm -f $POOLS create_poolset $POOLSET 32M:$POOL1:z 32M:$POOL2:z 32M:$POOL3:z\ R 32M:$REPL1:z 32M:$REPL2:z 32M:$REPL3:z check_file $POOLSET rm -f $POOLS expect_normal_exit $PMEMPOOL create obj --layout pmempool $POOLSET expect_normal_exit $PMEMSPOIL $POOLSET --replica 0 "pmemobj.layout=replica0" expect_normal_exit $PMEMPOOL info --replica 0 $POOLSET -f obj\ | $GREP '^Layout.*' >> $LOG expect_normal_exit $PMEMSPOIL $POOLSET --replica 1 "pmemobj.layout=replica1" expect_normal_exit $PMEMPOOL info --replica 1 $POOLSET -f obj\ | $GREP '^Layout.*' >> $LOG check pass pmdk-1.11.1/src/test/pmemspoil/Makefile0000664000000000000000000000027214123364546016452 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # src/test/pmemspoil/Makefile -- build pmemspoil unittest # USE_PMEMSPOIL=y include ../Makefile.inc pmdk-1.11.1/src/test/pmemspoil/out0.log.match0000664000000000000000000000011014123364546017466 0ustar rootrootLayout : replica0 Layout : replica1 pmdk-1.11.1/src/test/pmemspoil/TEST0.PS10000664000000000000000000000224214123364546016175 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmemspoil/TEST0 -- test for pmemspoil # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup $LOG = "out${Env:UNITTEST_NUM}.log" rm $LOG -Force -ea si touch $LOG $POOLSET = "$DIR\pool.set" $POOL1 = "$DIR\pool.part1" $POOL2 = "$DIR\pool.part2" $POOL3 = "$DIR\pool.part3" $REPL1 = "$DIR\pool.rep.part1" $REPL2 = "$DIR\pool.rep.part2" $REPL3 = "$DIR\pool.rep.part3" $POOLS = "$POOL1 $POOL2 $POOL3 $REPL1 $REPL2 $REPL3" rm $POOLS -Force -ea si create_poolset $POOLSET 32M:${POOL1}:z 32M:${POOL2}:z 32M:${POOL3}:z ` R 32M:${REPL1}:z 32M:${REPL2}:z 32M:${REPL3}:z check_file $POOLSET rm $POOLS -Force -ea si expect_normal_exit $PMEMPOOL create obj --layout pmempool $POOLSET expect_normal_exit $PMEMSPOIL $POOLSET --replica 0 "pmemobj.layout=replica0" expect_normal_exit $PMEMPOOL info --replica 0 $POOLSET -f obj ` | sls '^Layout.*' | %{$_.Line} >> $LOG expect_normal_exit $PMEMSPOIL $POOLSET --replica 1 "pmemobj.layout=replica1" expect_normal_exit $PMEMPOOL info --replica 1 $POOLSET -f obj ` | sls '^Layout.*' | %{$_.Line} >> $LOG check pass pmdk-1.11.1/src/test/pmemspoil/pmemspoil.vcxproj0000664000000000000000000000725414123364546020443 0ustar rootroot Debug x64 Release x64 {B6F4B85D-FE55-4A1B-AE97-D4A9ECFE195F} pmemspoil 10.0.17134.0 tools_pmemspoil Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) {11e158ae-c85a-4a6e-b66a-ed2994709276} pmdk-1.11.1/src/test/remote_obj_basic/0000775000000000000000000000000014123364546016272 5ustar rootrootpmdk-1.11.1/src/test/remote_obj_basic/node_0_trace3.log.match0000664000000000000000000000042214123364546022473 0ustar rootroot{$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST3: START: remote_obj_basic ./remote_obj_basic$(nW) open $(nW)pool3.set {$(nW)remote_obj_basic.c:$(N) main} The pool set $(nW)pool3.set has been opened {$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST3: DONE pmdk-1.11.1/src/test/remote_obj_basic/node_0_out0.log.match0000664000000000000000000000025114123364546022201 0ustar rootrootremote_obj_basic/TEST0: START: remote_obj_basic ./remote_obj_basic$(nW) create $(nW)pool0.set The pool set $(nW)pool0.set has been created remote_obj_basic/TEST0: DONE pmdk-1.11.1/src/test/remote_obj_basic/TEST30000775000000000000000000000271014123364546017062 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_obj_basic/TEST3 -- unit test for remote tests support # # timeout value for this test in seconds TIMEOUT=5 . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a unique name for pool file POOL_FILE=${NODE_DIR[0]}/pool-remote_obj_basic-TEST$UNITTEST_NUM-$$-`$DATE +%s` # create poolset file POOLSET_FILE=pool$UNITTEST_NUM.set create_poolset $POOLSET_FILE 10M:$POOL_FILE:x # copy required files to remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $POOLSET_FILE # remove local poolset file rm -f $POOLSET_FILE # PID file name for remote test run in background PID_FILE="pid-file-$$.txt" # register the list of PID files to be cleaned in case of an error clean_remote_node 0 $PID_FILE # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node_background 0 $PID_FILE ./remote_obj_basic$EXESUFFIX create ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit wait_on_node 0 $PID_FILE $TIMEOUT expect_normal_exit run_on_node_background 0 $PID_FILE ./remote_obj_basic$EXESUFFIX open ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit wait_on_node 0 $PID_FILE $TIMEOUT expect_normal_exit run_on_node 0 rm -f $POOL_FILE check pass pmdk-1.11.1/src/test/remote_obj_basic/TEST00000775000000000000000000000176114123364546017064 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_obj_basic/TEST0 -- unit test for remote tests support # . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a unique name for pool file POOL_FILE=${NODE_DIR[0]}/pool-remote_obj_basic-TEST$UNITTEST_NUM-$$-`$DATE +%s` # create poolset file POOLSET_FILE=pool$UNITTEST_NUM.set create_poolset $POOLSET_FILE 10M:$POOL_FILE:x # copy required files to remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $POOLSET_FILE # remove local poolset file rm -f $POOLSET_FILE # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node 0 ./remote_obj_basic$EXESUFFIX create ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit run_on_node 0 rm -f $POOL_FILE check pass pmdk-1.11.1/src/test/remote_obj_basic/node_0_trace2.log.match0000664000000000000000000000042514123364546022475 0ustar rootroot{$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST2: START: remote_obj_basic ./remote_obj_basic$(nW) create $(nW)pool2.set {$(nW)remote_obj_basic.c:$(N) main} The pool set $(nW)pool2.set has been created {$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST2: DONE pmdk-1.11.1/src/test/remote_obj_basic/Makefile0000664000000000000000000000042314123364546017731 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_obj_basic/Makefile -- build remote_obj_basic unit test # SCP_TO_REMOTE_NODES = y TARGET = remote_obj_basic OBJS = remote_obj_basic.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/remote_obj_basic/node_0_out2.log.match0000664000000000000000000000025114123364546022203 0ustar rootrootremote_obj_basic/TEST2: START: remote_obj_basic ./remote_obj_basic$(nW) create $(nW)pool2.set The pool set $(nW)pool2.set has been created remote_obj_basic/TEST2: DONE pmdk-1.11.1/src/test/remote_obj_basic/node_0_trace0.log.match0000664000000000000000000000042514123364546022473 0ustar rootroot{$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST0: START: remote_obj_basic ./remote_obj_basic$(nW) create $(nW)pool0.set {$(nW)remote_obj_basic.c:$(N) main} The pool set $(nW)pool0.set has been created {$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST0: DONE pmdk-1.11.1/src/test/remote_obj_basic/node_0_out3.log.match0000664000000000000000000000024614123364546022210 0ustar rootrootremote_obj_basic/TEST3: START: remote_obj_basic ./remote_obj_basic$(nW) open $(nW)pool3.set The pool set $(nW)pool3.set has been opened remote_obj_basic/TEST3: DONE pmdk-1.11.1/src/test/remote_obj_basic/remote_obj_basic.c0000664000000000000000000000177314123364546021734 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * remote_obj_basic.c -- unit test for remote tests support * * usage: remote_obj_basic */ #include "unittest.h" #define LAYOUT_NAME "remote_obj_basic" int main(int argc, char *argv[]) { PMEMobjpool *pop; START(argc, argv, "remote_obj_basic"); if (argc != 3) UT_FATAL("usage: %s ", argv[0]); const char *mode = argv[1]; const char *file = argv[2]; if (strcmp(mode, "create") == 0) { if ((pop = pmemobj_create(file, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", file); else UT_OUT("The pool set %s has been created", file); } else if (strcmp(mode, "open") == 0) { if ((pop = pmemobj_open(file, LAYOUT_NAME)) == NULL) UT_FATAL("!pmemobj_open: %s", file); else UT_OUT("The pool set %s has been opened", file); } else { UT_FATAL("wrong mode: %s\n", argv[1]); } pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/remote_obj_basic/node_0_out1.log.match0000664000000000000000000000024614123364546022206 0ustar rootrootremote_obj_basic/TEST1: START: remote_obj_basic ./remote_obj_basic$(nW) open $(nW)pool1.set The pool set $(nW)pool1.set has been opened remote_obj_basic/TEST1: DONE pmdk-1.11.1/src/test/remote_obj_basic/.gitignore0000664000000000000000000000002114123364546020253 0ustar rootrootremote_obj_basic pmdk-1.11.1/src/test/remote_obj_basic/README0000664000000000000000000000163614123364546017160 0ustar rootrootPersistent Memory Development Kit This is src/test/remote_obj_basic/README. This directory contains a unit test for remote tests support. The program in remote_obj_basic.c takes a mode (create or open) and a name of a poolset file as arguments and creates or opens a PMEMOBJ pool set with the given name. The TEST0 unit test copies a pool set file from the local host to the remote node, removes all pool set part files using pmempool and creates the pool set using the run_on_node() function. The TEST1 unit test does exactly what TEST0 does and additionally it opens the created pool set using the run_on_node() function. The TEST2 unit test does what TEST0 does but it creates the pool set using the run_on_node_background() and wait_on_node() functions. The TEST3 unit test does exactly what TEST2 does and additionally it opens the created pool set using the run_on_node_background() and wait_on_node() functions. pmdk-1.11.1/src/test/remote_obj_basic/TEST10000775000000000000000000000212014123364546017053 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_obj_basic/TEST1 -- unit test for remote tests support # . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a unique name for pool file POOL_FILE=${NODE_DIR[0]}/pool-remote_obj_basic-TEST$UNITTEST_NUM-$$-`$DATE +%s` # create poolset file POOLSET_FILE=pool$UNITTEST_NUM.set create_poolset $POOLSET_FILE 10M:$POOL_FILE:x # copy required files to remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $POOLSET_FILE # remove local poolset file rm -f $POOLSET_FILE # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node 0 ./remote_obj_basic$EXESUFFIX create ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit run_on_node 0 ./remote_obj_basic$EXESUFFIX open ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit run_on_node 0 rm -f $POOL_FILE check pass pmdk-1.11.1/src/test/remote_obj_basic/node_0_trace1.log.match0000664000000000000000000000042214123364546022471 0ustar rootroot{$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST1: START: remote_obj_basic ./remote_obj_basic$(nW) open $(nW)pool1.set {$(nW)remote_obj_basic.c:$(N) main} The pool set $(nW)pool1.set has been opened {$(nW)remote_obj_basic.c:$(N) main} remote_obj_basic/TEST1: DONE pmdk-1.11.1/src/test/remote_obj_basic/TEST20000775000000000000000000000243714123364546017067 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_obj_basic/TEST2 -- unit test for remote tests support # # timeout value for this test in seconds TIMEOUT=5 . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a unique name for pool file POOL_FILE=${NODE_DIR[0]}/pool-remote_obj_basic-TEST$UNITTEST_NUM-$$-`$DATE +%s` # create poolset file POOLSET_FILE=pool$UNITTEST_NUM.set create_poolset $POOLSET_FILE 10M:$POOL_FILE:x # copy required files to remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $POOLSET_FILE # remove local poolset file rm -f $POOLSET_FILE # PID file name for remote test run in background PID_FILE="pid-file-$$.txt" # register the list of PID files to be cleaned in case of an error clean_remote_node 0 $PID_FILE # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node_background 0 $PID_FILE ./remote_obj_basic$EXESUFFIX create ${NODE_DIR[0]}$POOLSET_FILE expect_normal_exit wait_on_node 0 $PID_FILE $TIMEOUT expect_normal_exit run_on_node 0 rm -f $POOL_FILE check pass pmdk-1.11.1/src/test/pmem2_include/0000775000000000000000000000000014123364546015527 5ustar rootrootpmdk-1.11.1/src/test/pmem2_include/pmem2_include.vcxproj0000664000000000000000000000625614123364546021700 0ustar rootroot Debug x64 Release x64 {B6C0521B-EECA-47EF-BFA8-147F9C3F6DFF} pmem2_include 10.0.17134.0 Application true v140 Application false v140 Disabled MaxSpeed {f596c36c-5c96-4f08-b420-8908af500954} pmdk-1.11.1/src/test/pmem2_include/pmem2_include.c0000664000000000000000000000042114123364546020413 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * pmem2_include.c -- include test for libpmem2 * * this is only a compilation test - do not run this program */ #include int main(int argc, char *argv[]) { return 0; } pmdk-1.11.1/src/test/pmem2_include/Makefile0000664000000000000000000000034714123364546017173 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem2_include/Makefile -- compilation test for libpmem2 # TARGET = pmem2_include OBJS = pmem2_include.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_include/.gitignore0000664000000000000000000000001614123364546017514 0ustar rootrootpmem2_include pmdk-1.11.1/src/test/pmem2_include/pmem2_include.vcxproj.filters0000664000000000000000000000076314123364546023344 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files pmdk-1.11.1/src/test/obj_ctl_alignment/0000775000000000000000000000000014123364546016456 5ustar rootrootpmdk-1.11.1/src/test/obj_ctl_alignment/TEST00000775000000000000000000000037214123364546017245 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any setup expect_normal_exit ./obj_ctl_alignment$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/obj_ctl_alignment/Makefile0000664000000000000000000000037114123364546020117 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_ctl_alignment/Makefile -- build obj_ctl_alignment test # TARGET = obj_ctl_alignment OBJS = obj_ctl_alignment.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_ctl_alignment/TEST0.PS10000664000000000000000000000036614123364546017647 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ..\unittest\unittest.ps1 require_test_type short require_fs_type any setup expect_normal_exit $Env:EXE_DIR\obj_ctl_alignment$Env:EXESUFFIX $DIR\testfile pass pmdk-1.11.1/src/test/obj_ctl_alignment/obj_ctl_alignment.c0000664000000000000000000000400714123364546022275 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2020, Intel Corporation */ /* * obj_ctl_alignment.c -- tests for the alloc class alignment */ #include "unittest.h" #define LAYOUT "obj_ctl_alignment" static PMEMobjpool *pop; static void test_fail(void) { struct pobj_alloc_class_desc ac; ac.header_type = POBJ_HEADER_NONE; ac.unit_size = 1024 - 1; ac.units_per_block = 100; ac.alignment = 512; int ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &ac); UT_ASSERTeq(ret, -1); /* unit_size must be multiple of alignment */ } static void test_aligned_allocs(size_t size, size_t alignment, enum pobj_header_type htype) { struct pobj_alloc_class_desc ac; ac.header_type = htype; ac.unit_size = size; ac.units_per_block = 100; ac.alignment = alignment; int ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &ac); UT_ASSERTeq(ret, 0); PMEMoid oid; ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(ac.class_id), NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERTeq(oid.off % alignment, 0); UT_ASSERTeq((uintptr_t)pmemobj_direct(oid) % alignment, 0); ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(ac.class_id), NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERTeq(oid.off % alignment, 0); UT_ASSERTeq((uintptr_t)pmemobj_direct(oid) % alignment, 0); char query[1024]; SNPRINTF(query, 1024, "heap.alloc_class.%u.desc", ac.class_id); struct pobj_alloc_class_desc read_ac; ret = pmemobj_ctl_get(pop, query, &read_ac); UT_ASSERTeq(ret, 0); UT_ASSERTeq(ac.alignment, read_ac.alignment); } int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_alignment"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL * 10, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); test_fail(); test_aligned_allocs(1024, 512, POBJ_HEADER_NONE); test_aligned_allocs(1024, 512, POBJ_HEADER_COMPACT); test_aligned_allocs(64, 64, POBJ_HEADER_COMPACT); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_ctl_alignment/.gitignore0000664000000000000000000000002214123364546020440 0ustar rootrootobj_ctl_alignment pmdk-1.11.1/src/test/obj_ctl_alignment/obj_ctl_alignment.vcxproj0000664000000000000000000000664314123364546023556 0ustar rootroot Debug x64 Release x64 {6DBD8C02-0C75-4DB0-BFDA-CD053B1B2D89} Win32Proj obj_ctl_alignment 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_ctl_alignment/obj_ctl_alignment.vcxproj.filters0000664000000000000000000000140614123364546025215 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Test Files pmdk-1.11.1/src/test/obj_action/0000775000000000000000000000000014123364546015113 5ustar rootrootpmdk-1.11.1/src/test/obj_action/obj_action.vcxproj0000664000000000000000000001016314123364546020640 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {2ED26FDA-3C4E-4514-B387-5E77C302FF71} Win32Proj obj_action 10.0.17134.0 Application true v140 Application false v140 true NotUsing Disabled CompileAsCpp NotUsing MaxSpeed stdafx.h CompileAsCpp pmdk-1.11.1/src/test/obj_action/obj_action.vcxproj.filters0000664000000000000000000000144014123364546022305 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c01d120f-0cb1-4d38-8eab-0fb965a987e4} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/obj_action/TEST00000775000000000000000000000100614123364546015675 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_action/TEST0 -- unit test (short) for obj_action # . ../unittest/unittest.sh require_test_type short require_fs_type any # TEST1 runs valgrind memcheck configure_valgrind memcheck force-disable # TEST2 runs valgrind pmemcheck configure_valgrind pmemcheck force-disable setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 expect_normal_exit ./obj_action$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/obj_action/Makefile0000664000000000000000000000033514123364546016554 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_action/Makefile -- build obj_action test # TARGET = obj_action OBJS = obj_action.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_action/TEST0.PS10000664000000000000000000000042114123364546016274 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ..\unittest\unittest.ps1 require_test_type medium setup $Env:PMEM_IS_PMEM_FORCE=1 $Env:PMEMOBJ_LOG_LEVEL=1 expect_normal_exit $Env:EXE_DIR\obj_action$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_action/.gitignore0000664000000000000000000000001314123364546017075 0ustar rootrootobj_action pmdk-1.11.1/src/test/obj_action/obj_action.c0000664000000000000000000002054414123364546017373 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2019, Intel Corporation */ /* * obj_action.c -- test the action API */ #include #include "unittest.h" #define LAYOUT_NAME "obj_action" struct macro_reserve_s { PMEMoid oid; uint64_t value; }; TOID_DECLARE(struct macro_reserve_s, 1); struct foo { int bar; }; struct root { struct { PMEMoid oid; uint64_t value; } reserved; struct { PMEMoid oid; uint64_t value; } published; struct { PMEMoid oid; } tx_reserved; struct { PMEMoid oid; } tx_reserved_fulfilled; struct { PMEMoid oid; } tx_published; }; #define HUGE_ALLOC_SIZE ((1 << 20) * 3) #define MAX_ACTS 10 static void test_resv_cancel_huge(PMEMobjpool *pop) { PMEMoid oid; unsigned nallocs = 0; struct pobj_action *act = (struct pobj_action *) ZALLOC(sizeof(struct pobj_action) * MAX_ACTS); do { oid = pmemobj_reserve(pop, &act[nallocs++], HUGE_ALLOC_SIZE, 0); } while (!OID_IS_NULL(oid)); pmemobj_cancel(pop, act, nallocs - 1); unsigned nallocs2 = 0; do { oid = pmemobj_reserve(pop, &act[nallocs2++], HUGE_ALLOC_SIZE, 0); } while (!OID_IS_NULL(oid)); pmemobj_cancel(pop, act, nallocs2 - 1); UT_ASSERTeq(nallocs, nallocs2); FREE(act); } static void test_defer_free(PMEMobjpool *pop) { PMEMoid oid; int ret = pmemobj_alloc(pop, &oid, sizeof(struct foo), 0, NULL, NULL); UT_ASSERTeq(ret, 0); struct pobj_action act; pmemobj_defer_free(pop, oid, &act); pmemobj_publish(pop, &act, 1); struct foo *f = (struct foo *)pmemobj_direct(oid); f->bar = 5; /* should trigger memcheck error */ ret = pmemobj_alloc(pop, &oid, sizeof(struct foo), 0, NULL, NULL); UT_ASSERTeq(ret, 0); pmemobj_defer_free(pop, oid, &act); pmemobj_cancel(pop, &act, 1); f = (struct foo *)pmemobj_direct(oid); f->bar = 5; /* should NOT trigger memcheck error */ } /* * This function tests if macros included in action.h api compile and * allocate memory. */ static void test_api_macros(PMEMobjpool *pop) { struct pobj_action macro_reserve_act[1]; TOID(struct macro_reserve_s) macro_reserve_p = POBJ_RESERVE_NEW(pop, struct macro_reserve_s, ¯o_reserve_act[0]); UT_ASSERT(!OID_IS_NULL(macro_reserve_p.oid)); pmemobj_publish(pop, macro_reserve_act, 1); POBJ_FREE(¯o_reserve_p); macro_reserve_p = POBJ_RESERVE_ALLOC(pop, struct macro_reserve_s, sizeof(struct macro_reserve_s), ¯o_reserve_act[0]); UT_ASSERT(!OID_IS_NULL(macro_reserve_p.oid)); pmemobj_publish(pop, macro_reserve_act, 1); POBJ_FREE(¯o_reserve_p); macro_reserve_p = POBJ_XRESERVE_NEW(pop, struct macro_reserve_s, ¯o_reserve_act[0], 0); UT_ASSERT(!OID_IS_NULL(macro_reserve_p.oid)); pmemobj_publish(pop, macro_reserve_act, 1); POBJ_FREE(¯o_reserve_p); macro_reserve_p = POBJ_XRESERVE_ALLOC(pop, struct macro_reserve_s, sizeof(struct macro_reserve_s), ¯o_reserve_act[0], 0); UT_ASSERT(!OID_IS_NULL(macro_reserve_p.oid)); pmemobj_publish(pop, macro_reserve_act, 1); POBJ_FREE(¯o_reserve_p); } #define POBJ_MAX_ACTIONS 60 static void test_many(PMEMobjpool *pop, size_t n) { struct pobj_action *act = (struct pobj_action *) MALLOC(sizeof(struct pobj_action) * n); PMEMoid *oid = (PMEMoid *) MALLOC(sizeof(PMEMoid) * n); for (int i = 0; i < n; ++i) { oid[i] = pmemobj_reserve(pop, &act[i], 1, 0); UT_ASSERT(!OID_IS_NULL(oid[i])); } UT_ASSERTeq(pmemobj_publish(pop, act, n), 0); for (int i = 0; i < n; ++i) { pmemobj_defer_free(pop, oid[i], &act[i]); } UT_ASSERTeq(pmemobj_publish(pop, act, n), 0); FREE(oid); FREE(act); } static void test_duplicate(PMEMobjpool *pop) { struct pobj_alloc_class_desc alloc_class_128; alloc_class_128.header_type = POBJ_HEADER_COMPACT; alloc_class_128.unit_size = 1024 * 100; alloc_class_128.units_per_block = 1; alloc_class_128.alignment = 0; int ret = pmemobj_ctl_set(pop, "heap.alloc_class.128.desc", &alloc_class_128); UT_ASSERTeq(ret, 0); struct pobj_action a[10]; PMEMoid oid[10]; oid[0] = pmemobj_xreserve(pop, &a[0], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); pmemobj_cancel(pop, a, 1); oid[0] = pmemobj_xreserve(pop, &a[0], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[1], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[2], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); pmemobj_cancel(pop, a, 3); oid[0] = pmemobj_xreserve(pop, &a[0], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[1], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[2], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[3], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); oid[0] = pmemobj_xreserve(pop, &a[4], 1, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid[0])); pmemobj_cancel(pop, a, 5); } static void test_many_sets(PMEMobjpool *pop, size_t n) { struct pobj_action *act = (struct pobj_action *) MALLOC(sizeof(struct pobj_action) * n); PMEMoid oid; pmemobj_alloc(pop, &oid, sizeof(uint64_t) * n, 0, NULL, NULL); UT_ASSERT(!OID_IS_NULL(oid)); uint64_t *values = (uint64_t *)pmemobj_direct(oid); for (uint64_t i = 0; i < n; ++i) pmemobj_set_value(pop, &act[i], values + i, i); UT_ASSERTeq(pmemobj_publish(pop, act, n), 0); for (uint64_t i = 0; i < n; ++i) UT_ASSERTeq(*(values + i), i); pmemobj_free(&oid); FREE(act); } int main(int argc, char *argv[]) { START(argc, argv, "obj_action"); if (argc < 2) UT_FATAL("usage: %s filename", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid root = pmemobj_root(pop, sizeof(struct root)); struct root *rootp = (struct root *)pmemobj_direct(root); struct pobj_action reserved[2]; struct pobj_action published[2]; struct pobj_action tx_reserved; struct pobj_action tx_reserved_fulfilled; struct pobj_action tx_published; rootp->reserved.oid = pmemobj_reserve(pop, &reserved[0], sizeof(struct foo), 0); pmemobj_set_value(pop, &reserved[1], &rootp->reserved.value, 1); rootp->tx_reserved.oid = pmemobj_reserve(pop, &tx_reserved, sizeof(struct foo), 0); rootp->tx_reserved_fulfilled.oid = pmemobj_reserve(pop, &tx_reserved_fulfilled, sizeof(struct foo), 0); rootp->tx_published.oid = pmemobj_reserve(pop, &tx_published, sizeof(struct foo), 0); rootp->published.oid = pmemobj_reserve(pop, &published[0], sizeof(struct foo), 0); TX_BEGIN(pop) { pmemobj_tx_publish(&tx_reserved, 1); pmemobj_tx_abort(EINVAL); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_publish(&tx_reserved_fulfilled, 1); pmemobj_tx_publish(NULL, 0); /* this is to force resv fulfill */ pmemobj_tx_abort(EINVAL); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END pmemobj_set_value(pop, &published[1], &rootp->published.value, 1); pmemobj_publish(pop, published, 2); TX_BEGIN(pop) { pmemobj_tx_publish(&tx_published, 1); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_persist(pop, rootp, sizeof(*rootp)); pmemobj_close(pop); UT_ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1); UT_ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL); root = pmemobj_root(pop, sizeof(struct root)); rootp = (struct root *)pmemobj_direct(root); struct foo *reserved_foop = (struct foo *)pmemobj_direct(rootp->reserved.oid); reserved_foop->bar = 1; /* should trigger memcheck error */ UT_ASSERTeq(rootp->reserved.value, 0); struct foo *published_foop = (struct foo *)pmemobj_direct(rootp->published.oid); published_foop->bar = 1; /* should NOT trigger memcheck error */ UT_ASSERTeq(rootp->published.value, 1); struct foo *tx_reserved_foop = (struct foo *)pmemobj_direct(rootp->tx_reserved.oid); tx_reserved_foop->bar = 1; /* should trigger memcheck error */ struct foo *tx_reserved_fulfilled_foop = (struct foo *)pmemobj_direct(rootp->tx_reserved_fulfilled.oid); tx_reserved_fulfilled_foop->bar = 1; /* should trigger memcheck error */ struct foo *tx_published_foop = (struct foo *)pmemobj_direct(rootp->tx_published.oid); tx_published_foop->bar = 1; /* should NOT trigger memcheck error */ test_resv_cancel_huge(pop); test_defer_free(pop); test_api_macros(pop); test_many(pop, POBJ_MAX_ACTIONS * 2); test_many_sets(pop, POBJ_MAX_ACTIONS * 2); test_duplicate(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_action/TEST10000775000000000000000000000065114123364546015703 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_action/TEST1 -- unit test (memcheck) for obj_action # . ../unittest/unittest.sh require_test_type medium require_build_type debug configure_valgrind memcheck force-enable setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 expect_normal_exit ./obj_action$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_action/memcheck1.log.match0000664000000000000000000000564514123364546020560 0ustar rootroot==$(N)== Memcheck, a memory error detector ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: $(*) ==$(N)== Parent PID: $(N) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): main ($(*)obj_action$(*)) ==$(N)== Address 0x$(X) is $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): main ($(*)obj_action$(*)) ==$(N)== Address 0x$(X) is $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): main ($(*)obj_action$(*)) ==$(N)== Address 0x$(X) is $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_defer_free ($(*)obj_action$(*)) ==$(N)== by 0x$(X): main ($(*)obj_action$(*)) ==$(N)== Address 0x$(X) is 0 bytes inside a block of size 112 free'd $(OPT)==$(N)== at 0x$(X): palloc_heap_action_on_process (palloc.c:$(N)) $(OPX)==$(N)== at 0x$(X): palloc_heap_action_on_process ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): palloc_exec_actions (palloc.c:$(N)) $(OPX)==$(N)== by 0x$(X): palloc_exec_actions ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): palloc_publish (palloc.c:$(N)) $(OPX)==$(N)== by 0x$(X): palloc_publish ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): pmemobj_publish (obj.c:$(N)) $(OPX)==$(N)== by 0x$(X): pmemobj_publish ($(*)src/debug/libpmemobj.so.1.0.0) ==$(N)== by 0x$(X): test_defer_free ($(*)obj_action$(*)) ==$(N)== by 0x$(X): main ($(*)obj_action$(*)) ==$(N)== Block was alloc'd at $(OPT)==$(N)== at 0x$(X): alloc_prep_block (palloc.c:$(N)) $(OPX)==$(N)== at 0x$(X): alloc_prep_block ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): palloc_reservation_create (palloc.c:$(N)) $(OPX)==$(N)== by 0x$(X): palloc_reservation_create ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): palloc_operation (palloc.c:$(N)) $(OPX)==$(N)== by 0x$(X): palloc_operation ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): obj_alloc_construct (obj.c:$(N)) $(OPX)==$(N)== by 0x$(X): obj_alloc_construct ($(*)src/debug/libpmemobj.so.1.0.0) $(OPT)==$(N)== by 0x$(X): pmemobj_alloc (obj.c:$(N)) $(OPX)==$(N)== by 0x$(X): pmemobj_alloc ($(*)src/debug/libpmemobj.so.1.0.0) ==$(N)== by 0x$(X): test_defer_free ($(*)obj_action$(*)) ==$(N)== by 0x$(X): main ($(*)obj_action$(*)) ==$(N)== ==$(N)== ==$(N)== HEAP SUMMARY: ==$(N)== in use at exit: $(NC) bytes in $(N) blocks ==$(N)== total heap usage: $(NC) allocs, $(NC) frees, $(NC) bytes allocated ==$(N)== $(OPT)==$(N)== All heap blocks were freed -- no leaks are possible $(OPT)==$(N)== LEAK SUMMARY: $(OPT)==$(N)== definitely lost: 0 bytes in 0 blocks $(OPT)==$(N)== indirectly lost: 0 bytes in 0 blocks $(OPT)==$(N)== possibly lost: 0 bytes in 0 blocks $(OPT)==$(N)== still reachable: 0 bytes in 0 blocks $(OPX)==$(N)== suppressed: $(NC) bytes in $(N) blocks $(OPT)==$(N)== ==$(N)== ==$(N)== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: $(N) from $(N)) pmdk-1.11.1/src/test/obj_action/pmemcheck2.log.match0000664000000000000000000000153414123364546020732 0ustar rootroot==$(N)== pmemcheck-$(*), a simple persistent store checker ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: $(*) ==$(N)== Parent PID: $(N) ==$(N)== ==$(N)== ==$(N)== Number of stores not made persistent: 4 ==$(N)== Stores not made persistent properly: ==$(N)== [0] at 0x$(X): test_defer_free (obj_action.c:$(N)) ==$(N)== by 0x$(X): main (obj_action.c:$(N)) ==$(N)== Address: 0x$(X) size: 4 state: DIRTY ==$(N)== [1] at 0x$(X): test_defer_free (obj_action.c:$(N)) ==$(N)== by 0x$(X): main (obj_action.c:$(N)) ==$(N)== Address: 0x$(X) size: 4 state: DIRTY ==$(N)== [2] at 0x$(X): main (obj_action.c:$(N)) ==$(N)== Address: 0x$(X) size: 4 state: DIRTY ==$(N)== [3] at 0x$(X): main (obj_action.c:$(N)) ==$(N)== Address: 0x$(X) size: 4 state: DIRTY ==$(N)== Total memory not made persistent: 16 ==$(N)== ERROR SUMMARY: 4 errors pmdk-1.11.1/src/test/obj_action/TEST20000775000000000000000000000072614123364546015707 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_action/TEST2 -- unit test (pmemcheck) for obj_action # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_valgrind 3.12 configure_valgrind pmemcheck force-enable setup export PMEM_IS_PMEM_FORCE=1 export PMEMOBJ_LOG_LEVEL=1 expect_normal_exit ./obj_action$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/mmap/0000775000000000000000000000000014123364546013736 5ustar rootrootpmdk-1.11.1/src/test/mmap/mmap.vcxproj.filters0000664000000000000000000000126414123364546017757 0ustar rootroot {8d8f2f00-0fff-43fb-a7ca-7ad92eac11a5} {a334316f-c0d2-4f89-becc-58c8d3584626} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/mmap/TEST00000775000000000000000000000061114123364546014521 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap/TEST0 -- unit test for memory mapping routines # . ../unittest/unittest.sh require_test_type medium require_fs_type any # XXX disabled for now, to be fixed in pmem/issues#1053. exit 0 setup touch $DIR/testfile expect_normal_exit ./mmap$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/mmap/Makefile0000664000000000000000000000027514123364546015402 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap/Makefile -- build mmap unit test # TARGET = mmap OBJS = mmap.o include ../Makefile.inc pmdk-1.11.1/src/test/mmap/TEST0.PS10000664000000000000000000000053514123364546015125 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap/TEST0 -- unit test for memory mapping routines # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup # create zero-length file touch $DIR\testfile expect_normal_exit $Env:EXE_DIR\mmap$Env:EXESUFFIX $DIR\testfile pass pmdk-1.11.1/src/test/mmap/mmap.c0000664000000000000000000007452214123364546015046 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * Copyright (c) 2016, Microsoft Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * mmap.c -- test memory mapping routines * * This test is intended to be used for testing Windows implementation * of memory mapping routines - mmap(), munmap(), msync() and mprotect(). * Those functions should provide the same functionality as their Linux * counterparts, at least with respect to the features that are used * in PMDK libraries. * * Known issues and differences between Linux and Windows implementation * are described in src/common/mmap_windows.c. */ #include "unittest.h" #include #include #include #ifdef _WIN32 #define MMAP_ALIGN ((uintptr_t)65536) #else #define MMAP_ALIGN ((uintptr_t)4096) #endif #define PAGE_SIZE 4096 #define MMAP_SIZE MMAP_ALIGN #define FILE_SIZE (MMAP_SIZE * 4) #define CHECK_RO 1 #define CHECK_PRIV 2 static ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { ut_siglongjmp(Jmp); } /* * check_access -- check access to mapped memory */ static void check_access(char *addr, size_t len, int prot) { volatile int i; /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char pat[PAGE_SIZE]; char buf[PAGE_SIZE]; for (i = 0; i < len / PAGE_SIZE; i++) { /* check read access */ if (!ut_sigsetjmp(Jmp)) { memcpy(buf, addr + PAGE_SIZE * i, PAGE_SIZE); if ((prot & PROT_READ) == 0) UT_FATAL("memory can be read"); } else { if (prot & PROT_READ) UT_FATAL("memory cannot be read"); } } /* fill up mapped region with new pattern */ memset(pat, 0xA5, PAGE_SIZE); for (i = 0; i < len / PAGE_SIZE; i++) { if (!ut_sigsetjmp(Jmp)) { memcpy(addr + PAGE_SIZE * i, pat, PAGE_SIZE); if ((prot & PROT_WRITE) == 0) UT_FATAL("memory can be written"); } else { if (prot & PROT_WRITE) UT_FATAL("memory cannot be written"); } } } /* * check_mapping -- check access to memory mapped file */ static void check_mapping(int fd, char *addr, size_t len, int prot, int flags, os_off_t offset) { volatile int i; /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char pat[PAGE_SIZE] = { 0 }; char buf[PAGE_SIZE]; if ((flags & CHECK_RO) == 0 && fd != -1) { /* write some pattern to the file */ memset(pat, 0x5A, PAGE_SIZE); for (i = 0; i < len / PAGE_SIZE; i++) { LSEEK(fd, offset + PAGE_SIZE * i, SEEK_SET); WRITE(fd, pat, PAGE_SIZE); LSEEK(fd, offset + PAGE_SIZE * i, SEEK_SET); if (READ(fd, buf, PAGE_SIZE) == PAGE_SIZE) { if (memcmp(pat, buf, PAGE_SIZE)) UT_FATAL("first %d bytes do not match", PAGE_SIZE); } } } check_access(addr, len, prot); munmap(addr, len); /* same memcpy from above should now fail */ for (i = 0; i < len / PAGE_SIZE; i++) { if (!ut_sigsetjmp(Jmp)) { memcpy(addr + PAGE_SIZE * i, pat, PAGE_SIZE); UT_FATAL("unmap failed"); } } if (fd != -1) { /* expected pattern */ if ((flags & (CHECK_PRIV | CHECK_RO)) != 0 || (prot & PROT_WRITE) == 0) memset(pat, 0x5A, PAGE_SIZE); else memset(pat, 0xA5, PAGE_SIZE); for (i = 0; i < len / PAGE_SIZE; i++) { LSEEK(fd, offset + PAGE_SIZE * i, SEEK_SET); if (READ(fd, buf, PAGE_SIZE) == PAGE_SIZE) { if (memcmp(pat, buf, PAGE_SIZE)) UT_FATAL("first %d bytes do not match", PAGE_SIZE); } } } } /* * test_mmap_flags -- test supported flags */ static void test_mmap_flags(int fd) { char *ptr1; /* PRIVATE + SHARED */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_SHARED, fd, 0); UT_ASSERTeq(ptr1, MAP_FAILED); /* no PRIVATE/SHARED */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, 0, fd, 0); UT_ASSERTeq(ptr1, MAP_FAILED); /* ANON but no PRIVATE/SHARED */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON, fd, 0); UT_ASSERTeq(ptr1, MAP_FAILED); } /* * test_mmap_len -- test various lengths and offsets */ static void test_mmap_len(int fd) { char *ptr; /* len == 0 */ ptr = mmap(NULL, 0, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTeq(ptr, MAP_FAILED); /* len > file_size */ ptr = mmap(NULL, FILE_SIZE + MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, FILE_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); UT_ASSERTeq(munmap(ptr + FILE_SIZE, MMAP_SIZE), 0); /* offset == 0 */ ptr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* offset == PAGE_SIZE */ ptr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PAGE_SIZE); #ifndef _WIN32 UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, PAGE_SIZE); #else /* XXX - on Windows, offset must be aligned to allocation granularity */ UT_ASSERTeq(ptr, MAP_FAILED); #endif /* offset == MMAP_ALIGN */ ptr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, MMAP_ALIGN); UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, MMAP_ALIGN); /* unaligned offset */ ptr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 100); UT_ASSERTeq(ptr, MAP_FAILED); /* offset + len > file_size */ ptr = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, MMAP_SIZE); UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, FILE_SIZE - MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, MMAP_SIZE); UT_ASSERTeq(munmap(ptr + FILE_SIZE - MMAP_SIZE, MMAP_SIZE), 0); /* offset beyond file_size */ ptr = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_SHARED, fd, FILE_SIZE + MMAP_SIZE); #ifndef _WIN32 UT_ASSERTne(ptr, MAP_FAILED); check_mapping(fd, ptr, MMAP_SIZE, PROT_READ, CHECK_PRIV, FILE_SIZE + MMAP_SIZE); #else UT_ASSERTeq(ptr, MAP_FAILED); #endif } /* * test_mmap_hint -- test hint address */ static void test_mmap_hint(int fd) { char *ptr1; char *ptr2; /* map entire file first to get unused address */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); /* now try to map a part of it at specified address */ ptr2 = mmap(ptr1 + MMAP_ALIGN, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTeq(ptr2, ptr1 + MMAP_ALIGN); check_mapping(fd, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); /* non-aligned hint address - should be ignored */ ptr2 = mmap(ptr1 + 100, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERTne(ptr2, ptr1 + 100); check_mapping(fd, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); /* hint address is busy */ ptr1 = mmap(NULL, FILE_SIZE / 2, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERT(ptr2 < ptr1 || ptr2 >= ptr1 + FILE_SIZE / 2); munmap(ptr1, FILE_SIZE / 2); check_mapping(fd, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); } /* * test_mmap_fixed -- test MAP_FIXED flag */ static void test_mmap_fixed(int fd) { char *ptr1; char *ptr2; /* map entire file first to get unused address */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); /* now try to map a part of it at specified address */ ptr2 = mmap(ptr1 + MMAP_ALIGN, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0); UT_ASSERTeq(ptr2, ptr1 + MMAP_ALIGN); check_mapping(fd, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); /* non-aligned hint address - should fail */ ptr2 = mmap(ptr1 + 100, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0); UT_ASSERTeq(ptr2, MAP_FAILED); /* hint address is busy */ ptr1 = mmap(NULL, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE); check_mapping(fd, ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); check_mapping(fd, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, CHECK_PRIV, 0); } /* * test_mmap_anon -- test anonymous mappings */ static void test_mmap_anon(int fd) { char *ptr1; char *ptr2; /* fd == -1, but no MAP_ANON - should fail */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, -1, 0); UT_ASSERTeq(ptr1, MAP_FAILED); /* fd should be ignored */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(-1, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* offset should be ignored */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, MMAP_ALIGN); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(-1, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* now try to map a part of it at specified address */ ptr2 = mmap(ptr1 + MMAP_ALIGN, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); UT_ASSERTeq(ptr2, ptr1 + MMAP_ALIGN); check_mapping(-1, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* non-aligned hint address - should be ignored */ ptr2 = mmap(ptr1 + 100, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERTne(ptr2, ptr1 + 100); check_mapping(-1, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* non-aligned hint address + MAP_FIXED - should fail */ ptr2 = mmap(ptr1 + 100, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED|MAP_FIXED, -1, 0); UT_ASSERTeq(ptr2, MAP_FAILED); /* hint address is busy */ ptr1 = mmap(NULL, FILE_SIZE / 2, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERT(ptr2 < ptr1 || ptr2 >= ptr1 + FILE_SIZE / 2); munmap(ptr1, FILE_SIZE / 2); check_mapping(-1, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* hint address is busy + MAP_FIXED */ ptr1 = mmap(NULL, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED|MAP_FIXED, -1, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE); check_mapping(-1, ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); check_mapping(-1, ptr2, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); } /* * test_mmap_prot -- test R/W protection */ static void test_mmap_prot(int fd, int fd_ro) { char *ptr1; /* read/write */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* read/write on file opened in read-only mode - should fail */ errno = 0; ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_ro, 0); UT_ASSERTeq(ptr1, MAP_FAILED); UT_ASSERTeq(errno, EACCES); /* read-only */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ, 0, 0); /* read-only on file opened in read-only mode - should succeed */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED, fd_ro, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd_ro, ptr1, FILE_SIZE, PROT_READ, CHECK_RO, 0); /* no access */ ptr1 = mmap(NULL, FILE_SIZE, PROT_NONE, MAP_SHARED, fd, 0); #ifndef _WIN32 UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_NONE, 0, 0); #else /* XXX - PROT_NONE not supported yet */ UT_ASSERTeq(ptr1, MAP_FAILED); #endif /* no access on read-only file */ ptr1 = mmap(NULL, FILE_SIZE, PROT_NONE, MAP_SHARED, fd_ro, 0); #ifndef _WIN32 UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd_ro, ptr1, FILE_SIZE, PROT_NONE, CHECK_RO, 0); #else /* XXX - PROT_NONE not supported yet */ UT_ASSERTeq(ptr1, MAP_FAILED); #endif } /* * test_mmap_prot_anon -- test R/W protection on anonymous mappings */ static void test_mmap_prot_anon(void) { char *ptr1; /* read/write */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(-1, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* read-only */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(-1, ptr1, FILE_SIZE, PROT_READ, 0, 0); /* no access */ ptr1 = mmap(NULL, FILE_SIZE, PROT_NONE, MAP_SHARED|MAP_ANON, -1, 0); #ifndef _WIN32 UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(-1, ptr1, FILE_SIZE, PROT_NONE, 0, 0); #else /* XXX - PROT_NONE not supported yet */ UT_ASSERTeq(ptr1, MAP_FAILED); #endif } /* * test_mmap_shared -- test shared mappings */ static void test_mmap_shared(int fd) { char *ptr1; ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); } /* * test_munmap -- test mapping deletion */ static void test_munmap(int fd) { char *ptr1; char *ptr2; ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); /* unaligned address - should fail */ errno = 0; UT_ASSERTeq(munmap(ptr1 + 100, FILE_SIZE), -1); UT_ASSERTeq(errno, EINVAL); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); /* unaligned length - should succeed */ UT_ASSERTeq(munmap(ptr1, FILE_SIZE - 100), 0); check_mapping(fd, ptr1, FILE_SIZE, PROT_NONE, 0, 0); check_mapping(fd, ptr1 + FILE_SIZE - 100, 100, PROT_NONE, 0, 0); ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); /* len == 0 - should fail */ errno = 0; UT_ASSERTne(munmap(ptr1, 0), 0); UT_ASSERTeq(errno, EINVAL); check_mapping(fd, ptr1, FILE_SIZE, PROT_READ|PROT_WRITE, 0, 0); ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); /* delete entire mapping (len > file_size) */ UT_ASSERTeq(munmap(ptr1, FILE_SIZE + MMAP_SIZE), 0); check_mapping(fd, ptr1, FILE_SIZE, PROT_NONE, 0, 0); /* delete non existing mapping - should succeed */ UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); /* partial unmap */ UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); check_mapping(fd, ptr1, MMAP_SIZE, PROT_NONE, 0, 0); check_mapping(fd, ptr1 + MMAP_SIZE, FILE_SIZE - MMAP_SIZE, PROT_READ|PROT_WRITE, 0, MMAP_SIZE); /* unmap pages from two adjacent mappings */ ptr1 = mmap(ptr1, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE * 2, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, MMAP_SIZE * 2); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE * 2); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE, MMAP_SIZE * 2), 0); check_mapping(fd, ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, 0); check_mapping(fd, ptr1 + MMAP_SIZE, MMAP_SIZE * 2, PROT_NONE, 0, MMAP_SIZE); check_mapping(fd, ptr1 + MMAP_SIZE * 3, MMAP_SIZE, PROT_READ|PROT_WRITE, 0, MMAP_SIZE * 3); } #define MS_ALL (MS_SYNC|MS_ASYNC|MS_INVALIDATE) /* * test_msync -- test synchronizing a file with a memory map */ static void test_msync(int fd) { char *ptr1; char *ptr2; ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(munmap(ptr2, FILE_SIZE), 0); /* unknown flag - should fail */ errno = 0; UT_ASSERTne(msync(ptr1, MMAP_SIZE, MS_ALL + 1), 0); UT_ASSERTeq(errno, EINVAL); /* SYNC + ASYNC - should fail */ errno = 0; UT_ASSERTne(msync(ptr1, MMAP_SIZE, MS_SYNC|MS_ASYNC), 0); UT_ASSERTeq(errno, EINVAL); /* no SYNC, nor ASYNC - should fail according to POSIX... */ errno = 0; #ifndef _WIN32 /* ... but it is allowed on Linux */ UT_ASSERTeq(msync(ptr1, MMAP_SIZE, 0), 0); UT_ASSERTeq(errno, 0); #else UT_ASSERTne(msync(ptr1, MMAP_SIZE, 0), 0); UT_ASSERTeq(errno, EINVAL); #endif /* len == 0 - should succeed */ UT_ASSERTeq(msync(ptr1, 0, MS_SYNC), 0); /* len == SIZE_MAX - should fail */ errno = 0; #ifndef _WIN32 /* ... but it is allowed on Linux */ UT_ASSERTeq(msync(ptr1, SIZE_MAX, MS_SYNC), 0); UT_ASSERTeq(errno, 0); #else UT_ASSERTne(msync(ptr1, SIZE_MAX, MS_SYNC), 0); UT_ASSERTeq(errno, ENOMEM); #endif /* unaligned pointer - should fail */ errno = 0; UT_ASSERTne(msync(ptr1 + 100, FILE_SIZE, MS_SYNC), 0); UT_ASSERTeq(errno, EINVAL); /* invalid pointer - should fail */ UT_ASSERTne(msync(ptr2, FILE_SIZE, MS_SYNC), 0); /* unaligned length - should succeed */ UT_ASSERTeq(msync(ptr1, FILE_SIZE - 100, MS_SYNC), 0); /* len > mapping size - should fail */ UT_ASSERTeq(munmap(ptr1 + FILE_SIZE / 2, FILE_SIZE / 2), 0); errno = 0; UT_ASSERTne(msync(ptr1, FILE_SIZE, MS_SYNC), 0); UT_ASSERTeq(errno, ENOMEM); /* partial sync */ UT_ASSERTeq(msync(ptr1 + PAGE_SIZE, MMAP_SIZE, MS_SYNC), 0); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* range includes invalid addresses - should fail */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE, MMAP_SIZE), 0); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE * 3, MMAP_SIZE), 0); errno = 0; UT_ASSERTne(msync(ptr1, FILE_SIZE, MS_SYNC), 0); UT_ASSERTeq(errno, ENOMEM); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* synchronize two adjacent mappings */ ptr1 = mmap(ptr1, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE * 2, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, MMAP_SIZE * 2); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE * 2); UT_ASSERTeq(msync(ptr1 + MMAP_SIZE, MMAP_SIZE * 2, MS_SYNC), 0); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE * 4), 0); /* anonymous mapping */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(msync(ptr1, FILE_SIZE, MS_SYNC), 0); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); } #define PROT_ALL (PROT_READ|PROT_WRITE|PROT_EXEC) /* * test_mprotect -- test memory protection */ static void test_mprotect(int fd, int fd_ro) { char *ptr1; char *ptr2; /* unknown PROT flag - should succeed */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_ALL + 1), 0); check_access(ptr1, MMAP_SIZE, PROT_NONE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* len == 0 - should succeed */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, 0, PROT_READ), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* len > mapping size - should fail */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTeq(munmap(ptr1 + FILE_SIZE / 2, FILE_SIZE / 2), 0); errno = 0; UT_ASSERTne(mprotect(ptr1, FILE_SIZE, PROT_READ), 0); UT_ASSERTeq(errno, ENOMEM); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* change protection: R/O => R/W */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); #ifndef _WIN32 UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); #else /* XXX - not supported yet */ UT_ASSERTne(mprotect(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); #endif /* change protection; R/W => R/O */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_READ), 0); check_access(ptr1, MMAP_SIZE, PROT_READ); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* change protection; R/W => none */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_NONE), 0); check_access(ptr1, MMAP_SIZE, PROT_NONE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* unaligned pointer - should fail */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); errno = 0; UT_ASSERTne(mprotect(ptr1 + 100, MMAP_SIZE, PROT_READ), 0); UT_ASSERTeq(errno, EINVAL); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* invalid pointer - should fail */ errno = 0; UT_ASSERTne(mprotect(ptr1, MMAP_SIZE, PROT_READ), 0); UT_ASSERTeq(errno, ENOMEM); /* unaligned len - should succeed */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, PAGE_SIZE + 100, PROT_READ), 0); check_access(ptr1, PAGE_SIZE * 2, PROT_READ); check_access(ptr1 + PAGE_SIZE * 2, FILE_SIZE - PAGE_SIZE * 2, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* partial protection change (on page boundary) */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1 + PAGE_SIZE, PAGE_SIZE, PROT_READ), 0); UT_ASSERTeq(mprotect(ptr1 + PAGE_SIZE * 2, PAGE_SIZE, PROT_NONE), 0); check_access(ptr1, PAGE_SIZE, PROT_READ|PROT_WRITE); check_access(ptr1 + PAGE_SIZE, PAGE_SIZE, PROT_READ); check_access(ptr1 + PAGE_SIZE * 2, PAGE_SIZE, PROT_NONE); check_access(ptr1 + PAGE_SIZE * 3, FILE_SIZE - PAGE_SIZE * 3, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* range includes invalid addresses - should fail */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE, MMAP_SIZE), 0); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE * 3, MMAP_SIZE), 0); check_access(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_NONE); check_access(ptr1 + MMAP_SIZE * 3, MMAP_SIZE, PROT_NONE); errno = 0; UT_ASSERTne(mprotect(ptr1, MMAP_SIZE * 4, PROT_READ), 0); UT_ASSERTeq(errno, ENOMEM); #ifndef _WIN32 /* protection changed for all the pages up to the first invalid */ check_access(ptr1, MMAP_SIZE, PROT_READ); check_access(ptr1 + MMAP_SIZE * 2, MMAP_SIZE, PROT_READ|PROT_WRITE); #else /* XXX - protection changed for all the valid pages */ check_access(ptr1, MMAP_SIZE, PROT_READ); check_access(ptr1 + MMAP_SIZE * 2, MMAP_SIZE, PROT_READ); #endif UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* change protection on two adjacent mappings */ ptr1 = mmap(ptr1, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE * 2, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, MMAP_SIZE * 2); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE * 2); UT_ASSERTeq(mprotect(ptr1 + MMAP_SIZE, MMAP_SIZE * 2, PROT_NONE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); check_access(ptr1 + MMAP_SIZE, MMAP_SIZE * 2, PROT_NONE); check_access(ptr1 + MMAP_SIZE * 3, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE * 4), 0); /* change protection to R/W on file opened in read-only mode */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_SHARED, fd_ro, 0); UT_ASSERTne(ptr1, MAP_FAILED); errno = 0; UT_ASSERTne(mprotect(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE), 0); UT_ASSERTeq(errno, EACCES); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); } /* * test_mprotect_anon -- test memory protection on anonymous mappings */ static void test_mprotect_anon(void) { char *ptr1; char *ptr2; /* unknown PROT flag - should succeed */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_ALL + 1), 0); check_access(ptr1, MMAP_SIZE, PROT_NONE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* len == 0 - should succeed */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, 0, PROT_READ), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* change protection: R/O => R/W */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); #ifndef _WIN32 UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); #else /* XXX - not supported yet */ UT_ASSERTne(mprotect(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); #endif /* change protection; R/W => R/O */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_READ), 0); check_access(ptr1, MMAP_SIZE, PROT_READ); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* change protection; R/W => none */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, MMAP_SIZE, PROT_NONE), 0); check_access(ptr1, MMAP_SIZE, PROT_NONE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* unaligned pointer - should fail */ ptr1 = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); errno = 0; UT_ASSERTne(mprotect(ptr1 + 100, MMAP_SIZE, PROT_READ), 0); UT_ASSERTeq(errno, EINVAL); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE), 0); /* invalid pointer - should fail */ errno = 0; UT_ASSERTne(mprotect(ptr1, MMAP_SIZE, PROT_READ), 0); UT_ASSERTeq(errno, ENOMEM); /* unaligned len - should succeed */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1, PAGE_SIZE + 100, PROT_READ), 0); check_access(ptr1, PAGE_SIZE * 2, PROT_READ); check_access(ptr1 + PAGE_SIZE * 2, FILE_SIZE - PAGE_SIZE * 2, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* partial protection change (on page boundary) */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(mprotect(ptr1 + PAGE_SIZE, PAGE_SIZE, PROT_READ), 0); UT_ASSERTeq(mprotect(ptr1 + PAGE_SIZE * 2, PAGE_SIZE, PROT_NONE), 0); check_access(ptr1, PAGE_SIZE, PROT_READ|PROT_WRITE); check_access(ptr1 + PAGE_SIZE, PAGE_SIZE, PROT_READ); check_access(ptr1 + PAGE_SIZE * 2, PAGE_SIZE, PROT_NONE); check_access(ptr1 + PAGE_SIZE * 3, FILE_SIZE - PAGE_SIZE * 3, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* range includes invalid addresses - should fail */ ptr1 = mmap(NULL, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE, MMAP_SIZE), 0); UT_ASSERTeq(munmap(ptr1 + MMAP_SIZE * 3, MMAP_SIZE), 0); check_access(ptr1 + MMAP_SIZE, MMAP_SIZE, PROT_NONE); check_access(ptr1 + MMAP_SIZE * 3, MMAP_SIZE, PROT_NONE); errno = 0; UT_ASSERTne(mprotect(ptr1, MMAP_SIZE * 4, PROT_READ), 0); UT_ASSERTeq(errno, ENOMEM); #ifndef _WIN32 /* protection changed for all the pages up to the first invalid */ check_access(ptr1, MMAP_SIZE, PROT_READ); check_access(ptr1 + MMAP_SIZE * 2, MMAP_SIZE, PROT_READ|PROT_WRITE); #else /* XXX - protection changed for all the valid pages */ check_access(ptr1, MMAP_SIZE, PROT_READ); check_access(ptr1 + MMAP_SIZE * 2, MMAP_SIZE, PROT_READ); #endif UT_ASSERTeq(munmap(ptr1, FILE_SIZE), 0); /* change protection on two adjacent mappings */ ptr1 = mmap(ptr1, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); UT_ASSERTne(ptr1, MAP_FAILED); ptr2 = mmap(ptr1 + MMAP_SIZE * 2, MMAP_SIZE * 2, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, MMAP_SIZE * 2); UT_ASSERTeq(ptr2, ptr1 + MMAP_SIZE * 2); UT_ASSERTeq(mprotect(ptr1 + MMAP_SIZE, MMAP_SIZE * 2, PROT_NONE), 0); check_access(ptr1, MMAP_SIZE, PROT_READ|PROT_WRITE); check_access(ptr1 + MMAP_SIZE, MMAP_SIZE * 2, PROT_NONE); check_access(ptr1 + MMAP_SIZE * 3, MMAP_SIZE, PROT_READ|PROT_WRITE); UT_ASSERTeq(munmap(ptr1, MMAP_SIZE * 4), 0); } int main(int argc, char *argv[]) { START(argc, argv, "mmap"); if (argc != 2) UT_FATAL("usage: %s file", argv[0]); int fd = OPEN(argv[1], O_RDWR); int fd_ro = OPEN(argv[1], O_RDONLY); POSIX_FALLOCATE(fd, 0, FILE_SIZE); test_mmap_flags(fd); test_mmap_len(fd); test_mmap_hint(fd); test_mmap_fixed(fd); test_mmap_anon(fd); test_mmap_shared(fd); test_mmap_prot(fd, fd_ro); test_mmap_prot_anon(); test_munmap(fd); test_msync(fd); test_mprotect(fd, fd_ro); test_mprotect_anon(); CLOSE(fd_ro); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/mmap/.gitignore0000664000000000000000000000000514123364546015721 0ustar rootrootmmap pmdk-1.11.1/src/test/mmap/mmap.vcxproj0000664000000000000000000000613514123364546016312 0ustar rootroot Debug x64 Release x64 {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {5580D11C-FDA6-4CF2-A0E8-1C2D3FBC11F1} Win32Proj 10.0.17134.0 mmap mmap Application true v140 Application false v140 pmdk-1.11.1/src/test/obj_sds/0000775000000000000000000000000014123364546014427 5ustar rootrootpmdk-1.11.1/src/test/obj_sds/TEST7.PS10000664000000000000000000000147514123364546015631 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST7 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # no error expect_normal_exit $Env:EXE_DIR\obj_sds 1 0 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 # the pool closed and ADR failure expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 1 $POOLSET ` 5 1 7 1 9 1 11 0 12 0 # the pool not closed but SDS is fixed expect_normal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 1 7 1 9 1 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST1.PS10000664000000000000000000000131214123364546015611 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST1 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # the pool not closed but there was no an ADR failure expect_abnormal_exit $Env:EXE_DIR\obj_sds 1 1 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 expect_normal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST5.PS10000664000000000000000000000131314123364546015616 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST5 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # the pool not closed and part moved to another dimm expect_abnormal_exit $Env:EXE_DIR\obj_sds 1 1 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 0 7 0 9 0 11 0 121 0 pass pmdk-1.11.1/src/test/obj_sds/TEST30000775000000000000000000000131314123364546015215 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST3 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # the pool not closed and ADR failure expect_abnormal_exit ./obj_sds 1 1 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit ./obj_sds 0 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 1 pass pmdk-1.11.1/src/test/obj_sds/mocks_windows.h0000664000000000000000000000045614123364546017473 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2018-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of dimm functions */ #ifndef WRAP_REAL #define pmem2_source_device_usc __wrap_pmem2_source_device_usc #define pmem2_source_device_idU __wrap_pmem2_source_device_id #endif pmdk-1.11.1/src/test/obj_sds/TEST00000775000000000000000000000125314123364546015215 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST0 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # no error expect_normal_exit ./obj_sds 1 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_normal_exit ./obj_sds 0 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/Makefile0000664000000000000000000000043514123364546016071 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # src/test/obj_sds/Makefile -- shutdown_state unit test # TARGET = obj_sds OBJS = obj_sds.o LIBPMEMPOOL=y LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_sds.c) pmdk-1.11.1/src/test/obj_sds/TEST3.PS10000664000000000000000000000127414123364546015622 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST3 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # the pool not closed and ADR failure expect_abnormal_exit $Env:EXE_DIR\obj_sds 1 1 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 0 7 0 9 0 11 0 12 1 pass pmdk-1.11.1/src/test/obj_sds/TEST2.PS10000664000000000000000000000127414123364546015621 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST2 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # the pool not closed and ADR failure expect_abnormal_exit $Env:EXE_DIR\obj_sds 1 1 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 1 7 1 9 1 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST50000775000000000000000000000133214123364546015220 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST5 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # the pool not closed and part moved to another dimm expect_abnormal_exit ./obj_sds 1 1 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit ./obj_sds 0 0 $POOLSET\ 5 0 7 0 9 0 11 0 121 0 pass pmdk-1.11.1/src/test/obj_sds/TEST6.PS10000664000000000000000000000147714123364546015632 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST6 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # no error expect_normal_exit $Env:EXE_DIR\obj_sds 1 0 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 # the pool closed and ADR failure expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 1 $POOLSET ` 5 1 7 1 9 1 11 0 12 0 # the pool not closed and pool moved expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 43 0 11 0 23 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST40000775000000000000000000000133314123364546015220 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST4 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # the pool not closed and part moved to another dimm expect_abnormal_exit ./obj_sds 1 1 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit ./obj_sds 0 0 $POOLSET\ 5 0 7 0 23 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST70000775000000000000000000000150014123364546015217 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST7 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # no error expect_normal_exit ./obj_sds 1 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 # the pool closed and ADR failure expect_abnormal_exit ./obj_sds 0 1 $POOLSET\ 5 1 7 1 9 1 11 0 12 0 # the pool not closed but SDS is fixed expect_normal_exit ./obj_sds 0 0 $POOLSET\ 5 1 7 1 9 1 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST0.PS10000664000000000000000000000121214123364546015607 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST0 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # no error expect_normal_exit $Env:EXE_DIR\obj_sds 1 0 $POOLSET 5 0 7 0 9 0 11 0 12 0 expect_normal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET 5 0 7 0 9 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/obj_sds.vcxproj0000664000000000000000000001471214123364546017474 0ustar rootroot Debug x64 Release x64 {EDD5FA29-69AF-445F-842A-132E65D3C92B} Win32Proj obj_sds 10.0.17134.0 Application true v140 Application false v140 false NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) mocks_windows.h;%(ForcedIncludeFiles) WRAP_REAL;%(PreprocessorDefinitions) WRAP_REAL;%(PreprocessorDefinitions) {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_sds/.gitignore0000664000000000000000000000001014123364546016406 0ustar rootrootobj_sds pmdk-1.11.1/src/test/obj_sds/obj_sds.vcxproj.filters0000664000000000000000000001220014123364546021131 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {18a24826-3f5b-411c-b4a1-fa378e9b84e4} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files pmdk-1.11.1/src/test/obj_sds/TEST60000775000000000000000000000153014123364546015221 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST6 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # no error expect_normal_exit ./obj_sds 1 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 # the pool closed and ADR failure expect_abnormal_exit ./obj_sds 0 1 $POOLSET\ 5 1 7 1 9 1 11 0 12 0 PMEMOBJ_LOG_LEVEL=4 # the pool not closed and pool moved expect_abnormal_exit ./obj_sds 0 0 $POOLSET\ 43 0 11 0 23 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST10000775000000000000000000000133114123364546015213 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST1 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # the pool not closed but there was no an ADR failure expect_abnormal_exit ./obj_sds 1 1 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_normal_exit ./obj_sds 0 0 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST4.PS10000664000000000000000000000131414123364546015616 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST4 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $POOLSET="$DIR\pool.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile01:x ` 20M:$DIR\testfile02:x ` 20M:$DIR\testfile03:x ` R ` 40M:$DIR\testfile14:x ` 20M:$DIR\testfile15:x # the pool not closed and part moved to another dimm expect_abnormal_exit $Env:EXE_DIR\obj_sds 1 1 $POOLSET ` 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit $Env:EXE_DIR\obj_sds 0 0 $POOLSET ` 5 0 7 0 23 0 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/TEST20000775000000000000000000000131314123364546015214 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sds/TEST2 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug require_sds ./obj_sds setup POOLSET=$DIR/pool.set # Create poolset file create_poolset $POOLSET \ 20M:$DIR/testfile01:x \ 20M:$DIR/testfile02:x \ 20M:$DIR/testfile03:x \ R \ 40M:$DIR/testfile14:x \ 20M:$DIR/testfile15:x # the pool not closed and ADR failure expect_abnormal_exit ./obj_sds 1 1 $POOLSET\ 5 0 7 0 9 0 11 0 12 0 expect_abnormal_exit ./obj_sds 0 0 $POOLSET\ 5 1 7 1 9 1 11 0 12 0 pass pmdk-1.11.1/src/test/obj_sds/obj_sds.c0000664000000000000000000000425214123364546016221 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2020, Intel Corporation */ /* * util_sds.c -- unit test for shutdown status functions */ #include "unittest.h" #include "shutdown_state.h" #include #include static char **uids; static size_t uids_size; static size_t uid_it; static uint64_t *uscs; static size_t uscs_size; static size_t usc_it; int main(int argc, char *argv[]) { START(argc, argv, "obj_sds"); if (argc < 2) UT_FATAL("usage: %s init fail file (uuid usc)...", argv[0]); unsigned files = (unsigned)(argc - 3) / 2; uids = MALLOC(files * sizeof(uids[0])); uscs = MALLOC(files * sizeof(uscs[0])); uids_size = files; uscs_size = files; int init = atoi(argv[1]); int fail = atoi(argv[2]); char *path = argv[3]; char **args = argv + 4; for (unsigned i = 0; i < files; i++) { uids[i] = args[i * 2]; uscs[i] = strtoull(args[i * 2 + 1], NULL, 0); } PMEMobjpool *pop; if (init) { if ((pop = pmemobj_create(path, "LAYOUT", 0, 0600)) == NULL) { UT_FATAL("!%s: pmemobj_create", path); } #if !defined(_WIN32) && !NDCTL_ENABLED pmemobj_close(pop); pmempool_feature_enable(path, PMEMPOOL_FEAT_SHUTDOWN_STATE, 0); if ((pop = pmemobj_open(path, "LAYOUT")) == NULL) { UT_FATAL("!%s: pmemobj_open", path); } #endif } else { if ((pop = pmemobj_open(path, "LAYOUT")) == NULL) { UT_FATAL("!%s: pmemobj_open", path); } } if (!fail) pmemobj_close(pop); FREE(uids); FREE(uscs); if (fail) exit(1); DONE(NULL); } FUNC_MOCK(pmem2_source_device_id, int, const struct pmem2_source *src, char *uid, size_t *len) FUNC_MOCK_RUN_DEFAULT { if (uid_it < uids_size) { if (uid != NULL) { strcpy(uid, uids[uid_it]); uid_it++; } else { *len = strlen(uids[uid_it]) + 1; } } else { return -1; } return 0; } FUNC_MOCK_END FUNC_MOCK(pmem2_source_device_usc, int, const struct pmem2_source *src, uint64_t *usc) FUNC_MOCK_RUN_DEFAULT { if (usc_it < uscs_size) { *usc = uscs[usc_it]; usc_it++; } else { return -1; } return 0; } FUNC_MOCK_END #ifdef _MSC_VER /* * Since libpmemobj is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) #endif pmdk-1.11.1/src/test/obj_tx_invalid/0000775000000000000000000000000014123364546015777 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_invalid/obj_tx_invalid.vcxproj0000664000000000000000000000726414123364546022420 0ustar rootroot Debug x64 Release x64 {9D9E33EB-4C24-4646-A3FB-35DA17247917} Win32Proj obj_tx_invalid 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(IncludePath) Disabled {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_invalid/TEST00000775000000000000000000001435314123364546016572 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_invalid/TEST0 # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_no_asan setup expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 alloc expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zalloc expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 strdup expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 realloc expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 zrealloc expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 free expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 add_range_direct expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 abort expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end-in-work expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end-in-abort expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end-in-commit expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 end expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process-in-work expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process-in-abort expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process-in-commit expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process-in-finally expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process-after-tx expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 process expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin-in-work expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin-in-abort expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin-in-commit expect_abnormal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin-in-finally expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin-after-tx expect_normal_exit ./obj_tx_invalid$EXESUFFIX $DIR/testfile1 begin pass pmdk-1.11.1/src/test/obj_tx_invalid/obj_tx_invalid.c0000664000000000000000000002571514123364546021150 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * obj_tx_invalid.c -- tests which transactional functions are available in * which transaction stages */ #include #include "file.h" #include "unittest.h" /* * Layout definition */ POBJ_LAYOUT_BEGIN(tx_invalid); POBJ_LAYOUT_ROOT(tx_invalid, struct dummy_root); POBJ_LAYOUT_TOID(tx_invalid, struct dummy_node); POBJ_LAYOUT_END(tx_invalid); struct dummy_node { int value; }; struct dummy_root { TOID(struct dummy_node) node; }; int main(int argc, char *argv[]) { if (argc != 3) UT_FATAL("usage: %s file-name op", argv[0]); START(argc, argv, "obj_tx_invalid %s", argv[2]); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(tx_invalid) != 1); PMEMobjpool *pop; const char *path = argv[1]; int exists = util_file_exists(path); if (exists < 0) UT_FATAL("!util_file_exists"); if (!exists) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(tx_invalid), PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) { UT_FATAL("!pmemobj_create %s", path); } } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(tx_invalid))) == NULL) { UT_FATAL("!pmemobj_open %s", path); } } PMEMoid oid = pmemobj_first(pop); if (OID_IS_NULL(oid)) { if (pmemobj_alloc(pop, &oid, 10, 1, NULL, NULL)) UT_FATAL("!pmemobj_alloc"); } else { UT_ASSERTeq(pmemobj_type_num(oid), 1); } if (strcmp(argv[2], "alloc") == 0) pmemobj_tx_alloc(10, 1); else if (strcmp(argv[2], "alloc-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_alloc(10, 1); } TX_END } else if (strcmp(argv[2], "alloc-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_alloc(10, 1); } TX_END } else if (strcmp(argv[2], "alloc-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_alloc(10, 1); } TX_END } else if (strcmp(argv[2], "alloc-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_alloc(10, 1); } TX_END } else if (strcmp(argv[2], "alloc-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_alloc(10, 1); } else if (strcmp(argv[2], "zalloc") == 0) pmemobj_tx_zalloc(10, 1); else if (strcmp(argv[2], "zalloc-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_zalloc(10, 1); } TX_END } else if (strcmp(argv[2], "zalloc-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_zalloc(10, 1); } TX_END } else if (strcmp(argv[2], "zalloc-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_zalloc(10, 1); } TX_END } else if (strcmp(argv[2], "zalloc-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_zalloc(10, 1); } TX_END } else if (strcmp(argv[2], "zalloc-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_zalloc(10, 1); } else if (strcmp(argv[2], "strdup") == 0) pmemobj_tx_strdup("aaa", 1); else if (strcmp(argv[2], "strdup-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_strdup("aaa", 1); } TX_END } else if (strcmp(argv[2], "strdup-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_strdup("aaa", 1); } TX_END } else if (strcmp(argv[2], "strdup-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_strdup("aaa", 1); } TX_END } else if (strcmp(argv[2], "strdup-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_strdup("aaa", 1); } TX_END } else if (strcmp(argv[2], "strdup-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_strdup("aaa", 1); } else if (strcmp(argv[2], "realloc") == 0) pmemobj_tx_realloc(oid, 10, 1); else if (strcmp(argv[2], "realloc-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_realloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "realloc-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_realloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "realloc-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_realloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "realloc-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_realloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "realloc-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_realloc(oid, 10, 1); } else if (strcmp(argv[2], "zrealloc") == 0) pmemobj_tx_zrealloc(oid, 10, 1); else if (strcmp(argv[2], "zrealloc-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_zrealloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "zrealloc-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_zrealloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "zrealloc-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_zrealloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "zrealloc-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_zrealloc(oid, 10, 1); } TX_END } else if (strcmp(argv[2], "zrealloc-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_zrealloc(oid, 10, 1); } else if (strcmp(argv[2], "free") == 0) pmemobj_tx_free(oid); else if (strcmp(argv[2], "free-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_free(oid); } TX_END } else if (strcmp(argv[2], "free-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_free(oid); } TX_END } else if (strcmp(argv[2], "free-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_free(oid); } TX_END } else if (strcmp(argv[2], "free-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_free(oid); } TX_END } else if (strcmp(argv[2], "free-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_free(oid); } else if (strcmp(argv[2], "add_range") == 0) pmemobj_tx_add_range(oid, 0, 10); else if (strcmp(argv[2], "add_range-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_add_range(oid, 0, 10); } TX_END } else if (strcmp(argv[2], "add_range-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_add_range(oid, 0, 10); } TX_END } else if (strcmp(argv[2], "add_range-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_add_range(oid, 0, 10); } TX_END } else if (strcmp(argv[2], "add_range-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_add_range(oid, 0, 10); } TX_END } else if (strcmp(argv[2], "add_range-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_add_range(oid, 0, 10); } else if (strcmp(argv[2], "add_range_direct") == 0) pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); else if (strcmp(argv[2], "add_range_direct-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); } TX_END } else if (strcmp(argv[2], "add_range_direct-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); } TX_END } else if (strcmp(argv[2], "add_range_direct-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); } TX_END } else if (strcmp(argv[2], "add_range_direct-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); } TX_END } else if (strcmp(argv[2], "add_range_direct-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_add_range_direct(pmemobj_direct(oid), 10); } else if (strcmp(argv[2], "abort") == 0) pmemobj_tx_abort(ENOMEM); else if (strcmp(argv[2], "abort-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_END } else if (strcmp(argv[2], "abort-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_abort(ENOMEM); } TX_END } else if (strcmp(argv[2], "abort-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_abort(ENOMEM); } TX_END } else if (strcmp(argv[2], "abort-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_abort(ENOMEM); } TX_END } else if (strcmp(argv[2], "abort-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_abort(ENOMEM); } else if (strcmp(argv[2], "commit") == 0) pmemobj_tx_commit(); else if (strcmp(argv[2], "commit-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_commit(); } TX_END } else if (strcmp(argv[2], "commit-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_commit(); } TX_END } else if (strcmp(argv[2], "commit-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_commit(); } TX_END } else if (strcmp(argv[2], "commit-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_commit(); } TX_END } else if (strcmp(argv[2], "commit-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_commit(); } else if (strcmp(argv[2], "end") == 0) pmemobj_tx_end(); else if (strcmp(argv[2], "end-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_end(); } TX_END } else if (strcmp(argv[2], "end-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_end(); pmemobj_close(pop); exit(0); } TX_END } else if (strcmp(argv[2], "end-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_end(); pmemobj_close(pop); exit(0); } TX_END } else if (strcmp(argv[2], "end-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_end(); pmemobj_close(pop); exit(0); } TX_END } else if (strcmp(argv[2], "end-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_end(); } else if (strcmp(argv[2], "process") == 0) pmemobj_tx_process(); else if (strcmp(argv[2], "process-in-work") == 0) { TX_BEGIN(pop) { pmemobj_tx_process(); } TX_END } else if (strcmp(argv[2], "process-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { pmemobj_tx_process(); } TX_END } else if (strcmp(argv[2], "process-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { pmemobj_tx_process(); } TX_END } else if (strcmp(argv[2], "process-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { pmemobj_tx_process(); pmemobj_tx_end(); pmemobj_close(pop); exit(0); } TX_END } else if (strcmp(argv[2], "process-after-tx") == 0) { TX_BEGIN(pop) { } TX_END pmemobj_tx_process(); } else if (strcmp(argv[2], "begin") == 0) { TX_BEGIN(pop) { } TX_END } else if (strcmp(argv[2], "begin-in-work") == 0) { TX_BEGIN(pop) { TX_BEGIN(pop) { } TX_END } TX_END } else if (strcmp(argv[2], "begin-in-abort") == 0) { TX_BEGIN(pop) { pmemobj_tx_abort(ENOMEM); } TX_ONABORT { TX_BEGIN(pop) { } TX_END } TX_END } else if (strcmp(argv[2], "begin-in-commit") == 0) { TX_BEGIN(pop) { } TX_ONCOMMIT { TX_BEGIN(pop) { } TX_END } TX_END } else if (strcmp(argv[2], "begin-in-finally") == 0) { TX_BEGIN(pop) { } TX_FINALLY { TX_BEGIN(pop) { } TX_END } TX_END } else if (strcmp(argv[2], "begin-after-tx") == 0) { TX_BEGIN(pop) { } TX_END TX_BEGIN(pop) { } TX_END } pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_invalid/Makefile0000664000000000000000000000040214123364546017433 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_invalid/Makefile -- build obj_tx_invalid unit test # TARGET = obj_tx_invalid OBJS = obj_tx_invalid.o LIBPMEMOBJ=y LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_invalid/TEST0.PS10000664000000000000000000001651714123364546017175 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_invalid/TEST0 # # # parameter handling # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 alloc expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zalloc expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 strdup expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 realloc expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 zrealloc expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 free expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 add_range_direct expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 abort expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end-in-work expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end-in-abort expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end-in-commit expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 end expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process-in-work expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process-in-abort expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process-in-commit expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process-in-finally expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process-after-tx expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 process expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin-in-work expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin-in-abort expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin-in-commit expect_abnormal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin-in-finally expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin-after-tx expect_normal_exit $Env:EXE_DIR\obj_tx_invalid$Env:EXESUFFIX $DIR\testfile1 begin pass pmdk-1.11.1/src/test/obj_tx_invalid/obj_tx_invalid.vcxproj.filters0000664000000000000000000000134414123364546024060 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {3df9e9ab-9427-4e59-ac1a-90791f31be5e} Source Files Test scripts pmdk-1.11.1/src/test/obj_tx_invalid/.gitignore0000664000000000000000000000001714123364546017765 0ustar rootrootobj_tx_invalid pmdk-1.11.1/src/test/obj_constructor/0000775000000000000000000000000014123364546016223 5ustar rootrootpmdk-1.11.1/src/test/obj_constructor/TEST00000775000000000000000000000405214123364546017011 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # obj_constructor/TEST0 -- test for obj_constructor # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind memcheck force-disable setup create_holey_file 16M $DIR/testfile1 # This is a pretty length test on non-pmem devices, so force clflushes. export PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_constructor$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_constructor/Makefile0000664000000000000000000000036114123364546017663 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_constructor/Makefile -- build obj_constructor test # TARGET = obj_constructor OBJS = obj_constructor.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_constructor/TEST0.PS10000664000000000000000000000376514123364546017422 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # obj_constructor/TEST0 -- test for obj_constructor # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 16M $DIR\testfile1 # This is a pretty length test on non-pmem devices, so force clflushes. $Env:PMEM_IS_PMEM_FORCE=1 expect_normal_exit $Env:EXE_DIR\obj_constructor$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_constructor/.gitignore0000664000000000000000000000002014123364546020203 0ustar rootrootobj_constructor pmdk-1.11.1/src/test/obj_constructor/TEST10000775000000000000000000000414614123364546017016 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # obj_constructor/TEST1 -- test for obj_constructor # . ../unittest/unittest.sh require_test_type long require_fs_type any configure_valgrind memcheck force-enable require_build_type debug setup create_holey_file 16M $DIR/testfile1 # This is a pretty length test on non-pmem devices, so force clflushes. export PMEM_IS_PMEM_FORCE=1 export VALIDATE_VALGRIND_LOG=0 expect_normal_exit\ ./obj_constructor$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_constructor/obj_constructor.vcxproj.filters0000664000000000000000000000141014123364546024522 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {4c635e1e-5322-46bd-b2dd-d546dcdc461e} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/obj_constructor/obj_constructor.c0000664000000000000000000001042114123364546021604 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * obj_constructor.c -- tests for constructor */ #include #include "unittest.h" /* * Command line toggle indicating use of a bigger node structure for querying * pool size expressed in a number of possible allocations. A small node * structure results in a great number of allocations impossible to replicate * in assumed timeout. It is required by unit tests using remote replication to * pass on Travis. */ #define USE_BIG_ALLOC "--big-alloc" /* * Layout definition */ POBJ_LAYOUT_BEGIN(constr); POBJ_LAYOUT_ROOT(constr, struct root); POBJ_LAYOUT_TOID(constr, struct node); POBJ_LAYOUT_TOID(constr, struct node_big); POBJ_LAYOUT_END(constr); struct root { TOID(struct node) n; POBJ_LIST_HEAD(head, struct node) list; POBJ_LIST_HEAD(head_big, struct node_big) list_big; }; struct node { POBJ_LIST_ENTRY(struct node) next; }; struct node_big { POBJ_LIST_ENTRY(struct node_big) next; int weight[2048]; }; static int root_constr_cancel(PMEMobjpool *pop, void *ptr, void *arg) { return 1; } static int node_constr_cancel(PMEMobjpool *pop, void *ptr, void *arg) { return 1; } struct foo { int bar; }; static struct foo *Canceled_ptr; static int vg_test_save_ptr(PMEMobjpool *pop, void *ptr, void *arg) { Canceled_ptr = (struct foo *)ptr; return 1; } int main(int argc, char *argv[]) { START(argc, argv, "obj_constructor"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(constr) != 2); int big = (argc == 3 && strcmp(argv[2], USE_BIG_ALLOC) == 0); size_t node_size; size_t next_off; if (big) { node_size = sizeof(struct node_big); next_off = offsetof(struct node_big, next); } else if (argc == 2) { node_size = sizeof(struct node); next_off = offsetof(struct node, next); } else { UT_FATAL("usage: %s file-name [ %s ]", argv[0], USE_BIG_ALLOC); } const char *path = argv[1]; PMEMobjpool *pop = NULL; int ret; TOID(struct root) root; TOID(struct node) node; TOID(struct node_big) node_big; if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(constr), 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); errno = 0; root.oid = pmemobj_root_construct(pop, sizeof(struct root), root_constr_cancel, NULL); UT_ASSERT(TOID_IS_NULL(root)); UT_ASSERTeq(errno, ECANCELED); /* * Allocate memory until OOM, so we can check later if the alloc * cancellation didn't damage the heap in any way. */ int allocs = 0; while (pmemobj_alloc(pop, NULL, node_size, 1, NULL, NULL) == 0) allocs++; UT_ASSERTne(allocs, 0); PMEMoid oid; PMEMoid next; POBJ_FOREACH_SAFE(pop, oid, next) pmemobj_free(&oid); errno = 0; ret = pmemobj_alloc(pop, NULL, node_size, 1, node_constr_cancel, NULL); UT_ASSERTeq(ret, -1); UT_ASSERTeq(errno, ECANCELED); /* the same number of allocations should be possible. */ while (pmemobj_alloc(pop, NULL, node_size, 1, NULL, NULL) == 0) allocs--; UT_ASSERT(allocs <= 0); POBJ_FOREACH_SAFE(pop, oid, next) pmemobj_free(&oid); root.oid = pmemobj_root_construct(pop, sizeof(struct root), NULL, NULL); UT_ASSERT(!TOID_IS_NULL(root)); errno = 0; if (big) { node_big.oid = pmemobj_list_insert_new(pop, next_off, &D_RW(root)->list_big, OID_NULL, 0, node_size, 1, node_constr_cancel, NULL); UT_ASSERT(TOID_IS_NULL(node_big)); } else { node.oid = pmemobj_list_insert_new(pop, next_off, &D_RW(root)->list, OID_NULL, 0, node_size, 1, node_constr_cancel, NULL); UT_ASSERT(TOID_IS_NULL(node)); } UT_ASSERTeq(errno, ECANCELED); pmemobj_alloc(pop, &oid, sizeof(struct foo), 1, vg_test_save_ptr, NULL); UT_ASSERTne(Canceled_ptr, NULL); /* this should generate a valgrind memcheck warning */ Canceled_ptr->bar = 5; pmemobj_persist(pop, &Canceled_ptr->bar, sizeof(Canceled_ptr->bar)); /* * Allocate and cancel a huge object. It should return back to the * heap and it should be possible to allocate it again. */ Canceled_ptr = NULL; ret = pmemobj_alloc(pop, &oid, sizeof(struct foo) + (1 << 22), 1, vg_test_save_ptr, NULL); UT_ASSERTne(Canceled_ptr, NULL); void *first_ptr = Canceled_ptr; Canceled_ptr = NULL; ret = pmemobj_alloc(pop, &oid, sizeof(struct foo) + (1 << 22), 1, vg_test_save_ptr, NULL); UT_ASSERTeq(first_ptr, Canceled_ptr); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_constructor/memcheck1.log.match0000664000000000000000000000611314123364546021657 0ustar rootroot==$(N)== Memcheck, a memory error detector ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: $(*) ==$(N)== Parent PID: $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): main (obj_constructor.c:$(N)) ==$(N)== Address 0x$(X) is $(N) bytes after a block of size $(N) free'd ==$(N)== at 0x$(X): ${alloc_prep_block|???} $(*) ==$(N)== by 0x$(X): ${palloc_reservation_create|???} $(*) ==$(N)== by 0x$(X): ${palloc_operation|???} $(*) ==$(N)== by 0x$(X): ${obj_alloc_construct|???} $(*) ==$(N)== by 0x$(X): pmemobj_alloc (obj.c:$(N)) ==$(N)== by 0x$(X): main (obj_constructor.c:$(N)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== at 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== by 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== by 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== by 0x$(X): ${obj_alloc_construct|???} $(*) $(OPT)==$(N)== by 0x$(X): pmemobj_alloc (obj.c:$(N)) $(OPT)==$(N)== by 0x$(X): main (obj_constructor.c:$(N)) ==$(N)== ==$(N)== Unaddressable byte(s) found during client check request ==$(N)== at 0x$(X): pmem_flush (pmem.c:$(N)) ==$(N)== by 0x$(X): pmem_persist (pmem.c:$(N)) ==$(N)== by 0x$(X): ${obj_norep_persist|???} $(*) ==$(N)== by 0x$(X): ${pmemops_xpersist|???} $(*) ==$(N)== by 0x$(X): ${pmemops_persist|???} $(*) ==$(N)== by 0x$(X): pmemobj_persist (obj.c:$(N)) ==$(N)== by 0x$(X): main (obj_constructor.c:$(N)) ==$(N)== Address 0x$(X) is 16 bytes after a block of size 112 free'd ==$(N)== at 0x$(X): ${alloc_prep_block|???} $(*) ==$(N)== by 0x$(X): ${palloc_reservation_create|???} $(*) ==$(N)== by 0x$(X): ${palloc_operation|???} $(*) ==$(N)== by 0x$(X): ${obj_alloc_construct|???} $(*) ==$(N)== by 0x$(X): pmemobj_alloc (obj.c:$(N)) ==$(N)== by 0x$(X): main (obj_constructor.c:$(N)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== at 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== by 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== by 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== by 0x$(X): ${obj_alloc_construct|???} $(*) $(OPT)==$(N)== by 0x$(X): pmemobj_alloc (obj.c:$(N)) $(OPT)==$(N)== by 0x$(X): main (obj_constructor.c:$(N)) ==$(N)== ==$(N)== ==$(N)== HEAP SUMMARY: $(OPT)==$(N)== in use at exit: 0 bytes in 0 blocks $(OPX)==$(N)== in use at exit: $(NC) bytes in $(N) blocks ==$(N)== total heap usage: $(NC) allocs, $(NC) frees, $(NC) bytes allocated ==$(N)== $(OPT)==$(N)== All heap blocks were freed -- no leaks are possible $(OPT)==$(N)== $(OPX)==$(N)== LEAK SUMMARY: $(OPT)==$(N)== definitely lost: 0 bytes in 0 blocks $(OPT)==$(N)== indirectly lost: 0 bytes in 0 blocks $(OPT)==$(N)== possibly lost: 0 bytes in 0 blocks $(OPT)==$(N)== still reachable: 0 bytes in 0 blocks $(OPT)==$(N)== suppressed: $(NC) bytes in $(N) blocks $(OPT)==$(N)== Reachable blocks (those to which a pointer was found) are not shown. $(OPT)==$(N)== To see them, rerun with: --leak-check=full --show-leak-kinds=all $(OPT)==$(N)== ==$(N)== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: $(N) from $(N)) pmdk-1.11.1/src/test/obj_constructor/TEST20000775000000000000000000000372214123364546017016 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # obj_constructor/TEST2 -- test for obj_constructor # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem configure_valgrind memcheck force-disable setup create_holey_file 32M $DIR/testfile1 expect_normal_exit\ ./obj_constructor$EXESUFFIX $DIR/testfile1 --big-alloc pass pmdk-1.11.1/src/test/obj_constructor/obj_constructor.vcxproj0000664000000000000000000000714114123364546023062 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {E7691F81-86EF-467D-82E1-F5B9416386F9} Win32Proj obj_constructor 10.0.17134.0 Application true v140 Application false v140 NotUsing CompileAsCpp NotUsing CompileAsCpp pmdk-1.11.1/src/test/libpmempool_rm_win/0000775000000000000000000000000014123364546016676 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_rm_win/libpmempool_rm_win.c0000664000000000000000000000247514123364546022744 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2019, Intel Corporation */ /* * libpmempool_rm_win -- a unittest for pmempool_rm. * */ #include #include #include #include #include #include "unittest.h" #define FATAL_USAGE(n) UT_FATAL("usage: %s [-f -l -r] path..", (n)) static PMEMobjpool *Pop; int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "libpmempool_rm_win"); if (argc < 2) FATAL_USAGE(ut_toUTF8(argv[0])); unsigned flags = 0; int do_open = 0; int i = 1; for (; i < argc - 1; i++) { wchar_t *optarg = argv[i + 1]; if (wcscmp(L"-f", argv[i]) == 0) flags |= PMEMPOOL_RM_FORCE; else if (wcscmp(L"-r", argv[i]) == 0) flags |= PMEMPOOL_RM_POOLSET_REMOTE; else if (wcscmp(L"-l", argv[i]) == 0) flags |= PMEMPOOL_RM_POOLSET_LOCAL; else if (wcscmp(L"-o", argv[i]) == 0) do_open = 1; else if (wcschr(argv[i], L'-') == argv[i]) FATAL_USAGE(argv[0]); else break; } for (; i < argc; i++) { const wchar_t *path = argv[i]; if (do_open) { Pop = pmemobj_openW(path, NULL); UT_ASSERTne(Pop, NULL); } int ret = pmempool_rmW(path, flags); if (ret) { UT_OUT("!%s: %s", ut_toUTF8(path), pmempool_errormsgU()); } if (do_open) { UT_ASSERTne(Pop, NULL); pmemobj_close(Pop); } } DONEW(NULL); } pmdk-1.11.1/src/test/libpmempool_rm_win/TEST1.PS10000664000000000000000000000456714123364546020077 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # libpmempool_rm_win/TEST0 -- test pmempool_rm with pool set files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR\pool1p1r.set 32M:$DIR\pool1p1.obj:x create_poolset $DIR\pool3p2r.set 32M:$DIR\pool2p1.obj:x ` 32M:$DIR\pool2p2.obj:x 32M:$DIR\pool2p3.obj:x ` R 32M:$DIR\pool3p1.obj:x 32M:$DIR\pool3p2.obj:x 32M:$DIR\pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool3p2r.set check_files $DIR\pool1p1r.set $DIR\pool1p1.obj ` $DIR\pool3p2r.set $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # this should remove all the pool files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\pool1p1r.set $DIR\pool3p2r.set # check if all pool files are removed check_no_files $DIR\pool1p1.obj $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # poolset files should exist check_files $DIR\pool1p1r.set $DIR\pool3p2r.set create_poolset $DIR\pool1p1r.set 32M:$DIR\pool1p1.obj:x create_poolset $DIR\pool3p2r.set 32M:$DIR\pool2p1.obj:x ` 32M:$DIR\pool2p2.obj:x 32M:$DIR\pool2p3.obj:x ` R 32M:$DIR\pool3p1.obj:x 32M:$DIR\pool3p2.obj:x 32M:$DIR\pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool3p2r.set check_files $DIR\pool1p1r.set $DIR\pool1p1.obj ` $DIR\pool3p2r.set $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # this should remove all the pool files and pool sets expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -l $DIR\pool1p1r.set $DIR\pool3p2r.set # check if all pool files are removed check_no_files $DIR\pool1p1.obj $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj ` $DIR\pool1p1r.set $DIR\pool3p2r.set # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\pool1p1r.set $DIR\pool3p2r.set # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -f $DIR\pool1p1r.set $DIR\pool3p2r.set check pass pmdk-1.11.1/src/test/libpmempool_rm_win/libpmempool_rm_win.vcxproj.filters0000664000000000000000000000314414123364546025656 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {647c8d91-a249-479c-8257-48485cca5496} {4b815d42-293f-4247-a398-ddb95991a88a} Source Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/libpmempool_rm_win/libpmempool_rm_win.vcxproj0000664000000000000000000001062114123364546024205 0ustar rootroot Debug x64 Release x64 {67AC1343-98FD-4143-92C0-559C55F749F5} Win32Proj libpmempool_rm_win 10.0.17134.0 Application true v140 Application false v140 true false $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) true $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {1baa1617-93ae-4196-8a1a-bd492fb18aef} {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_rm_win/TEST3.PS10000664000000000000000000000107014123364546020063 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # libpmempool_rm_win/TEST3 -- test pmempool_rm with directories # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append mkdir $DIR\dir.1 | out-null mkdir $DIR\dir.2 | out-null mkdir $DIR\dir.2\dir.3 | out-null expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\dir.1 $DIR\dir.2 $DIR\dir.2\dir.3 expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -f $DIR\dir.1 $DIR\dir.2 $DIR\dir.2\dir.3 check pass pmdk-1.11.1/src/test/libpmempool_rm_win/TEST2.PS10000664000000000000000000000213414123364546020064 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # libpmempool_rm_win/TEST2 -- test pmempool_rm with non-pool files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append [System.IO.File]::WriteAllText("$DIR\file.1", "TEST"); [System.IO.File]::WriteAllText("$DIR\file.2", "TEST`n"); [System.IO.File]::WriteAllText("$DIR\file.3", ""); [System.IO.File]::WriteAllText("$DIR\file.4", "NOTAPMEMPOOLSET`n"); check_files $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should remove all the files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # check if all pool files are removed check_no_files $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -f $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 check pass pmdk-1.11.1/src/test/libpmempool_rm_win/out0.log.match0000664000000000000000000000106114123364546021361 0ustar rootrootlibpmempool_rm_win/TEST0: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) libpmempool_rm_win/TEST0: DONE libpmempool_rm_win/TEST0: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) $(nW)pool.blk: removing file failed: No such file or directory $(nW)pool.log: removing file failed: No such file or directory $(nW)pool.obj: removing file failed: No such file or directory libpmempool_rm_win/TEST0: DONE libpmempool_rm_win/TEST0: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -f $(*) libpmempool_rm_win/TEST0: DONE pmdk-1.11.1/src/test/libpmempool_rm_win/TEST0.PS10000664000000000000000000000204214123364546020060 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # libpmempool_rm_win/TEST0 -- test pmempool_rm with single-file pools # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append expect_normal_exit $PMEMPOOL$EXESUFFIX create blk 512 $DIR\pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create log $DIR\pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.obj check_files $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should remove all the pool files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # check if all pool files are removed check_no_files $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -f $DIR\pool.blk $DIR\pool.log $DIR\pool.obj check pass pmdk-1.11.1/src/test/libpmempool_rm_win/README0000664000000000000000000000021514123364546017554 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_rm_win/README. This directory contains unit tests for pmempool_rm function. pmdk-1.11.1/src/test/libpmempool_rm_win/TEST4.PS10000664000000000000000000000140714123364546020070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # libpmempool_rm_win/TEST4 -- test pmempool_rm with opened files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR\pool.set 32M:$DIR\pool.obj.1:x 32M:$DIR\pool.obj.2:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.obj expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.set check_files $DIR\pool.obj $DIR\pool.set $DIR\pool.obj.1 expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -o $DIR\pool.obj check_files $DIR\pool.obj expect_normal_exit $Env:EXE_DIR\libpmempool_rm_win$Env:EXESUFFIX -o $DIR\pool.set check_files $DIR\pool.set $DIR\pool.obj.1 $DIR\pool.obj.2 check pass pmdk-1.11.1/src/test/libpmempool_rm_win/out1.log.match0000664000000000000000000000116714123364546021371 0ustar rootrootlibpmempool_rm_win/TEST1: START: libpmempool_rm_win$(nW) $(nW)ibpmempool_rm_win$(nW) $(*) libpmempool_rm_win/TEST1: DONE libpmempool_rm_win/TEST1: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -l $(*) libpmempool_rm_win/TEST1: DONE libpmempool_rm_win/TEST1: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) $(nW)pool1p1r.set: removing file failed: No such file or directory $(nW)pool3p2r.set: removing file failed: No such file or directory libpmempool_rm_win/TEST1: DONE libpmempool_rm_win/TEST1: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -f $(*) libpmempool_rm_win/TEST1: DONE pmdk-1.11.1/src/test/libpmempool_rm_win/out5.log.match0000664000000000000000000000025214123364546021367 0ustar rootrootlibpmempool_rm_win/TEST5: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) $(nW): removing file failed: Permission denied libpmempool_rm_win/TEST5: DONE pmdk-1.11.1/src/test/libpmempool_rm_win/out3.log.match0000664000000000000000000000100114123364546021356 0ustar rootrootlibpmempool_rm_win/TEST3: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory libpmempool_rm_win/TEST3: DONE libpmempool_rm_win/TEST3: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -f $(*) $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory libpmempool_rm_win/TEST3: DONE pmdk-1.11.1/src/test/libpmempool_rm_win/out4.log.match0000664000000000000000000000050714123364546021371 0ustar rootrootlibpmempool_rm_win/TEST4: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -o $(*) $(nW): removing file failed: $(*) libpmempool_rm_win/TEST4: DONE libpmempool_rm_win/TEST4: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -o $(*) $(nW): $(nW): removing file failed: $(*) libpmempool_rm_win/TEST4: DONE pmdk-1.11.1/src/test/libpmempool_rm_win/out2.log.match0000664000000000000000000000112014123364546021357 0ustar rootrootlibpmempool_rm_win/TEST2: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) libpmempool_rm_win/TEST2: DONE libpmempool_rm_win/TEST2: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) $(*) $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory libpmempool_rm_win/TEST2: DONE libpmempool_rm_win/TEST2: START: libpmempool_rm_win$(nW) $(nW)libpmempool_rm_win$(nW) -f $(*) libpmempool_rm_win/TEST2: DONE pmdk-1.11.1/src/test/pmem2_map_prot/0000775000000000000000000000000014123364546015725 5ustar rootrootpmdk-1.11.1/src/test/pmem2_map_prot/pmem2_map_prot.c0000664000000000000000000003265614123364546021026 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_map_prot.c -- pmem2_map_prot unit tests */ #include #include #include #include "config.h" #include "source.h" #include "map.h" #include "out.h" #include "pmem2.h" #include "unittest.h" #include "ut_pmem2.h" #include "ut_pmem2_setup.h" #include "ut_fh.h" struct res { struct FHandle *fh; struct pmem2_config cfg; struct pmem2_source *src; }; /* * res_prepare -- set access mode and protection flags */ static void res_prepare(const char *file, struct res *res, int access, unsigned proto) { #ifdef _WIN32 enum file_handle_type fh_type = FH_HANDLE; #else enum file_handle_type fh_type = FH_FD; #endif ut_pmem2_prepare_config(&res->cfg, &res->src, &res->fh, fh_type, file, 0, 0, access); pmem2_config_set_protection(&res->cfg, proto); } /* * res_cleanup -- free resources */ static void res_cleanup(struct res *res) { PMEM2_SOURCE_DELETE(&res->src); UT_FH_CLOSE(res->fh); } static const char *word1 = "Persistent or nonpersistent: this is the question."; static ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { ut_siglongjmp(Jmp); } /* * test_rw_mode_rw_prot -- test R/W protection * pmem2_map_new() - should success * memcpy() - should success */ static int test_rw_mode_rw_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rw_mode_rw_prot "); struct res res; /* read/write on file opened in read/write mode - should success */ res_prepare(argv[0], &res, FH_RDWR, PMEM2_PROT_READ | PMEM2_PROT_WRITE); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); void *addr_map = pmem2_map_get_address(map); memcpy_fn(addr_map, word1, strlen(word1), 0); UT_ASSERTeq(memcmp(addr_map, word1, strlen(word1)), 0); pmem2_map_delete(&map); res_cleanup(&res); return 1; } /* * template_mode_prot_mismatch - try to map file with mutually exclusive FD * access and map protection */ static void template_mode_prot_mismatch(char *file, int access, unsigned prot) { struct res res; /* read/write on file opened in read-only mode - should fail */ res_prepare(file, &res, access, prot); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_NO_ACCESS); res_cleanup(&res); } /* * test_r_mode_rw_prot -- test R/W protection * pmem2_map_new() - should fail */ static int test_r_mode_rw_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_r_mode_rw_prot "); char *file = argv[0]; template_mode_prot_mismatch(file, FH_READ, PMEM2_PROT_WRITE | PMEM2_PROT_READ); return 1; } /* * test_rw_mode_rwx_prot - test R/W/X protection on R/W file * pmem2_map_new() - should fail */ static int test_rw_modex_rwx_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rw_modex_rwx_prot "); char *file = argv[0]; template_mode_prot_mismatch(file, FH_RDWR, PMEM2_PROT_EXEC |PMEM2_PROT_WRITE | PMEM2_PROT_READ); return 1; } /* * test_rw_modex_rx_prot - test R/X protection on R/W file * pmem2_map_new() - should fail */ static int test_rw_modex_rx_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rw_modex_rx_prot "); char *file = argv[0]; template_mode_prot_mismatch(file, FH_RDWR, PMEM2_PROT_EXEC | PMEM2_PROT_READ); return 1; } /* * test_rw_mode_r_prot -- test R/W protection * pmem2_map_new() - should success * memcpy() - should fail */ static int test_rw_mode_r_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rw_mode_r_prot "); /* arrange to catch SIGSEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); struct res res; /* read-only on file opened in read/write mode - should success */ res_prepare(argv[0], &res, FH_RDWR, PMEM2_PROT_READ); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); void *addr_map = pmem2_map_get_address(map); if (!ut_sigsetjmp(Jmp)) { /* memcpy should now fail */ memcpy_fn(addr_map, word1, strlen(word1), 0); UT_FATAL("memcpy successful"); } pmem2_map_delete(&map); res_cleanup(&res); signal(SIGSEGV, SIG_DFL); return 1; } /* * test_r_mode_r_prot -- test R/W protection * pmem2_map_new() - should success * memcpy() - should fail */ static int test_r_mode_r_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_r_mode_r_prot "); /* arrange to catch SIGSEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); struct res res; /* read-only on file opened in read-only mode - should succeed */ res_prepare(argv[0], &res, FH_READ, PMEM2_PROT_READ); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); void *addr_map = pmem2_map_get_address(map); if (!ut_sigsetjmp(Jmp)) { /* memcpy should now fail */ memcpy_fn(addr_map, word1, strlen(word1), 0); UT_FATAL("memcpy successful"); } pmem2_map_delete(&map); res_cleanup(&res); signal(SIGSEGV, SIG_DFL); return 1; } /* * test_rw_mode_none_prot -- test R/W protection * pmem2_map_new() - should success * memcpy() - should fail */ static int test_rw_mode_none_prot(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rw_mode_none_prot "); /* arrange to catch SIGSEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); struct res res; /* none on file opened in read-only mode - should success */ res_prepare(argv[0], &res, FH_READ, PMEM2_PROT_NONE); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); void *addr_map = pmem2_map_get_address(map); if (!ut_sigsetjmp(Jmp)) { /* memcpy should now fail */ memcpy_fn(addr_map, word1, strlen(word1), 0); UT_FATAL("memcpy successful"); } pmem2_map_delete(&map); res_cleanup(&res); signal(SIGSEGV, SIG_DFL); return 1; } /* * sum_asm[] --> simple program in assembly which calculates '2 + 2' and * returns the result */ static unsigned char sum_asm[] = { 0x55, /* push %rbp */ 0x48, 0x89, 0xe5, /* mov %rsp,%rbp */ 0xc7, 0x45, 0xf8, 0x02, 0x00, 0x00, 0x00, /* movl $0x2,-0x8(%rbp) */ 0x8b, 0x45, 0xf8, /* mov -0x8(%rbp),%eax */ 0x01, 0xc0, /* add %eax,%eax */ 0x89, 0x45, 0xfc, /* mov %eax,-0x4(%rbp) */ 0x8b, 0x45, 0xfc, /* mov -0x4(%rbp),%eax */ 0x5d, /* pop %rbp */ 0xc3, /* retq */ }; typedef int (*sum_fn)(void); /* * test_rx_mode_rx_prot_do_execute -- copy string with the program to mapped * memory to prepare memory, execute the program and verify result */ static int test_rx_mode_rx_prot_do_execute(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_rx_mode_rx_prot_do_execute "); char *file = argv[0]; struct res res; /* Windows does not support PMEM2_PROT_WRITE combination */ res_prepare(file, &res, FH_EXEC | FH_RDWR, PMEM2_PROT_WRITE | PMEM2_PROT_READ); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); char *addr_map = pmem2_map_get_address(map); map->memcpy_fn(addr_map, sum_asm, sizeof(sum_asm), 0); pmem2_map_delete(&map); /* Windows does not support PMEM2_PROT_EXEC combination */ pmem2_config_set_protection(&res.cfg, PMEM2_PROT_READ | PMEM2_PROT_EXEC); ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); sum_fn sum = (sum_fn)addr_map; int sum_result = sum(); UT_ASSERTeq(sum_result, 4); pmem2_map_delete(&map); res_cleanup(&res); return 1; } /* * test_rwx_mode_rx_prot_do_write -- try to copy the string into mapped memory, * expect failure */ static int test_rwx_mode_rx_prot_do_write(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL( "usage: test_rwx_mode_rx_prot_do_write "); struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char *file = argv[0]; unsigned if_sharing = ATOU(argv[1]); struct res res; /* Windows does not support PMEM2_PROT_EXEC combination */ res_prepare(file, &res, FH_EXEC | FH_RDWR, PMEM2_PROT_READ | PMEM2_PROT_EXEC); if (if_sharing) pmem2_config_set_sharing(&res.cfg, PMEM2_PRIVATE); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); char *addr_map = pmem2_map_get_address(map); if (!ut_sigsetjmp(Jmp)) { /* memcpy_fn should fail */ map->memcpy_fn(addr_map, sum_asm, sizeof(sum_asm), 0); } pmem2_map_delete(&map); res_cleanup(&res); signal(SIGSEGV, SIG_DFL); return 2; } /* * test_rwx_mode_rwx_prot_do_execute -- copy string with the program to mapped * memory to prepare memory, execute the program and verify result */ static int test_rwx_mode_rwx_prot_do_execute(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL( "usage: test_rwx_mode_rwx_prot_do_execute "); char *file = argv[0]; unsigned if_sharing = ATOU(argv[1]); struct res res; res_prepare(file, &res, FH_EXEC | FH_RDWR, PMEM2_PROT_EXEC | PMEM2_PROT_WRITE | PMEM2_PROT_READ); if (if_sharing) pmem2_config_set_sharing(&res.cfg, PMEM2_PRIVATE); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); char *addr_map = pmem2_map_get_address(map); map->memcpy_fn(addr_map, sum_asm, sizeof(sum_asm), 0); sum_fn sum = (sum_fn)addr_map; int sum_result = sum(); UT_ASSERTeq(sum_result, 4); pmem2_map_delete(&map); res_cleanup(&res); signal(SIGSEGV, SIG_DFL); return 2; } /* * test_rw_mode_rw_prot_do_execute -- copy string with the program to mapped * memory to prepare memory, and execute the program - should fail */ static int test_rw_mode_rw_prot_do_execute(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL( "usage: test_rw_mode_rwx_prot_do_execute "); struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char *file = argv[0]; unsigned if_sharing = ATOU(argv[1]); struct res res; res_prepare(file, &res, FH_RDWR, PMEM2_PROT_WRITE | PMEM2_PROT_READ); if (if_sharing) pmem2_config_set_sharing(&res.cfg, PMEM2_PRIVATE); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); void *addr_map = pmem2_map_get_address(map); map->memcpy_fn(addr_map, sum_asm, sizeof(sum_asm), 0); sum_fn sum = (sum_fn)addr_map; if (!ut_sigsetjmp(Jmp)) { sum(); /* sum function should now fail */ } pmem2_map_delete(&map); res_cleanup(&res); return 2; } static const char initial_state[] = "No code."; /* * test_rwx_prot_map_priv_do_execute -- copy string with the program to * the mapped memory with MAP_PRIVATE to prepare memory, execute the program * and verify the result */ static int test_rwx_prot_map_priv_do_execute(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL( "usage: test_rwx_prot_map_priv_do_execute "); char *file = argv[0]; struct res res; res_prepare(file, &res, FH_RDWR, PMEM2_PROT_WRITE | PMEM2_PROT_READ); struct pmem2_map *map; int ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); char *addr_map = pmem2_map_get_address(map); map->memcpy_fn(addr_map, initial_state, sizeof(initial_state), 0); pmem2_map_delete(&map); res_cleanup(&res); res_prepare(file, &res, FH_READ | FH_EXEC, PMEM2_PROT_EXEC | PMEM2_PROT_WRITE | PMEM2_PROT_READ); pmem2_config_set_sharing(&res.cfg, PMEM2_PRIVATE); ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); addr_map = pmem2_map_get_address(map); map->memcpy_fn(addr_map, sum_asm, sizeof(sum_asm), 0); sum_fn sum = (sum_fn)addr_map; int sum_result = sum(); UT_ASSERTeq(sum_result, 4); pmem2_map_delete(&map); ret = pmem2_map_new(&map, &res.cfg, res.src); UT_ASSERTeq(ret, 0); addr_map = pmem2_map_get_address(map); /* check if changes in private mapping affect initial state */ UT_ASSERTeq(memcmp(addr_map, initial_state, strlen(initial_state)), 0); pmem2_map_delete(&map); res_cleanup(&res); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_rw_mode_rw_prot), TEST_CASE(test_r_mode_rw_prot), TEST_CASE(test_rw_modex_rwx_prot), TEST_CASE(test_rw_modex_rx_prot), TEST_CASE(test_rw_mode_r_prot), TEST_CASE(test_r_mode_r_prot), TEST_CASE(test_rw_mode_none_prot), TEST_CASE(test_rx_mode_rx_prot_do_execute), TEST_CASE(test_rwx_mode_rx_prot_do_write), TEST_CASE(test_rwx_mode_rwx_prot_do_execute), TEST_CASE(test_rw_mode_rw_prot_do_execute), TEST_CASE(test_rwx_prot_map_priv_do_execute), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_map_prot"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } #ifdef _MSC_VER MSVC_CONSTR(libpmem2_init) MSVC_DESTR(libpmem2_fini) #endif pmdk-1.11.1/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj0000664000000000000000000001342014123364546022263 0ustar rootroot Debug x64 Release x64 {59D9E21C-57D7-4D18-B792-24738BD26DE4} pmem2_map_prot 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_map_prot/Makefile0000664000000000000000000000063314123364546017367 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # # src/test/pmem2_map_prot/Makefile -- build pmem2_map_prot unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_map_prot OBJS += pmem2_map_prot.o\ ut_pmem2_config.o\ ut_pmem2_utils.o\ ut_pmem2_setup.o\ ut_pmem2_source.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_map_prot/TESTS.py0000664000000000000000000001150414123364546017202 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t class PMEM2_MAP_PROT(t.Test): test_type = t.Short filesize = 16 * t.MiB def run(self, ctx): filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmem2_map_prot', self.test_case, filepath) class TEST0(PMEM2_MAP_PROT): """ READ/WRITE protection on file opened in read-write mode - should succeed """ test_case = "test_rw_mode_rw_prot" class TEST1(PMEM2_MAP_PROT): """ READ/WRITE protection on file opened in read-only mode - should fail """ test_case = "test_r_mode_rw_prot" @t.windows_only class TEST2(PMEM2_MAP_PROT): """ READ/WRITE protection on file opened in read-only mode - should fail """ test_case = "test_rw_modex_rwx_prot" @t.windows_only class TEST3(PMEM2_MAP_PROT): """ READ/WRITE protection on file opened in read-only mode - should fail """ test_case = "test_rw_modex_rx_prot" class TEST4(PMEM2_MAP_PROT): """ READ protection on file opened in read-write mode - should succeed """ test_case = "test_rw_mode_r_prot" class TEST5(PMEM2_MAP_PROT): """ READ protection on file opened in read-only mode - should succeed """ test_case = "test_r_mode_r_prot" # PMEM2_PROT_NONE flag is not supported by the CreateFileMapping function. # This test on purpose performs an "Invalid write" # which causes Memcheck to fail. @t.windows_exclude @t.require_valgrind_disabled('memcheck') class TEST6(PMEM2_MAP_PROT): """ NONE protection on file opened in read-write mode - should succeed """ test_case = "test_rw_mode_none_prot" @t.require_architectures('x86_64') class TEST7(PMEM2_MAP_PROT): """ READ|EXEC protection on file opened in read|write|exec mode; test runs the program, which is put in mapped memory - should succeed """ test_case = "test_rx_mode_rx_prot_do_execute" class PMEM2_PROT_EXEC(t.Test): test_type = t.Short filesize = 16 * t.MiB is_map_private = 0 def run(self, ctx): filepath = ctx.create_holey_file(self.filesize, 'testfile') ctx.exec('pmem2_map_prot', self.test_case, filepath, self.is_map_private) class TEST8(PMEM2_PROT_EXEC): """ READ|EXEC protection on file opened in read|write|exec mode; test writes data to mapped memory - should failed """ test_case = "test_rwx_mode_rx_prot_do_write" class TEST9(PMEM2_PROT_EXEC): """ READ|EXEC protection on file opened in read|write|exec mode; test writes data to mapped memory with MAP_PRIVATE - should failed """ test_case = "test_rwx_mode_rx_prot_do_write" is_map_private = 1 @t.require_architectures('x86_64') class TEST10(PMEM2_PROT_EXEC): """ READ|WRITE|EXEC protection on file opened in read|write|exec mode; test runs the program, which is put in mapped memory - should succeed """ test_case = "test_rwx_mode_rwx_prot_do_execute" @t.require_architectures('x86_64') class TEST11(PMEM2_PROT_EXEC): """ READ|WRITE protection on file opened in read|write mode; test runs the program, which is put in mapped memory with MAP_PRIVATE - should succeed """ test_case = "test_rwx_mode_rwx_prot_do_execute" is_map_private = 1 @t.require_architectures('x86_64') class TEST12(PMEM2_PROT_EXEC): """ READ|EXEC protection on file opened in read|write mode; test runs the program, which is put in mapped memory - should failed """ test_case = "test_rw_mode_rw_prot_do_execute" @t.require_architectures('x86_64') class TEST13(PMEM2_PROT_EXEC): """ READ|EXEC protection on file opened in read|write mode; test runs the program, which is put in mapped memory with MAP_PRIVATE - should failed """ test_case = "test_rw_mode_rw_prot_do_execute" is_map_private = 1 @t.require_architectures('x86_64') class TEST14(PMEM2_MAP_PROT): """ READ|EXEC protection on file opened in read|exec|write mode; test runs the program, which is put in mapped memory with MAP_PRIVATE - should succeed """ test_case = "test_rwx_prot_map_priv_do_execute" @t.windows_exclude @t.require_devdax(t.DevDax('devdax1')) class PMEM2_MAP_DEVDAX(t.Test): test_type = t.Short def run(self, ctx): dd = ctx.devdaxes.devdax1 ctx.exec('pmem2_map_prot', self.test_case, dd.path) class TEST15(PMEM2_MAP_DEVDAX): """ READ/WRITE protection on device DAX opened in read-write mode - should succeed """ test_case = "test_rw_mode_rw_prot" @t.require_fs_exec @t.require_architectures('x86_64') class TEST16(PMEM2_MAP_DEVDAX): """ READ|EXEC protection on device DAX opened in read|write|exec mode; test runs the program, which is put in mapped memory - should succeed """ test_case = "test_rx_mode_rx_prot_do_execute" pmdk-1.11.1/src/test/pmem2_map_prot/.gitignore0000664000000000000000000000001714123364546017713 0ustar rootrootpmem2_map_prot pmdk-1.11.1/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj.filters0000664000000000000000000000723714123364546023743 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {4557bbd3-f8c2-4d53-821f-ec79100e2b50} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Test Scripts pmdk-1.11.1/src/test/rpmemd_obc/0000775000000000000000000000000014123364546015113 5ustar rootrootpmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_common.c0000664000000000000000000001736414123364546022010 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmemd_obc_test_common.c -- common definitions for rpmemd_obc tests */ #include #include #include #include "os.h" #include "rpmemd_obc_test_common.h" #define CMD_BUFF_SIZE 4096 static const char *rpmem_cmd; /* * set_rpmem_cmd -- set RPMEM_CMD variable */ void set_rpmem_cmd(const char *fmt, ...) { static char cmd_buff[CMD_BUFF_SIZE]; if (!rpmem_cmd) { char *cmd = os_getenv(RPMEM_CMD_ENV); UT_ASSERTne(cmd, NULL); rpmem_cmd = STRDUP(cmd); } ssize_t ret; size_t cnt = 0; va_list ap; va_start(ap, fmt); ret = SNPRINTF(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, "%s ", rpmem_cmd); UT_ASSERT(ret > 0); cnt += (size_t)ret; ret = vsnprintf(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, fmt, ap); UT_ASSERT(ret > 0); cnt += (size_t)ret; va_end(ap); ret = os_setenv(RPMEM_CMD_ENV, cmd_buff, 1); UT_ASSERTeq(ret, 0); /* * Rpmem has internal RPMEM_CMD variable copy and it is assumed * RPMEMD_CMD will not change its value during execution. To refresh the * internal copy it must be destroyed and a instance must be initialized * manually. */ rpmem_util_cmds_fini(); rpmem_util_cmds_init(); } /* * req_cb_check_req -- validate request attributes */ static void req_cb_check_req(const struct rpmem_req_attr *req) { UT_ASSERTeq(req->nlanes, NLANES); UT_ASSERTeq(req->pool_size, POOL_SIZE); UT_ASSERTeq(req->provider, PROVIDER); UT_ASSERTeq(strcmp(req->pool_desc, POOL_DESC), 0); } /* * req_cb_check_pool_attr -- validate pool attributes */ static void req_cb_check_pool_attr(const struct rpmem_pool_attr *pool_attr) { struct rpmem_pool_attr attr = POOL_ATTR_INIT; UT_ASSERTeq(memcmp(&attr, pool_attr, sizeof(attr)), 0); } /* * req_cb_create -- callback for create request operation * * This function behaves according to arguments specified via * struct req_cb_arg. */ static int req_cb_create(struct rpmemd_obc *obc, void *arg, const struct rpmem_req_attr *req, const struct rpmem_pool_attr *pool_attr) { UT_ASSERTne(arg, NULL); UT_ASSERTne(req, NULL); UT_ASSERTne(pool_attr, NULL); req_cb_check_req(req); req_cb_check_pool_attr(pool_attr); struct req_cb_arg *args = arg; args->types |= (1 << RPMEM_MSG_TYPE_CREATE); int ret = args->ret; if (args->resp) { struct rpmem_resp_attr resp = { .port = PORT, .rkey = RKEY, .raddr = RADDR, .persist_method = PERSIST_METHOD, .nlanes = NLANES_RESP, }; ret = rpmemd_obc_create_resp(obc, args->status, &resp); } if (args->force_ret) ret = args->ret; return ret; } /* * req_cb_open -- callback for open request operation * * This function behaves according to arguments specified via * struct req_cb_arg. */ static int req_cb_open(struct rpmemd_obc *obc, void *arg, const struct rpmem_req_attr *req) { UT_ASSERTne(arg, NULL); UT_ASSERTne(req, NULL); req_cb_check_req(req); struct req_cb_arg *args = arg; args->types |= (1 << RPMEM_MSG_TYPE_OPEN); int ret = args->ret; if (args->resp) { struct rpmem_resp_attr resp = { .port = PORT, .rkey = RKEY, .raddr = RADDR, .persist_method = PERSIST_METHOD, .nlanes = NLANES_RESP, }; struct rpmem_pool_attr pool_attr = POOL_ATTR_INIT; ret = rpmemd_obc_open_resp(obc, args->status, &resp, &pool_attr); } if (args->force_ret) ret = args->ret; return ret; } /* * req_cb_close -- callback for close request operation * * This function behaves according to arguments specified via * struct req_cb_arg. */ static int req_cb_close(struct rpmemd_obc *obc, void *arg, int flags) { UT_ASSERTne(arg, NULL); struct req_cb_arg *args = arg; args->types |= (1 << RPMEM_MSG_TYPE_CLOSE); int ret = args->ret; if (args->resp) ret = rpmemd_obc_close_resp(obc, args->status); if (args->force_ret) ret = args->ret; return ret; } /* * req_cb_set_attr -- callback for set attributes request operation * * This function behaves according to arguments specified via * struct req_cb_arg. */ static int req_cb_set_attr(struct rpmemd_obc *obc, void *arg, const struct rpmem_pool_attr *pool_attr) { UT_ASSERTne(arg, NULL); struct req_cb_arg *args = arg; args->types |= (1 << RPMEM_MSG_TYPE_SET_ATTR); int ret = args->ret; if (args->resp) ret = rpmemd_obc_set_attr_resp(obc, args->status); if (args->force_ret) ret = args->ret; return ret; } /* * REQ_CB -- request callbacks */ struct rpmemd_obc_requests REQ_CB = { .create = req_cb_create, .open = req_cb_open, .close = req_cb_close, .set_attr = req_cb_set_attr, }; /* * clnt_wait_disconnect -- wait for disconnection */ void clnt_wait_disconnect(struct rpmem_ssh *ssh) { int ret; ret = rpmem_ssh_monitor(ssh, 0); UT_ASSERTne(ret, 1); } /* * clnt_connect -- create a ssh connection with specified target */ struct rpmem_ssh * clnt_connect(char *target) { struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); struct rpmem_ssh *ssh = rpmem_ssh_open(info); UT_ASSERTne(ssh, NULL); rpmem_target_free(info); return ssh; } /* * clnt_close -- close client */ void clnt_close(struct rpmem_ssh *ssh) { rpmem_ssh_close(ssh); } /* * clnt_send -- send data */ void clnt_send(struct rpmem_ssh *ssh, const void *buff, size_t len) { int ret; ret = rpmem_ssh_send(ssh, buff, len); UT_ASSERTeq(ret, 0); } /* * clnt_recv -- receive data */ void clnt_recv(struct rpmem_ssh *ssh, void *buff, size_t len) { int ret; ret = rpmem_ssh_recv(ssh, buff, len); UT_ASSERTeq(ret, 0); } /* * server_msg_args -- process a message according to specified arguments */ static void server_msg_args(struct rpmemd_obc *rpdc, enum conn_wait_close conn, struct req_cb_arg *args) { int ret; unsigned long long types = args->types; args->types = 0; ret = rpmemd_obc_process(rpdc, &REQ_CB, args); UT_ASSERTeq(ret, args->ret); UT_ASSERTeq(args->types, types); if (conn == CONN_WAIT_CLOSE) { ret = rpmemd_obc_process(rpdc, &REQ_CB, args); UT_ASSERTeq(ret, 1); } rpmemd_obc_fini(rpdc); } /* * server_msg_resp -- process a message of specified type, response to client * with specific status value and return status of sending response function */ int server_msg_resp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: %s msg_type status", tc->name); unsigned type = ATOU(argv[0]); int status = atoi(argv[1]); int ret; struct rpmemd_obc *rpdc; rpdc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO); UT_ASSERTne(rpdc, NULL); ret = rpmemd_obc_status(rpdc, 0); UT_ASSERTeq(ret, 0); struct req_cb_arg args = { .ret = 0, .force_ret = 0, .resp = 1, .types = (1U << type), .status = status, }; server_msg_args(rpdc, CONN_WAIT_CLOSE, &args); return 2; } /* * server_msg_noresp -- process a message of specified type, do not response to * client and return specific value from process callback */ int server_msg_noresp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s msg_type", tc->name); int type = atoi(argv[0]); int ret; struct rpmemd_obc *rpdc; rpdc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO); UT_ASSERTne(rpdc, NULL); ret = rpmemd_obc_status(rpdc, 0); UT_ASSERTeq(ret, 0); struct req_cb_arg args = { .ret = -1, .force_ret = 1, .resp = 0, .types = (1U << type), .status = 0, }; server_msg_args(rpdc, CONN_CLOSE, &args); return 1; } /* * server_bad_msg -- process a message and expect * error returned from rpmemd_obc_process function */ int server_bad_msg(const struct test_case *tc, int argc, char *argv[]) { int ret; struct rpmemd_obc *rpdc; rpdc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO); UT_ASSERTne(rpdc, NULL); ret = rpmemd_obc_status(rpdc, 0); UT_ASSERTeq(ret, 0); ret = rpmemd_obc_process(rpdc, &REQ_CB, NULL); UT_ASSERTne(ret, 0); rpmemd_obc_fini(rpdc); return 0; } pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_misc.c0000664000000000000000000000412014123364546021435 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * rpmemd_obc_test_misc.c -- miscellaneous test cases for rpmemd_obc module */ #include "rpmemd_obc_test_common.h" /* * client_send_disconnect -- connect, send specified number of bytes and * disconnect */ static void client_send_disconnect(char *target, void *msg, size_t size) { struct rpmem_ssh *ssh = clnt_connect(target); if (size) clnt_send(ssh, msg, size); clnt_close(ssh); } /* * client_econnreset -- test case for closing connection when operation on * server is in progress - client side */ int client_econnreset(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; size_t msg_size = sizeof(CREATE_MSG) + POOL_DESC_SIZE; struct rpmem_msg_create *msg = MALLOC(msg_size); *msg = CREATE_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); rpmem_hton_msg_create(msg); set_rpmem_cmd("server_econnreset"); { /* * Connect and disconnect immediately. */ client_send_disconnect(target, msg, 0); } { /* * Connect, send half of a message header and close the * connection. */ client_send_disconnect(target, msg, sizeof(struct rpmem_msg_hdr) / 2); } { /* * Connect, send only a message header and close the * connection. */ client_send_disconnect(target, msg, sizeof(struct rpmem_msg_hdr)); } { /* * Connect, send half of a message and close the connection. */ client_send_disconnect(target, msg, msg_size / 2); } FREE(msg); return 1; } /* * server_econnreset -- test case for closing connection when operation on * server is in progress - server side */ int server_econnreset(const struct test_case *tc, int argc, char *argv[]) { struct rpmemd_obc *rpdc; int ret; rpdc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO); UT_ASSERTne(rpdc, NULL); ret = rpmemd_obc_status(rpdc, 0); UT_ASSERTeq(ret, 0); ret = rpmemd_obc_process(rpdc, &REQ_CB, NULL); UT_ASSERTne(ret, 0); rpmemd_obc_fini(rpdc); return 0; } pmdk-1.11.1/src/test/rpmemd_obc/TEST30000775000000000000000000000061014123364546015700 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/TEST3 -- unit test for rpmemd_obc_process # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmemd_obc$EXESUFFIX\ client_close ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test.c0000664000000000000000000000212014123364546020420 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2017, Intel Corporation */ /* * rpmemd_obc_test.c -- unit test for rpmemd_obc module */ #include "rpmemd_obc_test_common.h" #include "out.h" #include "os.h" /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(server_bad_msg), TEST_CASE(server_msg_noresp), TEST_CASE(server_msg_resp), TEST_CASE(client_bad_msg_hdr), TEST_CASE(server_econnreset), TEST_CASE(client_econnreset), TEST_CASE(client_create), TEST_CASE(client_open), TEST_CASE(client_close), TEST_CASE(client_set_attr), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "rpmemd_obc"); out_init("rpmemd_obc", "RPMEM_LOG_LEVEL", "RPMEM_LOG_FILE", 0, 0); rpmemd_log_init("rpmemd", os_getenv("RPMEMD_LOG_FILE"), 0); rpmemd_log_level = rpmemd_log_level_from_str( os_getenv("RPMEMD_LOG_LEVEL")); rpmem_util_cmds_init(); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); rpmem_util_cmds_fini(); rpmemd_log_close(); out_fini(); DONE(NULL); } pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_msg_hdr.c0000664000000000000000000000232014123364546022125 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * rpmemd_obc_test_msg_hdr.c -- test cases for message header */ #include "rpmemd_obc_test_common.h" /* * Number of cases for checking message header. Must be kept in sync with * client_bad_msg_hdr function. */ #define BAD_MSG_HDR_COUNT 6 /* * client_bad_msg_hdr -- test case for checking message header */ int client_bad_msg_hdr(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_bad_msg"); for (int i = 0; i < BAD_MSG_HDR_COUNT; i++) { struct rpmem_ssh *ssh = clnt_connect(target); struct rpmem_msg_hdr msg = MSG_HDR; switch (i) { case 0: msg.size -= 1; break; case 1: msg.size = 0; break; case 2: msg.type = MAX_RPMEM_MSG_TYPE; break; case 3: msg.type = RPMEM_MSG_TYPE_OPEN_RESP; break; case 4: msg.type = RPMEM_MSG_TYPE_CREATE_RESP; break; case 5: msg.type = RPMEM_MSG_TYPE_CLOSE_RESP; break; default: UT_ASSERT(0); } rpmem_hton_msg_hdr(&msg); clnt_send(ssh, &msg, sizeof(msg)); clnt_wait_disconnect(ssh); clnt_close(ssh); } return 1; } pmdk-1.11.1/src/test/rpmemd_obc/TEST00000775000000000000000000000061614123364546015703 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/TEST0 -- unit test for rpmemd_obc_process # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmemd_obc$EXESUFFIX\ client_bad_msg_hdr ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmemd_obc/Makefile0000664000000000000000000000152414123364546016555 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/Makefile -- build rpmemd_obc test # SCP_TO_REMOTE_NODES = y vpath %.c ../../tools/rpmemd vpath %.c ../../rpmem_common vpath %.c ../../librpmem TARGET = rpmemd_obc OBJS = rpmemd_obc_test.o\ rpmemd_obc_test_common.o\ rpmemd_log.o\ rpmem_common.o\ rpmem_util.o\ rpmem_ssh.o\ rpmem_cmd.o\ rpmemd_obc.o\ rpmemd_obc_test_msg_hdr.o\ rpmemd_obc_test_misc.o\ rpmemd_obc_test_create.o\ rpmemd_obc_test_open.o\ rpmemd_obc_test_set_attr.o\ rpmemd_obc_test_close.o BIULD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -DRPMEMC_LOG_RPMEMD INCS += -I../../tools/rpmemd INCS += -I../../rpmem_common INCS += -I../../librpmem pmdk-1.11.1/src/test/rpmemd_obc/TEST40000775000000000000000000000061314123364546015704 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/TEST4 -- unit test for rpmemd_obc_process # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmemd_obc$EXESUFFIX\ client_set_attr ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_common.h0000664000000000000000000000740514123364546022010 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmemd_obc_test_common.h -- common declarations for rpmemd_obc test */ #include "unittest.h" #include "librpmem.h" #include "rpmem_proto.h" #include "rpmem_common.h" #include "rpmem_ssh.h" #include "rpmem_util.h" #include "rpmemd_log.h" #include "rpmemd_obc.h" #define PORT 1234 #define RKEY 0x0123456789abcdef #define RADDR 0xfedcba9876543210 #define PERSIST_METHOD RPMEM_PM_APM #define POOL_ATTR_INIT {\ .signature = "",\ .major = 1,\ .compat_features = 2,\ .incompat_features = 3,\ .ro_compat_features = 4,\ .poolset_uuid = "POOLSET_UUID0123",\ .uuid = "UUID0123456789AB",\ .next_uuid = "NEXT_UUID0123456",\ .prev_uuid = "PREV_UUID0123456",\ .user_flags = "USER_FLAGS012345",\ } #define POOL_ATTR_ALT {\ .signature = "",\ .major = 5,\ .compat_features = 6,\ .incompat_features = 7,\ .ro_compat_features = 8,\ .poolset_uuid = "UUID_POOLSET_ALT",\ .uuid = "ALT_UUIDCDEFFEDC",\ .next_uuid = "456UUID_NEXT_ALT",\ .prev_uuid = "UUID012_ALT_PREV",\ .user_flags = "012345USER_FLAGS",\ } #define POOL_SIZE 0x0001234567abcdef #define NLANES 0x123 #define NLANES_RESP 16 #define PROVIDER RPMEM_PROV_LIBFABRIC_SOCKETS #define POOL_DESC "pool.set" #define BUFF_SIZE 8192 static const char pool_desc[] = POOL_DESC; #ifdef POOL_DESC_SIZE #undef POOL_DESC_SIZE #endif #define POOL_DESC_SIZE (sizeof(pool_desc) / sizeof(pool_desc[0])) struct rpmem_ssh *clnt_connect(char *target); void clnt_wait_disconnect(struct rpmem_ssh *ssh); void clnt_send(struct rpmem_ssh *ssh, const void *buff, size_t len); void clnt_recv(struct rpmem_ssh *ssh, void *buff, size_t len); void clnt_close(struct rpmem_ssh *ssh); enum conn_wait_close { CONN_CLOSE, CONN_WAIT_CLOSE, }; void set_rpmem_cmd(const char *fmt, ...); extern struct rpmemd_obc_requests REQ_CB; struct req_cb_arg { int resp; unsigned long long types; int force_ret; int ret; int status; }; static const struct rpmem_msg_hdr MSG_HDR = { .type = RPMEM_MSG_TYPE_CLOSE, .size = sizeof(struct rpmem_msg_hdr), }; static const struct rpmem_msg_create CREATE_MSG = { .hdr = { .type = RPMEM_MSG_TYPE_CREATE, .size = sizeof(struct rpmem_msg_create), }, .c = { .major = RPMEM_PROTO_MAJOR, .minor = RPMEM_PROTO_MINOR, .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .buff_size = BUFF_SIZE, }, .pool_attr = POOL_ATTR_INIT, .pool_desc = { .size = POOL_DESC_SIZE, }, }; static const struct rpmem_msg_open OPEN_MSG = { .hdr = { .type = RPMEM_MSG_TYPE_OPEN, .size = sizeof(struct rpmem_msg_open), }, .c = { .major = RPMEM_PROTO_MAJOR, .minor = RPMEM_PROTO_MINOR, .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .buff_size = BUFF_SIZE, }, .pool_desc = { .size = POOL_DESC_SIZE, }, }; static const struct rpmem_msg_close CLOSE_MSG = { .hdr = { .type = RPMEM_MSG_TYPE_CLOSE, .size = sizeof(struct rpmem_msg_close), }, }; static const struct rpmem_msg_set_attr SET_ATTR_MSG = { .hdr = { .type = RPMEM_MSG_TYPE_SET_ATTR, .size = sizeof(struct rpmem_msg_set_attr), }, .pool_attr = POOL_ATTR_ALT, }; TEST_CASE_DECLARE(server_accept_sim); TEST_CASE_DECLARE(server_accept_sim_fork); TEST_CASE_DECLARE(client_accept_sim); TEST_CASE_DECLARE(server_accept_seq); TEST_CASE_DECLARE(server_accept_seq_fork); TEST_CASE_DECLARE(client_accept_seq); TEST_CASE_DECLARE(client_bad_msg_hdr); TEST_CASE_DECLARE(server_bad_msg); TEST_CASE_DECLARE(server_msg_noresp); TEST_CASE_DECLARE(server_msg_resp); TEST_CASE_DECLARE(client_econnreset); TEST_CASE_DECLARE(server_econnreset); TEST_CASE_DECLARE(client_create); TEST_CASE_DECLARE(server_open); TEST_CASE_DECLARE(client_close); TEST_CASE_DECLARE(server_close); TEST_CASE_DECLARE(client_open); TEST_CASE_DECLARE(client_set_attr); pmdk-1.11.1/src/test/rpmemd_obc/.gitignore0000664000000000000000000000001314123364546017075 0ustar rootrootrpmemd_obc pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_create.c0000664000000000000000000001010514123364546021745 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmemd_obc_test_create.c -- test cases for create request message */ #include "rpmemd_obc_test_common.h" /* * Number of cases for checking create request message. Must be kept in sync * with client_bad_msg_create function. */ #define BAD_MSG_CREATE_COUNT 11 /* * client_bad_msg_create -- check if server detects invalid create request * messages */ static void client_bad_msg_create(const char *ctarget) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(CREATE_MSG) + POOL_DESC_SIZE; struct rpmem_msg_create *msg = MALLOC(msg_size); for (int i = 0; i < BAD_MSG_CREATE_COUNT; i++) { struct rpmem_ssh *ssh = clnt_connect(target); *msg = CREATE_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); switch (i) { case 0: msg->c.provider = 0; break; case 1: msg->c.provider = MAX_RPMEM_PROV; break; case 2: msg->pool_desc.size -= 1; break; case 3: msg->pool_desc.size += 1; break; case 4: msg->pool_desc.size = 0; msg->hdr.size = sizeof(CREATE_MSG) + msg->pool_desc.size; break; case 5: msg->pool_desc.size = 1; msg->hdr.size = sizeof(CREATE_MSG) + msg->pool_desc.size; break; case 6: msg->pool_desc.desc[0] = '\0'; break; case 7: msg->pool_desc.desc[POOL_DESC_SIZE / 2] = '\0'; break; case 8: msg->pool_desc.desc[POOL_DESC_SIZE - 1] = 'E'; break; case 9: msg->c.major = RPMEM_PROTO_MAJOR + 1; break; case 10: msg->c.minor = RPMEM_PROTO_MINOR + 1; break; default: UT_ASSERT(0); } rpmem_hton_msg_create(msg); clnt_send(ssh, msg, msg_size); clnt_wait_disconnect(ssh); clnt_close(ssh); } FREE(msg); FREE(target); } /* * client_msg_create_noresp -- send create request message and don't expect * a response */ static void client_msg_create_noresp(const char *ctarget) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(CREATE_MSG) + POOL_DESC_SIZE; struct rpmem_msg_create *msg = MALLOC(msg_size); struct rpmem_ssh *ssh = clnt_connect(target); *msg = CREATE_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); rpmem_hton_msg_create(msg); clnt_send(ssh, msg, msg_size); clnt_close(ssh); FREE(msg); FREE(target); } /* * client_msg_create_resp -- send create request message and expect a response * with specified status. If status is 0, validate create request response * message */ static void client_msg_create_resp(const char *ctarget, int status) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(CREATE_MSG) + POOL_DESC_SIZE; struct rpmem_msg_create *msg = MALLOC(msg_size); struct rpmem_msg_create_resp resp; struct rpmem_ssh *ssh = clnt_connect(target); *msg = CREATE_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); rpmem_hton_msg_create(msg); clnt_send(ssh, msg, msg_size); clnt_recv(ssh, &resp, sizeof(resp)); rpmem_ntoh_msg_create_resp(&resp); if (status) { UT_ASSERTeq(resp.hdr.status, (uint32_t)status); } else { UT_ASSERTeq(resp.hdr.type, RPMEM_MSG_TYPE_CREATE_RESP); UT_ASSERTeq(resp.hdr.size, sizeof(struct rpmem_msg_create_resp)); UT_ASSERTeq(resp.hdr.status, (uint32_t)status); UT_ASSERTeq(resp.ibc.port, PORT); UT_ASSERTeq(resp.ibc.rkey, RKEY); UT_ASSERTeq(resp.ibc.raddr, RADDR); UT_ASSERTeq(resp.ibc.persist_method, PERSIST_METHOD); } clnt_close(ssh); FREE(msg); FREE(target); } /* * client_create -- test case for create request message - client side */ int client_create(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_bad_msg"); client_bad_msg_create(target); set_rpmem_cmd("server_msg_noresp %d", RPMEM_MSG_TYPE_CREATE); client_msg_create_noresp(target); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_CREATE, 0); client_msg_create_resp(target, 0); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_CREATE, 1); client_msg_create_resp(target, 1); return 1; } pmdk-1.11.1/src/test/rpmemd_obc/TEST10000775000000000000000000000061114123364546015677 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/TEST1 -- unit test for rpmemd_obc_process # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmemd_obc$EXESUFFIX\ client_create ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_close.c0000664000000000000000000000337714123364546021624 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * rpmemd_obc_test_close.c -- test cases for close request message */ #include "rpmemd_obc_test_common.h" /* * client_msg_close_noresp -- send close request message and don't expect a * response */ static void client_msg_close_noresp(const char *ctarget) { char *target = STRDUP(ctarget); struct rpmem_msg_close msg = CLOSE_MSG; rpmem_hton_msg_close(&msg); struct rpmem_ssh *ssh = clnt_connect(target); clnt_send(ssh, &msg, sizeof(msg)); clnt_wait_disconnect(ssh); clnt_close(ssh); FREE(target); } /* * client_msg_close_resp -- send close request message and expect a response * with specified status. If status is 0, validate close request response * message */ static void client_msg_close_resp(const char *ctarget, int status) { char *target = STRDUP(ctarget); struct rpmem_msg_close msg = CLOSE_MSG; rpmem_hton_msg_close(&msg); struct rpmem_msg_close_resp resp; struct rpmem_ssh *ssh = clnt_connect(target); clnt_send(ssh, &msg, sizeof(msg)); clnt_recv(ssh, &resp, sizeof(resp)); rpmem_ntoh_msg_close_resp(&resp); if (status) UT_ASSERTeq(resp.hdr.status, (uint32_t)status); clnt_close(ssh); FREE(target); } /* * client_close -- test case for close request message - client side */ int client_close(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_msg_noresp %d", RPMEM_MSG_TYPE_CLOSE); client_msg_close_noresp(target); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_CLOSE, 0); client_msg_close_resp(target, 0); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_CLOSE, 1); client_msg_close_resp(target, 1); return 1; } pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_open.c0000664000000000000000000001001114123364546021437 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmemd_obc_test_open.c -- test cases for open request message */ #include "rpmemd_obc_test_common.h" /* * Number of cases for checking open request message. Must be kept in sync * with client_bad_msg_open function. */ #define BAD_MSG_OPEN_COUNT 11 /* * client_bad_msg_open -- check if server detects invalid open request * messages */ static void client_bad_msg_open(const char *ctarget) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(OPEN_MSG) + POOL_DESC_SIZE; struct rpmem_msg_open *msg = MALLOC(msg_size); for (int i = 0; i < BAD_MSG_OPEN_COUNT; i++) { struct rpmem_ssh *ssh = clnt_connect(target); *msg = OPEN_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); switch (i) { case 0: msg->c.provider = 0; break; case 1: msg->c.provider = MAX_RPMEM_PROV; break; case 2: msg->pool_desc.size -= 1; break; case 3: msg->pool_desc.size += 1; break; case 4: msg->pool_desc.size = 0; msg->hdr.size = sizeof(OPEN_MSG) + msg->pool_desc.size; break; case 5: msg->pool_desc.size = 1; msg->hdr.size = sizeof(OPEN_MSG) + msg->pool_desc.size; break; case 6: msg->pool_desc.desc[0] = '\0'; break; case 7: msg->pool_desc.desc[POOL_DESC_SIZE / 2] = '\0'; break; case 8: msg->pool_desc.desc[POOL_DESC_SIZE - 1] = 'E'; break; case 9: msg->c.major = RPMEM_PROTO_MAJOR + 1; break; case 10: msg->c.minor = RPMEM_PROTO_MINOR + 1; break; default: UT_ASSERT(0); } rpmem_hton_msg_open(msg); clnt_send(ssh, msg, msg_size); clnt_wait_disconnect(ssh); clnt_close(ssh); } FREE(msg); FREE(target); } /* * client_msg_open_noresp -- send open request message and don't expect a * response */ static void client_msg_open_noresp(const char *ctarget) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(OPEN_MSG) + POOL_DESC_SIZE; struct rpmem_msg_open *msg = MALLOC(msg_size); struct rpmem_ssh *ssh = clnt_connect(target); *msg = OPEN_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); rpmem_hton_msg_open(msg); clnt_send(ssh, msg, msg_size); clnt_wait_disconnect(ssh); clnt_close(ssh); FREE(msg); FREE(target); } /* * client_msg_open_resp -- send open request message and expect a response * with specified status. If status is 0, validate open request response * message */ static void client_msg_open_resp(const char *ctarget, int status) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(OPEN_MSG) + POOL_DESC_SIZE; struct rpmem_msg_open *msg = MALLOC(msg_size); struct rpmem_msg_open_resp resp; struct rpmem_ssh *ssh = clnt_connect(target); *msg = OPEN_MSG; msg->hdr.size = msg_size; memcpy(msg->pool_desc.desc, POOL_DESC, POOL_DESC_SIZE); rpmem_hton_msg_open(msg); clnt_send(ssh, msg, msg_size); clnt_recv(ssh, &resp, sizeof(resp)); rpmem_ntoh_msg_open_resp(&resp); if (status) { UT_ASSERTeq(resp.hdr.status, (uint32_t)status); } else { UT_ASSERTeq(resp.hdr.type, RPMEM_MSG_TYPE_OPEN_RESP); UT_ASSERTeq(resp.hdr.size, sizeof(struct rpmem_msg_open_resp)); UT_ASSERTeq(resp.hdr.status, (uint32_t)status); UT_ASSERTeq(resp.ibc.port, PORT); UT_ASSERTeq(resp.ibc.rkey, RKEY); UT_ASSERTeq(resp.ibc.raddr, RADDR); UT_ASSERTeq(resp.ibc.persist_method, PERSIST_METHOD); } clnt_close(ssh); FREE(msg); FREE(target); } /* * client_open -- test case for open request message - client side */ int client_open(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_bad_msg"); client_bad_msg_open(target); set_rpmem_cmd("server_msg_noresp %d", RPMEM_MSG_TYPE_OPEN); client_msg_open_noresp(target); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_OPEN, 0); client_msg_open_resp(target, 0); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_OPEN, 1); client_msg_open_resp(target, 1); return 1; } pmdk-1.11.1/src/test/rpmemd_obc/TEST20000775000000000000000000000060714123364546015705 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/TEST2 -- unit test for rpmemd_obc_process # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmemd_obc$EXESUFFIX\ client_open ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmemd_obc/rpmemd_obc_test_set_attr.c0000664000000000000000000000431714123364546022337 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * rpmemd_obc_test_set_attr.c -- test cases for set attributes request message */ #include "rpmemd_obc_test_common.h" /* * client_msg_set_attr_noresp -- send set attributes request message and don't * expect a response */ static void client_msg_set_attr_noresp(const char *ctarget) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(SET_ATTR_MSG); struct rpmem_msg_set_attr *msg = MALLOC(msg_size); struct rpmem_ssh *ssh = clnt_connect(target); *msg = SET_ATTR_MSG; rpmem_hton_msg_set_attr(msg); clnt_send(ssh, msg, msg_size); clnt_wait_disconnect(ssh); clnt_close(ssh); FREE(msg); FREE(target); } /* * client_msg_set_attr_resp -- send set attributes request message and expect * a response with specified status. If status is 0, validate set attributes * request response message */ static void client_msg_set_attr_resp(const char *ctarget, int status) { char *target = STRDUP(ctarget); size_t msg_size = sizeof(SET_ATTR_MSG); struct rpmem_msg_set_attr *msg = MALLOC(msg_size); struct rpmem_msg_set_attr_resp resp; struct rpmem_ssh *ssh = clnt_connect(target); *msg = SET_ATTR_MSG; rpmem_hton_msg_set_attr(msg); clnt_send(ssh, msg, msg_size); clnt_recv(ssh, &resp, sizeof(resp)); rpmem_ntoh_msg_set_attr_resp(&resp); if (status) { UT_ASSERTeq(resp.hdr.status, (uint32_t)status); } else { UT_ASSERTeq(resp.hdr.type, RPMEM_MSG_TYPE_SET_ATTR_RESP); UT_ASSERTeq(resp.hdr.size, sizeof(struct rpmem_msg_set_attr_resp)); UT_ASSERTeq(resp.hdr.status, (uint32_t)status); } clnt_close(ssh); FREE(msg); FREE(target); } /* * client_set_attr -- test case for set attributes request message - client * side */ int client_set_attr(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_msg_noresp %d", RPMEM_MSG_TYPE_SET_ATTR); client_msg_set_attr_noresp(target); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_SET_ATTR, 0); client_msg_set_attr_resp(target, 0); set_rpmem_cmd("server_msg_resp %d %d", RPMEM_MSG_TYPE_SET_ATTR, 1); client_msg_set_attr_resp(target, 1); return 1; } pmdk-1.11.1/src/test/rpmemd_obc/setup.sh0000664000000000000000000000110214123364546016601 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_obc/setup.sh -- common setup for rpmemd_obc tests # require_nodes 2 require_node_log_files 1 $RPMEM_LOG_FILE RPMEM_CMD="\"cd ${NODE_TEST_DIR[0]} && UNITTEST_FORCE_QUIET=1" RPMEM_CMD="$RPMEM_CMD RPMEMD_LOG_FILE=$RPMEMD_LOG_FILE" RPMEM_CMD="$RPMEM_CMD RPMEMD_LOG_LEVEL=$RPMEMD_LOG_LEVEL" RPMEM_CMD="$RPMEM_CMD LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[0]}:$REMOTE_LD_LIBRARY_PATH" RPMEM_CMD="$RPMEM_CMD ./rpmemd_obc$EXESUFFIX\"" export_vars_node 1 RPMEM_CMD pmdk-1.11.1/src/test/obj_heap_interrupt/0000775000000000000000000000000014123364546016667 5ustar rootrootpmdk-1.11.1/src/test/obj_heap_interrupt/obj_heap_interrupt.c0000664000000000000000000000420214123364546022714 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * obj_heap_interrupt.c -- unit test for pool heap interruption */ #include "heap_layout.h" #include "memops.h" #include "unittest.h" POBJ_LAYOUT_BEGIN(heap_interrupt); POBJ_LAYOUT_END(heap_interrupt); static int exit_on_finish = 0; FUNC_MOCK(operation_finish, void, struct operation_context *ctx, unsigned flags) FUNC_MOCK_RUN_DEFAULT { if (exit_on_finish) exit(0); else _FUNC_REAL(operation_finish)(ctx, flags); } FUNC_MOCK_END static void sc0_create(PMEMobjpool *pop) { PMEMoid oids[3]; TX_BEGIN(pop) { oids[0] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); oids[1] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); oids[2] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); } TX_END pmemobj_free(&oids[0]); exit_on_finish = 1; pmemobj_free(&oids[1]); } /* * noop_verify -- used in cases in which a successful open means that the test * have passed successfully. */ static void noop_verify(PMEMobjpool *pop) { } typedef void (*scenario_func)(PMEMobjpool *pop); static struct { scenario_func create; scenario_func verify; } scenarios[] = { {sc0_create, noop_verify}, }; int main(int argc, char *argv[]) { START(argc, argv, "heap_interrupt"); UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(heap_interrupt) != 0); if (argc != 4) UT_FATAL("usage: %s file [cmd: c/o] [scenario]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; int exists = argv[2][0] == 'o'; int scenario = atoi(argv[3]); if (!exists) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(heap_interrupt), 0, S_IWUSR | S_IRUSR)) == NULL) { UT_FATAL("failed to create pool\n"); } scenarios[scenario].create(pop); /* if we get here, something is wrong with function mocking */ UT_ASSERT(0); } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(heap_interrupt))) == NULL) { UT_FATAL("failed to open pool\n"); } scenarios[scenario].verify(pop); } pmemobj_close(pop); DONE(NULL); } #ifdef _MSC_VER /* * Since libpmemobj is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) #endif pmdk-1.11.1/src/test/obj_heap_interrupt/mocks_windows.h0000664000000000000000000000110514123364546021723 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of memops functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmemobj * files, when compiled for the purpose of obj_heap_interrupt test. * It would replace default implementation with mocked functions defined * in obj_heap_interrupt.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define operation_finish __wrap_operation_finish #endif pmdk-1.11.1/src/test/obj_heap_interrupt/Makefile.inc0000664000000000000000000000054114123364546021077 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/obj_heap_interrupt/Makefile.inc -- build obj_heap_interrupt and # obj_rpmem_heap_interrupt unit tests # ../obj_heap_interrupt/obj_heap_interrupt: $(MAKE) -C ../obj_heap_interrupt all all: ../obj_heap_interrupt/obj_heap_interrupt include ../Makefile.inc pmdk-1.11.1/src/test/obj_heap_interrupt/TEST00000775000000000000000000000430114123364546017452 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_heap_interrupt/TEST0 -- unit test for pool heap interruption # . ../unittest/unittest.sh require_test_type medium require_no_asan # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable setup # exits in the middle of transaction, so pool cannot be closed export MEMCHECK_DONT_CHECK_LEAKS=1 create_holey_file 16M $DIR/testfile expect_normal_exit ./obj_heap_interrupt$EXESUFFIX $DIR/testfile c 0 expect_normal_exit ./obj_heap_interrupt$EXESUFFIX $DIR/testfile o 0 pass pmdk-1.11.1/src/test/obj_heap_interrupt/Makefile0000664000000000000000000000050714123364546020331 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_heap_interrupt/Makefile -- build obj_heap_interrupt unit test # TARGET = obj_heap_interrupt OBJS = obj_heap_interrupt.o LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_heap_interrupt.c) pmdk-1.11.1/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj0000664000000000000000000001400614123364546024170 0ustar rootroot Debug x64 Release x64 _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {07A153D9-DF17-4DE8-A3C2-EBF171B961AE} Win32Proj obj_heap_interrupt 10.0.17134.0 Application true v140 Application false v140 NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) pmdk-1.11.1/src/test/obj_heap_interrupt/TEST0.PS10000664000000000000000000000375514123364546020065 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_heap_interrupt/TEST0 -- unit test for pool heap interruption # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 16M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_heap_interrupt$Env:EXESUFFIX $DIR\testfile c 0 expect_normal_exit $Env:EXE_DIR\obj_heap_interrupt$Env:EXESUFFIX $DIR\testfile o 0 pass pmdk-1.11.1/src/test/obj_heap_interrupt/.gitignore0000664000000000000000000000002314123364546020652 0ustar rootrootobj_heap_interrupt pmdk-1.11.1/src/test/obj_heap_interrupt/obj_heap_interrupt.vcxproj.filters0000664000000000000000000000675214123364546025650 0ustar rootroot Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts {a11954b4-8aaf-468d-a906-c84fcfd6d465} {43626e07-8468-41b2-87e3-7e1eae80798d} {b704c7ca-683d-49ac-b4f7-9fa01d1d6e67} Header Files pmdk-1.11.1/src/test/pmem_is_pmem_windows/0000775000000000000000000000000014123364546017225 5ustar rootrootpmdk-1.11.1/src/test/pmem_is_pmem_windows/pmem_is_pmem_windows.vcxproj0000664000000000000000000001224214123364546025064 0ustar rootroot Debug x64 Release x64 {5F8A56F8-2C5B-48B6-9654-DD642D3E5F5C} Win32Proj pmem_is_pmem_windows 10.0.17134.0 Application true v140 Application false v140 $(IncludePath) Disabled $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)libpmem;$(SolutionDir)libpmem2;%(AdditionalIncludeDirectories) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST1.PS10000664000000000000000000000367214123364546020422 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST1 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type non-pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 begin check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST5.PS10000664000000000000000000000366714123364546020432 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST5 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 middle check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/pmem_is_pmem_windows.vcxproj.filters0000664000000000000000000000631114123364546026533 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {536c2f4f-3c81-491f-ba02-693e90378819} match {79cb81e3-cffe-4198-bbba-ab4956e04fa6} ps1 {c02bbce0-b885-4fed-8edf-2d0688725bac} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Header files Header files pmdk-1.11.1/src/test/pmem_is_pmem_windows/pmem_is_pmem_windows.c0000664000000000000000000001544214123364546023620 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2020, Intel Corporation */ /* * Copyright (c) 2015-2017, Microsoft Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * pmem_is_pmem_windows.c -- Windows specific unit test for is_pmem_detect() * * usage: pmem_is_pmem_windows file [env] */ #include "unittest.h" #include "pmem.h" #include "queue.h" #include "win_mmap.h" #include "util.h" #define NTHREAD 16 static void *Addr; static size_t Size; static int pmem_is_pmem_force = 0; enum test_mmap_scenarios { TEST_MMAP_SCENARIO_UNKNOWN, TEST_MMAP_SCENARIO_BEGIN_HOLE, TEST_MMAP_SCENARIO_END_HOLE, TEST_MMAP_SCENARIO_MIDDLE_HOLE, TEST_MMAP_SCENARIO_NO_HOLE }; enum test_mmap_scenarios get_mmap_scenarios(char *name) { if (stricmp(name, "nothing") == 0) return TEST_MMAP_SCENARIO_NO_HOLE; if (stricmp(name, "begin") == 0) return TEST_MMAP_SCENARIO_BEGIN_HOLE; if (stricmp(name, "end") == 0) return TEST_MMAP_SCENARIO_END_HOLE; if (stricmp(name, "middle") == 0) return TEST_MMAP_SCENARIO_MIDDLE_HOLE; return TEST_MMAP_SCENARIO_UNKNOWN; } /* * mmap_file_mapping_comparer -- (internal) compares the two file mapping * trackers */ static LONG_PTR mmap_file_mapping_comparer(PFILE_MAPPING_TRACKER a, PFILE_MAPPING_TRACKER b) { return ((LONG_PTR)a->BaseAddress - (LONG_PTR)b->BaseAddress); } /* * worker -- the work each thread performs */ static void * worker(void *arg) { int *ret = (int *)arg; /* * We honor the force just to let the scenarios that require pmem fs * work in the environment that forces pmem. * * NOTE: We can't use pmem_is_pmem instead of checking for the ENV * variable explicitly, because we want to call is_pmem_detect that is * defined in this test so that it will use the FileMappingQHead * that's defined here. Because we are crafting the Q in the test. */ if (pmem_is_pmem_force) *ret = 1; else *ret = is_pmem_detect(Addr, Size); return NULL; } extern SRWLOCK FileMappingQLock; extern struct FMLHead FileMappingQHead; int main(int argc, char *argv[]) { HANDLE file_map; SIZE_T chunk_length; enum test_mmap_scenarios scenario; int still_holey = 1; int already_holey = 0; START(argc, argv, "pmem_is_pmem_windows"); if (argc != 3) UT_FATAL("usage: %s file {begin|end|middle|nothing}", argv[0]); util_init(); /* to initialize Mmap_align */ char *str_pmem_is_pmem_force = os_getenv("PMEM_IS_PMEM_FORCE"); if (str_pmem_is_pmem_force && atoi(str_pmem_is_pmem_force) == 1) pmem_is_pmem_force = 1; scenario = get_mmap_scenarios(argv[2]); UT_ASSERT(scenario != TEST_MMAP_SCENARIO_UNKNOWN); int fd = OPEN(argv[1], O_RDWR); os_stat_t stbuf; FSTAT(fd, &stbuf); Size = stbuf.st_size; chunk_length = Mmap_align; /* * We don't support too small a file size. */ UT_ASSERT(Size / 8 > chunk_length); file_map = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL); UT_ASSERT(file_map != NULL); Addr = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); /* * let's setup FileMappingQHead such that, it appears to have lot of * DAX mapping created through our mmap. Here are our cases based * on the input: * - entire region in mapped through our mmap * - there is a region at the beginning that's not mapped through our * mmap * - there is a region at the end that's not mapped through our mmap * - there is a region in the middle that mapped through our mmap */ for (size_t offset = 0; offset < Size; offset += chunk_length) { void *base_address = (void *)((char *)Addr + offset); switch (scenario) { case TEST_MMAP_SCENARIO_BEGIN_HOLE: if (still_holey && ((offset == 0) || ((rand() % 2) == 0)) && (offset < (Size / 2))) continue; else still_holey = 0; break; case TEST_MMAP_SCENARIO_END_HOLE: if ((offset > (Size / 2)) && (already_holey || ((rand() % 2) == 0) || (offset >= (Size - chunk_length)))) { already_holey = 1; continue; } else UT_ASSERT(!already_holey); break; case TEST_MMAP_SCENARIO_MIDDLE_HOLE: if ((((offset > (Size / 8)) && ((rand() % 2) == 0)) || (offset > (Size / 8) * 6)) && (offset < (Size / 8) * 7)) continue; break; } PFILE_MAPPING_TRACKER mt = MALLOC(sizeof(struct FILE_MAPPING_TRACKER)); mt->Flags = FILE_MAPPING_TRACKER_FLAG_DIRECT_MAPPED; mt->FileHandle = (HANDLE)_get_osfhandle(fd); mt->FileMappingHandle = file_map; mt->BaseAddress = base_address; mt->EndAddress = (void *)((char *)base_address + chunk_length); mt->Access = FILE_MAP_READ; mt->Offset = offset; AcquireSRWLockExclusive(&FileMappingQLock); PMDK_SORTEDQ_INSERT(&FileMappingQHead, mt, ListEntry, FILE_MAPPING_TRACKER, mmap_file_mapping_comparer); ReleaseSRWLockExclusive(&FileMappingQLock); } CloseHandle(file_map); CLOSE(fd); os_thread_t threads[NTHREAD]; int ret[NTHREAD]; /* kick off NTHREAD threads */ for (int i = 0; i < NTHREAD; i++) THREAD_CREATE(&threads[i], NULL, worker, &ret[i]); /* wait for all the threads to complete */ for (int i = 0; i < NTHREAD; i++) THREAD_JOIN(&threads[i], NULL); /* verify that all the threads return the same value */ for (int i = 1; i < NTHREAD; i++) UT_ASSERTeq(ret[0], ret[i]); UT_OUT("%d", ret[0]); DONE(NULL); } /* * Since libpmem is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmem_init) MSVC_DESTR(libpmem_fini) pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST3.PS10000664000000000000000000000367014123364546020422 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST3 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type non-pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 end check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST2.PS10000664000000000000000000000367314123364546020424 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST2 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type non-pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 middle check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST6.PS10000664000000000000000000000366414123364546020430 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST6 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 end check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/out0.log.match0000664000000000000000000000023214123364546021707 0ustar rootrootpmem_is_pmem_windows$(nW)TEST0: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 nothing 1 pmem_is_pmem_windows$(nW)TEST0: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST0.PS10000664000000000000000000000367414123364546020423 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST0 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type non-pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 nothing check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/README0000664000000000000000000000112214123364546020101 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_is_pmem_windows/README. This test is Windows specific. This directory contains a unit test for pmem_is_pmem(). The program in pmem_is_pmem_windows.c takes a file as an argument, memory maps that file, and prints out the return value from pmem_is_pmem() on the resulting range. For true persistent memory, 1 is the expected output. 0 is the expected output for everything else. The tests in this directory also check that the PMEM_IS_PMEM_FORCE environment variable can be used to force a specific return value from pmem_is_pmem(). pmdk-1.11.1/src/test/pmem_is_pmem_windows/TEST4.PS10000664000000000000000000000366614123364546020430 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\pmem_is_pmem_windows\TEST4 -- unit test for pmem_is_pmem # . ..\unittest\unittest.ps1 require_fs_type pmem require_test_type medium setup create_holey_file 4M $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\pmem_is_pmem_windows$Env:EXESUFFIX ` $DIR\testfile1 begin check pass pmdk-1.11.1/src/test/pmem_is_pmem_windows/out6.log.match0000664000000000000000000000022614123364546021720 0ustar rootrootpmem_is_pmem_windows$(nW)TEST6: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 end 1 pmem_is_pmem_windows$(nW)TEST6: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/out1.log.match0000664000000000000000000000023014123364546021706 0ustar rootrootpmem_is_pmem_windows$(nW)TEST1: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 begin 0 pmem_is_pmem_windows$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/out5.log.match0000664000000000000000000000023114123364546021713 0ustar rootrootpmem_is_pmem_windows$(nW)TEST5: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 middle 1 pmem_is_pmem_windows$(nW)TEST5: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/out3.log.match0000664000000000000000000000022614123364546021715 0ustar rootrootpmem_is_pmem_windows$(nW)TEST3: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 end 0 pmem_is_pmem_windows$(nW)TEST3: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/out4.log.match0000664000000000000000000000023014123364546021711 0ustar rootrootpmem_is_pmem_windows$(nW)TEST4: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 begin 1 pmem_is_pmem_windows$(nW)TEST4: DONE pmdk-1.11.1/src/test/pmem_is_pmem_windows/out2.log.match0000664000000000000000000000023114123364546021710 0ustar rootrootpmem_is_pmem_windows$(nW)TEST2: START: pmem_is_pmem_windows $(nW)pmem_is_pmem_windows$(nW) $(nW)testfile1 middle 0 pmem_is_pmem_windows$(nW)TEST2: DONE pmdk-1.11.1/src/test/mmap_fixed/0000775000000000000000000000000014123364546015115 5ustar rootrootpmdk-1.11.1/src/test/mmap_fixed/TEST00000775000000000000000000000067714123364546015714 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap_fixed/TEST0 -- unit test for memory mapping routines # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LEN1=$((256 * 1024)) LEN2=$(($LEN1 - 4096)) LEN3=$(($LEN1 + 4096)) LEN4=$(($LEN1 - 1)) LEN5=$(($LEN1 + 1)) expect_normal_exit ./mmap_fixed$EXESUFFIX $DIR $LEN1 $LEN2 $LEN3 $LEN4 $LEN5 pass pmdk-1.11.1/src/test/mmap_fixed/Makefile0000664000000000000000000000032514123364546016555 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap_fixed/Makefile -- build mmap_fixed unit test # TARGET = mmap_fixed OBJS = mmap_fixed.o include ../Makefile.inc pmdk-1.11.1/src/test/mmap_fixed/mmap_fixed.c0000664000000000000000000000473214123364546017400 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * mmap_fixed.c -- test memory mapping with MAP_FIXED for various lengths * * This test is intended to be used for testing Windows implementation * of memory mapping routines - mmap(), munmap(), msync() and mprotect(). * Those functions should provide the same functionality as their Linux * counterparts, at least with respect to the features that are used * in PMDK libraries. * * Known issues and differences between Linux and Windows implementation * are described in src/common/mmap_windows.c. */ #include "unittest.h" #include #define ALIGN(size) ((size) & ~(Ut_mmap_align - 1)) /* * test_mmap_fixed -- test fixed mappings */ static void test_mmap_fixed(const char *name1, const char *name2, size_t len1, size_t len2) { size_t len1_aligned = ALIGN(len1); size_t len2_aligned = ALIGN(len2); UT_OUT("len: %zu (%zu) + %zu (%zu) = %zu", len1, len1_aligned, len2, len2_aligned, len1_aligned + len2_aligned); int fd1 = OPEN(name1, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR); int fd2 = OPEN(name2, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR); POSIX_FALLOCATE(fd1, 0, (os_off_t)len1); POSIX_FALLOCATE(fd2, 0, (os_off_t)len2); char *ptr1 = mmap(NULL, len1_aligned + len2_aligned, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0); UT_ASSERTne(ptr1, MAP_FAILED); UT_OUT("ptr1: %p, ptr2: %p", ptr1, ptr1 + len1_aligned); char *ptr2 = mmap(ptr1 + len1_aligned, len2_aligned, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd2, 0); UT_ASSERTne(ptr2, MAP_FAILED); UT_ASSERTeq(ptr2, ptr1 + len1_aligned); UT_ASSERTne(munmap(ptr1, len1_aligned), -1); UT_ASSERTne(munmap(ptr2, len2_aligned), -1); CLOSE(fd1); CLOSE(fd2); UNLINK(name1); UNLINK(name2); } int main(int argc, char *argv[]) { START(argc, argv, "mmap_fixed"); if (argc < 4) UT_FATAL("usage: %s dirname len1 len2 ...", argv[0]); size_t *lengths = MALLOC(sizeof(size_t) * (size_t)argc - 2); UT_ASSERTne(lengths, NULL); size_t appendix_length = 20; /* a file name length */ char *name1 = MALLOC(strlen(argv[1]) + appendix_length); char *name2 = MALLOC(strlen(argv[1]) + appendix_length); sprintf(name1, "%s\\testfile1", argv[1]); sprintf(name2, "%s\\testfile2", argv[1]); for (int i = 0; i < argc - 2; i++) lengths[i] = ATOULL(argv[i + 2]); for (int i = 0; i < argc - 2; i++) for (int j = 0; j < argc - 2; j++) test_mmap_fixed(name1, name2, lengths[i], lengths[j]); FREE(name1); FREE(name2); FREE(lengths); DONE(NULL); } pmdk-1.11.1/src/test/mmap_fixed/mmap_fixed.vcxproj.filters0000664000000000000000000000140514123364546022312 0ustar rootroot {8d8f2f00-0fff-43fb-a7ca-7ad92eac11a5} {a334316f-c0d2-4f89-becc-58c8d3584626} ps1 Test Scripts Test Scripts Source Files pmdk-1.11.1/src/test/mmap_fixed/mmap_fixed.vcxproj0000664000000000000000000000621414123364546020646 0ustar rootroot Debug x64 Release x64 {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {FEA09B48-34C2-4963-8A5A-F97BDA136D72} Win32Proj 10.0.17134.0 mmap_fixed mmap_fixed Application true v140 Application false v140 pmdk-1.11.1/src/test/mmap_fixed/TEST0.PS10000664000000000000000000000066614123364546016311 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/mmap_fixed/TEST0 -- unit test for memory mapping routines # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LEN1 = 256 * 1024 $LEN2 = $LEN1 - 4096 $LEN3 = $LEN1 + 4096 $LEN4 = $LEN1 - 1 $LEN5 = $LEN1 + 1 expect_normal_exit $Env:EXE_DIR\mmap_fixed$Env:EXESUFFIX $DIR ` $LEN1 $LEN2 $LEN3 $LEN4 $LEN5 pass pmdk-1.11.1/src/test/mmap_fixed/.gitignore0000664000000000000000000000001314123364546017077 0ustar rootrootmmap_fixed pmdk-1.11.1/src/test/pmem2_granularity/0000775000000000000000000000000014123364546016445 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/pmem2_granularity.vcxproj.filters0000664000000000000000000001005714123364546025175 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {bfc2182c-11f1-4b3c-8a7c-5570f93e83b6} {1366f987-c669-4170-b470-c38486d38e83} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Test Scripts Match Files Match Files Match Files pmdk-1.11.1/src/test/pmem2_granularity/err4.log.match0000664000000000000000000000021514123364546021115 0ustar rootroot$(*)requested granularity not available because fd doesn't point to DAX-enabled file or kernel doesn't support MAP_SYNC flag (Linux >= 4.15) pmdk-1.11.1/src/test/pmem2_granularity/err3.log.match0000664000000000000000000000014514123364546021116 0ustar rootroot$(*)requested granularity not available because specified volume is not a direct access (DAX) volume pmdk-1.11.1/src/test/pmem2_granularity/pmem2_granularity.c0000664000000000000000000001677614123364546022273 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * pmem2_granularity.c -- test for graunlarity functionality */ #include #include #include #include "config.h" #include "source.h" #include "pmem2_granularity.h" #include "unittest.h" #include "ut_pmem2_config.h" #include "ut_pmem2_utils.h" #include "out.h" size_t Is_nfit = 1; size_t Pc_type = 7; size_t Pc_capabilities; /* * parse_args -- parse args from the input */ static int parse_args(const struct test_case *tc, int argc, char *argv[], char **file) { if (argc < 1) UT_FATAL("usage: %s ", tc->name); *file = argv[0]; return 1; } /* * set_eadr -- set variable required for mocked functions */ static void set_eadr() { int is_eadr = atoi(os_getenv("IS_EADR")); if (is_eadr) Pc_capabilities = 3; else Pc_capabilities = 2; } /* * test_ctx -- essential parameters used by test */ struct test_ctx { int fd; enum pmem2_granularity requested_granularity; enum pmem2_granularity expected_granularity; }; /* * init_test -- initialize basic parameters for test */ static void init_test(char *file, struct test_ctx *ctx, enum pmem2_granularity granularity) { set_eadr(); ctx->fd = OPEN(file, O_RDWR); ctx->requested_granularity = granularity; int is_eadr = atoi(os_getenv("IS_EADR")); int is_pmem = atoi(os_getenv("IS_PMEM")); if (is_eadr) { if (is_pmem) ctx->expected_granularity = PMEM2_GRANULARITY_BYTE; else UT_FATAL("invalid configuration IS_EADR && !IS_PMEM"); } else if (is_pmem) { ctx->expected_granularity = PMEM2_GRANULARITY_CACHE_LINE; } else { ctx->expected_granularity = PMEM2_GRANULARITY_PAGE; } } /* * init_cfg -- initialize basic pmem2 config */ static void init_cfg(struct pmem2_config *cfg, struct pmem2_source **src, struct test_ctx *ctx) { pmem2_config_init(cfg); int ret = pmem2_source_from_fd(src, ctx->fd); UT_PMEM2_EXPECT_RETURN(ret, 0); } /* * cleanup -- cleanup the environment after test */ static void cleanup(struct pmem2_source *src, struct test_ctx *ctx) { #ifdef _WIN32 CloseHandle(src->value.handle); #else CLOSE(ctx->fd); #endif } /* * map_with_available_granularity -- map the range with valid granularity, * includes cleanup */ static void map_with_available_granularity(struct pmem2_config *cfg, struct pmem2_source *src, struct test_ctx *ctx) { cfg->requested_max_granularity = ctx->requested_granularity; struct pmem2_map *map; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(map, NULL); UT_ASSERTeq(ctx->expected_granularity, pmem2_map_get_store_granularity(map)); /* cleanup after the test */ pmem2_map_delete(&map); } /* * map_with_unavailable_granularity -- map the range with invalid * granularity (unsuccessful) */ static void map_with_unavailable_granularity(struct pmem2_config *cfg, struct pmem2_source *src, struct test_ctx *ctx) { cfg->requested_max_granularity = ctx->requested_granularity; struct pmem2_map *map; int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_GRANULARITY_NOT_SUPPORTED); UT_ERR("%s", pmem2_errormsg()); UT_ASSERTeq(map, NULL); } typedef void(*map_func)(struct pmem2_config *cfg, struct pmem2_source *src, struct test_ctx *ctx); /* * granularity_template -- template for testing granularity in pmem2 */ static int granularity_template(const struct test_case *tc, int argc, char *argv[], map_func map_do, enum pmem2_granularity granularity) { char *file = NULL; int ret = parse_args(tc, argc, argv, &file); struct test_ctx ctx = { 0 }; init_test(file, &ctx, granularity); struct pmem2_config cfg; struct pmem2_source *src; init_cfg(&cfg, &src, &ctx); map_do(&cfg, src, &ctx); cleanup(src, &ctx); pmem2_source_delete(&src); return ret; } /* * test_granularity_req_byte_avail_byte -- require byte granularity, * when byte granularity is available */ static int test_granularity_req_byte_avail_byte(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_BYTE); } /* * test_granularity_req_byte_avail_cl -- require byte granularity, * when cache line granularity is available */ static int test_granularity_req_byte_avail_cl(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_unavailable_granularity, PMEM2_GRANULARITY_BYTE); } /* * test_granularity_req_byte_avail_page -- require byte granularity, * when page granularity is available */ static int test_granularity_req_byte_avail_page(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_unavailable_granularity, PMEM2_GRANULARITY_BYTE); } /* * test_granularity_req_cl_avail_byte -- require cache line granularity, * when byte granularity is available */ static int test_granularity_req_cl_avail_byte(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_CACHE_LINE); } /* * test_granularity_req_cl_avail_cl -- require cache line granularity, * when cache line granularity is available */ static int test_granularity_req_cl_avail_cl(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_CACHE_LINE); } /* * test_granularity_req_cl_avail_page -- require cache line granularity, * when page granularity is available */ static int test_granularity_req_cl_avail_page(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_unavailable_granularity, PMEM2_GRANULARITY_CACHE_LINE); } /* * test_granularity_req_page_avail_byte -- require page granularity, * when byte granularity is available */ static int test_granularity_req_page_avail_byte(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_PAGE); } /* * test_granularity_req_byte_avail_cl -- require page granularity, * when byte cache line is available */ static int test_granularity_req_page_avail_cl(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_PAGE); } /* * test_granularity_req_page_avail_page -- require page granularity, * when page granularity is available */ static int test_granularity_req_page_avail_page(const struct test_case *tc, int argc, char *argv[]) { return granularity_template(tc, argc, argv, map_with_available_granularity, PMEM2_GRANULARITY_PAGE); } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_granularity_req_byte_avail_byte), TEST_CASE(test_granularity_req_byte_avail_cl), TEST_CASE(test_granularity_req_byte_avail_page), TEST_CASE(test_granularity_req_cl_avail_byte), TEST_CASE(test_granularity_req_cl_avail_cl), TEST_CASE(test_granularity_req_cl_avail_page), TEST_CASE(test_granularity_req_page_avail_byte), TEST_CASE(test_granularity_req_page_avail_cl), TEST_CASE(test_granularity_req_page_avail_page), }; #define NTESTS ARRAY_SIZE(test_cases) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_granularity"); out_init("pmem2_granularity", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } #ifdef _MSC_VER MSVC_CONSTR(libpmem2_init) MSVC_DESTR(libpmem2_fini) #endif pmdk-1.11.1/src/test/pmem2_granularity/pmem2_granularity.vcxproj0000664000000000000000000001530114123364546023523 0ustar rootroot Debug x64 Release x64 {EF951090-8938-4F7D-8674-7F6FB1F2C25E} pmem2_granularity 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) mocks_dax_windows.h;$(SolutionDir)\test\pmem_has_auto_flush_win\mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) mocks_dax_windows.h;$(SolutionDir)\test\pmem_has_auto_flush_win\mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true true {ce3f2dfb-8470-4802-ad37-21caf6cb2681} _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL %(PreprocessorDefinitions);WRAP_REAL _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL %(PreprocessorDefinitions);WRAP_REAL pmdk-1.11.1/src/test/pmem2_granularity/Makefile0000664000000000000000000000063414123364546020110 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem2_granularity/Makefile -- build pmem2_granularity test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmem2_granularity OBJS += pmem2_granularity.o\ ut_pmem2_config.o\ ut_pmem2_utils.o\ mocks_posix.o LIBPMEM2=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, mocks_posix.c) pmdk-1.11.1/src/test/pmem2_granularity/err1.log.match0000664000000000000000000000012214123364546021107 0ustar rootroot$(*)requested granularity not available because the platform doesn't support eADR pmdk-1.11.1/src/test/pmem2_granularity/mocks_dax_windows.c0000664000000000000000000000126014123364546022332 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * mocks_dax_windows.c -- mocked function required to control * FILE_DAX_VOLUME value reported by the OS APIs */ #include "unittest.h" FUNC_MOCK_DLLIMPORT(GetVolumeInformationByHandleW, BOOL, HANDLE hFile, LPWSTR lpVolumeNameBuffer, DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags, LPWSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize) FUNC_MOCK_RUN_DEFAULT { size_t is_pmem = atoi(os_getenv("IS_PMEM")); if (is_pmem) *lpFileSystemFlags = FILE_DAX_VOLUME; else *lpFileSystemFlags = 0; return TRUE; } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem2_granularity/TESTS.py0000775000000000000000000001104214123364546017722 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # import os from enum import Enum import testframework as t from testframework import granularity as g class Granularity(Enum): BYTE = 1 CACHE_LINE = 2 PAGE = 3 @g.require_granularity(g.ANY) class PMEM2_GRANULARITY(t.BaseTest): test_type = t.Short available_granularity = None def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') bus_dev_path_without_eADR = os.path.join( self.cwd, "linux_eadr_paths/eadr_not_available/sys/bus/nd/devices/") bus_dev_path_with_eADR = os.path.join( self.cwd, "linux_eadr_paths/eadr_available/sys/bus/nd/devices/") # Testframework may set this variable to emulate the certain type of # granularity. # This test mocks all granularity checks but they are skipped if # granularity is forced so this test requires unforced granularity. ctx.env['PMEM2_FORCE_GRANULARITY'] = '0' if self.available_granularity == Granularity.BYTE: ctx.env['IS_EADR'] = '1' ctx.env['IS_PMEM'] = '1' ctx.env['BUS_DEVICE_PATH'] = bus_dev_path_with_eADR elif self.available_granularity == Granularity.CACHE_LINE: ctx.env['IS_EADR'] = '0' ctx.env['IS_PMEM'] = '1' ctx.env['BUS_DEVICE_PATH'] = bus_dev_path_without_eADR elif self.available_granularity == Granularity.PAGE: ctx.env['IS_EADR'] = '0' ctx.env['IS_PMEM'] = '0' ctx.env['BUS_DEVICE_PATH'] = bus_dev_path_without_eADR ctx.exec('pmem2_granularity', self.test_case, filepath) class TEST0(PMEM2_GRANULARITY): """pass byte granularity, available byte granularity""" test_case = "test_granularity_req_byte_avail_byte" available_granularity = Granularity.BYTE @t.windows_only class TEST1(PMEM2_GRANULARITY): """pass byte granularity, available cache line granularity""" test_case = "test_granularity_req_byte_avail_cl" available_granularity = Granularity.CACHE_LINE @t.linux_only class TEST2(PMEM2_GRANULARITY): """pass byte granularity, available cache line granularity""" test_case = "test_granularity_req_byte_avail_cl" available_granularity = Granularity.CACHE_LINE @t.windows_only class TEST3(PMEM2_GRANULARITY): """pass byte granularity, available page granularity""" test_case = "test_granularity_req_byte_avail_page" available_granularity = Granularity.PAGE @t.linux_only class TEST4(PMEM2_GRANULARITY): """pass byte granularity, available page granularity""" test_case = "test_granularity_req_byte_avail_page" available_granularity = Granularity.PAGE @t.freebsd_only class TEST5(PMEM2_GRANULARITY): """pass byte granularity, available page granularity""" test_case = "test_granularity_req_byte_avail_page" available_granularity = Granularity.PAGE class TEST6(PMEM2_GRANULARITY): """pass cache line granularity, available byte granularity""" test_case = "test_granularity_req_cl_avail_byte" available_granularity = Granularity.BYTE class TEST7(PMEM2_GRANULARITY): """pass cache line granularity, available cache line granularity""" test_case = "test_granularity_req_cl_avail_cl" available_granularity = Granularity.CACHE_LINE @t.windows_only class TEST8(PMEM2_GRANULARITY): """pass cache line granularity, available page granularity""" test_case = "test_granularity_req_cl_avail_page" available_granularity = Granularity.PAGE @t.linux_only class TEST9(PMEM2_GRANULARITY): """pass cache line granularity, available page granularity""" test_case = "test_granularity_req_cl_avail_page" available_granularity = Granularity.PAGE @t.freebsd_only class TEST10(PMEM2_GRANULARITY): """pass cache line granularity, available page granularity""" test_case = "test_granularity_req_cl_avail_page" available_granularity = Granularity.PAGE class TEST11(PMEM2_GRANULARITY): """pass page granularity, available byte granularity""" test_case = "test_granularity_req_page_avail_byte" available_granularity = Granularity.BYTE class TEST12(PMEM2_GRANULARITY): """pass page granularity, available cache line granularity""" test_case = "test_granularity_req_page_avail_cl" available_granularity = Granularity.CACHE_LINE class TEST13(PMEM2_GRANULARITY): """pass page granularity, available page granularity""" test_case = "test_granularity_req_page_avail_page" available_granularity = Granularity.PAGE pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/0000775000000000000000000000000014123364546021776 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/0000775000000000000000000000000014123364546025571 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/0000775000000000000000000000000014123364546026407 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/0000775000000000000000000000000014123364546030031 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/0000775000000000000000000000000014123364546031655 5ustar rootroot././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem/pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem0000775000000000000000000000000014123364546032534 5ustar rootroot././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem/ndbus/pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem0000775000000000000000000000000014123364546032534 5ustar rootroot././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem/ndbus/region0/pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem0000775000000000000000000000000014123364546032534 5ustar rootroot././@LongLink0000644000000000000000000000020600000000000011601 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem/ndbus/region0/persistence_domainpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/devices/platform/pmem0000664000000000000000000000000014123364546032524 0ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/bus/0000775000000000000000000000000014123364546027200 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/bus/nd/0000775000000000000000000000000014123364546027601 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/bus/nd/devices/0000775000000000000000000000000014123364546031223 5ustar rootroot././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/bus/nd/devices/region0pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_not_available/sys/bus/nd/devices/region0000777000000000000000000000000014123364546042151 2../../../devices/platform/pmem/ndbus/region0/ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/0000775000000000000000000000000014123364546024711 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/0000775000000000000000000000000014123364546025527 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/0000775000000000000000000000000014123364546027151 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/0000775000000000000000000000000014123364546030775 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/0000775000000000000000000000000014123364546031733 5ustar rootroot././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndbus/pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndb0000775000000000000000000000000014123364546032417 5ustar rootroot././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndbus/region0/pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndb0000775000000000000000000000000014123364546032417 5ustar rootroot././@LongLink0000644000000000000000000000020200000000000011575 Lustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndbus/region0/persistence_domainpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/devices/platform/pmem/ndb0000664000000000000000000000001214123364546032412 0ustar rootrootcpu_cache pmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/bus/0000775000000000000000000000000014123364546026320 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/bus/nd/0000775000000000000000000000000014123364546026721 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/bus/nd/devices/0000775000000000000000000000000014123364546030343 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/linux_eadr_paths/eadr_available/sys/bus/nd/devices/region00000777000000000000000000000000014123364546041351 2../../../devices/platform/pmem/ndbus/region0/ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity/.gitignore0000664000000000000000000000002214123364546020427 0ustar rootrootpmem2_granularity pmdk-1.11.1/src/test/pmem2_granularity/mocks_dax_windows.h0000664000000000000000000000170414123364546022342 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * mocks_dax_windows.h -- redefinitions of GetVolumeInformationByHandleW * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmem2 * files, when compiled for the purpose of pmem2_granularity test. * It would replace default implementation with mocked functions defined * in mocks_windows.c * * This WRAP_REAL define could also be passed as a preprocessor definition. */ #ifndef MOCKS_WINDOWS_H #define MOCKS_WINDOWS_H 1 #include #ifndef WRAP_REAL #define GetVolumeInformationByHandleW __wrap_GetVolumeInformationByHandleW BOOL __wrap_GetVolumeInformationByHandleW(HANDLE hFile, LPWSTR lpVolumeNameBuffer, DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags, LPWSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize); #endif #endif pmdk-1.11.1/src/test/pmem2_granularity/err9.log.match0000664000000000000000000000021514123364546021122 0ustar rootroot$(*)requested granularity not available because fd doesn't point to DAX-enabled file or kernel doesn't support MAP_SYNC flag (Linux >= 4.15) pmdk-1.11.1/src/test/pmem2_granularity/err2.log.match0000664000000000000000000000012214123364546021110 0ustar rootroot$(*)requested granularity not available because the platform doesn't support eADR pmdk-1.11.1/src/test/pmem2_granularity/pmem2_granularity.h0000664000000000000000000000050214123364546022254 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * pmem2_granularity.h -- header file for windows mocks * for pmem2_granularity */ #ifndef PMEM2_GRANULARITY_H #define PMEM2_GRANULARITY_H 1 extern size_t Is_nfit; extern size_t Pc_type; extern size_t Pc_capabilities; #endif pmdk-1.11.1/src/test/pmem2_granularity/err8.log.match0000664000000000000000000000014514123364546021123 0ustar rootroot$(*)requested granularity not available because specified volume is not a direct access (DAX) volume pmdk-1.11.1/src/test/pmem2_granularity/err5.log.match0000664000000000000000000000014214123364546021115 0ustar rootroot$(*)the operating system doesn't provide a method of detecting whether the platform supports eADR pmdk-1.11.1/src/test/pmem2_granularity/mocks_posix.c0000664000000000000000000000437614123364546021161 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * mocks_posix.c -- mocked functions used in auto_flush_linux.c */ #include #include "map.h" #include "../common/mmap.h" #include "fs.h" #include "unittest.h" #define BUS_DEVICE_PATH "/sys/bus/nd/devices" /* * mmap - mock mmap */ FUNC_MOCK(mmap, void *, void *addr, size_t len, int prot, int flags, int fd, __off_t offset) FUNC_MOCK_RUN_DEFAULT { char *str_map_sync = os_getenv("IS_PMEM"); const int ms = MAP_SYNC | MAP_SHARED_VALIDATE; int map_sync_try = ((flags & ms) == ms) ? 1 : 0; if (str_map_sync && atoi(str_map_sync) == 1) { if (map_sync_try) { flags &= ~ms; flags |= MAP_SHARED; return _FUNC_REAL(mmap)(addr, len, prot, flags, fd, offset); } } else if (map_sync_try) { errno = EINVAL; return MAP_FAILED; } return _FUNC_REAL(mmap)(addr, len, prot, flags, fd, offset); } FUNC_MOCK_END /* * open -- open mock */ FUNC_MOCK(open, int, const char *path, int flags, ...) FUNC_MOCK_RUN_DEFAULT { va_list ap; va_start(ap, flags); int mode = va_arg(ap, int); va_end(ap); char *is_bus_device_path = strstr(path, BUS_DEVICE_PATH); if (!is_bus_device_path || (is_bus_device_path && strstr(path, "region"))) return _FUNC_REAL(open)(path, flags, mode); const char *mock_path = os_getenv("BUS_DEVICE_PATH"); return _FUNC_REAL(open)(mock_path, flags, mode); } FUNC_MOCK_END struct fs { FTS *ft; struct fs_entry entry; }; /* * fs_new -- creates fs traversal instance */ FUNC_MOCK(fs_new, struct fs *, const char *path) FUNC_MOCK_RUN_DEFAULT { char *is_bus_device_path = strstr(path, BUS_DEVICE_PATH); if (!is_bus_device_path || (is_bus_device_path && strstr(path, "region"))) return _FUNC_REAL(fs_new)(path); const char *mock_path = os_getenv("BUS_DEVICE_PATH"); return _FUNC_REAL(fs_new)(mock_path); } FUNC_MOCK_END /* * os_stat -- os_stat mock to handle sysfs path */ FUNC_MOCK(os_stat, int, const char *path, os_stat_t *buf) FUNC_MOCK_RUN_DEFAULT { char *is_bus_device_path = strstr(path, BUS_DEVICE_PATH); if (!is_bus_device_path || (is_bus_device_path && strstr(path, "region"))) return _FUNC_REAL(os_stat)(path, buf); const char *mock_path = os_getenv("BUS_DEVICE_PATH"); return _FUNC_REAL(os_stat)(mock_path, buf); } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem2_granularity/err10.log.match0000664000000000000000000000011314123364546021167 0ustar rootroot$(*)the operating system doesn't provide a method of detecting granularity pmdk-1.11.1/src/test/pmem_map_file/0000775000000000000000000000000014123364546015576 5ustar rootrootpmdk-1.11.1/src/test/pmem_map_file/pmem_map_file.vcxproj0000664000000000000000000001263714123364546022016 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {12A1A3EF-202C-4DD0-9B5A-F5126CAB078F} Win32Proj pmem_map_file 10.0.17134.0 Application true v140 Application false v140 mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;$(SolutionDir)\libpmem2\x86_64;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;$(SolutionDir)\libpmem2\x86_64;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem_map_file/TEST1.PS10000664000000000000000000000263514123364546016771 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file/TEST1 -- unit test for pmem_map_file # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup # # pass the file of zero length expect_normal_exit $Env:EXE_DIR\pmem_map_file$Env:EXESUFFIX ` $DIR\testfile1 0 - 0666 1 1 0 ` $DIR\testfile2 0 C 0666 0 0 0 ` $DIR\testfile3 4096 C 0666 1 1 0 ` $DIR\testfile4 0 E 0666 1 1 0 ` $DIR\testfile5 4096 E 0666 1 1 0 ` $DIR\testfile6 4096 CE 0666 1 1 0 ` $DIR\testfile7 4096 CES 0666 1 1 0 ` $DIR\testfile8 4096 CS 0666 1 1 0 ` $DIR\testfile9 -1 C 0666 1 1 0 ` $DIR\testfile10 4096 X 0666 1 1 0 ` $DIR\testfile11 4096 CX 0666 1 1 0 ` $DIR\testfile12 0x1FFFFFFFFFFFFFFF CE 0666 1 1 0 ` $DIR 0 T 0666 1 1 0 ` $DIR 4096 T 0666 1 1 0 ` $DIR 4096 TC 0666 1 1 0 ` $DIR 4096 TE 0666 1 1 0 ` $DIR 4096 TS 0666 1 1 0 ` $DIR 4096 TSE 0666 1 1 0 ` $DIR 4096 TCE 0666 1 1 0 ` $DIR 4096 TSEC 0666 1 1 0 ` \nul\nonexistingdir 4096 T 0666 1 1 0 check_files $DIR\testfile3 ` $DIR\testfile6 ` $DIR\testfile7 ` $DIR\testfile8 check_no_files $DIR\testfile1 ` $DIR\testfile2 ` $DIR\testfile4 ` $DIR\testfile5 ` $DIR\testfile9 ` $DIR\testfile10 ` $DIR\testfile11 ` $DIR\testfile12 check pass pmdk-1.11.1/src/test/pmem_map_file/TEST30000775000000000000000000000173714123364546016376 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem_map_file/TEST3 -- unit test for pmem_map_file # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup is_sparse(){ file_name=$1 apparent_size=`du --apparent-size $file_name | awk '{print $1}'` actual_size=`du $file_name | awk '{print $1}'` if [ $apparent_size -le $actual_size ]; then msg "error: file is not sparse" exit 1 fi } create_file 4K $DIR/testfile2 create_file 4K $DIR/testfile3 create_holey_file 4K $DIR/sparsefile1 # expect_normal_exit ./pmem_map_file$EXESUFFIX \ $DIR/testfile1 0 0 0666 nullptr nullptr 0 \ $DIR/testfile2 4096 CE 0666 1 1 EEXIST \ $DIR/testfile3 4096 CES 0666 1 1 EEXIST \ $DIR/sparsefile1 0 CS 0666 1 1 0 \ /nul/nonexistingdir 0 0 0666 1 1 ENOENT \ /nul/nonexistingdir 4096 CET 0666 1 1 ENOENT is_sparse $DIR/sparsefile1 check pass pmdk-1.11.1/src/test/pmem_map_file/mocks_windows.h0000664000000000000000000000114314123364546020634 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of libc functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmem * files, when compiled for the purpose of pmem_map_file test. * It would replace default implementation with mocked functions defined * in pmem_map_file.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define os_posix_fallocate __wrap_os_posix_fallocate #define os_ftruncate __wrap_os_ftruncate #endif pmdk-1.11.1/src/test/pmem_map_file/pmem_map_file.vcxproj.filters0000664000000000000000000000416414123364546023461 0ustar rootroot {189d0bf0-2f10-40d2-9a97-1c627dede493} {c775678f-276b-4eef-a23a-1e2e5e70e6f2} {1c3585e0-7b64-4460-86ee-dd837e30fecd} {d5932343-5e43-4cca-82a3-cde9c0443952} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts Match Files Test Scripts Match Files Header Files pmdk-1.11.1/src/test/pmem_map_file/TEST00000775000000000000000000000203714123364546016365 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file/TEST0 -- unit test for pmem_map_file # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind memcheck force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 truncate -s 2G $DIR/testfile1 # expect_normal_exit ./pmem_map_file$EXESUFFIX \ $DIR/testfile1 0 - 0 1 1 0 \ $DIR/testfile1 -1 - 0 1 1 0 \ $DIR/testfile1 0 - 0 0 0 0 \ $DIR/testfile1 0 X 0 0 0 0 \ $DIR/testfile1 0 - 0644 1 1 0 \ $DIR/testfile1 1024 - 0 1 1 0 \ $DIR/testfile1 0 C 0 1 1 0 \ $DIR/testfile1 0 E 0 1 1 0 \ $DIR/testfile1 4096 T 0644 1 1 0 \ $DIR/testfile1 4096 E 0644 1 1 0 \ $DIR/testfile1 0 - 0644 1 1 0 \ $DIR/testfile1 4096 C 0644 1 1 0 \ $DIR/testfile1 8192 C 0644 1 1 0 \ $DIR/testfile1 4096 CS 0644 1 1 0 check_files $DIR/testfile1 check pass pmdk-1.11.1/src/test/pmem_map_file/Makefile0000664000000000000000000000041514123364546017236 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # src/test/pmem_map_file/Makefile -- build pmem_map_file() unit test # TARGET = pmem_map_file OBJS = pmem_map_file.o mocks_posix.o LIBPMEM=y include ../Makefile.inc LIBS += $(LIBDL) pmdk-1.11.1/src/test/pmem_map_file/TEST3.PS10000664000000000000000000000163214123364546016767 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem_map_file/TEST3 -- unit test for pmem_map_file # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup function is_sparse(){ $file = $args[0] $res = fsutil sparse queryflag $file if ($res -match "This file is NOT set as sparse"){ fail "error: file is not sparse" } } create_file 4K $DIR/testfile2 create_file 4K $DIR/testfile3 create_holey_file 4K $DIR/sparsefile1 # expect_normal_exit $Env:EXE_DIR\pmem_map_file$Env:EXESUFFIX ` $DIR/testfile1 0 0 0666 nullptr nullptr 0 ` $DIR/testfile2 4096 CE 0666 1 1 EEXIST ` $DIR/testfile3 4096 CES 0666 1 1 EEXIST ` $DIR/sparsefile1 0 CS 0666 1 1 0 ` \nul\nonexistingdir 0 0 0666 1 1 ENOENT ` \nul\nonexistingdir 4096 CET 0666 1 1 ENOENT is_sparse $DIR/sparsefile1 check pass pmdk-1.11.1/src/test/pmem_map_file/pmem_map_file.c0000664000000000000000000001116014123364546020533 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2019, Intel Corporation */ /* * pmem_map_file.c -- unit test for mapping persistent memory for raw access * * usage: pmem_map_file file */ #define _GNU_SOURCE #include "unittest.h" #include #define CHECK_BYTES 4096 /* bytes to compare before/after map call */ static ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { ut_siglongjmp(Jmp); } #define PMEM_FILE_ALL_FLAGS\ (PMEM_FILE_CREATE|PMEM_FILE_EXCL|PMEM_FILE_SPARSE|PMEM_FILE_TMPFILE) static int is_dev_dax = 0; /* * parse_err_code -- parse 'err_code' string */ static int parse_err_code(const char *err_str) { int ret = 0; if (strcmp(err_str, "ENOENT") == 0) { ret = ENOENT; } else if (strcmp(err_str, "EEXIST") == 0) { ret = EEXIST; } else if (strcmp(err_str, "0") == 0) { ret = 0; } else { UT_FATAL("unknown err_code: %c", *err_str); } return ret; } /* * parse_flags -- parse 'flags' string */ static int parse_flags(const char *flags_str) { int ret = 0; while (*flags_str != '\0') { switch (*flags_str) { case '0': case '-': /* no flags */ break; case 'T': ret |= PMEM_FILE_TMPFILE; break; case 'S': ret |= PMEM_FILE_SPARSE; break; case 'C': ret |= PMEM_FILE_CREATE; break; case 'E': ret |= PMEM_FILE_EXCL; break; case 'X': /* not supported flag */ ret |= (PMEM_FILE_ALL_FLAGS + 1); break; case 'D': is_dev_dax = 1; break; default: UT_FATAL("unknown flags: %c", *flags_str); } flags_str++; }; return ret; } /* * do_check -- check the mapping */ static void do_check(int fd, void *addr, size_t mlen) { /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); char pat[CHECK_BYTES]; char buf[CHECK_BYTES]; /* write some pattern to the file */ memset(pat, 0x5A, CHECK_BYTES); WRITE(fd, pat, CHECK_BYTES); if (memcmp(pat, addr, CHECK_BYTES)) UT_OUT("first %d bytes do not match", CHECK_BYTES); /* fill up mapped region with new pattern */ memset(pat, 0xA5, CHECK_BYTES); memcpy(addr, pat, CHECK_BYTES); UT_ASSERTeq(pmem_msync(addr, CHECK_BYTES), 0); UT_ASSERTeq(pmem_unmap(addr, mlen), 0); if (!ut_sigsetjmp(Jmp)) { /* same memcpy from above should now fail */ memcpy(addr, pat, CHECK_BYTES); } else { UT_OUT("unmap successful"); } LSEEK(fd, (os_off_t)0, SEEK_SET); if (READ(fd, buf, CHECK_BYTES) == CHECK_BYTES) { if (memcmp(pat, buf, CHECK_BYTES)) UT_OUT("first %d bytes do not match", CHECK_BYTES); } } int main(int argc, char *argv[]) { START(argc, argv, "pmem_map_file"); int fd; void *addr; size_t mlen; size_t *mlenp; const char *path; unsigned long long len; int flags; unsigned mode; int is_pmem; int *is_pmemp; int use_mlen; int use_is_pmem; int err_code; if (argc < 8) UT_FATAL("usage: %s path len flags mode use_mlen " "use_is_pmem err_code...", argv[0]); for (int i = 1; i + 6 < argc; i += 7) { path = argv[i]; len = strtoull(argv[i + 1], NULL, 0); flags = parse_flags(argv[i + 2]); mode = STRTOU(argv[i + 3], NULL, 8); use_mlen = atoi(argv[i + 4]); use_is_pmem = atoi(argv[i + 5]); err_code = parse_err_code(argv[i + 6]); mlen = SIZE_MAX; if (use_mlen) mlenp = &mlen; else mlenp = NULL; if (use_is_pmem) is_pmemp = &is_pmem; else is_pmemp = NULL; UT_OUT("%s %lld %s %o %d %d %d", path, len, argv[i + 2], mode, use_mlen, use_is_pmem, err_code); addr = pmem_map_file(path, len, flags, mode, mlenp, is_pmemp); if (err_code != 0) { UT_ASSERTeq(errno, err_code); } if (addr == NULL) { UT_OUT("!pmem_map_file"); continue; } if (use_mlen) { UT_ASSERTne(mlen, SIZE_MAX); UT_OUT("mapped_len %zu", mlen); } else { mlen = len; } if (addr) { /* is_pmem must be true for device DAX */ int is_pmem_check = pmem_is_pmem(addr, mlen); UT_ASSERT(!is_dev_dax || is_pmem_check); /* check is_pmem returned from pmem_map_file */ if (use_is_pmem) UT_ASSERTeq(is_pmem, is_pmem_check); if ((flags & PMEM_FILE_TMPFILE) == 0 && !is_dev_dax) { fd = OPEN(argv[i], O_RDWR); if (!use_mlen) { os_stat_t stbuf; FSTAT(fd, &stbuf); mlen = (size_t)stbuf.st_size; } if (fd != -1) { do_check(fd, addr, mlen); (void) CLOSE(fd); } else { UT_OUT("!cannot open file: %s", argv[i]); } } else { UT_ASSERTeq(pmem_unmap(addr, mlen), 0); } } } DONE(NULL); } #ifdef _MSC_VER /* * Since libpmem is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmem_init) MSVC_DESTR(libpmem_fini) #endif pmdk-1.11.1/src/test/pmem_map_file/out0.log.match0000664000000000000000000000212714123364546020265 0ustar rootrootpmem_map_file$(nW)TEST0: START: pmem_map_file$(nW) $(nW)pmem_map_file$(nW) $(*) $(nW)testfile1 0 - 0 1 1 0 mapped_len 2147483648 unmap successful $(nW)testfile1 -1 - 0 1 1 0 pmem_map_file: Invalid argument $(nW)testfile1 0 - 0 0 0 0 unmap successful $(nW)testfile1 0 X 0 0 0 0 pmem_map_file: Invalid argument $(nW)testfile1 0 - 644 1 1 0 mapped_len 2147483648 unmap successful $(nW)testfile1 1024 - 0 1 1 0 pmem_map_file: Invalid argument $(nW)testfile1 0 C 0 1 1 0 pmem_map_file: Invalid argument $(nW)testfile1 0 E 0 1 1 0 mapped_len 2147483648 unmap successful $(nW)testfile1 4096 T 644 1 1 0 pmem_map_file: Invalid argument $(nW)testfile1 4096 E 644 1 1 0 pmem_map_file: Invalid argument $(nW)testfile1 0 - 644 1 1 0 mapped_len 2147483648 unmap successful $(nW)testfile1 4096 C 644 1 1 0 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 unmap successful $(nW)testfile1 8192 C 644 1 1 0 ftruncate: len 8192 posix_fallocate: off 0 len 8192 mapped_len 8192 unmap successful $(nW)testfile1 4096 CS 644 1 1 0 ftruncate: len 4096 mapped_len 4096 unmap successful pmem_map_file$(nW)TEST0: DONE pmdk-1.11.1/src/test/pmem_map_file/TEST0.PS10000664000000000000000000000165314123364546016767 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file/TEST0 -- unit test for pmem_map_file # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 2G $DIR\testfile1 # expect_normal_exit $Env:EXE_DIR\pmem_map_file$Env:EXESUFFIX ` $DIR\testfile1 0 - 0 1 1 0 ` $DIR\testfile1 -1 - 0 1 1 0 ` $DIR\testfile1 0 - 0 0 0 0 ` $DIR\testfile1 0 X 0 0 0 0 ` $DIR\testfile1 0 - 0644 1 1 0 ` $DIR\testfile1 1024 - 0 1 1 0 ` $DIR\testfile1 0 C 0 1 1 0 ` $DIR\testfile1 0 E 0 1 1 0 ` $DIR\testfile1 4096 T 0644 1 1 0 ` $DIR\testfile1 4096 E 0644 1 1 0 ` $DIR\testfile1 0 - 0644 1 1 0 ` $DIR\testfile1 4096 C 0644 1 1 0 ` $DIR\testfile1 8192 C 0644 1 1 0 ` $DIR\testfile1 4096 CS 0644 1 1 0 check_files $DIR\testfile1 check pass pmdk-1.11.1/src/test/pmem_map_file/.gitignore0000664000000000000000000000001614123364546017563 0ustar rootrootpmem_map_file pmdk-1.11.1/src/test/pmem_map_file/README0000664000000000000000000000236114123364546016460 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_map_file/README. This directory contains a unit test for pmem_map_file(). The program in pmem_map_file.c takes a path, file length, flags, mode, use_mapped_len, use_is_pmem flags and err_code. The accepted flags in 'flags' string are: 'C' - PMEM_FILE_CREATE 'T' - PMEM_FILE_TMPFILE 'E' - PMEM_FILE_EXCL 'S' - PMEM_FILE_SPARSE '-' or '0' - no flag 'X' - not supported flag 'mode' - an an octal number that specifies the file mode Example: $ pmem_map_file /mnt/pmem/testfile 4096 CTS 0644 1 1 0 ... If the file is successfully mapped to memory, and it is not a temporary file, then initially the first 4k of the file is populated with some pattern using write(). The file content is verified after successful mapping with pmem_map_file(). Then, the program overwrites the first 4k of the mapped memory region with another pattern, unmaps the file, and verifies its content once again. Since this test unmaps the file with pmem_unmap(), it also tests that function by trying to access the address after it was unmapped and verifying it can't. Finally, the program re-opens the file with read-only access then tries to map the file and prints an error message if pmem_map_file() fails (which it should). pmdk-1.11.1/src/test/pmem_map_file/TEST10000775000000000000000000000277214123364546016374 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file/TEST1 -- unit test for pmem_map_file # . ../unittest/unittest.sh require_test_type medium require_fs_type any configure_valgrind memcheck force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 # # pass the file of zero length expect_normal_exit ./pmem_map_file$EXESUFFIX \ $DIR/testfile1 0 - 0666 1 1 0 \ $DIR/testfile2 0 C 0666 0 0 0 \ $DIR/testfile3 4096 C 0666 1 1 0 \ $DIR/testfile4 0 E 0666 1 1 0 \ $DIR/testfile5 4096 E 0666 1 1 0 \ $DIR/testfile6 4096 CE 0666 1 1 0 \ $DIR/testfile7 4096 CES 0666 1 1 0 \ $DIR/testfile8 4096 CS 0666 1 1 0 \ $DIR/testfile9 -1 C 0666 1 1 0 \ $DIR/testfile10 4096 X 0666 1 1 0 \ $DIR/testfile11 4096 CX 0666 1 1 0 \ $DIR/testfile12 0x1FFFFFFFFFFFFFFF CE 0666 1 1 0 \ $DIR 0 T 0666 1 1 0 \ $DIR 4096 T 0666 1 1 0 \ $DIR 4096 TC 0666 1 1 0 \ $DIR 4096 TE 0666 1 1 0 \ $DIR 4096 TS 0666 1 1 0 \ $DIR 4096 TSE 0666 1 1 0 \ $DIR 4096 TCE 0666 1 1 0 \ $DIR 4096 TSEC 0666 1 1 0 \ /proc/nonexistingdir 4096 T 0666 1 1 0 check_files $DIR/testfile3 \ $DIR/testfile6 \ $DIR/testfile7 \ $DIR/testfile8 check_no_files $DIR/testfile1 \ $DIR/testfile2 \ $DIR/testfile4 \ $DIR/testfile5 \ $DIR/testfile9 \ $DIR/testfile10 \ $DIR/testfile11 \ $DIR/testfile12 check pass pmdk-1.11.1/src/test/pmem_map_file/mocks_windows.c0000664000000000000000000000154414123364546020634 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * mocks_windows.c -- mocked functions used in pmem_map_file.c * (Windows-specific) */ #include "unittest.h" #define MAX_LEN (4 * 1024 * 1024) /* * posix_fallocate -- interpose on libc posix_fallocate() */ FUNC_MOCK(os_posix_fallocate, int, int fd, os_off_t offset, os_off_t len) FUNC_MOCK_RUN_DEFAULT { UT_OUT("posix_fallocate: off %ju len %ju", offset, len); if (len > MAX_LEN) return ENOSPC; return _FUNC_REAL(os_posix_fallocate)(fd, offset, len); } FUNC_MOCK_END /* * ftruncate -- interpose on libc ftruncate() */ FUNC_MOCK(os_ftruncate, int, int fd, os_off_t len) FUNC_MOCK_RUN_DEFAULT { UT_OUT("ftruncate: len %ju", len); if (len > MAX_LEN) { errno = ENOSPC; return -1; } return _FUNC_REAL(os_ftruncate)(fd, len); } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem_map_file/out1.log.match0000664000000000000000000000321114123364546020261 0ustar rootrootpmem_map_file$(nW)TEST1: START: pmem_map_file$(nW) $(nW)pmem_map_file$(nW) $(*) $(nW)testfile1 0 - 666 1 1 0 pmem_map_file: No such file or directory $(nW)testfile2 0 C 666 0 0 0 pmem_map_file: Invalid argument $(nW)testfile3 4096 C 666 1 1 0 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 unmap successful $(nW)testfile4 0 E 666 1 1 0 pmem_map_file: No such file or directory $(nW)testfile5 4096 E 666 1 1 0 pmem_map_file: Invalid argument $(nW)testfile6 4096 CE 666 1 1 0 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 unmap successful $(nW)testfile7 4096 CES 666 1 1 0 ftruncate: len 4096 mapped_len 4096 unmap successful $(nW)testfile8 4096 CS 666 1 1 0 ftruncate: len 4096 mapped_len 4096 unmap successful $(nW)testfile9 -1 C 666 1 1 0 pmem_map_file: Invalid argument $(nW)testfile10 4096 X 666 1 1 0 pmem_map_file: Invalid argument $(nW)testfile11 4096 CX 666 1 1 0 pmem_map_file: Invalid argument $(nW)testfile12 2305843009213693951 CE 666 1 1 0 ftruncate: len 2305843009213693951 pmem_map_file: $(*) $(nW) 0 T 666 1 1 0 pmem_map_file: Invalid argument $(nW) 4096 T 666 1 1 0 pmem_map_file: Invalid argument $(nW) 4096 TC 666 1 1 0 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 $(nW) 4096 TE 666 1 1 0 pmem_map_file: Invalid argument $(nW) 4096 TS 666 1 1 0 pmem_map_file: Invalid argument $(nW) 4096 TSE 666 1 1 0 pmem_map_file: Invalid argument $(nW) 4096 TCE 666 1 1 0 ftruncate: len 4096 posix_fallocate: off 0 len 4096 mapped_len 4096 $(nW) 4096 TSEC 666 1 1 0 ftruncate: len 4096 mapped_len 4096 $(nW)nonexistingdir 4096 T 666 1 1 0 pmem_map_file: Invalid argument pmem_map_file$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem_map_file/TEST20000775000000000000000000000143014123364546016363 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/pmem_map_file/TEST2 -- unit test for pmem_map_file # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 require_fs_type any configure_valgrind memcheck force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 # # pass the file of zero length expect_normal_exit ./pmem_map_file$EXESUFFIX\ $DEVICE_DAX_PATH 0 D 0666 1 1 0\ $DEVICE_DAX_PATH 0 DSC 0666 1 1 0\ $DEVICE_DAX_PATH 0 DT 0666 1 1 0\ $DEVICE_DAX_PATH 0 DCE 0666 1 1 0\ $DEVICE_DAX_PATH 0 DC 0666 1 1 0\ $DEVICE_DAX_PATH 2097152 DC 0666 1 1 0\ # len != 0 check pass pmdk-1.11.1/src/test/pmem_map_file/out3.log.match0000664000000000000000000000101314123364546020261 0ustar rootrootpmem_map_file$(nW)TEST3: START: pmem_map_file$(nW) $(nW)pmem_map_file$(nW) $(*) $(nW)testfile1 0 0 666 0 0 0 pmem_map_file: No such file or directory $(nW)testfile2 4096 CE 666 1 1 17 pmem_map_file: File exists $(nW)testfile3 4096 CES 666 1 1 17 pmem_map_file: File exists $(nW)sparsefile1 0 CS 666 1 1 0 pmem_map_file: Invalid argument $(nW)nonexistingdir 0 0 666 1 1 2 pmem_map_file: No such file or directory $(nW)nonexistingdir 4096 CET 666 1 1 2 pmem_map_file: No such file or directory pmem_map_file$(nW)TEST3: DONE pmdk-1.11.1/src/test/pmem_map_file/mocks_posix.c0000664000000000000000000000205014123364546020275 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * mocks_posix.c -- mocked functions used in pmem_map_file.c (Posix-specific) */ #define _GNU_SOURCE #include "unittest.h" #include #define MAX_LEN (4 * 1024 * 1024) /* * posix_fallocate -- interpose on libc posix_fallocate() */ int posix_fallocate(int fd, os_off_t offset, off_t len) { UT_OUT("posix_fallocate: off %ju len %ju", offset, len); static int (*posix_fallocate_ptr)(int fd, os_off_t offset, off_t len); if (posix_fallocate_ptr == NULL) posix_fallocate_ptr = dlsym(RTLD_NEXT, "posix_fallocate"); if (len > MAX_LEN) return ENOSPC; return (*posix_fallocate_ptr)(fd, offset, len); } /* * ftruncate -- interpose on libc ftruncate() */ int ftruncate(int fd, os_off_t len) { UT_OUT("ftruncate: len %ju", len); static int (*ftruncate_ptr)(int fd, os_off_t len); if (ftruncate_ptr == NULL) ftruncate_ptr = dlsym(RTLD_NEXT, "ftruncate"); if (len > MAX_LEN) { errno = ENOSPC; return -1; } return (*ftruncate_ptr)(fd, len); } pmdk-1.11.1/src/test/pmem_map_file/out2.log.match0000664000000000000000000000101214123364546020257 0ustar rootrootpmem_map_file$(nW)TEST2: START: pmem_map_file$(nW) $(nW)pmem_map_file$(nW) $(nW) 0 D 0666 1 1 0 $(nW) 0 DSC 0666 1 1 0 $(nW) 0 DT 0666 1 1 0 $(nW) 0 DCE 0666 1 1 0 $(nW) 0 DC 0666 1 1 0 $(nW) 2097152 DC 0666 1 1 0 $(nW) 0 D 666 1 1 0 mapped_len $(N) $(nW) 0 DSC 666 1 1 0 mapped_len $(N) $(nW) 0 DT 666 1 1 0 pmem_map_file: Invalid argument $(nW) 0 DCE 666 1 1 0 pmem_map_file: Invalid argument $(nW) 0 DC 666 1 1 0 mapped_len $(N) $(nW) 2097152 DC 666 1 1 0 pmem_map_file: Invalid argument pmem_map_file$(nW)TEST2: DONE pmdk-1.11.1/src/test/testconfig.py.example0000664000000000000000000000761514123364546017166 0ustar rootroot# # src/test/testconfig.py -- configuration for local and remote unit tests # config = { # # 1) *** LOCAL CONFIGURATION *** # # The first part of the file tells the test framework # which file system locations are to be used for local testing. # # # Set logging level. Possible values: # 0 - silent (only error messages) # 1 - normal (above + SETUP + START + DONE + PASS + SKIP messages) # 2 - verbose (above + stdout from test binaries) # 'unittest_log_level': 1, # # For tests that require filesystem with page granularity, set the # path to a directory on a filesystem with such granularity. # This line may stay commented out if there's no such filesystem # available on your system. # # 'page_fs_dir': '/tmp', # # Enforce that the library will act in accordance with # page granularity, even if the underlying filesystem is not page # granular. # 'force_page': False, # # For tests that require filesystem with cache line granularity, set # the path to a directory on a filesystem with such granularity. # This line may stay commented out if there's no such filesystem # available on your system. # # 'cacheline_fs_dir': '/mnt/pmem', # # Enforce that the library will act in accordance with # cache line granularity, even if the underlying filesystem is not # cache line granular. # 'force_cacheline': False, # # For tests that require filesystem with byte granularity, set # the path to a directory on a filesystem with such granularity. # This line may stay commented out if there's no such filesystem # available on your system. # # 'byte_fs_dir': '/mnt/pmem', # # Enforce that the library will act in accordance with # byte granularity, even if the underlying filesystem is not byte # granular. # 'force_byte': False, # # To display execution time of each test # 'tm': True, # # Overwrite default test type: # check, short, medium, long, all # where: check = short + medium; all = short + medium + long # 'test_type': 'check', # # Set build type to be run: # debug, release, static-debug, static-release, all # Can be a string or a list: ['debug', 'release'] # 'build': 'all', # # Set filesystem granularity to be run: # page, cacheline, byte, none, all (default) # 'granularity': 'all', # # If keep_going is set to True, execution continues despite test failures. # 'keep_going': False, # # Skips will be treated as Fails if set to True # 'fail_on_skip': False, # # Set timeout # (floating point number with an optional suffix: 's' for seconds, # 'm' for minutes, 'h' for hours or 'd' for days) # 'timeout': '3m', # # In case of test fail all log files will be written. You can specify how # many lines should be written by setting this variable. If 'dump_lines' is # not set default value is 30. # 'dump_lines': 30, # Forcibly run tests with selected Valgrind tool, unless the test # explicitly disables it. # Possible values: None (do not force), 'memcheck', # 'pmemcheck', 'drd', 'helgrind' # 'force_enable': None, # For tests that require raw dax devices without a file system, add paths to # those devices to the list 'device_dax_path'. For most tests one device # is enough, but some might require more. # Eg. ['/dev/dax0.0', '/dev/dax1.0'] # 'device_dax_path' : [], # Enable tests that require administrative privileges. # They can be potentially very harmful, # so they have to be enabled deliberately. # # In case of linux OSes the 'sudo' command needs to be available # in the non-interactive mode (no password required to perform the command). # 'enable_admin_tests': False } pmdk-1.11.1/src/test/pmemset_perror/0000775000000000000000000000000014123364546016047 5ustar rootrootpmdk-1.11.1/src/test/pmemset_perror/pmemset_perror.c0000664000000000000000000000564114123364546021264 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmemset_perror.c -- pmemset_perror unittests */ #include "libpmemset.h" #include "file.h" #include "source.h" #include "out.h" #include "unittest.h" #include "ut_pmemset_utils.h" /* * test_fail_pmemset_func_simple - simply check print message when func from * pmemset API fails. */ static int test_fail_pmemset_func_simple(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_source *src; /* "randomly" chosen function to be failed */ int ret = pmemset_source_from_file(&src, NULL); UT_ASSERTne(ret, 0); pmemset_perror("pmemset_source_from_file"); return 0; } /* * test_fail_pmemset_func_format - check print message when func * from pmemset API fails and ellipsis operator is used */ static int test_fail_pmemset_func_format(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_source *src; /* "randomly" chosen function to be failed */ int ret = pmemset_source_from_file(&src, NULL); UT_ASSERTne(ret, 0); pmemset_perror("pmemset_source_from_file %d", 123); return 0; } /* * test_fail_system_func_simple - check print message when directly called * system func fails */ static int test_fail_system_func_simple(const struct test_case *tc, int argc, char *argv[]) { /* "randomly" chosen function to be failed */ int ret = os_open("XXX", O_RDONLY); UT_ASSERTeq(ret, -1); ERR("!open"); pmemset_perror("test"); return 0; } /* * test_fail_system_func_format - check print message when directly called * system func fails and ellipsis operator is used */ static int test_fail_system_func_format(const struct test_case *tc, int argc, char *argv[]) { /* "randomly" chosen function to be failed */ int ret = os_open("XXX", O_RDONLY); UT_ASSERTeq(ret, -1); ERR("!open"); pmemset_perror("test %d", 123); return 0; } /* * test_pmemset_err_to_errno_simple - check if conversion * from pmemset err value to errno works fine */ static int test_pmemset_err_to_errno_simple(const struct test_case *tc, int argc, char *argv[]) { int ret_errno = pmemset_err_to_errno(PMEMSET_E_NOSUPP); UT_ASSERTeq(ret_errno, ENOTSUP); ret_errno = pmemset_err_to_errno(PMEMSET_E_UNKNOWN); UT_ASSERTeq(ret_errno, EINVAL); ret_errno = pmemset_err_to_errno(-ENOTSUP); UT_ASSERTeq(ret_errno, ENOTSUP); return 0; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_fail_pmemset_func_simple), TEST_CASE(test_fail_pmemset_func_format), TEST_CASE(test_fail_system_func_simple), TEST_CASE(test_fail_system_func_format), TEST_CASE(test_pmemset_err_to_errno_simple), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmemset_perror"); util_init(); out_init("pmemset_perror", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } pmdk-1.11.1/src/test/pmemset_perror/test3.log.match0000664000000000000000000000005214123364546020704 0ustar rootroottest 123: open: No such file or directory pmdk-1.11.1/src/test/pmemset_perror/test1.log.match0000664000000000000000000000007014123364546020702 0ustar rootrootpmemset_source_from_file 123: file path cannot be empty pmdk-1.11.1/src/test/pmemset_perror/Makefile0000664000000000000000000000061314123364546017507 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020-2021, Intel Corporation # # # src/test/pmemset_perror/Makefile -- build pmemset_perror unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmemset INCS += -I$(TOP)/src/libpmemset TARGET = pmemset_perror OBJS += pmemset_perror.o\ ut_pmemset_utils.o LIBPMEMSET=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmemset_perror/TESTS.py0000775000000000000000000000247414123364546017335 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class PMEMSET_PERROR(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmemset_perror', self.test_case, stderr_file=self.stderr_file) class TEST0(PMEMSET_PERROR): """check print message when func from pmemset API fails""" test_case = 'test_fail_pmemset_func_simple' stderr_file = 'test0.log' class TEST1(PMEMSET_PERROR): """ check print message when func from pmemset API fails and ellipsis operator is used """ test_case = 'test_fail_pmemset_func_format' stderr_file = 'test1.log' class TEST2(PMEMSET_PERROR): """check print message when directly called system func fails""" test_case = 'test_fail_system_func_simple' stderr_file = 'test2.log' class TEST3(PMEMSET_PERROR): """ check print message when directly called system func fails and ellipsis operator is used """ test_case = 'test_fail_system_func_format' stderr_file = 'test3.log' class TEST4(PMEMSET_PERROR): """check if conversion from pmemset err value to errno works fine""" test_case = 'test_pmemset_err_to_errno_simple' stderr_file = 'test4.log' pmdk-1.11.1/src/test/pmemset_perror/.gitignore0000664000000000000000000000001714123364546020035 0ustar rootrootpmemset_perror pmdk-1.11.1/src/test/pmemset_perror/pmemset_perror.vcxproj.filters0000664000000000000000000000360114123364546024176 0ustar rootroot {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts Match files Match files Match files Match files pmdk-1.11.1/src/test/pmemset_perror/pmemset_perror.vcxproj0000664000000000000000000001123414123364546022530 0ustar rootroot Debug x64 Release x64 {E2788189-C17F-4D37-B36B-BBD6C2FC9960} pmemset_perror 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {fbaefc34-d221-4203-8bf6-162de1a5be1c} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmemset_perror/test2.log.match0000664000000000000000000000004614123364546020706 0ustar rootroottest: open: No such file or directory pmdk-1.11.1/src/test/pmemset_perror/test0.log.match0000664000000000000000000000006414123364546020704 0ustar rootrootpmemset_source_from_file: file path cannot be empty pmdk-1.11.1/src/test/log_pool/0000775000000000000000000000000014123364546014616 5ustar rootrootpmdk-1.11.1/src/test/log_pool/out11w.log.match0000664000000000000000000000025514123364546017556 0ustar rootrootlog_pool$(nW)TEST11w: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testset 0 0600 $(nW)testset: file size $(N) usable space 41869312 mode 0600 log_pool$(nW)TEST11w: DONE pmdk-1.11.1/src/test/log_pool/TEST20.PS10000664000000000000000000000052614123364546016067 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST20 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST20 non-existing file # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST7.PS10000664000000000000000000000100314123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST7 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_nonzeroed_file 2M 8K $DIR\testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST230000775000000000000000000000374614123364546015502 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST23 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile # # TEST23 existing file, file size >= min required size # (empty pool header) # expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST220000775000000000000000000000074214123364546015472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST22 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST22 existing file, file size < min required size # (valid pool header) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0640 truncate -s 1M $DIR/testfile expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST28.PS10000664000000000000000000000217714123364546016103 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST28 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST28 existing file, file size >= min required size # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile1 20 0600 cp $DIR\testfile1 $DIR\testfile2 &$PMEMSPOIL $DIR\testfile1 pool_hdr.uuid=1111111111111111 ` pool_hdr.next_part_uuid=1111111111111111 ` pool_hdr.prev_part_uuid=1111111111111111 ` pool_hdr.next_repl_uuid=2222222222222222 ` pool_hdr.prev_repl_uuid=2222222222222222 ` "pool_hdr.f:checksum_gen" &$PMEMSPOIL $DIR\testfile2 pool_hdr.uuid=2222222222222222 ` pool_hdr.next_part_uuid=2222222222222222 ` pool_hdr.prev_part_uuid=2222222222222222 ` pool_hdr.next_repl_uuid=1111111111111111 ` pool_hdr.prev_repl_uuid=1111111111111111 ` "pool_hdr.f:checksum_gen" create_poolset $DIR\testset 20M:$DIR\testfile1 R 20M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testset check pass pmdk-1.11.1/src/test/log_pool/TEST1.PS10000664000000000000000000000071214123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST1 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_holey_file 40M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST5.PS10000664000000000000000000000067714123364546016021 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST5 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST5 non-existing file, poolsize > 0 # (path is invalid, directory does not exist) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c \NULL\testfile 20 0600 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST22.PS10000664000000000000000000000077314123364546016075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST22 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST22 existing file, file size < min required size # (valid pool header) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0640 truncate -s 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/out24.log.match0000664000000000000000000000022714123364546017372 0ustar rootrootlog_pool$(nW)TEST24: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Permission denied log_pool$(nW)TEST24: DONE pmdk-1.11.1/src/test/log_pool/TEST240000775000000000000000000000076514123364546015501 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST24 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST24 existing file, file size >= min required size # (no read permissions) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0640 chmod -r $DIR/testfile expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST9.PS10000664000000000000000000000135614123364546016020 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST9 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # deny write (make write only) & icacls $DIR\testfile /deny ${Env:USERNAME}:R >$null # # TEST9 existing file, file length >= min required size, poolsize == 0, # (no read permissions) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 # restore full permissions & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST27.PS10000664000000000000000000000100514123364546016067 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST27 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST27 existing file, file size >= min required size # create_poolset $DIR\testset 20M:$DIR\testfile1:x 20M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testset 0 0600 expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testset check pass pmdk-1.11.1/src/test/log_pool/log_pool.vcxproj0000664000000000000000000001164314123364546020052 0ustar rootroot Debug x64 Release x64 {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {3CF270CD-0F56-48E3-AD84-82F369C568BF} Win32Proj log_pool 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/log_pool/out10.log.match0000664000000000000000000000024014123364546017360 0ustar rootrootlog_pool$(nW)TEST10: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: pmemlog_create: Permission denied log_pool$(nW)TEST10: DONE pmdk-1.11.1/src/test/log_pool/TEST25.PS10000664000000000000000000000132314123364546016070 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST25 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST25 existing file, file size >= min required size # (no write permissions) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0600 # deny write & icacls $DIR\testfile /deny ${Env:USERNAME}:W >$null expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile # restore full permissions & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/log_pool/TEST30000775000000000000000000000402514123364546015407 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST3 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile chmod 0600 $DIR/testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST11w.PS10000664000000000000000000000077714123364546016266 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST11 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST11 non-existing file, poolsize > 0 # (pool set) # create_poolset $DIR\testset 20M:$DIR\testfile1:x 20M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testset 0 0600 check_files $DIR\testset $DIR\testfile1 $DIR\testfile2 check pass pmdk-1.11.1/src/test/log_pool/TEST10.PS10000664000000000000000000000136114123364546016064 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST10 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # deny write (make read only) & icacls $DIR\testfile /deny ${Env:USERNAME}:W >$null # # TEST11 existing file, file length >= min required size, poolsize == 0, # (no write permissions) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 # restore full permissions & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST90000775000000000000000000000411214123364546015412 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST9 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0240 $DIR/testfile # # TEST9 existing file, file length >= min required size, poolsize == 0, # (no read permissions) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/out23.log.match0000664000000000000000000000022614123364546017370 0ustar rootrootlog_pool$(nW)TEST23: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Invalid argument log_pool$(nW)TEST23: DONE pmdk-1.11.1/src/test/log_pool/TEST120000775000000000000000000000103314123364546015463 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/log_pool/TEST12 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST12 non-existing file, poolsize > 0 # (pool set with replica section) # create_poolset $DIR/testset 20M:$DIR/testfile1:x R 20M:$DIR/testfile2:x expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testset 0 0600 check_files $DIR/testset check_no_files $DIR/testfile1 $DIR/testfile2 check pass pmdk-1.11.1/src/test/log_pool/out26.log.match0000664000000000000000000000021514123364546017371 0ustar rootrootlog_pool$(nW)TEST26: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Success log_pool$(nW)TEST26: DONE pmdk-1.11.1/src/test/log_pool/log_pool.c0000664000000000000000000000313514123364546016576 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * log_pool.c -- unit test for pmemlog_create() and pmemlog_open() * * usage: log_pool op path [poolsize mode] * * op can be: * c - create * o - open * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #define MB ((size_t)1 << 20) static void pool_create(const char *path, size_t poolsize, unsigned mode) { PMEMlogpool *plp = pmemlog_create(path, poolsize, mode); if (plp == NULL) UT_OUT("!%s: pmemlog_create", path); else { os_stat_t stbuf; STAT(path, &stbuf); UT_OUT("%s: file size %zu usable space %zu mode 0%o", path, stbuf.st_size, pmemlog_nbyte(plp), stbuf.st_mode & 0777); pmemlog_close(plp); int result = pmemlog_check(path); if (result < 0) UT_OUT("!%s: pmemlog_check", path); else if (result == 0) UT_OUT("%s: pmemlog_check: not consistent", path); } } static void pool_open(const char *path) { PMEMlogpool *plp = pmemlog_open(path); if (plp == NULL) UT_OUT("!%s: pmemlog_open", path); else { UT_OUT("%s: pmemlog_open: Success", path); pmemlog_close(plp); } } int main(int argc, char *argv[]) { START(argc, argv, "log_pool"); if (argc < 3) UT_FATAL("usage: %s op path [poolsize mode]", argv[0]); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = strtoul(argv[3], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[4], NULL, 8); pool_create(argv[2], poolsize, mode); break; case 'o': pool_open(argv[2]); break; default: UT_FATAL("unknown operation"); } DONE(NULL); } pmdk-1.11.1/src/test/log_pool/out21.log.match0000664000000000000000000000022614123364546017366 0ustar rootrootlog_pool$(nW)TEST21: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Invalid argument log_pool$(nW)TEST21: DONE pmdk-1.11.1/src/test/log_pool/TEST200000775000000000000000000000051414123364546015465 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST20 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST20 non-existing file # expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST00000775000000000000000000000057514123364546015412 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST0 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST250000775000000000000000000000076614123364546015503 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST25 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST25 existing file, file size >= min required size # (no write permissions) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0640 chmod -w $DIR/testfile expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/Makefile0000664000000000000000000000035214123364546016256 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/Makefile -- build log_pool unit test # TARGET = log_pool OBJS = log_pool.o LIBPMEMLOG=y USE_PMEMSPOIL=y include ../Makefile.inc pmdk-1.11.1/src/test/log_pool/TEST3.PS10000664000000000000000000000071214123364546016005 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST3 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_holey_file 20M $DIR\testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST2.PS10000664000000000000000000000061214123364546016003 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST2 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST50000775000000000000000000000066514123364546015417 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST5 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST5 non-existing file, poolsize > 0 # (path is invalid, directory does not exist) # expect_normal_exit ./log_pool$EXESUFFIX c /NULL/testfile 20 0600 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/out7.log.match0000664000000000000000000000037114123364546017313 0ustar rootrootlog_pool$(nW)TEST7: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(OPT)$(nW)testfile: file size 2097152 usable space 2088960 mode 0600 $(OPX)$(nW)testfile: file size 2097152 usable space 1966080 mode 0600 log_pool$(nW)TEST7: DONE pmdk-1.11.1/src/test/log_pool/TEST6.PS10000664000000000000000000000076014123364546016013 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST6 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_nonzeroed_file 2M 0K $DIR\testfile # # TEST6 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST40000775000000000000000000000071014123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST4 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 touch $DIR/testfile chmod 0600 $DIR/testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST70000775000000000000000000000414114123364546015412 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST7 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_nonzeroed_file 2M $(log_pool_desc_size) $DIR/testfile chmod 0600 $DIR/testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST23.PS10000664000000000000000000000066414123364546016075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST23 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_holey_file 20M $DIR\testfile # # TEST23 existing file, file size >= min required size # (empty pool header) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/out0.log.match0000664000000000000000000000037614123364546017311 0ustar rootrootlog_pool$(nW)TEST0: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 20 0600 $(OPT)$(nW)testfile: file size 20971520 usable space 20963328 mode 0600 $(OPX)$(nW)testfile: file size 20971520 usable space 20840448 mode 0600 log_pool$(nW)TEST0: DONE pmdk-1.11.1/src/test/log_pool/TEST24.PS10000664000000000000000000000132114123364546016065 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST24 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST24 existing file, file size >= min required size # (no read permissions) # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0600 # deny read & icacls $DIR\testfile /deny ${Env:USERNAME}:R >$null expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile # restore full permissions & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/log_pool/TEST210000775000000000000000000000373114123364546015472 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST21 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 1M $DIR/testfile # # TEST21 existing file, file size < min required size # expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile rm $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/out25.log.match0000664000000000000000000000022714123364546017373 0ustar rootrootlog_pool$(nW)TEST25: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Permission denied log_pool$(nW)TEST25: DONE pmdk-1.11.1/src/test/log_pool/out9.log.match0000664000000000000000000000023614123364546017315 0ustar rootrootlog_pool$(nW)TEST9: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: pmemlog_create: Permission denied log_pool$(nW)TEST9: DONE pmdk-1.11.1/src/test/log_pool/TEST0.PS10000664000000000000000000000060714123364546016005 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST0 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/TEST26.PS10000664000000000000000000000070214123364546016071 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST26 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST26 existing file, file size >= min required size # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 20 0600 expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/.gitignore0000664000000000000000000000001114123364546016576 0ustar rootrootlog_pool pmdk-1.11.1/src/test/log_pool/TEST12.PS10000664000000000000000000000104514123364546016065 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST12 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST12 non-existing file, poolsize > 0 # (pool set with replica section) # create_poolset $DIR\testset 20M:$DIR\testfile1:x R 20M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testset 0 0600 check_files $DIR\testset check_no_files $DIR\testfile1 $DIR\testfile2 check pass pmdk-1.11.1/src/test/log_pool/README0000664000000000000000000000442714123364546015505 0ustar rootrootPersistent Memory Development Kit This is src/test/log_pool/README. This directory contains a unit test for pmemlog_create() and pmemlog_open(). The program in log_pool.c takes: operation, path, poolsize, mode Operation can be: c - create o - open For example: ./log_pool c /my/file 20 0640 This calls pmemlog_create() with the given arguments. Note that poolsize is given in megabytes. Test cases: - pmemlog_create: TEST0 (pass) non-existing file, poolsize >= min required size TEST1 (pass) existing file, file length >= min required size, poolsize == 0 TEST2 (fail) non-existing file, poolsize == 0 TEST3 (fail) existing file, file length >= min required size, poolsize != 0 TEST4 (fail) existing file, file length < min required size, poolsize == 0 TEST5 (fail) non-existing file, poolsize >= min required size (path is invalid, directory does not exist) TEST6 (fail) existing file, file length >= min required size, poolsize == 0 (file contains garbage) TEST7 (pass) existing file, file length >= min required size, poolsize == 0 (file contains garbage, except for header) TEST8 (fail) non-existing file, poolsize < min required size TEST9 (fail) existing file, file length >= min required size, poolsize == 0 (no read permissions) TEST10 (fail) existing file, file length >= min required size, poolsize == 0 (no write permissions) TEST11 (pass) non-existing file, poolsize >= min required size (pool set) TEST12 (fail) non-existing file, poolsize >= min required size (pool set with replica section) - pmemlog_open: TEST20 (fail) non-existing file TEST21 (fail) existing file, file length < min required size TEST22 (fail) existing file, file length < min required size (valid pool header) TEST23 (fail) existing file, file length >= min required size (empty pool header) TEST24 (fail) existing file, file length >= min required size (no read permissions) TEST25 (fail) existing file, file length >= min required size (no write permissions) TEST26 (pass) existing file, file length >= min required size TEST27 (pass) existing file, file length >= min required size (pool set) TEST28 (fail) existing file, file length >= min required size (pool set with replica section) - each case outputs: - error, if error happened - resulting file size, mode, consistency check results pmdk-1.11.1/src/test/log_pool/TEST21.PS10000664000000000000000000000064714123364546016074 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST21 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup create_holey_file 1M $DIR\testfile # # TEST21 existing file, file size < min required size # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX o $DIR\testfile rm $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/out20.log.match0000664000000000000000000000023714123364546017367 0ustar rootrootlog_pool$(nW)TEST20: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: No such file or directory log_pool$(nW)TEST20: DONE pmdk-1.11.1/src/test/log_pool/TEST60000775000000000000000000000407314123364546015415 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST6 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_nonzeroed_file 2M 0K $DIR/testfile chmod 0640 $DIR/testfile # # TEST6 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/out27.log.match0000664000000000000000000000021314123364546017370 0ustar rootrootlog_pool$(nW)TEST27: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testset $(nW)testset: pmemlog_open: Success log_pool$(nW)TEST27: DONE pmdk-1.11.1/src/test/log_pool/TEST10000775000000000000000000000402514123364546015405 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST1 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 40M $DIR/testfile chmod 0600 $DIR/testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST260000775000000000000000000000065114123364546015475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST26 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST26 existing file, file size >= min required size # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 20 0640 expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST4.PS10000664000000000000000000000067314123364546016014 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST4 -- unit test for pmemlog_createte # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup touch $DIR\testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/out11.log.match0000664000000000000000000000036414123364546017370 0ustar rootrootlog_pool$(nW)TEST11: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testset 0 0600 $(OPT)$(nW)testset: file size $(N) usable space 41930752 mode 0666 $(OPX)$(nW)testset: file size $(N) usable space 41746432 mode 0666 log_pool$(nW)TEST11: DONE pmdk-1.11.1/src/test/log_pool/out6.log.match0000664000000000000000000000023014123364546017304 0ustar rootrootlog_pool$(nW)TEST6: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: pmemlog_create: File exists log_pool$(nW)TEST6: DONE pmdk-1.11.1/src/test/log_pool/TEST80000775000000000000000000000061714123364546015417 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST8 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST8 non-existing file, poolsize < min required size # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 1 0600 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/log_pool.vcxproj.filters0000664000000000000000000001057314123364546021522 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {e0803b93-70ee-46fd-bc41-8d5af1e0abbd} ps1 {6f9013b1-e713-4763-870b-c5654da397a4} match Source Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/log_pool/TEST8.PS10000664000000000000000000000063114123364546016012 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST8 -- unit test for pmemlog_create # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type "any" setup # # TEST8 non-existing file, poolsize < min required size # expect_normal_exit $Env:EXE_DIR\log_pool$Env:EXESUFFIX c $DIR\testfile 1 0600 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/log_pool/out22.log.match0000664000000000000000000000022614123364546017367 0ustar rootrootlog_pool$(nW)TEST22: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testfile $(nW)testfile: pmemlog_open: Invalid argument log_pool$(nW)TEST22: DONE pmdk-1.11.1/src/test/log_pool/out28.log.match0000664000000000000000000000023314123364546017373 0ustar rootrootlog_pool$(nW)TEST28: START: log_pool$(nW) $(nW)log_pool$(nW) o $(nW)testset $(nW)testset: pmemlog_open: Operation not supported log_pool$(nW)TEST28: DONE pmdk-1.11.1/src/test/log_pool/out1.log.match0000664000000000000000000000037514123364546017311 0ustar rootrootlog_pool$(nW)TEST1: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(OPT)$(nW)testfile: file size 41943040 usable space 41934848 mode 0600 $(OPX)$(nW)testfile: file size 41943040 usable space 41811968 mode 0600 log_pool$(nW)TEST1: DONE pmdk-1.11.1/src/test/log_pool/TEST270000775000000000000000000000075514123364546015503 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/log_pool/TEST27 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST27 existing file, file size >= min required size # create_poolset $DIR/testset 20M:$DIR/testfile1:x 20M:$DIR/testfile2:x expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testset 0 0640 expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testset check pass pmdk-1.11.1/src/test/log_pool/TEST100000775000000000000000000000411614123364546015466 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_pool/TEST10 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0440 $DIR/testfile # # TEST11 existing file, file length >= min required size, poolsize == 0, # (no write permissions) # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/TEST20000775000000000000000000000060014123364546015401 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool/TEST2 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile 0 0600 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/log_pool/out5.log.match0000664000000000000000000000027114123364546017310 0ustar rootrootlog_pool$(nW)TEST5: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)NULL$(nW)testfile 20 0600 $(nW)NULL$(nW)testfile: pmemlog_create: No such file or directory log_pool$(nW)TEST5: DONE pmdk-1.11.1/src/test/log_pool/out3.log.match0000664000000000000000000000023114123364546017302 0ustar rootrootlog_pool$(nW)TEST3: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 20 0600 $(nW)testfile: pmemlog_create: File exists log_pool$(nW)TEST3: DONE pmdk-1.11.1/src/test/log_pool/out4.log.match0000664000000000000000000000023514123364546017307 0ustar rootrootlog_pool$(nW)TEST4: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: pmemlog_create: Invalid argument log_pool$(nW)TEST4: DONE pmdk-1.11.1/src/test/log_pool/TEST280000775000000000000000000000214414123364546015476 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/log_pool/TEST28 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST28 existing file, file size >= min required size # expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testfile1 20 0640 cp $DIR/testfile1 $DIR/testfile2 $PMEMSPOIL $DIR/testfile1 pool_hdr.uuid=1111111111111111 \ pool_hdr.next_part_uuid=1111111111111111 \ pool_hdr.prev_part_uuid=1111111111111111 \ pool_hdr.next_repl_uuid=2222222222222222 \ pool_hdr.prev_repl_uuid=2222222222222222 \ "pool_hdr.f:checksum_gen" $PMEMSPOIL $DIR/testfile2 pool_hdr.uuid=2222222222222222 \ pool_hdr.next_part_uuid=2222222222222222 \ pool_hdr.prev_part_uuid=2222222222222222 \ pool_hdr.next_repl_uuid=1111111111111111 \ pool_hdr.prev_repl_uuid=1111111111111111 \ "pool_hdr.f:checksum_gen" create_poolset $DIR/testset 20M:$DIR/testfile1 R 20M:$DIR/testfile2 expect_normal_exit ./log_pool$EXESUFFIX o $DIR/testset check pass pmdk-1.11.1/src/test/log_pool/out8.log.match0000664000000000000000000000023514123364546017313 0ustar rootrootlog_pool$(nW)TEST8: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 1 0600 $(nW)testfile: pmemlog_create: Invalid argument log_pool$(nW)TEST8: DONE pmdk-1.11.1/src/test/log_pool/out2.log.match0000664000000000000000000000024614123364546017307 0ustar rootrootlog_pool$(nW)TEST2: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testfile 0 0600 $(nW)testfile: pmemlog_create: No such file or directory log_pool$(nW)TEST2: DONE pmdk-1.11.1/src/test/log_pool/out12.log.match0000664000000000000000000000024414123364546017366 0ustar rootrootlog_pool$(nW)TEST12: START: log_pool$(nW) $(nW)log_pool$(nW) c $(nW)testset 0 0600 $(nW)testset: pmemlog_create: Operation not supported log_pool$(nW)TEST12: DONE pmdk-1.11.1/src/test/log_pool/TEST110000775000000000000000000000076514123364546015475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/log_pool/TEST11 -- unit test for pmemlog_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST11 non-existing file, poolsize > 0 # (pool set) # create_poolset $DIR/testset 20M:$DIR/testfile1:x 20M:$DIR/testfile2:x expect_normal_exit ./log_pool$EXESUFFIX c $DIR/testset 0 0600 check_files $DIR/testset $DIR/testfile1 $DIR/testfile2 check pass pmdk-1.11.1/src/test/drd-libfabric.supp0000664000000000000000000000026514123364546016404 0ustar rootroot{ drd:MutexErr ... fun:pthread_spin_destroy fun:fastlock_destroy fun:fi_ibv_eq_close ... } pmdk-1.11.1/src/test/bttdevice/0000775000000000000000000000000014123364546014755 5ustar rootrootpmdk-1.11.1/src/test/bttdevice/TEST1.PS10000664000000000000000000000120014123364546016133 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # bttdevice/TEST1 -- test for checking pmempool info for spoiled btt device # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" rm $LOG -Force -ea si touch $LOG expect_normal_exit $BTTCREATE -v $POOL >> $LOG &$PMEMSPOIL -v $POOL "bttdevice.arena(0).btt_info.sig=BADSIGNATURE" ` "bttdevice.arena(0).btt_info.external_lbasize=10" ` "bttdevice.arena(0).btt_info.major=0x0" >> $LOG expect_normal_exit $PMEMPOOL info $POOL -f btt >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/bttdevice/bttdevice.vcxproj.filters0000664000000000000000000000210014123364546022003 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {ebe671a1-5994-4fb2-a32a-7d594157a7ed} {d625cd8f-94b7-45c5-b123-7c0c730edbd9} Test Scripts Test Scripts Source Files Source Files pmdk-1.11.1/src/test/bttdevice/TEST00000775000000000000000000000144014123364546015541 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # bttdevice/TEST0 -- test for checking bttcreate tool # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG echo "Create btt device - uuid defined by the user" >> $LOG expect_normal_exit $BTTCREATE -s 20M -b 1K -l 256 \ -u "9047cad6-53e1-4ba8-bcdd-a9fb411f7392" -v $POOL >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX info $POOL >> $LOG check_file $POOL rm -f $POOL echo -e "\nCreate btt device - automatic uuid generation" >> $LOG expect_normal_exit $BTTCREATE -s 40M -b 2K -l 256 -v $POOL >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX info $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/bttdevice/Makefile0000664000000000000000000000034614123364546016420 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/bttdevice/Makefile -- build unittest for testing tools operating # on btt device # USE_PMEMSPOIL=y USE_BTTCREATE=y include ../Makefile.inc pmdk-1.11.1/src/test/bttdevice/out0.log.match0000664000000000000000000000400414123364546017440 0ustar rootrootCreate btt device - uuid defined by the user BTT successfully created: $(nW) poolsize 20971520B blocksize 1024B maxlanes 256 uuid 9047cad6-53e1-4ba8-bcdd-a9fb411f7392 BTT Device [ARENA 0] PMEM BLK BTT Info Header: Signature : BTT_ARENA_INFO UUID of container : 9047cad6-53e1-4ba8-bcdd-a9fb411f7392 Flags : 0x0 Major : 1 Minor : 1 External LBA size : 1024 $(OPT)External LBA count : 20112 $(OPX)External LBA count : 20052 Internal LBA size : 1024 $(OPT)Internal LBA count : 20368 $(OPX)Internal LBA count : 20308 Free blocks : 256 Info block size : 4096 Next arena offset : 0x0 Arena data offset : 0x1000 $(OPT)Area map offset : 0x13e6000 $(OPX)Area map offset : 0x13d7000 $(OPT)Area flog offset : 0x13fa000 $(OPX)Area flog offset : 0x13eb000 $(OPT)Info block backup offset : 0x13fe000 $(OPX)Info block backup offset : 0x13ef000 Checksum : $(XX) [OK] Create btt device - automatic uuid generation BTT successfully created: $(nW) poolsize 41943040B blocksize 2048B maxlanes 256 uuid $(nW) BTT Device [ARENA 0] PMEM BLK BTT Info Header: Signature : BTT_ARENA_INFO UUID of container : $(nW) Flags : 0x0 Major : 1 Minor : 1 External LBA size : 2048 $(OPT)External LBA count : 20168 $(OPX)External LBA count : 20138 Internal LBA size : 2048 $(OPT)Internal LBA count : 20424 $(OPX)Internal LBA count : 20394 Free blocks : 256 Info block size : 4096 Next arena offset : 0x0 Arena data offset : 0x1000 $(OPT)Area map offset : 0x27e6000 $(OPX)Area map offset : 0x27d7000 $(OPT)Area flog offset : 0x27fa000 $(OPX)Area flog offset : 0x27eb000 $(OPT)Info block backup offset : 0x27fe000 $(OPX)Info block backup offset : 0x27ef000 Checksum : $(XX) [OK] pmdk-1.11.1/src/test/bttdevice/TEST0.PS10000664000000000000000000000142014123364546016136 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # bttdevice/TEST0 -- test for checking bttcreate tool # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" rm $LOG -Force -ea si touch $LOG echo "Create btt device - uuid defined by the user" >> $LOG expect_normal_exit $BTTCREATE -s '20M' -b 1K -l 256 ` -u "9047cad6-53e1-4ba8-bcdd-a9fb411f7392" -v $POOL >> $LOG expect_normal_exit $PMEMPOOL info $POOL >> $LOG check_file $POOL rm $POOL -Force -ea si echo "`nCreate btt device - automatic uuid generation" >> $LOG expect_normal_exit $BTTCREATE -s 40M -b 2K -l 256 -v $POOL >> $LOG expect_normal_exit $PMEMPOOL info $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/bttdevice/README0000664000000000000000000000044314123364546015636 0ustar rootrootPersistent Memory Development Kit This is src/test/bttdevice/README. This directory contains a unit test for tools that use btt device. The tests in this directory verify the creation of btt pool, support for corrupting the pool in pmemspoil tool and analyzing the pool by pmempool info. pmdk-1.11.1/src/test/bttdevice/TEST10000775000000000000000000000121514123364546015542 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # bttdevice/TEST1 -- test for checking pmempool info for spoiled btt device # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $BTTCREATE -v $POOL >> $LOG $PMEMSPOIL -v $POOL "bttdevice.arena(0).btt_info.sig=BADSIGNATURE"\ "bttdevice.arena(0).btt_info.external_lbasize=10"\ "bttdevice.arena(0).btt_info.major=0x0" >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX info $POOL -f btt >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/bttdevice/out1.log.match0000664000000000000000000000216314123364546017445 0ustar rootrootBTT successfully created: $(nW) poolsize 20971520B blocksize 512B maxlanes 256 uuid $(nW) $(nW): spoil: bttdevice.arena(0).btt_info.sig=BADSIGNATURE $(nW): spoil: bttdevice.arena(0).btt_info.external_lbasize=10 $(nW): spoil: bttdevice.arena(0).btt_info.major=0x0 BTT Device [ARENA 0] PMEM BLK BTT Info Header: Signature : BADSIGNATUREFO UUID of container : $(nW) Flags : 0x0 Major : 0 Minor : 1 External LBA size : 10 $(OPT)External LBA count : 40322 $(OPX)External LBA count : 40203 Internal LBA size : 512 $(OPT)Internal LBA count : 40578 $(OPX)Internal LBA count : 40459 Free blocks : 256 Info block size : 4096 Next arena offset : 0x0 Arena data offset : 0x1000 $(OPT)Area map offset : 0x13d2000 $(OPX)Area map offset : 0x13c3000 $(OPT)Area flog offset : 0x13fa000 $(OPX)Area flog offset : 0x13eb000 $(OPT)Info block backup offset : 0x13fe000 $(OPX)Info block backup offset : 0x13ef000 Checksum : $(XX) [wrong! should be: $(XX)] pmdk-1.11.1/src/test/bttdevice/bttdevice.vcxproj0000664000000000000000000001140614123364546020345 0ustar rootroot Debug x64 Release x64 {25758581-DD46-4AE4-99D9-11E736F72AD1} Win32Proj bttdevice 10.0.17134.0 Application true v140 Application false v140 true $(SolutionDir)\core;$(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\windows\getopt;$(SolutionDir)\libpmemlog;$(SolutionDir)\libpmemblk;$(SolutionDir)\libpmemobj;$(SolutionDir)\tools\pmempool;$(IncludePath) false $(SolutionDir)\core;$(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\windows\getopt;$(SolutionDir)\libpmemlog;$(SolutionDir)\libpmemblk;$(SolutionDir)\libpmemobj;$(SolutionDir)\tools\pmempool;$(IncludePath) $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) true $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {9186eac4-2f34-4f17-b940-6585d7869bcd} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_sds/0000775000000000000000000000000014123364546014632 5ustar rootrootpmdk-1.11.1/src/test/util_sds/err7.log.match0000664000000000000000000000007114123364546017305 0ustar rootroot$(*)ADR failure is detected, the pool might be corrupted pmdk-1.11.1/src/test/util_sds/TEST7.PS10000664000000000000000000000142214123364546016024 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST7 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after an open flag is set expect_normal_exit $Env:EXE_DIR\util_sds 1 5 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 # ADR failure - USC was incremented expect_abnormal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 3 0 ` $DIR\testfile2 7 1 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/util_sds.vcxproj0000664000000000000000000001760114123364546020102 0ustar rootroot Debug x64 Release x64 {5EC35099-9777-45E8-9520-EB2EE75BDF88} Win32Proj util_sds 10.0.17134.0 Application true v140 Application false v140 false NotSet Disabled mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2\x86_64;$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmem2\x86_64;$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;WRAP_REAL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;WRAP_REAL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions AdvancedVectorExtensions WRAP_REAL;%(PreprocessorDefinitions) WRAP_REAL;%(PreprocessorDefinitions) {2fa3155b-6f26-4d15-ac03-9d82d48dbc42} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_sds/TEST1.PS10000664000000000000000000000135614123364546016024 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST1 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail before a sds initialization expect_normal_exit $Env:EXE_DIR\util_sds 1 2 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/TEST5.PS10000664000000000000000000000135414123364546016026 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST5 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after an open flag is set expect_normal_exit $Env:EXE_DIR\util_sds 1 5 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/err6.log.match0000664000000000000000000000007114123364546017304 0ustar rootroot$(*)ADR failure is detected, the pool might be corrupted pmdk-1.11.1/src/test/util_sds/util_sds.c0000664000000000000000000001013014123364546016617 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2020, Intel Corporation */ /* * util_sds.c -- unit test for shutdown state functions */ #include #include "unittest.h" #include "ut_pmem2.h" #include "shutdown_state.h" #include "set.h" #define PMEM_LEN 4096 static char **uids; static size_t uids_size; static size_t uid_it; static uint64_t *uscs; static size_t uscs_size; static size_t usc_it; static pmem2_persist_fn persist; #define FAIL(X, Y) \ if ((X) == (Y)) { \ goto out; \ } int main(int argc, char *argv[]) { START(argc, argv, "util_sds"); if (argc < 2) UT_FATAL("usage: %s init fail (file uuid usc)...", argv[0]); unsigned files = (unsigned)(argc - 2) / 3; char **pmemaddr = MALLOC(files * sizeof(char *)); int *fds = MALLOC(files * sizeof(fds[0])); struct pmem2_map **maps = MALLOC(files * sizeof(maps[0])); uids = MALLOC(files * sizeof(uids[0])); uscs = MALLOC(files * sizeof(uscs[0])); uids_size = files; uscs_size = files; int init = atoi(argv[1]); int fail_on = atoi(argv[2]); char **args = argv + 3; struct pmem2_config *cfg; PMEM2_CONFIG_NEW(&cfg); pmem2_config_set_required_store_granularity(cfg, PMEM2_GRANULARITY_PAGE); for (unsigned i = 0; i < files; i++) { fds[i] = OPEN(args[i * 3], O_CREAT | O_RDWR, 0666); POSIX_FALLOCATE(fds[i], 0, PMEM_LEN); struct pmem2_source *src; PMEM2_SOURCE_FROM_FD(&src, fds[i]); if (pmem2_map_new(&maps[i], cfg, src)) { UT_FATAL("pmem2_map: %s", pmem2_errormsg()); } pmemaddr[0] = pmem2_map_get_address(maps[i]); uids[i] = args[i * 3 + 1]; uscs[i] = strtoull(args[i * 3 + 2], NULL, 0); PMEM2_SOURCE_DELETE(&src); } persist = pmem2_get_persist_fn(maps[0]); FAIL(fail_on, 1); struct pool_replica *rep = MALLOC( sizeof(*rep) + sizeof(struct pool_set_part)); memset(rep, 0, sizeof(*rep) + sizeof(struct pool_set_part)); struct shutdown_state *pool_sds = (struct shutdown_state *)pmemaddr[0]; if (init) { /* initialize pool shutdown state */ shutdown_state_init(pool_sds, rep); FAIL(fail_on, 2); for (unsigned i = 0; i < files; i++) { if (shutdown_state_add_part(pool_sds, fds[i], rep)) UT_FATAL("shutdown_state_add_part"); FAIL(fail_on, 3); } } else { /* verify a shutdown state saved in the pool */ struct shutdown_state current_sds; shutdown_state_init(¤t_sds, NULL); FAIL(fail_on, 2); for (unsigned i = 0; i < files; i++) { if (shutdown_state_add_part(¤t_sds, fds[i], NULL)) UT_FATAL("shutdown_state_add_part"); FAIL(fail_on, 3); } if (shutdown_state_check(¤t_sds, pool_sds, rep)) { UT_FATAL( "An ADR failure is detected, the pool might be corrupted"); } } FAIL(fail_on, 4); shutdown_state_set_dirty(pool_sds, rep); /* pool is open */ FAIL(fail_on, 5); /* close pool */ shutdown_state_clear_dirty(pool_sds, rep); FAIL(fail_on, 6); out: for (unsigned i = 0; i < files; i++) { pmem2_map_delete(&maps[i]); CLOSE(fds[i]); } PMEM2_CONFIG_DELETE(&cfg); FREE(pmemaddr); FREE(uids); FREE(uscs); FREE(fds); FREE(maps); DONE(NULL); } FUNC_MOCK(pmem2_source_device_id, int, const struct pmem2_source *src, char *uid, size_t *len) FUNC_MOCK_RUN_DEFAULT { if (uid_it < uids_size) { if (uid != NULL) { strcpy(uid, uids[uid_it]); uid_it++; } else { *len = strlen(uids[uid_it]) + 1; } } else { return -1; } return 0; } FUNC_MOCK_END FUNC_MOCK(pmem2_source_device_usc, int, const struct pmem2_source *src, uint64_t *usc) FUNC_MOCK_RUN_DEFAULT { if (usc_it < uscs_size) { *usc = uscs[usc_it]; usc_it++; } else { return -1; } return 0; } FUNC_MOCK_END int os_part_deep_common(struct pool_replica *rep, unsigned partidx, void *addr, size_t len, int flush); /* * os_part_deep_common -- XXX temporally workaround until we will have pmem2 * integrated with common */ int os_part_deep_common(struct pool_replica *rep, unsigned partidx, void *addr, size_t len, int flush) { /* * this is test - we don't need to deep persist anything - * just call regular persist to make valgrind happy */ persist(addr, len); return 0; } #ifdef _MSC_VER MSVC_CONSTR(libpmem2_init) MSVC_DESTR(libpmem2_fini) #endif pmdk-1.11.1/src/test/util_sds/TEST30000775000000000000000000000127714123364546015431 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST3 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail during sds creation expect_normal_exit ./util_sds 1 3 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/mocks_windows.h0000664000000000000000000000045614123364546017676 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2018-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of dimm functions */ #ifndef WRAP_REAL #define pmem2_source_device_usc __wrap_pmem2_source_device_usc #define pmem2_source_device_idU __wrap_pmem2_source_device_id #endif pmdk-1.11.1/src/test/util_sds/grep3.log.match0000664000000000000000000000021514123364546017446 0ustar rootroot: <2> [shutdown_state.c:$(N) shutdown_state_check] an ADR failure was detected but the pool was closed - SDS will be reinitialized pmdk-1.11.1/src/test/util_sds/TEST00000775000000000000000000000125714123364546015424 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST0 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # no error expect_normal_exit ./util_sds 1 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/Makefile0000664000000000000000000000076714123364546016304 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/util_sds/Makefile -- shutdown_tests unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest/ vpath %.c $(TOP)/src/common/ TARGET = util_sds OBJS = util_sds.o\ shutdown_state.o\ ut_pmem2_config.o\ ut_pmem2_source.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc # add DEBUG define for logs from shutdown_state.c CFLAGS += -DDEBUG=1 LDFLAGS += $(call extract_funcs, util_sds.c) pmdk-1.11.1/src/test/util_sds/TEST3.PS10000664000000000000000000000135314123364546016023 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST3 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after sds initialization expect_normal_exit $Env:EXE_DIR\util_sds 1 3 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/grep0.log.match0000664000000000000000000000000014123364546017433 0ustar rootrootpmdk-1.11.1/src/test/util_sds/TEST2.PS10000664000000000000000000000135314123364546016022 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST1 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after sds initialization expect_normal_exit $Env:EXE_DIR\util_sds 1 2 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/TEST50000775000000000000000000000130514123364546015423 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST5 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail after an open flag is set expect_normal_exit ./util_sds 1 5 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/TEST6.PS10000664000000000000000000000142314123364546016024 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST6 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after an open flag is set expect_normal_exit $Env:EXE_DIR\util_sds 1 5 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 # files was moved to another dimm expect_abnormal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 15 0 ` $DIR\testfile2 73 0 ` $DIR\testfile3 49 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/TEST40000775000000000000000000000131614123364546015424 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST4 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail before setting open flag expect_normal_exit ./util_sds 1 4 \ $DIR/testfile1 5 12 \ $DIR/testfile2 7 156 \ $DIR/testfile3 9 134 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 12 \ $DIR/testfile2 7 156 \ $DIR/testfile3 9 134 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/grep7.log.match0000664000000000000000000000016614123364546017457 0ustar rootroot: <1> [shutdown_state.c:$(N) shutdown_state_check] an ADR failure was detected, the pool might be corrupted pmdk-1.11.1/src/test/util_sds/TEST70000775000000000000000000000135314123364546015430 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST7 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail after an open flag is set expect_normal_exit ./util_sds 1 5 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 # ADR failure - USC was incremented expect_abnormal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 1 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/TEST0.PS10000664000000000000000000000133114123364546016014 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST0 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # no error expect_normal_exit $Env:EXE_DIR\util_sds 1 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -contains 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/grep4.log.match0000664000000000000000000000000014123364546017437 0ustar rootrootpmdk-1.11.1/src/test/util_sds/.gitignore0000664000000000000000000000001114123364546016612 0ustar rootrootutil_sds pmdk-1.11.1/src/test/util_sds/grep8.log.match0000664000000000000000000000000014123364546017443 0ustar rootrootpmdk-1.11.1/src/test/util_sds/TEST60000775000000000000000000000135414123364546015430 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST6 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail after an open flag is set expect_normal_exit ./util_sds 1 5 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 # files was moved to another dimm expect_abnormal_exit ./util_sds 0 0 \ $DIR/testfile1 15 0 \ $DIR/testfile2 73 0 \ $DIR/testfile3 49 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/grep6.log.match0000664000000000000000000000016614123364546017456 0ustar rootroot: <1> [shutdown_state.c:$(N) shutdown_state_check] an ADR failure was detected, the pool might be corrupted pmdk-1.11.1/src/test/util_sds/TEST10000775000000000000000000000130714123364546015421 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST1 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail before a sds initialization expect_normal_exit ./util_sds 1 1 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/grep5.log.match0000664000000000000000000000016114123364546017450 0ustar rootroot: <2> [shutdown_state.c:$(N) shutdown_state_check] the pool was not closed - SDS will be reinitialized pmdk-1.11.1/src/test/util_sds/TEST4.PS10000664000000000000000000000136514123364546016027 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST4 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail before setting open flag expect_normal_exit $Env:EXE_DIR\util_sds 1 4 ` $DIR\testfile1 5 12 ` $DIR\testfile2 7 156 ` $DIR\testfile3 9 134 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 12 ` $DIR\testfile2 7 156 ` $DIR\testfile3 9 134 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/TEST80000775000000000000000000000131114123364546015423 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # src/test/util_sds/TEST8 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail after an open flag is cleared expect_normal_exit ./util_sds 1 6 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/TEST8.PS10000664000000000000000000000135414123364546016031 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST8 -- unittest for shutdown state # . ..\unittest\unittest.PS1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM2_LOG_LEVEL=2 $Env:PMEM2_LOG_FILE=".\test$Env:UNITTEST_NUM.log" # fail after an open flag is set expect_normal_exit $Env:EXE_DIR\util_sds 1 6 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 expect_normal_exit $Env:EXE_DIR\util_sds 0 0 ` $DIR\testfile1 5 0 ` $DIR\testfile2 7 0 ` $DIR\testfile3 9 0 Get-Content test$Env:UNITTEST_NUM.log | Where-Object {$_ -match 'shutdown_state_check'} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/util_sds/grep1.log.match0000664000000000000000000000000014123364546017434 0ustar rootrootpmdk-1.11.1/src/test/util_sds/grep2.log.match0000664000000000000000000000000014123364546017435 0ustar rootrootpmdk-1.11.1/src/test/util_sds/TEST20000775000000000000000000000130414123364546015417 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/util_sds/TEST2 -- unittest for shutdown state # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_build_type debug setup export PMEM2_LOG_LEVEL=2 export PMEM2_LOG_FILE=./test$UNITTEST_NUM.log # fail after sds initialization expect_normal_exit ./util_sds 1 2 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 expect_normal_exit ./util_sds 0 0 \ $DIR/testfile1 5 0 \ $DIR/testfile2 7 0 \ $DIR/testfile3 9 0 grep "shutdown_state_check" test$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/util_sds/util_sds.vcxproj.filters0000664000000000000000000001172014123364546021545 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {18a24826-3f5b-411c-b4a1-fa378e9b84e4} {bc5d0076-9158-46f8-a4b3-a8660f5331f3} {c6f26e3f-f5a7-4697-ac20-6fc3f501f78d} Source Files Source Files Source Files Source Files Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2\x86_64 Source Files\pmem2 Source Files Source Files Source Files\pmem2 Source Files\pmem2 Source Files\pmem2 Header Files Header Files pmdk-1.11.1/src/test/rpmem_fip/0000775000000000000000000000000014123364546014762 5ustar rootrootpmdk-1.11.1/src/test/rpmem_fip/rpmem_fip_oob.c0000664000000000000000000000642114123364546017746 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_fip_oob.c -- simple oob connection implementation for exchanging * required RDMA related data */ #include #include #include #include #include "rpmem_common.h" #include "rpmem_proto.h" #include "rpmem_fip_oob.h" #include "rpmem_ssh.h" #include "unittest.h" #include "rpmem_util.h" #include "os.h" #define CMD_BUFF_SIZE 4096 static const char *rpmem_cmd; /* * set_rpmem_cmd -- set RPMEM_CMD variable */ void set_rpmem_cmd(const char *fmt, ...) { static char cmd_buff[CMD_BUFF_SIZE]; if (!rpmem_cmd) { char *cmd = os_getenv(RPMEM_CMD_ENV); UT_ASSERTne(cmd, NULL); rpmem_cmd = STRDUP(cmd); } ssize_t ret; size_t cnt = 0; va_list ap; va_start(ap, fmt); ret = SNPRINTF(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, "%s ", rpmem_cmd); UT_ASSERT(ret > 0); cnt += (size_t)ret; ret = vsnprintf(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, fmt, ap); UT_ASSERT(ret > 0); cnt += (size_t)ret; va_end(ap); ret = os_setenv(RPMEM_CMD_ENV, cmd_buff, 1); UT_ASSERTeq(ret, 0); /* * Rpmem has internal RPMEM_CMD variable copy and it is assumed * RPMEMD_CMD will not change its value during execution. To refresh the * internal copy it must be destroyed and a instance must be initialized * manually. */ rpmem_util_cmds_fini(); rpmem_util_cmds_init(); } /* * client_exchange -- connect to remote host and exchange required information */ client_t * client_exchange(struct rpmem_target_info *info, unsigned nlanes, enum rpmem_provider provider, struct rpmem_resp_attr *resp) { struct rpmem_ssh *ssh = rpmem_ssh_open(info); UT_ASSERTne(ssh, NULL); int ret; ret = rpmem_ssh_send(ssh, &nlanes, sizeof(nlanes)); UT_ASSERTeq(ret, 0); ret = rpmem_ssh_send(ssh, &provider, sizeof(provider)); UT_ASSERTeq(ret, 0); ret = rpmem_ssh_recv(ssh, resp, sizeof(*resp)); UT_ASSERTeq(ret, 0); return ssh; } /* * client_close_begin -- begin closing connection */ void client_close_begin(client_t *c) { int cmd = 1; int ret; ret = rpmem_ssh_send(c, &cmd, sizeof(cmd)); UT_ASSERTeq(ret, 0); ret = rpmem_ssh_recv(c, &cmd, sizeof(cmd)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(cmd, 0); } /* * client_close_end -- end closing connection */ void client_close_end(client_t *c) { rpmem_ssh_close(c); } /* * server_exchange_begin -- accept a connection and read required information */ void server_exchange_begin(unsigned *lanes, enum rpmem_provider *provider, char **addr) { UT_ASSERTne(addr, NULL); char *conn = rpmem_get_ssh_conn_addr(); UT_ASSERTne(conn, NULL); *addr = strdup(conn); UT_ASSERTne(*addr, NULL); uint32_t status = 0; WRITE(STDOUT_FILENO, &status, sizeof(status)); READ(STDIN_FILENO, lanes, sizeof(*lanes)); READ(STDIN_FILENO, provider, sizeof(*provider)); } /* * server_exchange_end -- send response to client */ void server_exchange_end(struct rpmem_resp_attr resp) { WRITE(STDOUT_FILENO, &resp, sizeof(resp)); } /* * server_close_begin -- wait for close command */ void server_close_begin(void) { int cmd = 0; READ(STDIN_FILENO, &cmd, sizeof(cmd)); UT_ASSERTeq(cmd, 1); } /* * server_close_end -- send close response and wait for disconnect */ void server_close_end(void) { int cmd = 0; WRITE(STDOUT_FILENO, &cmd, sizeof(cmd)); } pmdk-1.11.1/src/test/rpmem_fip/rpmem_fip_oob.h0000664000000000000000000000135714123364546017756 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_fip_sock.h -- simple oob connection implementation for exchanging * required RDMA related data */ #include #include typedef struct rpmem_ssh client_t; client_t *client_exchange(struct rpmem_target_info *info, unsigned nlanes, enum rpmem_provider provider, struct rpmem_resp_attr *resp); void client_close_begin(client_t *c); void client_close_end(client_t *c); void server_exchange_begin(unsigned *lanes, enum rpmem_provider *provider, char **addr); void server_exchange_end(struct rpmem_resp_attr resp); void server_close_begin(void); void server_close_end(void); void set_rpmem_cmd(const char *fmt, ...); pmdk-1.11.1/src/test/rpmem_fip/TEST30000775000000000000000000000056114123364546015554 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/TEST3 -- tests for rpmem_fip and rpmemd_fip modules # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_read ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/TEST00000775000000000000000000000056114123364546015551 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/TEST0 -- tests for rpmem_fip and rpmemd_fip modules # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_init ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/Makefile0000664000000000000000000000160414123364546016423 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/test/rpmem_fip/Makefile -- build rpmem_fip test # include ../../common.inc vpath %.c ../../librpmem/ vpath %.c ../../rpmem_common/ vpath %.c ../../tools/rpmemd ifeq ($(BUILD_RPMEM), y) SCP_TO_REMOTE_NODES = y TARGET = rpmem_fip OBJS = rpmem_fip_test.o\ rpmem_fip_oob.o\ rpmem_fip.o\ rpmemd_fip.o\ rpmem_util.o\ rpmem_ssh.o\ rpmem_cmd.o\ rpmem_common.o\ rpmem_fip_common.o\ rpmemd_util.o\ rpmemd_obc.o\ rpmemd_log.o endif BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc ifeq ($(BUILD_RPMEM), y) LIBS += $(LIBFABRIC_LIBS) CFLAGS += $(LIBFABRIC_CFLAGS) CFLAGS += -DDEBUG CFLAGS += -DRPMEMC_LOG_RPMEM INCS += -I../../librpmem/ INCS += -I../../rpmem_common/ INCS += -I../../tools/rpmemd endif pmdk-1.11.1/src/test/rpmem_fip/TEST50000775000000000000000000000177014123364546015561 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/rpmem_fip/TEST5 -- test WQ size evaluation # . ../unittest/unittest.sh require_test_type medium setup . setup.sh function rpmem_fip_test() { local wq_size=$1 expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_wq_size ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM\ $wq_size } # WQ size is common for all lanes export RPMEM_WORK_QUEUE_SIZE=1 export_vars_node 1 RPMEM_WORK_QUEUE_SIZE UINT_MAX=$((2**32)) TOO_LARGE=$((UINT_MAX + 1)) WQ_SIZE_VALUES=(8 -1 0 1 $TOO_LARGE) for wq_size in ${wq_SIZE_VALUES[@]}; do # limit size of WQ queue export RPMEM_WORK_QUEUE_SIZE=$wq_size export_vars_node 1 RPMEM_WORK_QUEUE_SIZE rpmem_fip_test $wq_size done # relative values WQ_SIZE_VALUES=("LT_MAX_WQ_SIZE" "EQ_MAX_WQ_SIZE" "GT_MAX_WQ_SIZE") for wq_size in ${WQ_SIZE_VALUES[@]}; do # RPMEM_WORK_QUEUE_SIZE will be set according to maximum supported WQ size rpmem_fip_test $wq_size done pass pmdk-1.11.1/src/test/rpmem_fip/TEST40000775000000000000000000000056714123364546015563 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/TEST4 -- tests for rpmem_fip and rpmemd_fip modules # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_persist_mt ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/TEST70000775000000000000000000000062714123364546015563 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/rpmem_fip/TEST7 -- rpmem_fip_flush and rpmem_fip_drain # multi-threaded # # single-threaded in TEST6 # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_flush_mt ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/.gitignore0000664000000000000000000000001214123364546016743 0ustar rootrootrpmem_fip pmdk-1.11.1/src/test/rpmem_fip/README0000664000000000000000000000101214123364546015634 0ustar rootrootTests in this directory rely on an ability to spawn ctrld daemon on remote node(s) over ssh and close the ssh connection. On systems with systemd version >= 230 all user processes started in one session are killed on logout, even when they were detached using daemon(3). To workaround this issue, change "KillUserProcesses" back to "no" in logind.conf and restart systemd-logind service (systemctl reload systemd-logind.service). https://github.com/systemd/systemd/blob/3a74d4fc90cb322a4784a3515bef7118c8f8c5ba/NEWS#L29. pmdk-1.11.1/src/test/rpmem_fip/config.sh0000664000000000000000000000044014123364546016561 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2017, Intel Corporation # # # src/test/rpmem_fip/config.sh -- test configuration # CONF_GLOBAL_FS_TYPE=none CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/rpmem_fip/TEST60000775000000000000000000000062414123364546015557 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/rpmem_fip/TEST6 -- rpmem_fip_flush and rpmem_fip_drain # single-threaded # # multi-threaded in TEST7 # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_flush ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/rpmem_fip_test.c0000664000000000000000000005407214123364546020153 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_fip_test.c -- tests for rpmem_fip and rpmemd_fip modules */ #include #include #include #include #include "unittest.h" #include "pmemcommon.h" #include "librpmem.h" #include "rpmem.h" #include "rpmem_proto.h" #include "rpmem_common.h" #include "rpmem_util.h" #include "rpmem_fip_common.h" #include "rpmem_fip_oob.h" #include "rpmemd_fip.h" #include "rpmemd_log.h" #include "rpmemd_util.h" #include "rpmem_fip.h" #include "os.h" #define SIZE_PER_LANE 64 #define COUNT_PER_LANE 32 #define NLANES 1024 #define SOCK_NLANES 32 #define NTHREADS 32 #define TOTAL_PER_LANE (SIZE_PER_LANE * COUNT_PER_LANE) #define POOL_SIZE (NLANES * TOTAL_PER_LANE) static uint8_t lpool[POOL_SIZE]; static uint8_t rpool[POOL_SIZE]; TEST_CASE_DECLARE(client_init); TEST_CASE_DECLARE(server_init); TEST_CASE_DECLARE(client_connect); TEST_CASE_DECLARE(server_connect); TEST_CASE_DECLARE(server_process); TEST_CASE_DECLARE(client_flush); TEST_CASE_DECLARE(client_flush_mt); TEST_CASE_DECLARE(client_persist); TEST_CASE_DECLARE(client_persist_mt); TEST_CASE_DECLARE(client_read); TEST_CASE_DECLARE(client_wq_size); struct fip_client { enum rpmem_provider provider; unsigned max_wq_size; unsigned nlanes; }; #define FIP_CLIENT_DEFAULT {RPMEM_PROV_UNKNOWN, 0, NLANES} /* * get_persist_method -- parse persist method */ static enum rpmem_persist_method get_persist_method(const char *pm) { if (strcmp(pm, "GPSPM") == 0) return RPMEM_PM_GPSPM; else if (strcmp(pm, "APM") == 0) return RPMEM_PM_APM; else UT_FATAL("unknown method"); } /* * get_provider -- get provider for given target */ static void get_provider(const char *target, const char *prov_name, struct fip_client *client) { struct rpmem_fip_probe probe; int ret; int any = 0; if (strcmp(prov_name, "any") == 0) any = 1; ret = rpmem_fip_probe_get(target, &probe); UT_ASSERTeq(ret, 0); UT_ASSERT(rpmem_fip_probe_any(probe)); if (any) { /* return verbs in first place */ if (rpmem_fip_probe(probe, RPMEM_PROV_LIBFABRIC_VERBS)) client->provider = RPMEM_PROV_LIBFABRIC_VERBS; else if (rpmem_fip_probe(probe, RPMEM_PROV_LIBFABRIC_SOCKETS)) client->provider = RPMEM_PROV_LIBFABRIC_SOCKETS; else UT_ASSERT(0); } else { client->provider = rpmem_provider_from_str(prov_name); UT_ASSERTne(client->provider, RPMEM_PROV_UNKNOWN); UT_ASSERT(rpmem_fip_probe(probe, client->provider)); } /* * Decrease number of lanes for socket provider because * the test may be too long. */ if (client->provider == RPMEM_PROV_LIBFABRIC_SOCKETS) client->nlanes = min(client->nlanes, SOCK_NLANES); client->max_wq_size = probe.max_wq_size[client->provider]; } /* * set_pool_data -- set pools data to well known values */ static void set_pool_data(uint8_t *pool, int inverse) { for (unsigned l = 0; l < NLANES; l++) { for (unsigned i = 0; i < COUNT_PER_LANE; i++) { size_t offset = l * TOTAL_PER_LANE + i * SIZE_PER_LANE; unsigned val = i + l; if (inverse) val = ~val; memset(&pool[offset], (int)val, SIZE_PER_LANE); } } } /* * flush_arg -- arguments for client persist and flush / drain threads */ struct flush_arg { struct rpmem_fip *fip; unsigned lane; }; typedef void *(*flush_fn)(void *arg); /* * client_flush_thread -- thread callback for flush / drain operation */ static void * client_flush_thread(void *arg) { struct flush_arg *args = arg; int ret; /* persist with len == 0 should always succeed */ ret = rpmem_fip_flush(args->fip, args->lane * TOTAL_PER_LANE, 0, args->lane, RPMEM_FLUSH_WRITE); UT_ASSERTeq(ret, 0); for (unsigned i = 0; i < COUNT_PER_LANE; i++) { size_t offset = args->lane * TOTAL_PER_LANE + i * SIZE_PER_LANE; unsigned val = args->lane + i; memset(&lpool[offset], (int)val, SIZE_PER_LANE); ret = rpmem_fip_flush(args->fip, offset, SIZE_PER_LANE, args->lane, RPMEM_FLUSH_WRITE); UT_ASSERTeq(ret, 0); } ret = rpmem_fip_drain(args->fip, args->lane); UT_ASSERTeq(ret, 0); return NULL; } /* * client_persist_thread -- thread callback for persist operation */ static void * client_persist_thread(void *arg) { struct flush_arg *args = arg; int ret; /* persist with len == 0 should always succeed */ ret = rpmem_fip_persist(args->fip, args->lane * TOTAL_PER_LANE, 0, args->lane, RPMEM_FLUSH_WRITE); UT_ASSERTeq(ret, 0); for (unsigned i = 0; i < COUNT_PER_LANE; i++) { size_t offset = args->lane * TOTAL_PER_LANE + i * SIZE_PER_LANE; unsigned val = args->lane + i; memset(&lpool[offset], (int)val, SIZE_PER_LANE); ret = rpmem_fip_persist(args->fip, offset, SIZE_PER_LANE, args->lane, RPMEM_FLUSH_WRITE); UT_ASSERTeq(ret, 0); } return NULL; } /* * client_init -- test case for client initialization */ int client_init(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; set_rpmem_cmd("server_init %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); /* * Tune the maximum number of lanes according to environment. */ rpmem_util_get_env_max_nlanes(&Rpmem_max_nlanes); struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); client_close_begin(client); client_close_end(client); rpmem_fip_fini(fip); rpmem_target_free(info); return 3; } /* * server_init -- test case for server initialization */ int server_init(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s ", tc->name); enum rpmem_persist_method persist_method = get_persist_method(argv[0]); unsigned nlanes; enum rpmem_provider provider; char *addr = NULL; int ret; server_exchange_begin(&nlanes, &provider, &addr); UT_ASSERTne(addr, NULL); struct rpmemd_fip_attr attr = { .addr = rpool, .size = POOL_SIZE, .nlanes = nlanes, .provider = provider, .persist_method = persist_method, .nthreads = NTHREADS, }; ret = rpmemd_apply_pm_policy(&attr.persist_method, &attr.persist, &attr.memcpy_persist, 1 /* is pmem */); UT_ASSERTeq(ret, 0); struct rpmem_resp_attr resp; struct rpmemd_fip *fip; enum rpmem_err err; fip = rpmemd_fip_init(addr, NULL, &attr, &resp, &err); UT_ASSERTne(fip, NULL); server_exchange_end(resp); server_close_begin(); server_close_end(); rpmemd_fip_fini(fip); FREE(addr); return 1; } /* * client_connect -- test case for establishing connection - client side */ int client_connect(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; set_rpmem_cmd("server_connect %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; int ret; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); ret = rpmem_fip_connect(fip); UT_ASSERTeq(ret, 0); client_close_begin(client); ret = rpmem_fip_close(fip); UT_ASSERTeq(ret, 0); client_close_end(client); rpmem_fip_fini(fip); rpmem_target_free(info); return 3; } /* * server_connect -- test case for establishing connection - server side */ int server_connect(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s ", tc->name); enum rpmem_persist_method persist_method = get_persist_method(argv[0]); unsigned nlanes; enum rpmem_provider provider; char *addr = NULL; server_exchange_begin(&nlanes, &provider, &addr); UT_ASSERTne(addr, NULL); struct rpmemd_fip_attr attr = { .addr = rpool, .size = POOL_SIZE, .nlanes = nlanes, .provider = provider, .persist_method = persist_method, .nthreads = NTHREADS, }; int ret; struct rpmem_resp_attr resp; struct rpmemd_fip *fip; enum rpmem_err err; ret = rpmemd_apply_pm_policy(&attr.persist_method, &attr.persist, &attr.memcpy_persist, 1 /* is pmem */); UT_ASSERTeq(ret, 0); fip = rpmemd_fip_init(addr, NULL, &attr, &resp, &err); UT_ASSERTne(fip, NULL); server_exchange_end(resp); ret = rpmemd_fip_accept(fip, -1); UT_ASSERTeq(ret, 0); server_close_begin(); server_close_end(); ret = rpmemd_fip_wait_close(fip, -1); UT_ASSERTeq(ret, 0); ret = rpmemd_fip_close(fip); UT_ASSERTeq(ret, 0); rpmemd_fip_fini(fip); FREE(addr); return 1; } /* * server_process -- test case for processing data on server side */ int server_process(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s ", tc->name); enum rpmem_persist_method persist_method = get_persist_method(argv[0]); set_pool_data(rpool, 1); unsigned nlanes; enum rpmem_provider provider; char *addr = NULL; server_exchange_begin(&nlanes, &provider, &addr); UT_ASSERTne(addr, NULL); struct rpmemd_fip_attr attr = { .addr = rpool, .size = POOL_SIZE, .nlanes = nlanes, .provider = provider, .persist_method = persist_method, .nthreads = NTHREADS, }; int ret; struct rpmem_resp_attr resp; struct rpmemd_fip *fip; enum rpmem_err err; ret = rpmemd_apply_pm_policy(&attr.persist_method, &attr.persist, &attr.memcpy_persist, 1 /* is pmem */); UT_ASSERTeq(ret, 0); fip = rpmemd_fip_init(addr, NULL, &attr, &resp, &err); UT_ASSERTne(fip, NULL); server_exchange_end(resp); ret = rpmemd_fip_accept(fip, -1); UT_ASSERTeq(ret, 0); ret = rpmemd_fip_process_start(fip); server_close_begin(); ret = rpmemd_fip_process_stop(fip); UT_ASSERTeq(ret, 0); server_close_end(); ret = rpmemd_fip_wait_close(fip, -1); UT_ASSERTeq(ret, 0); ret = rpmemd_fip_close(fip); UT_ASSERTeq(ret, 0); rpmemd_fip_fini(fip); FREE(addr); return 1; } /* * flush_common -- common part for single-threaded persist and flush / drain * test cases */ static void flush_common(char *target, char *prov_name, char *persist_method, flush_fn flush_func) { set_rpmem_cmd("server_process %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); int ret; set_pool_data(lpool, 1); set_pool_data(rpool, 1); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); ret = rpmem_fip_connect(fip); UT_ASSERTeq(ret, 0); struct flush_arg arg = { .fip = fip, .lane = 0, }; flush_func(&arg); ret = rpmem_fip_read(fip, rpool, POOL_SIZE, 0, 0); UT_ASSERTeq(ret, 0); client_close_begin(client); ret = rpmem_fip_close(fip); UT_ASSERTeq(ret, 0); client_close_end(client); rpmem_fip_fini(fip); ret = memcmp(rpool, lpool, POOL_SIZE); UT_ASSERTeq(ret, 0); rpmem_target_free(info); } /* * flush_common_mt -- common part for multi-threaded persist and flush / drain * test cases */ static int flush_common_mt(char *target, char *prov_name, char *persist_method, flush_fn flush_thread_func) { set_rpmem_cmd("server_process %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; int ret; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); set_pool_data(lpool, 1); set_pool_data(rpool, 1); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); ret = rpmem_fip_connect(fip); UT_ASSERTeq(ret, 0); os_thread_t *flush_thread = MALLOC(resp.nlanes * sizeof(os_thread_t)); struct flush_arg *args = MALLOC(resp.nlanes * sizeof(struct flush_arg)); for (unsigned i = 0; i < fip_client.nlanes; i++) { args[i].fip = fip; args[i].lane = i; THREAD_CREATE(&flush_thread[i], NULL, flush_thread_func, &args[i]); } for (unsigned i = 0; i < fip_client.nlanes; i++) THREAD_JOIN(&flush_thread[i], NULL); ret = rpmem_fip_read(fip, rpool, POOL_SIZE, 0, 0); UT_ASSERTeq(ret, 0); client_close_begin(client); ret = rpmem_fip_close(fip); UT_ASSERTeq(ret, 0); client_close_end(client); rpmem_fip_fini(fip); FREE(flush_thread); FREE(args); ret = memcmp(rpool, lpool, POOL_SIZE); UT_ASSERTeq(ret, 0); rpmem_target_free(info); return 3; } /* * client_flush -- test case for single-threaded flush / drain operation */ int client_flush(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; flush_common(target, prov_name, persist_method, client_flush_thread); return 3; } /* * client_flush_mt -- test case for multi-threaded flush / drain operation */ int client_flush_mt(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; flush_common_mt(target, prov_name, persist_method, client_flush_thread); return 3; } /* * client_persist -- test case for single-threaded persist operation */ int client_persist(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; flush_common(target, prov_name, persist_method, client_persist_thread); return 3; } /* * client_persist_mt -- test case for multi-threaded persist operation */ int client_persist_mt(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; flush_common_mt(target, prov_name, persist_method, client_persist_thread); return 3; } /* * client_read -- test case for read operation */ int client_read(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s ", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; set_rpmem_cmd("server_process %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; int ret; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); set_pool_data(lpool, 0); set_pool_data(rpool, 1); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); ret = rpmem_fip_connect(fip); UT_ASSERTeq(ret, 0); /* read with len == 0 should always succeed */ ret = rpmem_fip_read(fip, lpool, 0, 0, 0); UT_ASSERTeq(ret, 0); ret = rpmem_fip_read(fip, lpool, POOL_SIZE, 0, 0); UT_ASSERTeq(ret, 0); client_close_begin(client); ret = rpmem_fip_close(fip); UT_ASSERTeq(ret, 0); client_close_end(client); rpmem_fip_fini(fip); ret = memcmp(rpool, lpool, POOL_SIZE); UT_ASSERTeq(ret, 0); rpmem_target_free(info); return 3; } #define LT_MAX_WQ_SIZE "LT_MAX_WQ_SIZE" /* < max_wq_size */ #define EQ_MAX_WQ_SIZE "EQ_MAX_WQ_SIZE" /* == max_wq_size */ #define GT_MAX_WQ_SIZE "GT_MAX_WQ_SIZE" /* > max_wq_size */ /* * client_wq_size -- test case for WQ size adjustment */ int client_wq_size(const struct test_case *tc, int argc, char *argv[]) { if (argc < 3) UT_FATAL("usage: %s " "", tc->name); char *target = argv[0]; char *prov_name = argv[1]; char *persist_method = argv[2]; char *wq_size_env_str = argv[3]; set_rpmem_cmd("server_process %s", persist_method); char fip_service[NI_MAXSERV]; struct rpmem_target_info *info; int ret; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); struct fip_client fip_client = FIP_CLIENT_DEFAULT; get_provider(info->node, prov_name, &fip_client); rpmem_util_get_env_max_nlanes(&fip_client.nlanes); client_t *client; struct rpmem_resp_attr resp; client = client_exchange(info, fip_client.nlanes, fip_client.provider, &resp); struct rpmem_fip_attr attr = { .provider = fip_client.provider, .max_wq_size = fip_client.max_wq_size, .persist_method = resp.persist_method, .laddr = lpool, .size = POOL_SIZE, .nlanes = resp.nlanes, .raddr = (void *)resp.raddr, .rkey = resp.rkey, }; ssize_t sret = SNPRINTF(fip_service, NI_MAXSERV, "%u", resp.port); UT_ASSERT(sret > 0); /* check RPMEM_WORK_QUEUE_SIZE env processing */ unsigned wq_size_default = Rpmem_wq_size; if (strcmp(wq_size_env_str, LT_MAX_WQ_SIZE) == 0) { Rpmem_wq_size = fip_client.max_wq_size - 1; } else if (strcmp(wq_size_env_str, EQ_MAX_WQ_SIZE) == 0) { Rpmem_wq_size = fip_client.max_wq_size; } else if (strcmp(wq_size_env_str, GT_MAX_WQ_SIZE) == 0) { Rpmem_wq_size = fip_client.max_wq_size + 1; } else { long wq_size_env = STRTOL(wq_size_env_str, NULL, 10); rpmem_util_get_env_wq_size(&Rpmem_wq_size); if (wq_size_env > 0) { if (wq_size_env < UINT_MAX) UT_ASSERT(Rpmem_wq_size == wq_size_env); else UT_ASSERT(Rpmem_wq_size == UINT_MAX); } else UT_ASSERT(Rpmem_wq_size == wq_size_default); } struct rpmem_fip *fip; fip = rpmem_fip_init(info->node, fip_service, &attr, &fip_client.nlanes); UT_ASSERTne(fip, NULL); size_t req_wq_size = rpmem_fip_wq_size( resp.persist_method, RPMEM_FIP_NODE_CLIENT); size_t eff_wq_size = rpmem_fip_get_wq_size(fip); /* max supported meets minimal requirements */ UT_ASSERT(fip_client.max_wq_size >= req_wq_size); /* calculated meets minimal requirements */ UT_ASSERT(eff_wq_size >= req_wq_size); /* calculated is supported */ UT_ASSERT(eff_wq_size <= fip_client.max_wq_size); /* if forced by env meets minimal requirements */ if (Rpmem_wq_size > req_wq_size) { /* and it is supported */ if (Rpmem_wq_size <= fip_client.max_wq_size) { /* calculated is >= to forced */ UT_ASSERT(eff_wq_size >= Rpmem_wq_size); } else { /* calculated is clipped to max supported */ UT_ASSERT(eff_wq_size == fip_client.max_wq_size); } } ret = rpmem_fip_connect(fip); UT_ASSERTeq(ret, 0); client_close_begin(client); ret = rpmem_fip_close(fip); UT_ASSERTeq(ret, 0); client_close_end(client); rpmem_fip_fini(fip); rpmem_target_free(info); return 4; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(client_init), TEST_CASE(server_init), TEST_CASE(client_connect), TEST_CASE(server_connect), TEST_CASE(client_flush), TEST_CASE(client_flush_mt), TEST_CASE(client_persist), TEST_CASE(client_persist_mt), TEST_CASE(server_process), TEST_CASE(client_read), TEST_CASE(client_wq_size) }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { /* workaround for left-opened files by libfabric */ rpmem_fip_probe_get("localhost", NULL); START(argc, argv, "rpmem_obc"); common_init("rpmem_fip", "RPMEM_LOG_LEVEL", "RPMEM_LOG_FILE", 0, 0); rpmem_util_cmds_init(); rpmemd_log_init("rpmemd", os_getenv("RPMEMD_LOG_FILE"), 0); rpmemd_log_level = rpmemd_log_level_from_str( os_getenv("RPMEMD_LOG_LEVEL")); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); common_fini(); rpmemd_log_close(); rpmem_util_cmds_fini(); DONE(NULL); } pmdk-1.11.1/src/test/rpmem_fip/TEST10000775000000000000000000000056414123364546015555 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/TEST1 -- tests for rpmem_fip and rpmemd_fip modules # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_connect ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/TEST20000775000000000000000000000056414123364546015556 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/TEST2 -- tests for rpmem_fip and rpmemd_fip modules # . ../unittest/unittest.sh require_test_type medium setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_fip$EXESUFFIX\ client_persist ${NODE_ADDR[0]} $RPMEM_PROVIDER $RPMEM_PM pass pmdk-1.11.1/src/test/rpmem_fip/setup.sh0000664000000000000000000000142214123364546016455 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_fip/setup.sh -- common setup for rpmem_fip tests # set -e require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER require_node_log_files 0 $RPMEM_LOG_FILE $RPMEMD_LOG_FILE require_node_log_files 1 $RPMEM_LOG_FILE $RPMEMD_LOG_FILE SRV=srv${UNITTEST_NUM}.pid clean_remote_node 0 $SRV RPMEM_CMD="\"cd ${NODE_TEST_DIR[0]} && RPMEMD_LOG_LEVEL=\$RPMEMD_LOG_LEVEL RPMEMD_LOG_FILE=\$RPMEMD_LOG_FILE UNITTEST_FORCE_QUIET=1 \ LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[0]}:$REMOTE_LD_LIBRARY_PATH \ ./rpmem_fip$EXESUFFIX\"" export_vars_node 1 RPMEM_CMD if [ -n ${RPMEM_MAX_NLANES+x} ]; then export_vars_node 1 RPMEM_MAX_NLANES fi pmdk-1.11.1/src/test/libpmempool_transform/0000775000000000000000000000000014123364546017416 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_transform/out1w.log.match0000664000000000000000000000207114123364546022273 0ustar rootrootpoolset_in PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 poolset_out PMEMPOOLSET 20M $(nW)part00 20M $(nW)part01 REPLICA 20M $(nW)part10 20M $(nW)part11 $(nW)TEST1w: START: libpmempool_transform$(nW) Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: type : regular file part 1: type : regular file Replica 1 - local, 2 part(s): part 0: type : regular file part 1: type : regular file POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Alignment Descriptor : 0x0000077737773310[OK] Class : 64 Data : 2's complement, little endian Machine : $(*) PMEM OBJ Header: Layout : OBJ_LAYOUT$(nW) Lanes offset : 0x2000 Number of lanes : 1024 Heap offset : $(nW) Heap size : $(nW) Root offset : 0x0 pmdk-1.11.1/src/test/libpmempool_transform/TEST1.PS10000664000000000000000000000456414123364546020614 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_transform/TEST1.PS1 -- test for checking pmempool transform; # pmem/issues#320 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x ` create_poolset $POOLSET_OUT ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x ` R ` 10M:$DIR\testfile5:x ` 20M:$DIR\testfile6:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 22M srcp 0 TestOK111 srcp 20M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN | out-file -append -encoding ascii -literalpath $LOG_TEMP # Transform poolset $FLAGS = "0" expect_normal_exit $Env:EXE_DIR\libpmempool_transform$Env:EXESUFFIX ` $POOLSET_IN $POOLSET_OUT $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check metadata by pmempool info for ($i=0; $i -lt 7; $i++) { dump_pool_info $DIR\testfile$i | out-file -append -encoding ascii -literalpath $LOG_TEMP } mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/TEST00000775000000000000000000000357114123364546020211 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_transform/TEST0 -- test for checking replica transform # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x \ R \ 10M:$DIR/testfile5:x \ 20M:$DIR/testfile6:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 22M srcp 0 TestOK111 srcp 20M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset FLAGS=0 expect_normal_exit ./libpmempool_transform$EXESUFFIX \ $POOLSET_IN $POOLSET_OUT $FLAGS cat $LOG >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info for i in `seq 0 4` do dump_pool_info $DIR/testfile$i >> $LOG_TEMP done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/Makefile0000664000000000000000000000043314123364546021056 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/libpmempool_transform/Makefile -- build libpmempool transform test # TARGET = libpmempool_transform OBJS = libpmempool_transform.o LIBPMEMPOOL=y USE_PMEMOBJCLI=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_transform/TEST2.PS10000664000000000000000000000255714123364546020615 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_transform/TEST2.PS1 -- test for checking pmempool transform; # check if flags are supported # pmem/issues#367 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 10M:$DIR\part00:x create_poolset $POOLSET_OUT ` 10M:$DIR\part00:x ` r ` 10M:$DIR\part10:x # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat -Encoding Ascii $LOG | Out-File -append -encoding ascii $LOG_TEMP # Try to transform poolset $FLAGS = "1" # invalid flag expect_normal_exit $Env:EXE_DIR\libpmempool_transform$Env:EXESUFFIX ` $POOLSET_IN $POOLSET_OUT $FLAGS cat -Encoding Ascii $LOG | Out-File -append -encoding ascii $LOG_TEMP $FLAGS = "1024" expect_normal_exit $Env:EXE_DIR\libpmempool_transform$Env:EXESUFFIX ` $POOLSET_IN $POOLSET_OUT $FLAGS cat -Encoding Ascii $LOG | Out-File -append -encoding ascii $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/out0.log.match0000664000000000000000000000364614123364546022114 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 libpmempool_transform$(nW)TEST0: START: libpmempool_transform$(nW) $(nW)libpmempool_transform$(nW) $(nW)poolset.in $(nW)poolset.out 0 result: 0 libpmempool_transform$(nW)TEST0: DONE TestOK111 TestOK222 Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/libpmempool_transform/libpmempool_transform.vcxproj0000664000000000000000000000740214123364546025450 0ustar rootroot Debug x64 Release x64 {FB2D2B18-E616-4639-8593-0E1AF2DA01A8} Win32Proj libpmempool_transform 10.0.17134.0 Application true v140 Application false v140 true false true {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_transform/libpmempool_transform.vcxproj.filters0000664000000000000000000000220714123364546027115 0ustar rootroot {79b0d319-a85d-43bf-94e5-87c457c1f05c} {2d5753a4-85ac-4efb-8104-e5578b478c46} {af1b7ef5-685c-4345-bf41-bc144fb30ef8} Match Files Match Files Test Scripts Test Scripts Test Scripts Source Files pmdk-1.11.1/src/test/libpmempool_transform/TEST0.PS10000664000000000000000000000447314123364546020612 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_transform/TEST0.PS1 -- test for checking replica transform # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:$SUFFIX}" $POOLSET_IN = "$DIR\poolset.in" $POOLSET_OUT = "$DIR\poolset.out" # Create poolset files create_poolset $POOLSET_IN ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x ` R ` 10M:$DIR\testfile5:x ` 20M:$DIR\testfile6:x create_poolset $POOLSET_OUT ` 20M:$DIR\testfile0:x ` 10M:$DIR\testfile1:x ` R ` 10M:$DIR\testfile2:x ` 10M:$DIR\testfile3:x ` 10M:$DIR\testfile4:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 22M srcp 0 TestOK111 srcp 20M TestOK222 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET_IN cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET_IN | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_IN | out-file -append -encoding ascii -literalpath $LOG_TEMP # Transform poolset $FLAGS = "0" expect_normal_exit $Env:EXE_DIR\libpmempool_transform$Env:EXESUFFIX ` $POOLSET_IN $POOLSET_OUT $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET_OUT | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check metadata by pmempool info for ($i=0; $i -lt 5; $i++) { dump_pool_info $DIR\testfile$i | out-file -append -encoding ascii -literalpath $LOG_TEMP } mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/.gitignore0000664000000000000000000000002614123364546021404 0ustar rootrootlibpmempool_transform pmdk-1.11.1/src/test/libpmempool_transform/README0000664000000000000000000000031014123364546020270 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_transform/README. This directory contains unit tests for libpmempool transform. The tests check if adding and deleting replicas works. pmdk-1.11.1/src/test/libpmempool_transform/TEST10000775000000000000000000000357114123364546020212 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_transform/TEST1 -- test for checking replica transform # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x create_poolset $POOLSET_OUT \ 20M:$DIR/testfile0:x \ 10M:$DIR/testfile1:x \ R \ 10M:$DIR/testfile2:x \ 10M:$DIR/testfile3:x \ 10M:$DIR/testfile4:x \ R \ 10M:$DIR/testfile5:x \ 20M:$DIR/testfile6:x # CLI script for writing some data hitting all the parts WRITE_SCRIPT=$DIR/write_data cat << EOF > $WRITE_SCRIPT pr 22M srcp 0 TestOK111 srcp 20M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=$DIR/read_data cat << EOF > $READ_SCRIPT srpr 0 9 srpr 20M 9 EOF # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Write some data into the pool, hitting two part files expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $WRITE_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_IN >> \ $LOG_TEMP # Transform poolset FLAGS=0 expect_normal_exit ./libpmempool_transform$EXESUFFIX \ $POOLSET_IN $POOLSET_OUT $FLAGS cat $LOG >> $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $READ_SCRIPT $POOLSET_OUT >> \ $LOG_TEMP # Check metadata by pmempool info for i in `seq 0 6` do dump_pool_info $DIR/testfile$i >> $LOG_TEMP done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/libpmempool_transform.c0000664000000000000000000000115714123364546024200 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * libpmempool_transform -- a unittest for libpmempool transform. * */ #include #include #include #include #include "unittest.h" int main(int argc, char *argv[]) { START(argc, argv, "libpmempool_transform"); if (argc != 4) UT_FATAL("usage: %s poolset_in poolset_out flags", argv[0]); int ret = pmempool_transform(argv[1], argv[2], (unsigned)strtoul(argv[3], NULL, 0)); if (ret) UT_OUT("result: %d, errno: %d", ret, errno); else UT_OUT("result: %d", ret); DONE(NULL); } pmdk-1.11.1/src/test/libpmempool_transform/out1.log.match0000664000000000000000000000511614123364546022107 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 libpmempool_transform$(nW)TEST1: START: libpmempool_transform$(nW) $(nW)libpmempool_transform$(nW) $(nW)poolset.in $(nW)poolset.out 0 result: 0 libpmempool_transform$(nW)TEST1: DONE TestOK111 TestOK222 Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) pmdk-1.11.1/src/test/libpmempool_transform/TEST20000775000000000000000000000220014123364546020177 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_transform/TEST2 -- test for checking replica transform # check if flags are supported # pmem/issues#367 # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP LAYOUT=OBJ_LAYOUT$SUFFIX POOLSET_IN=$DIR/poolset.in POOLSET_OUT=$DIR/poolset.out # Create poolset files create_poolset $POOLSET_IN \ 10M:$DIR/part00:x create_poolset $POOLSET_OUT \ 10M:$DIR/part00:x \ r \ 10M:$DIR/part10:x # Create a pool expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout=$LAYOUT\ obj $POOLSET_IN cat $LOG >> $LOG_TEMP # Try to transform poolset FLAG=1 # invalid flag expect_normal_exit ./libpmempool_transform$EXESUFFIX \ $POOLSET_IN $POOLSET_OUT $FLAG cat $LOG >> $LOG_TEMP FLAG=1024 expect_normal_exit ./libpmempool_transform$EXESUFFIX \ $POOLSET_IN $POOLSET_OUT $FLAG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_transform/out2.log.match0000664000000000000000000000061114123364546022103 0ustar rootrootlibpmempool_transform$(nW)TEST2: START: libpmempool_transform$(nW) $(nW)libpmempool_transform$(nW) $(nW)poolset.in $(nW)poolset.out 1 result: -1, errno: 22 libpmempool_transform$(nW)TEST2: DONE libpmempool_transform$(nW)TEST2: START: libpmempool_transform$(nW) $(nW)libpmempool_transform$(nW) $(nW)poolset.in $(nW)poolset.out 1024 result: -1, errno: 22 libpmempool_transform$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_badblock/0000775000000000000000000000000014123364546015377 5ustar rootrootpmdk-1.11.1/src/test/obj_badblock/TEST00000775000000000000000000000176514123364546016175 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # obj_badblock/TEST0 -- test for inserting bad blocks into an obj pool # . ../unittest/unittest.sh require_test_type medium require_badblock_tests_enabled block_device setup . ../common_badblock.sh MOUNT_DIR="$DIR/mnt-pmem" badblock_test_init block_device $MOUNT_DIR POOLSET=$MOUNT_DIR/testset1 RESVSIZE=$((4 * 1024 * 1024 * 1024)) # 4GiB create_poolset $POOLSET\ $RESVSIZE:$MOUNT_DIR/testdir11:d\ O SINGLEHDR # create pool and allocate some amount of data expect_normal_exit ./obj_badblock$EXESUFFIX $POOLSET c # inject bad block into one of files created in pool directory during # allocation FIRST_SECTOR=$(expect_normal_exit $EXTENTS $MOUNT_DIR/testdir11/000010.pmem -l 0) ndctl_inject_error $NAMESPACE $FIRST_SECTOR 8 expect_bad_blocks $NAMESPACE expect_abnormal_exit ./obj_badblock$EXESUFFIX $POOLSET o ndctl_uninject_error $FULLDEV $NAMESPACE $FIRST_SECTOR 8 badblock_test_fini $MOUNT_DIR pass pmdk-1.11.1/src/test/obj_badblock/Makefile0000664000000000000000000000034014123364546017034 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_badblock/Makefile -- build obj_badblock test # TARGET = obj_badblock OBJS = obj_badblock.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_badblock/.gitignore0000664000000000000000000000001514123364546017363 0ustar rootrootobj_badblock pmdk-1.11.1/src/test/obj_badblock/obj_badblock.c0000664000000000000000000000261014123364546020135 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * obj_badblock.c -- Badblock tests on obj pool * */ #include #include "unittest.h" #include "libpmemobj.h" #define LAYOUT_NAME "obj_badblock" #define TEST_EXTEND_COUNT 32 #define EXTEND_SIZE (1024 * 1024 * 10) static void do_create_and_extend(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); ssize_t extend_size = EXTEND_SIZE; for (int i = 0; i < TEST_EXTEND_COUNT; ++i) { int ret = pmemobj_ctl_exec(pop, "heap.size.extend", &extend_size); UT_ASSERTeq(ret, 0); } pmemobj_close(pop); UT_ASSERT(pmemobj_check(path, LAYOUT_NAME) == 1); } static void do_open(const char *path) { PMEMobjpool *pop = pmemobj_open(path, LAYOUT_NAME); UT_ASSERT(pop != NULL); pmemobj_close(pop); } int main(int argc, char **argv) { START(argc, argv, "obj_badblock"); if (argc < 3) UT_FATAL("usage: %s file-name, o|c", argv[0]); const char *path = argv[1]; for (int arg = 2; arg < argc; arg++) { if (argv[arg][1] != '\0') UT_FATAL( "op must be c or o (c=create, o=open)"); switch (argv[arg][0]) { case 'c': do_create_and_extend(path); break; case 'o': do_open(path); default: UT_FATAL( "op must be c or o (c=clear, o=open)"); break; } } DONE(NULL); } pmdk-1.11.1/src/test/rpmemd_config/0000775000000000000000000000000014123364546015615 5ustar rootrootpmdk-1.11.1/src/test/rpmemd_config/rpmemd_config_test.c0000664000000000000000000000407714123364546021641 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * rpmemd_log_test.c -- unit tests for rpmemd_log */ #include #include #include #include #include #include "unittest.h" #include "rpmemd_log.h" #include "rpmemd_config.h" static const char *config_print_fmt = "log_file\t\t%s\n" "poolset_dir:\t\t%s\n" "persist_apm:\t\t%s\n" "persist_general:\t%s\n" "use_syslog:\t\t%s\n" "max_lanes:\t\t%" PRIu64 "\n" "log_level:\t\t%s"; /* * bool_to_str -- convert bool value to a string ("yes" / "no") */ static inline const char * bool_to_str(bool v) { return v ? "yes" : "no"; } /* * config_print -- print rpmemd_config to the stdout */ static void config_print(struct rpmemd_config *config) { UT_ASSERT(config->log_level < MAX_RPD_LOG); UT_OUT( config_print_fmt, config->log_file, config->poolset_dir, bool_to_str(config->persist_apm), bool_to_str(config->persist_general), bool_to_str(config->use_syslog), config->max_lanes, rpmemd_log_level_to_str(config->log_level)); } /* * parse_test_params -- parse command line options specific to the test * * usage: rpmemd_config [rpmemd options] [test options] * * Available test options: * - print_HOME_env prints current HOME_ENV value */ static void parse_test_params(int *argc, char *argv[]) { if (*argc <= 1) return; if (strcmp(argv[*argc - 1], "print_HOME_env") == 0) { char *home = os_getenv(HOME_ENV); if (home) { UT_OUT("$%s == %s", HOME_ENV, home); } else { UT_OUT("$%s is not set", HOME_ENV); } } else { return; } *argc -= 1; } int main(int argc, char *argv[]) { /* workaround for getpwuid open fd */ getpwuid(getuid()); START(argc, argv, "rpmemd_config"); int ret = rpmemd_log_init("rpmemd_log", NULL, 0); UT_ASSERTeq(ret, 0); parse_test_params(&argc, argv); struct rpmemd_config config; ret = rpmemd_config_read(&config, argc, argv); if (ret) { UT_OUT("invalid config"); } else { config_print(&config); } rpmemd_log_close(); if (!ret) rpmemd_config_free(&config); DONE(NULL); } pmdk-1.11.1/src/test/rpmemd_config/in3.conf0000664000000000000000000000045314123364546017157 0ustar rootrootlog-file=/nondefault/log/file/path # nondefault log-file path poolset-dir=/nondefault/dir/path # nondefault dir path persist-apm=no # nondefault persist-apm value persist-general=no # nondefault persist-general value use-syslog=no # nondefault use-syslog value log-level=warn # nondefault log-level pmdk-1.11.1/src/test/rpmemd_config/TEST30000775000000000000000000000136514123364546016412 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # rpmemd_config/TEST3 -- test for rpmemd config overwrite # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup RPMEMD=./rpmemd_config$EXESUFFIX LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_temp.log rm -f $LOG $LOG_TEMP CONFIG=in${UNITTEST_NUM}.conf CL_LOG_LEVEL=notice expect_normal_exit $RPMEMD -c $CONFIG cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $CONFIG\ --log-file=/cl/log/file/path\ --poolset-dir=/cl/dir/path\ --persist-apm\ --persist-general\ --use-syslog\ --log-level=$CL_LOG_LEVEL cat $LOG >> $LOG_TEMP $GREP -v rpmemd_config $LOG_TEMP > $LOG check pass pmdk-1.11.1/src/test/rpmemd_config/TEST00000775000000000000000000000254214123364546016405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # rpmemd_config/TEST0 -- test for rpmemd default config and cl arguments # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup RPMEMD=./rpmemd_config$EXESUFFIX OUT=stdout${UNITTEST_NUM}.log LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_temp.log rm -f $OUT $LOG $LOG_TEMP EMPTY_CONFIG=in${UNITTEST_NUM}.conf INVALID_CONFIG=$DIR/invalid.conf # use empty config to prevent loading config file from default location # which may have nondefault configuration expect_normal_exit $RPMEMD -c $EMPTY_CONFIG 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -V 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD --version 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -h 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD --help 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $EMPTY_CONFIG 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD --config $EMPTY_CONFIG 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $INVALID_CONFIG 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD --config $INVALID_CONFIG 1>> $OUT 2>&1 cat $LOG >> $LOG_TEMP $GREP -v rpmemd_config $LOG_TEMP > $LOG check pass pmdk-1.11.1/src/test/rpmemd_config/stdout2.log.match0000664000000000000000000000204614123364546021021 0ustar rootrootInvalid config file line at $(*):1 ; invalid comment format Invalid config file line at $(*):1 ; invalid comment format Invalid config file line at $(*):1 dir= # invalid dir path Invalid config file line at $(*):1 dir= # invalid dir path Invalid config file line at $(*):1 log-file= # invalid log-file path Invalid config file line at $(*):1 log-file= # invalid log-file path Invalid config file line at $(*):1 log-level=Invalid # invalid log-level Invalid config file line at $(*):1 log-level=Invalid # invalid log-level Invalid config file line at $(*):1 persist-apm=invalid # invalid persist-apm value Invalid config file line at $(*):1 persist-apm=invalid # invalid persist-apm value Invalid config file line at $(*):1 persist-general=invalid # invalid persist-general value Invalid config file line at $(*):1 persist-general=invalid # invalid persist-general value Invalid config file line at $(*):1 use-syslog=invalid # invalid use-syslog value Invalid config file line at $(*):1 use-syslog=invalid # invalid use-syslog value pmdk-1.11.1/src/test/rpmemd_config/Makefile0000664000000000000000000000066114123364546017260 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/rpmemd_log/Makefile -- build rpmemd_log test # TOP = ../../.. vpath %.c $(TOP)/src/tools/rpmemd TARGET = rpmemd_config OBJS = rpmemd_config_test.o rpmemd_config.o rpmemd_log.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -I../../tools/rpmemd CFLAGS += -DSRCVERSION='"$(SRCVERSION)"' pmdk-1.11.1/src/test/rpmemd_config/stdout0.log.match0000664000000000000000000000572614123364546021027 0ustar rootroot$(OPT)rpmemd_config/TEST0: START: rpmemd_config $(OPT)rpmemd_config/TEST0: START: rpmemd_config rpmemd version $(*) $(OPT)rpmemd_config/TEST0: START: rpmemd_config rpmemd version $(*) $(OPT)rpmemd_config/TEST0: START: rpmemd_config usage: $(*) [--version] [--help] [] rpmemd version $(*) Options: -c, --config configuration file location -r, --remove remove pool described by given poolset file -f, --force ignore errors when removing a pool -t, --nthreads number of processing threads -h, --help display help message and exit -V, --version display target daemon version and exit --log-file log file location --poolset-dir pool set files directory --persist-apm enable Appliance Persistency Method --persist-general enable General Server Persistency Mechanism --use-syslog use syslog(3) for logging messages --log-level set log level value err error conditions warn warning conditions notice normal, but significant, condition info informational message debug debug-level message For complete documentation see rpmemd(1) manual page. $(OPT)rpmemd_config/TEST0: START: rpmemd_config usage: $(*) [--version] [--help] [] rpmemd version $(*) Options: -c, --config configuration file location -r, --remove remove pool described by given poolset file -f, --force ignore errors when removing a pool -t, --nthreads number of processing threads -h, --help display help message and exit -V, --version display target daemon version and exit --log-file log file location --poolset-dir pool set files directory --persist-apm enable Appliance Persistency Method --persist-general enable General Server Persistency Mechanism --use-syslog use syslog(3) for logging messages --log-level set log level value err error conditions warn warning conditions notice normal, but significant, condition info informational message debug debug-level message For complete documentation see rpmemd(1) manual page. $(OPT)rpmemd_config/TEST0: START: rpmemd_config $(OPT)rpmemd_config/TEST0: START: rpmemd_config $(OPT)rpmemd_config/TEST0: START: rpmemd_config $(*): No such file or directory $(OPT)rpmemd_config/TEST0: START: rpmemd_config $(*): No such file or directory pmdk-1.11.1/src/test/rpmemd_config/in0.conf0000664000000000000000000000000014123364546017140 0ustar rootrootpmdk-1.11.1/src/test/rpmemd_config/TEST40000775000000000000000000000243714123364546016414 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # rpmemd_config/TEST4 -- test for rpmemd config usage of user home dir # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup RPMEMD=./rpmemd_config$EXESUFFIX LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_temp.log rm -f $LOG $LOG_TEMP # use empty config to prevent loading config file from default location # which may have nondefault configuration EMPTY_CONFIG=$DIR/empty.conf touch $EMPTY_CONFIG function check_user_home_dir { expect_normal_exit $RPMEMD -c $EMPTY_CONFIG print_HOME_env cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $EMPTY_CONFIG --poolset-dir='\$HOME' print_HOME_env cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $EMPTY_CONFIG --poolset-dir=prefix'\$HOME' print_HOME_env cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $EMPTY_CONFIG --poolset-dir='\$HOME'stickysuffix print_HOME_env cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD -c $EMPTY_CONFIG --poolset-dir='\$HOME'/suffix print_HOME_env cat $LOG >> $LOG_TEMP } HOME_BACKUP=$HOME unset HOME check_user_home_dir export HOME=/user/home/path check_user_home_dir HOME=$HOME_BACKUP $GREP -v rpmemd_config $LOG_TEMP > $LOG check pass pmdk-1.11.1/src/test/rpmemd_config/out0.log.match0000664000000000000000000000067414123364546020311 0ustar rootrootlog_file /var/log/rpmemd.log poolset_dir: $(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err log_file /var/log/rpmemd.log poolset_dir: $(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err log_file /var/log/rpmemd.log poolset_dir: $(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err invalid config invalid config pmdk-1.11.1/src/test/rpmemd_config/in1.conf0000664000000000000000000000133514123364546017155 0ustar rootroot# single line comment # single line comment with useless white space log-file = / # line with useless white space and a comment log-file=/log/file/path # valid log-file path poolset-dir=/dir/path # valid dir path persist-apm=yes # valid persist-apm value persist-apm=no # valid persist-apm value persist-general=yes # valid persist-general value persist-general=no # valid persist-general value use-syslog=yes # valid use-syslog value use-syslog=no # valid use-syslog value log-level=err # valid log-level log-level=warn # valid log-level log-level=notice # valid log-level log-level=info # valid log-level log-level=debug # valid log-level # log-level=invalid_value # commented out invalid line pmdk-1.11.1/src/test/rpmemd_config/.gitignore0000664000000000000000000000001614123364546017602 0ustar rootrootrpmemd_config pmdk-1.11.1/src/test/rpmemd_config/README0000664000000000000000000000024014123364546016471 0ustar rootrootPersistent Memory Development Kit This is src/test/rpmemd_config/README. This directory contains a unit test for rpmemd command line and config file parsing. pmdk-1.11.1/src/test/rpmemd_config/TEST10000775000000000000000000000113414123364546016402 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # rpmemd_config/TEST1 -- test for rpmemd valid config file # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup RPMEMD=./rpmemd_config$EXESUFFIX LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_temp.log rm -f $LOG $LOG_TEMP CONFIG=in${UNITTEST_NUM}.conf expect_normal_exit $RPMEMD -c $CONFIG cat $LOG >> $LOG_TEMP expect_normal_exit $RPMEMD --config $CONFIG cat $LOG >> $LOG_TEMP $GREP -v rpmemd_config $LOG_TEMP > $LOG check pass pmdk-1.11.1/src/test/rpmemd_config/out1.log.match0000664000000000000000000000042214123364546020301 0ustar rootrootlog_file /log/file/path poolset_dir: /dir/path persist_apm: no persist_general: no use_syslog: no max_lanes: 1024 log_level: debug log_file /log/file/path poolset_dir: /dir/path persist_apm: no persist_general: no use_syslog: no max_lanes: 1024 log_level: debug pmdk-1.11.1/src/test/rpmemd_config/TEST20000775000000000000000000000217714123364546016413 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # rpmemd_config/TEST2 -- test for rpmemd invalid config file # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type any setup RPMEMD=./rpmemd_config$EXESUFFIX OUT=stdout${UNITTEST_NUM}.log OUT_TEMP=stdout${UNITTEST_NUM}_temp.log rm -f $OUT $OUT_TEMP CONFIG=$DIR/in${UNITTEST_NUM}.conf INVALID_PATH=" \t\t \t\t" INVALID_FLAG=invalid INVALID_ENUM=Invalid function check_config { echo -e "$1" > $CONFIG expect_normal_exit $RPMEMD -c $CONFIG 1>> $OUT_TEMP 2>&1 expect_normal_exit $RPMEMD --config $CONFIG 1>> $OUT_TEMP 2>&1 } check_config "; invalid comment format" check_config "dir=$INVALID_PATH# invalid dir path" check_config "log-file=$INVALID_PATH # invalid log-file path" check_config "log-level=$INVALID_ENUM # invalid log-level" check_config "persist-apm=$INVALID_FLAG # invalid persist-apm value" check_config "persist-general=$INVALID_FLAG # invalid persist-general value" check_config "use-syslog=$INVALID_FLAG # invalid use-syslog value" $GREP -v START $OUT_TEMP > $OUT check pass pmdk-1.11.1/src/test/rpmemd_config/out3.log.match0000664000000000000000000000046114123364546020306 0ustar rootrootlog_file /nondefault/log/file/path poolset_dir: /nondefault/dir/path persist_apm: no persist_general: no use_syslog: no max_lanes: 1024 log_level: warn log_file /cl/log/file/path poolset_dir: /cl/dir/path persist_apm: yes persist_general: yes use_syslog: yes max_lanes: 1024 log_level: notice pmdk-1.11.1/src/test/rpmemd_config/out4.log.match0000664000000000000000000000322014123364546020303 0ustar rootroot$HOME is not set log_file /var/log/rpmemd.log poolset_dir: $(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME is not set log_file /var/log/rpmemd.log poolset_dir: $(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME is not set log_file /var/log/rpmemd.log poolset_dir: prefix$(nW) persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME is not set log_file /var/log/rpmemd.log poolset_dir: $HOMEstickysuffix persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME is not set log_file /var/log/rpmemd.log poolset_dir: $(nW)/suffix persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME == /user/home/path log_file /var/log/rpmemd.log poolset_dir: /user/home/path persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME == /user/home/path log_file /var/log/rpmemd.log poolset_dir: /user/home/path persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME == /user/home/path log_file /var/log/rpmemd.log poolset_dir: prefix/user/home/path persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME == /user/home/path log_file /var/log/rpmemd.log poolset_dir: $HOMEstickysuffix persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err $HOME == /user/home/path log_file /var/log/rpmemd.log poolset_dir: /user/home/path/suffix persist_apm: no persist_general: yes use_syslog: yes max_lanes: 1024 log_level: err pmdk-1.11.1/src/test/pmemset_new/0000775000000000000000000000000014123364546015327 5ustar rootrootpmdk-1.11.1/src/test/pmemset_new/pmemset_new.c0000775000000000000000000000665514123364546020035 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmemset_config.c -- pmemset_config unittests */ #include "fault_injection.h" #include "libpmemset.h" #include "unittest.h" #include "ut_pmemset_utils.h" #include "out.h" #include "config.h" #include "ravl_interval.h" /* * test_new_create_and_delete_valid - test pmemset_new allocation */ static int test_new_create_and_delete_valid(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_config *cfg; struct pmemset *set; pmemset_config_new(&cfg); int ret = pmemset_config_set_required_store_granularity(cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(set, NULL); ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(set, NULL); pmemset_config_delete(&cfg); return 0; } /* * test_alloc_new_enomem - test pmemset_new allocation with error injection in * set allocation */ static int test_alloc_new_enomem(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_config *cfg; struct pmemset *set; pmemset_config_new(&cfg); int ret = pmemset_config_set_required_store_granularity(cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); if (!core_fault_injection_enabled()) return 0; core_inject_fault_at(PMEM_MALLOC, 1, "pmemset_malloc"); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(set, NULL); pmemset_config_delete(&cfg); return 0; } /* * test_alloc_new_tree_enomem - test pmemset_new allocation with error * injection in tree allocation */ static int test_alloc_new_tree_enomem(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_config *cfg; struct pmemset *set; pmemset_config_new(&cfg); int ret = pmemset_config_set_required_store_granularity(cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); if (!core_fault_injection_enabled()) return 0; core_inject_fault_at(PMEM_MALLOC, 1, "ravl_interval_new"); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(set, NULL); pmemset_config_delete(&cfg); return 0; } /* * test_delete_null_set - test pmemset_delete on NULL set */ static int test_delete_null_set(const struct test_case *tc, int argc, char *argv[]) { struct pmemset *set = NULL; /* should not crash */ int ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(set, NULL); return 0; } /* * test_granularity_not_set - test pmemset_new without granularity */ static int test_granularity_not_set(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_config *cfg; struct pmemset *set; pmemset_config_new(&cfg); int ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_GRANULARITY_NOT_SET); pmemset_config_delete(&cfg); return 0; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_new_create_and_delete_valid), TEST_CASE(test_alloc_new_enomem), TEST_CASE(test_alloc_new_tree_enomem), TEST_CASE(test_delete_null_set), TEST_CASE(test_granularity_not_set), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmemset_new"); util_init(); out_init("pmemset_new", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } pmdk-1.11.1/src/test/pmemset_new/pmemset_new.vcxproj.filters0000775000000000000000000000514214123364546022743 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {de4f559b-32c6-4ca5-8595-5783009a8756} Test Scripts Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files pmdk-1.11.1/src/test/pmemset_new/Makefile0000775000000000000000000000047114123364546016774 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmemset_new/Makefile -- build pmemset_new unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmemset_new OBJS += pmemset_new.o\ ut_pmemset_utils.o LIBPMEMSET=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmemset_new/TESTS.py0000775000000000000000000000175714123364546016620 0ustar rootroot#!../envy # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) @g.no_testdir() class PmemSetNewNoDir(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmemset_new', self.test_case) class TEST0(PmemSetNewNoDir): """allocation and dealocation of pmemset_new""" test_case = "test_new_create_and_delete_valid" class TEST1(PmemSetNewNoDir): """allocation of pmemset in case of no memory in system when set created""" test_case = "test_alloc_new_enomem" class TEST2(PmemSetNewNoDir): """allocation of pmemset in case of no memory in system for ravl tree""" test_case = "test_alloc_new_tree_enomem" class TEST3(PmemSetNewNoDir): """deleting null pmemset""" test_case = "test_delete_null_set" class TEST4(PmemSetNewNoDir): """pmemset_new with invalid granularity value""" test_case = "test_granularity_not_set" pmdk-1.11.1/src/test/pmemset_new/.gitignore0000664000000000000000000000001414123364546017312 0ustar rootrootpmemset_new pmdk-1.11.1/src/test/pmemset_new/pmemset_new.vcxproj0000775000000000000000000001247314123364546021301 0ustar rootroot Debug x64 Release x64 {22C92B10-D40B-4B71-8C22-472DDD5AD4E6} pmemset_new 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;$(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {f596c36c-5c96-4f08-b420-8908af500954} {fbaefc34-d221-4203-8bf6-162de1a5be1c} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_ulog_size/0000775000000000000000000000000014123364546015636 5ustar rootrootpmdk-1.11.1/src/test/obj_ulog_size/obj_ulog_size.c0000664000000000000000000006321514123364546020643 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * obj_ulog_size.c -- unit tests for pmemobj_action API and * redo, undo logs */ #include #include #include #include "unittest.h" #include "util.h" /* * tx.h -- needed for TX_SNAPSHOT_LOG_ENTRY_ALIGNMENT, * TX_SNAPSHOT_LOG_BUFFER_OVERHEAD, TX_SNAPSHOT_LOG_ENTRY_OVERHEAD, * TX_INTENT_LOG_BUFFER_ALIGNMENT, TX_INTENT_LOG_BUFFER_OVERHEAD, * TX_INTENT_LOG_ENTRY_OVERHEAD */ #include "tx.h" /* needed for LANE_REDO_EXTERNAL_SIZE and LANE_UNDO_SIZE */ #include "lane.h" #define LAYOUT_NAME "obj_ulog_size" #define MIN_ALLOC 64 #define MAX_ALLOC (1024 * 1024) #define HALF_OF_DEFAULT_UNDO_SIZE (LANE_UNDO_SIZE / 2) #define ARRAY_SIZE_COMMON 3 /* the ranges of indices are describing the use of some allocations */ #define LOG_BUFFER 0 #define LOG_BUFFER_NUM 6 #define RANGE (LOG_BUFFER + LOG_BUFFER_NUM) #define RANGE_NUM 6 #define MIN_NOIDS (RANGE + RANGE_NUM) /* * REDO_OVERFLOW -- size for trigger out of memory * during redo log extension */ #define REDO_OVERFLOW ((size_t)((LANE_REDO_EXTERNAL_SIZE\ / TX_INTENT_LOG_ENTRY_OVERHEAD) + 1)) #define APPEND_SIZE SIZEOF_ALIGNED_ULOG(CACHELINE_SIZE) /* * free_pool -- frees the pool from all allocated objects * and releases oids dynamic array */ static void free_pool(PMEMoid *oids, size_t noids) { for (size_t i = 0; i < noids; i++) { pmemobj_free(&oids[i]); UT_ASSERT(OID_IS_NULL(oids[i])); } FREE(oids); } /* * fill_pool -- fills provided pmemobj pool with as many allocations * as possible. Returns array of PMEMoids allocated from the * provided pool. The number of valid allocation stored in the * returned array is stored in the noids output argument. */ static PMEMoid * fill_pool(PMEMobjpool *pop, size_t *noids) { size_t oids_size = 2048; /* let's start with something big enough */ PMEMoid *oids = (PMEMoid *)MALLOC(oids_size * sizeof(PMEMoid)); *noids = 0; int ret; /* alloc as much space as possible */ for (size_t size = MAX_ALLOC; size >= MIN_ALLOC; size /= 2) { ret = 0; while (ret == 0) { ret = pmemobj_alloc(pop, &oids[*noids], size, 0, NULL, NULL); if (!ret) (*noids)++; if (*noids == oids_size) { oids_size *= 2; oids = (PMEMoid *)REALLOC(oids, oids_size * sizeof(PMEMoid)); } } } return oids; } /* * do_tx_max_alloc_tx_publish_abort -- fills the pool and then tries * to overfill redo log - transaction abort expected */ static void do_tx_max_alloc_tx_publish_abort(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_tx_publish_abort"); PMEMoid *allocated = NULL; PMEMoid reservations[REDO_OVERFLOW]; size_t nallocated = 0; struct pobj_action act[REDO_OVERFLOW]; for (int i = 0; i < REDO_OVERFLOW; i++) { reservations[i] = pmemobj_reserve(pop, &act[i], MIN_ALLOC, 0); UT_ASSERT(!OID_IS_NULL(reservations[i])); } allocated = fill_pool(pop, &nallocated); /* * number of allocated buffers is not important * they are not used anyway */ /* it should abort - cannot extend redo log */ TX_BEGIN(pop) { pmemobj_tx_publish(act, REDO_OVERFLOW); } TX_ONABORT { UT_OUT("!Cannot extend redo log - the pool is full"); } TX_ONCOMMIT { UT_FATAL("Can extend redo log despite the pool is full"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_xpublish(act, REDO_OVERFLOW, POBJ_XPUBLISH_NO_ABORT); } TX_ONABORT { ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, ENOMEM); UT_OUT("!Cannot extend redo log - the pool is full"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_publish(act, REDO_OVERFLOW); } TX_ONABORT { ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, ENOMEM); UT_OUT("!Cannot extend redo log - the pool is full"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_xpublish(act, REDO_OVERFLOW, 0); } TX_ONABORT { ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, ENOMEM); UT_OUT("!Cannot extend redo log - the pool is full"); } TX_END free_pool(allocated, nallocated); pmemobj_cancel(pop, act, REDO_OVERFLOW); } /* * do_tx_max_alloc_no_user_alloc_snap -- fills the pool and tries to do * snapshot which is bigger than ulog size */ static void do_tx_max_alloc_no_user_alloc_snap(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_no_user_alloc_snap"); size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated >= MIN_NOIDS); size_t range_size = pmemobj_alloc_usable_size(allocated[LOG_BUFFER]); UT_ASSERT(range_size > LANE_UNDO_SIZE); void *range_addr = pmemobj_direct(allocated[LOG_BUFFER]); pmemobj_memset(pop, range_addr, 0, range_size, 0); TX_BEGIN(pop) { /* it should abort - cannot extend undo log */ pmemobj_tx_add_range(allocated[LOG_BUFFER], 0, range_size); } TX_ONABORT { UT_OUT("!Cannot extend undo log - the pool is full"); } TX_ONCOMMIT { UT_FATAL("Can extend undo log despite the pool is full"); } TX_END free_pool(allocated, nallocated); } /* * do_tx_max_alloc_user_alloc_snap -- fills the pool, appends allocated * buffer and tries to do snapshot which is bigger than ulog size */ static void do_tx_max_alloc_user_alloc_snap(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_user_alloc_snap"); size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated >= MIN_NOIDS); size_t buff_size = pmemobj_alloc_usable_size(allocated[LOG_BUFFER]); void *buff_addr = pmemobj_direct(allocated[LOG_BUFFER]); size_t range_size = pmemobj_alloc_usable_size(allocated[RANGE]); UT_ASSERT(range_size > LANE_UNDO_SIZE); void *range_addr = pmemobj_direct(allocated[RANGE]); pmemobj_memset(pop, range_addr, 0, range_size, 0); TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addr, buff_size); pmemobj_tx_add_range(allocated[RANGE], 0, range_size); } TX_ONABORT { UT_FATAL("!Cannot use the user appended undo log buffer"); } TX_ONCOMMIT { UT_OUT("Can use the user appended undo log buffer"); } TX_END free_pool(allocated, nallocated); } /* * do_tx_max_alloc_user_alloc_nested -- example of buffer appending * allocated by the user in a nested transaction */ static void do_tx_max_alloc_user_alloc_nested(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_user_alloc_nested"); size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated >= MIN_NOIDS); size_t buff_size = pmemobj_alloc_usable_size(allocated[LOG_BUFFER]); void *buff_addr = pmemobj_direct(allocated[LOG_BUFFER]); size_t range_size = pmemobj_alloc_usable_size(allocated[RANGE]); void *range_addr = pmemobj_direct(allocated[RANGE]); pmemobj_memset(pop, range_addr, 0, range_size, 0); TX_BEGIN(pop) { TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addr, buff_size); pmemobj_tx_add_range(allocated[RANGE], 0, range_size); } TX_ONABORT { UT_FATAL( "Cannot use the undo log appended by the user in a nested transaction"); } TX_ONCOMMIT { UT_OUT( "Can use the undo log appended by the user in a nested transaction"); } TX_END } TX_END free_pool(allocated, nallocated); } /* * do_tx_max_alloc_user_alloc_snap_multi -- appending of many buffers * in one transaction */ static void do_tx_max_alloc_user_alloc_snap_multi(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_user_alloc_snap_multi"); size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated >= MIN_NOIDS); size_t buff_sizes[ARRAY_SIZE_COMMON]; void *buff_addrs[ARRAY_SIZE_COMMON]; size_t range_sizes[ARRAY_SIZE_COMMON]; void *range_addrs[ARRAY_SIZE_COMMON]; /* * The maximum value of offset used in the for-loop below is * i_max == (ARRAY_SIZE_COMMON - 1) * 2. * It will cause using LOG_BUFFER + i_max and RANGE + i_max indices so * i_max has to be less than LOG_BUFFER_NUM and * i_max has to be less than RANGE_NUM. */ UT_COMPILE_ERROR_ON((ARRAY_SIZE_COMMON - 1) * 2 >= LOG_BUFFER_NUM); UT_COMPILE_ERROR_ON((ARRAY_SIZE_COMMON - 1) * 2 >= RANGE_NUM); for (unsigned long i = 0; i < ARRAY_SIZE_COMMON; i++) { /* we multiply the value to not use continuous memory blocks */ buff_sizes[i] = pmemobj_alloc_usable_size( allocated[LOG_BUFFER + (i *2)]); buff_addrs[i] = pmemobj_direct( allocated[LOG_BUFFER + (i * 2)]); range_sizes[i] = pmemobj_alloc_usable_size( allocated[RANGE + (i * 2)]); range_addrs[i] = pmemobj_direct(allocated[RANGE + (i * 2)]); pmemobj_memset(pop, range_addrs[i], 0, range_sizes[i], 0); } errno = 0; TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addrs[0], buff_sizes[0]); pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addrs[1], buff_sizes[1]); pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addrs[2], buff_sizes[1]); for (unsigned long i = 0; i < ARRAY_SIZE_COMMON; i++) { pmemobj_tx_add_range(allocated[RANGE + (i * 2)], 0, range_sizes[i]); } } TX_ONABORT { UT_FATAL("!Cannot use multiple user appended undo log buffers"); } TX_ONCOMMIT { UT_OUT("Can use multiple user appended undo log buffers"); } TX_END /* check if all user allocated buffers are used */ errno = 0; TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addrs[0], buff_sizes[0]); pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addrs[1], buff_sizes[1]); /* * do not append last buffer to make sure it is needed for this * transaction to succeed */ pmemobj_tx_add_range(allocated[RANGE + 0], 0, range_sizes[0]); pmemobj_tx_add_range(allocated[RANGE + 2], 0, range_sizes[1]); pmemobj_tx_add_range(allocated[RANGE + 4], 0, range_sizes[2]); } TX_ONABORT { UT_OUT("!All user appended undo log buffers are used"); } TX_ONCOMMIT { UT_FATAL( "Not all user appended undo log buffers are required - too small ranges"); } TX_END free_pool(allocated, nallocated); } /* * do_tx_auto_alloc_disabled -- blocking of automatic expansion * of ulog. When auto expansion of ulog is off, snapshot with size * of default undo log is going to fail, because of buffer overhead * (size of internal undo log and header size). */ static void do_tx_auto_alloc_disabled(PMEMobjpool *pop) { UT_OUT("do_tx_auto_alloc_disabled"); PMEMoid oid0, oid1; int ret = pmemobj_zalloc(pop, &oid0, HALF_OF_DEFAULT_UNDO_SIZE, 0); UT_ASSERTeq(ret, 0); ret = pmemobj_zalloc(pop, &oid1, HALF_OF_DEFAULT_UNDO_SIZE, 0); UT_ASSERTeq(ret, 0); TX_BEGIN(pop) { pmemobj_tx_log_auto_alloc(TX_LOG_TYPE_SNAPSHOT, 0); pmemobj_tx_add_range(oid0, 0, HALF_OF_DEFAULT_UNDO_SIZE); /* it should abort - cannot extend ulog (first entry is full) */ pmemobj_tx_add_range(oid1, 0, HALF_OF_DEFAULT_UNDO_SIZE); } TX_ONABORT { UT_OUT("!Disabled auto alloc prevented the undo log grow"); } TX_ONCOMMIT { UT_FATAL( "Disabled auto alloc did not prevent the undo log grow"); } TX_END pmemobj_free(&oid0); pmemobj_free(&oid1); } /* * do_tx_max_alloc_wrong_pop_addr -- allocates two pools and tries to * do transaction with the first pool and address from the second * pool. Abort expected - cannot allocate from different pool. */ static void do_tx_max_alloc_wrong_pop_addr(PMEMobjpool *pop, PMEMobjpool *pop2) { UT_OUT("do_tx_max_alloc_wrong_pop_addr"); size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); /* * number of allocated buffers is not important * they are not used anyway */ PMEMoid oid2; int ret = pmemobj_alloc(pop2, &oid2, MAX_ALLOC, 0, NULL, NULL); UT_ASSERTeq(ret, 0); /* pools are allocated now, let's try to get address from wrong pool */ size_t buff2_size = pmemobj_alloc_usable_size(oid2); void *buff2_addr = pmemobj_direct(oid2); /* abort expected - cannot allocate from different pool */ TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff2_addr, buff2_size); } TX_ONABORT { UT_OUT( "!Cannot append an undo log buffer from a different memory pool"); } TX_ONCOMMIT { UT_FATAL( "Can append an undo log buffer from a different memory pool"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_xlog_append_buffer(TX_LOG_TYPE_SNAPSHOT, buff2_addr, buff2_size, POBJ_XLOG_APPEND_BUFFER_NO_ABORT); } TX_ONABORT { UT_ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_OUT( "!Cannot append an undo log buffer from a different memory pool"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_SNAPSHOT, buff2_addr, buff2_size); } TX_ONABORT { UT_ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_OUT( "!Cannot append an undo log buffer from a different memory pool"); } TX_END /* it should fail without abort transaction */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_xlog_append_buffer(TX_LOG_TYPE_SNAPSHOT, buff2_addr, buff2_size, 0); } TX_ONABORT { UT_ASSERT(0); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); UT_OUT( "!Cannot append an undo log buffer from a different memory pool"); } TX_END free_pool(allocated, nallocated); pmemobj_free(&oid2); } /* * do_tx_buffer_currently_used -- the same buffer cannot be used * twice in the same time. */ static void do_tx_buffer_currently_used(PMEMobjpool *pop) { UT_OUT("do_tx_buffer_currently_used"); PMEMoid oid_buff; int verify_user_buffers = 1; /* by default verify_user_buffers should be 0 */ int ret = pmemobj_ctl_get(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); UT_ASSERTeq(verify_user_buffers, 0); int err = pmemobj_alloc(pop, &oid_buff, MAX_ALLOC, 0, NULL, NULL); UT_ASSERTeq(err, 0); /* this buffer we will try to use twice */ size_t buff_size = pmemobj_alloc_usable_size(oid_buff); void *buff_addr = pmemobj_direct(oid_buff); /* changes verify_user_buffers value */ verify_user_buffers = 1; ret = pmemobj_ctl_set(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); verify_user_buffers = 99; /* check if verify_user_buffers has changed */ ret = pmemobj_ctl_get(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); UT_ASSERTeq(verify_user_buffers, 1); /* if verify_user_buffers is set we should abort tx */ TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addr, buff_size); pmemobj_tx_log_append_buffer( TX_LOG_TYPE_SNAPSHOT, buff_addr, buff_size); } TX_ONABORT { UT_OUT("!User cannot append the same undo log buffer twice"); } TX_ONCOMMIT { UT_FATAL("User can append the same undo log buffer twice"); } TX_END pmemobj_free(&oid_buff); /* restore the default and verify */ verify_user_buffers = 0; ret = pmemobj_ctl_set(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); verify_user_buffers = 99; ret = pmemobj_ctl_get(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); UT_ASSERTeq(verify_user_buffers, 0); } /* * do_tx_max_alloc_tx_publish -- fills the pool and then tries * to overfill redo log with appended buffer */ static void do_tx_max_alloc_tx_publish(PMEMobjpool *pop) { UT_OUT("do_tx_max_alloc_tx_publish"); PMEMoid *allocated = NULL; PMEMoid reservations[REDO_OVERFLOW]; size_t nallocated = 0; struct pobj_action act[REDO_OVERFLOW]; for (int i = 0; i < REDO_OVERFLOW; i++) { reservations[i] = pmemobj_reserve(pop, &act[i], MIN_ALLOC, 0); UT_ASSERT(!OID_IS_NULL(reservations[i])); } allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated >= MIN_NOIDS); size_t buff_size = pmemobj_alloc_usable_size(allocated[LOG_BUFFER]); void *buff_addr = pmemobj_direct(allocated[LOG_BUFFER]); TX_BEGIN(pop) { pmemobj_tx_log_append_buffer( TX_LOG_TYPE_INTENT, buff_addr, buff_size); pmemobj_tx_publish(act, REDO_OVERFLOW); } TX_ONABORT { UT_FATAL("!Cannot extend redo log despite appended buffer"); } TX_ONCOMMIT { UT_OUT("Can extend redo log with appended buffer"); } TX_END free_pool(allocated, nallocated); for (int i = 0; i < REDO_OVERFLOW; ++i) { pmemobj_free(&reservations[i]); } } /* * do_tx_user_buffer_atomic_alloc -- checks if finish of atomic * allocation inside transaction will not break state of the ulog * with appended user buffer */ static void do_tx_user_buffer_atomic_alloc(PMEMobjpool *pop) { UT_OUT("do_tx_user_buffer_atomic_alloc"); PMEMoid user_buffer_oid; PMEMoid atomic_alloc_oid; PMEMoid reservations[REDO_OVERFLOW]; struct pobj_action act[REDO_OVERFLOW]; /* * we have to fill out first ulog in the redo log * to make sure that the user buffer will be needed * to proceed */ for (int i = 0; i < REDO_OVERFLOW; i++) { reservations[i] = pmemobj_reserve(pop, &act[i], MIN_ALLOC, 0); UT_ASSERT(!OID_IS_NULL(reservations[i])); } /* allocs some space for intent user buffer */ int ret = pmemobj_alloc(pop, &user_buffer_oid, MAX_ALLOC, 0, NULL, NULL); UT_ASSERTeq(ret, 0); size_t buff_size = pmemobj_alloc_usable_size(user_buffer_oid); void *buff_addr = pmemobj_direct(user_buffer_oid); TX_BEGIN(pop) { /* disable automatic ulog reservation and add user buffer */ pmemobj_tx_log_auto_alloc(TX_LOG_TYPE_INTENT, 0); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, buff_addr, buff_size); /* perform atomic allocation in the middle of transaction */ pmemobj_alloc(pop, &atomic_alloc_oid, MAX_ALLOC, 0, NULL, NULL); /* user buffer should be sill valid, so we try to use it */ pmemobj_tx_publish(act, REDO_OVERFLOW); } TX_ONCOMMIT { UT_OUT( "The transaction state is consistent after atomic allocation"); } TX_ONABORT { UT_FATAL( "The transaction state is consistent after atomic allocation"); } TX_END pmemobj_free(&user_buffer_oid); } /* * do_tx_buffer_overlapping -- checks if user buffer overlap detection works */ static void do_tx_buffer_overlapping(PMEMobjpool *pop) { UT_OUT("do_tx_buffer_overlapping"); /* changes verify_user_buffers value */ int verify_user_buffers = 1; int ret = pmemobj_ctl_set(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); PMEMoid oid = OID_NULL; pmemobj_alloc(pop, &oid, MAX_ALLOC, 0, NULL, NULL); UT_ASSERT(!OID_IS_NULL(oid)); char *ptr = (char *)pmemobj_direct(oid); ptr = (char *)ALIGN_UP((size_t)ptr, CACHELINE_SIZE); TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr + APPEND_SIZE, APPEND_SIZE); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_ONCOMMIT { UT_OUT("Overlap not detected"); } TX_END TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr + APPEND_SIZE, APPEND_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_ONCOMMIT { UT_OUT("Overlap not detected"); } TX_END TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); } TX_ONABORT { UT_OUT("Overlap detected"); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr + 128, APPEND_SIZE); } TX_ONABORT { UT_OUT("Overlap detected"); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr + 128, APPEND_SIZE); pmemobj_tx_log_append_buffer(TX_LOG_TYPE_INTENT, ptr, APPEND_SIZE); } TX_ONABORT { UT_OUT("Overlap detected"); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END pmemobj_free(&oid); verify_user_buffers = 0; ret = pmemobj_ctl_set(pop, "tx.debug.verify_user_buffers", &verify_user_buffers); UT_ASSERTeq(ret, 0); } /* * do_log_intents_max_size_limits -- test the pmemobj_tx_log_intents_max_size * function argument processing */ static void do_log_intents_max_size_limits(void) { UT_OUT("do_log_intent_max_size_limits"); size_t size = 0; /* 1st case */ size = pmemobj_tx_log_intents_max_size(0); UT_ASSERT(size > 0); UT_ASSERTne(size, SIZE_MAX); /* 2nd case */ size = pmemobj_tx_log_intents_max_size( SIZE_MAX / TX_INTENT_LOG_ENTRY_OVERHEAD); UT_ASSERTeq(size, SIZE_MAX); UT_ASSERTeq(errno, ERANGE); /* 3rd case */ const size_t toobign = (SIZE_MAX - TX_INTENT_LOG_BUFFER_OVERHEAD) / TX_INTENT_LOG_ENTRY_OVERHEAD + 1; size = pmemobj_tx_log_intents_max_size(toobign); UT_ASSERTeq(size, SIZE_MAX); UT_ASSERTeq(errno, ERANGE); } /* * do_log_intents_max_size -- verify pmemobj_tx_log_intents_max_size reported * size is sufficient */ static void do_log_intents_max_size(PMEMobjpool *pop) { UT_OUT("do_log_intent_max_size"); const size_t nintents = 15; /* an arbitrarily picked number */ /* query a required log size */ size_t req_buff_size = pmemobj_tx_log_intents_max_size(nintents); UT_ASSERTne(req_buff_size, SIZE_MAX); /* alloc the intent buffer */ PMEMoid buff_oid = OID_NULL; int ret = pmemobj_alloc(pop, &buff_oid, req_buff_size, 0, NULL, NULL); UT_ASSERTeq(ret, 0); void *buff_addr = pmemobj_direct(buff_oid); size_t buff_size = pmemobj_alloc_usable_size(buff_oid); UT_ASSERT(buff_size >= req_buff_size); /* make an assumed number of reservations */ PMEMoid reservations[nintents]; struct pobj_action act[nintents]; for (size_t i = 0; i < nintents; i++) { reservations[i] = pmemobj_reserve(pop, &act[i], MIN_ALLOC, 0); UT_ASSERT(!OID_IS_NULL(reservations[i])); } TX_BEGIN(pop) { pmemobj_tx_log_auto_alloc(TX_LOG_TYPE_INTENT, 0); pmemobj_tx_log_append_buffer( TX_LOG_TYPE_INTENT, buff_addr, buff_size); pmemobj_tx_publish(act, nintents); } TX_ONABORT { UT_FATAL("!Estimated intent log buffer size is too small"); } TX_ONCOMMIT { UT_OUT("Estimated intent log buffer size is sufficient"); } TX_END /* release all allocated resources */ for (size_t i = 0; i < nintents; ++i) { pmemobj_free(&reservations[i]); UT_ASSERT(OID_IS_NULL(reservations[i])); } pmemobj_free(&buff_oid); UT_ASSERT(OID_IS_NULL(buff_oid)); } /* * do_log_snapshots_max_size_limits -- test the * pmemobj_tx_log_snapshots_max_size function argument processing */ static void do_log_snapshots_max_size_limits(void) { UT_OUT("do_log_snapshot_max_size_limits"); const size_t nsizes = 1024; /* an arbitrarily picked number */ /* prepare array of big sizes */ size_t *sizes = (size_t *)MALLOC(sizeof(size_t) * nsizes); for (size_t i = 0, size = MAX_ALLOC; i < nsizes; ++i) { sizes[i] = size; if (size < SIZE_MAX / 2) size *= 2; } size_t size = 0; size = pmemobj_tx_log_snapshots_max_size(sizes, nsizes); UT_ASSERTeq(size, SIZE_MAX); UT_ASSERTeq(errno, ERANGE); /* release allocated resources */ FREE(sizes); } /* * do_log_snapshots_max_size -- verify pmemobj_tx_log_snapshots_max_size * reported size is sufficient */ static void do_log_snapshots_max_size(PMEMobjpool *pop) { UT_OUT("do_log_snapshot_max_size"); size_t nsizes_max = 15; /* an arbitrarily picked number */ size_t *sizes = (size_t *)MALLOC(nsizes_max * sizeof(size_t)); /* fill up the pool */ size_t nallocated = 0; PMEMoid *allocated = fill_pool(pop, &nallocated); UT_ASSERT(nallocated > LOG_BUFFER); /* the first allocation will be used for as a snapshot log buffer */ void *buff_addr = pmemobj_direct(allocated[LOG_BUFFER]); size_t max_buff_size = pmemobj_alloc_usable_size(allocated[LOG_BUFFER]); size_t req_buff_size = 0; /* how many ranges fit into the buffer */ size_t nsizes_valid = 0; for (size_t i = nallocated - 1; i > LOG_BUFFER; --i) { /* initialize the range */ size_t range_size = pmemobj_alloc_usable_size(allocated[i]); void *range_addr = pmemobj_direct(allocated[i]); pmemobj_memset(pop, range_addr, 0, range_size, 0); /* append to the list of sizes */ sizes[nsizes_valid] = range_size; ++nsizes_valid; if (nsizes_valid == nsizes_max) { nsizes_max *= 2; sizes = (size_t *)REALLOC(sizes, nsizes_max * sizeof(size_t)); } /* estimate a required buffer size for snapshots */ req_buff_size = pmemobj_tx_log_snapshots_max_size( sizes, nsizes_valid); UT_ASSERTne(req_buff_size, SIZE_MAX); if (req_buff_size > max_buff_size) { /* if it is too much we have to use one less */ --nsizes_valid; UT_ASSERTne(nsizes_valid, 0); req_buff_size = pmemobj_tx_log_snapshots_max_size( sizes, nsizes_valid); break; } } TX_BEGIN(pop) { pmemobj_tx_log_append_buffer(TX_LOG_TYPE_SNAPSHOT, buff_addr, req_buff_size); for (size_t i = 0; i < nsizes_valid; i++) { pmemobj_tx_add_range(allocated[nallocated - i - 1], 0, sizes[i]); } } TX_ONABORT { UT_FATAL("!Estimated snapshot log buffer size is too small"); } TX_ONCOMMIT { UT_OUT("Estimated snapshot log buffer size is sufficient"); } TX_END /* release all allocated resources */ free_pool(allocated, nallocated); FREE(sizes); } int main(int argc, char *argv[]) { START(argc, argv, "obj_ulog_size"); if (argc != 3) UT_FATAL("usage: %s [file] [file1]", argv[0]); PMEMobjpool *pop = pmemobj_create(argv[1], LAYOUT_NAME, 0, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create"); PMEMobjpool *pop2 = pmemobj_create(argv[2], LAYOUT_NAME, 0, S_IWUSR | S_IRUSR); if (pop2 == NULL) UT_FATAL("!pmemobj_create"); do_tx_max_alloc_no_user_alloc_snap(pop); do_tx_max_alloc_user_alloc_snap(pop); do_tx_max_alloc_user_alloc_nested(pop); do_tx_max_alloc_user_alloc_snap_multi(pop); do_tx_auto_alloc_disabled(pop); do_tx_max_alloc_wrong_pop_addr(pop, pop2); do_tx_max_alloc_tx_publish_abort(pop); do_tx_buffer_currently_used(pop); do_tx_max_alloc_tx_publish(pop); do_tx_user_buffer_atomic_alloc(pop); do_tx_buffer_overlapping(pop); do_log_intents_max_size_limits(); do_log_intents_max_size(pop); do_log_snapshots_max_size_limits(); do_log_snapshots_max_size(pop); pmemobj_close(pop); pmemobj_close(pop2); DONE(NULL); } pmdk-1.11.1/src/test/obj_ulog_size/obj_ulog_size.vcxproj0000664000000000000000000000767714123364546022126 0ustar rootroot Debug x64 Release x64 {C35052AF-2383-4F9C-B18B-55A01829F2BF} Win32Proj obj_ulog_size 10.0.17134.0 Application true v140 Application false v140 true Disabled false 4200 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) CompileAsCpp MaxSpeed 4200 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_ulog_size/Makefile0000664000000000000000000000043514123364546017300 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_ulog_size/Makefile -- build obj_ulog_size unit test # TOP = ../../.. TARGET = obj_ulog_size OBJS = obj_ulog_size.o LIBPMEMOBJ=y include ../Makefile.inc CFLAGS += -I$(TOP)/src/libpmemobj/ pmdk-1.11.1/src/test/obj_ulog_size/out0.log.match0000664000000000000000000000375014123364546020330 0ustar rootrootobj_ulog_size$(nW)TEST0: START: obj_ulog_size $(nW)obj_ulog_size$(nW) $(nW)testfile $(nW)testfile1 do_tx_max_alloc_no_user_alloc_snap Cannot extend undo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_user_alloc_snap Can use the user appended undo log buffer do_tx_max_alloc_user_alloc_nested Can use the undo log appended by the user in a nested transaction do_tx_max_alloc_user_alloc_snap_multi Can use multiple user appended undo log buffers All user appended undo log buffers are used: ${Cannot allocate memory|Not enough space} do_tx_auto_alloc_disabled Disabled auto alloc prevented the undo log grow: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_wrong_pop_addr Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument do_tx_max_alloc_tx_publish_abort Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_buffer_currently_used User cannot append the same undo log buffer twice: Invalid argument do_tx_max_alloc_tx_publish Can extend redo log with appended buffer do_tx_user_buffer_atomic_alloc The transaction state is consistent after atomic allocation do_tx_buffer_overlapping Overlap not detected Overlap not detected Overlap detected Overlap detected Overlap detected do_log_intent_max_size_limits do_log_intent_max_size Estimated intent log buffer size is sufficient do_log_snapshot_max_size_limits do_log_snapshot_max_size Estimated snapshot log buffer size is sufficient obj_ulog_size$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ulog_size/TESTS.py0000775000000000000000000000120414123364546017112 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation import testframework as t @t.require_build(['debug', 'release']) class BASE(t.Test): test_type = t.Medium def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile') filepath1 = ctx.create_holey_file(16 * t.MiB, 'testfile1') ctx.exec('obj_ulog_size', filepath, filepath1) @t.require_valgrind_disabled('memcheck', 'pmemcheck') class TEST0(BASE): pass @t.require_valgrind_enabled('memcheck') class TEST1(BASE): pass @t.require_valgrind_enabled('pmemcheck') class TEST2(BASE): pass pmdk-1.11.1/src/test/obj_ulog_size/.gitignore0000664000000000000000000000001614123364546017623 0ustar rootrootobj_ulog_size pmdk-1.11.1/src/test/obj_ulog_size/obj_ulog_size.vcxproj.filters0000664000000000000000000000177714123364546023570 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {9cef02dc-bf93-4bcc-88fd-82b274dbbf71} py {5ed3a714-4184-4abe-92cb-ce881168ad0c} match Source Files Test Scripts Match Files pmdk-1.11.1/src/test/obj_ulog_size/out1.log.match0000664000000000000000000000375014123364546020331 0ustar rootrootobj_ulog_size$(nW)TEST1: START: obj_ulog_size $(nW)obj_ulog_size$(nW) $(nW)testfile $(nW)testfile1 do_tx_max_alloc_no_user_alloc_snap Cannot extend undo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_user_alloc_snap Can use the user appended undo log buffer do_tx_max_alloc_user_alloc_nested Can use the undo log appended by the user in a nested transaction do_tx_max_alloc_user_alloc_snap_multi Can use multiple user appended undo log buffers All user appended undo log buffers are used: ${Cannot allocate memory|Not enough space} do_tx_auto_alloc_disabled Disabled auto alloc prevented the undo log grow: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_wrong_pop_addr Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument do_tx_max_alloc_tx_publish_abort Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_buffer_currently_used User cannot append the same undo log buffer twice: Invalid argument do_tx_max_alloc_tx_publish Can extend redo log with appended buffer do_tx_user_buffer_atomic_alloc The transaction state is consistent after atomic allocation do_tx_buffer_overlapping Overlap not detected Overlap not detected Overlap detected Overlap detected Overlap detected do_log_intent_max_size_limits do_log_intent_max_size Estimated intent log buffer size is sufficient do_log_snapshot_max_size_limits do_log_snapshot_max_size Estimated snapshot log buffer size is sufficient obj_ulog_size$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_ulog_size/out2.log.match0000664000000000000000000000375014123364546020332 0ustar rootrootobj_ulog_size$(nW)TEST2: START: obj_ulog_size $(nW)obj_ulog_size$(nW) $(nW)testfile $(nW)testfile1 do_tx_max_alloc_no_user_alloc_snap Cannot extend undo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_user_alloc_snap Can use the user appended undo log buffer do_tx_max_alloc_user_alloc_nested Can use the undo log appended by the user in a nested transaction do_tx_max_alloc_user_alloc_snap_multi Can use multiple user appended undo log buffers All user appended undo log buffers are used: ${Cannot allocate memory|Not enough space} do_tx_auto_alloc_disabled Disabled auto alloc prevented the undo log grow: ${Cannot allocate memory|Not enough space} do_tx_max_alloc_wrong_pop_addr Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument Cannot append an undo log buffer from a different memory pool: Invalid argument do_tx_max_alloc_tx_publish_abort Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} Cannot extend redo log - the pool is full: ${Cannot allocate memory|Not enough space} do_tx_buffer_currently_used User cannot append the same undo log buffer twice: Invalid argument do_tx_max_alloc_tx_publish Can extend redo log with appended buffer do_tx_user_buffer_atomic_alloc The transaction state is consistent after atomic allocation do_tx_buffer_overlapping Overlap not detected Overlap not detected Overlap detected Overlap detected Overlap detected do_log_intent_max_size_limits do_log_intent_max_size Estimated intent log buffer size is sufficient do_log_snapshot_max_size_limits do_log_snapshot_max_size Estimated snapshot log buffer size is sufficient obj_ulog_size$(nW)TEST2: DONE pmdk-1.11.1/src/test/match0000775000000000000000000001674214123364546014040 0ustar rootroot#!/usr/bin/env perl # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # match -- compare an output file with expected results # # usage: match [-adoqv] [match-file]... # # this script compares the output from a test run, stored in a file, with # the expected output. comparison is done line-by-line until either all # lines compare correctly (exit code 0) or a miscompare is found (exit # code nonzero). # # expected output is stored in a ".match" file, which contains a copy of # the expected output with embedded tokens for things that should not be # exact matches. the supported tokens are: # # $(N) an integer (i.e. one or more decimal digits) # $(NC) one or more decimal digits with comma separators # $(FP) a floating point number # $(S) ascii string # $(X) hex number # $(XX) hex number prefixed with 0x # $(W) whitespace # $(nW) non-whitespace # $(*) any string # $(DD) output of a "dd" run # $(OPT) line is optional (may be missing, matched if found) # $(OPX) ends a contiguous list of $(OPT)...$(OPX) lines, at least # one of which must match # ${string1|string2} string1 OR string2 # ${string1|string2|string3} string1 OR string2 OR string3 # # Additionally, if any "X.ignore" file exists, strings or phrases found per # line in the file will be ignored if found as a substring in the # corresponding output file (making it easy to skip entire output lines). # # arguments are: # # -a find all files of the form "X.match" in the current # directory and match them again the corresponding file "X". # # -o custom output filename - only one match file can be given # # -d debug -- show lots of debug output # # -q don't print log files on mismatch # # -v verbose -- show every line as it is being matched # use strict; use Getopt::Std; use Encode; use v5.16; select STDERR; binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); my ($color_ok, $color_bad, $color_end) = -t STDOUT ? ("", "\e[31;1m", "\e[0m") : ('')x3; my $Me = $0; $Me =~ s,.*/,,; our ($opt_a, $opt_d, $opt_q, $opt_v, $opt_o); $SIG{HUP} = $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = sub { die @_ if $^S; my $errstr = shift; die "FAIL: $Me: $errstr"; }; sub usage { my $msg = shift; warn "$Me: $msg\n" if $msg; warn "Usage: $Me [-adqv] [match-file]...\n"; warn " or: $Me [-dqv] -o output-file match-file...\n"; exit 1; } getopts('adoqv') or usage; my %match2file; if ($opt_a) { usage("-a and filename arguments are mutually exclusive") if $#ARGV != -1; opendir(DIR, '.') or die "opendir: .: $!\n"; my @matchfiles = grep { /(.*)\.match$/ && -f $1 } readdir(DIR); closedir(DIR); die "no files found to process\n" unless @matchfiles; foreach my $mfile (@matchfiles) { die "$mfile: $!\n" unless open(F, $mfile); close(F); my $ofile = $mfile; $ofile =~ s/\.match$//; die "$mfile found but cannot open $ofile: $!\n" unless open(F, $ofile); close(F); $match2file{$mfile} = $ofile; } } elsif ($opt_o) { usage("-o argument requires two paths") if $#ARGV != 1; $match2file{$ARGV[1]} = $ARGV[0]; } else { usage("no match-file arguments found") if $#ARGV == -1; # to improve the failure case, check all filename args exist and # are provided in pairs now, before going through and processing them foreach my $mfile (@ARGV) { my $ofile = $mfile; usage("$mfile: not a .match file") unless $ofile =~ s/\.match$//; usage("$mfile: $!") unless open(F, $mfile); close(F); usage("$ofile: $!") unless open(F, $ofile); close(F); $match2file{$mfile} = $ofile; } } my $mfile; my $ofile; my $ifile; print "Files to be processed:\n" if $opt_v; foreach $mfile (sort keys %match2file) { $ofile = $match2file{$mfile}; $ifile = $ofile . ".ignore"; $ifile = undef unless (-f $ifile); if ($opt_v) { print " match-file \"$mfile\" output-file \"$ofile\""; if ($ifile) { print " ignore-file $ifile\n"; } else { print "\n"; } } match($mfile, $ofile, $ifile); } exit 0; # # strip_it - user can optionally ignore lines from files that contain # any number of substrings listed in a file called "X.ignore" where X # is the name of the output file. # sub strip_it { my ($ifile, $file, $input) = @_; # if there is no ignore file just return unaltered input return $input unless $ifile; my @lines_in = split /^/, $input; my $output; my $line_in; my @i_file = split /^/, snarf($ifile); my $i_line; my $ignore_it = 0; foreach $line_in (@lines_in) { my @i_lines = @i_file; foreach $i_line (@i_lines) { chop($i_line); if (index($line_in, $i_line) != -1) { $ignore_it = 1; if ($opt_v) { print "Ignoring (from $file): $line_in"; } } } if ($ignore_it == 0) { $output .= $line_in; } $ignore_it = 0; } return $output; } # # match -- process a match-file, output-file pair # sub match { my ($mfile, $ofile, $ifile) = @_; my $pat; my $output = snarf($ofile); $output = strip_it($ifile, $ofile, $output); my $all_lines = $output; my $line_pat = 0; my $line_out = 0; my $opt = 0; my $opx = 0; my $opt_found = 0; my $fstr = snarf($mfile); $fstr = strip_it($ifile, $mfile, $fstr); for (split /^/, $fstr) { $pat = $_; $line_pat++; $line_out++; s/([*+?|{}.\\^\$\[()])/\\$1/g; s/\\\$\\\(FP\\\)/[-+]?\\d*\\.?\\d+([eE][-+]?\\d+)?/g; s/\\\$\\\(N\\\)/[-+]?\\d+/g; s/\\\$\\\(NC\\\)/[-+]?\\d+(,[0-9]+)*/g; s/\\\$\\\(\\\*\\\)/\\p{Print}*/g; s/\\\$\\\(S\\\)/\\P{IsC}+/g; s/\\\$\\\(X\\\)/\\p{XPosixXDigit}+/g; s/\\\$\\\(XX\\\)/0x\\p{XPosixXDigit}+/g; s/\\\$\\\(W\\\)/\\p{Blank}*/g; s/\\\$\\\(nW\\\)/\\p{Graph}*/g; s/\\\$\\\{([^|]*)\\\|([^|]*)\\\}/($1|$2)/g; s/\\\$\\\{([^|]*)\\\|([^|]*)\\\|([^|]*)\\\}/($1|$2|$3)/g; s/\\\$\\\(DD\\\)/\\d+\\+\\d+ records in\n\\d+\\+\\d+ records out\n\\d+ bytes \\\(\\d+ .B\\\) copied, [.0-9e-]+[^,]*, [.0-9]+ .B.s/g; if (s/\\\$\\\(OPT\\\)//) { $opt = 1; } elsif (s/\\\$\\\(OPX\\\)//) { $opx = 1; } else { $opt_found = 0; } if ($opt_v) { my @lines = split /\n/, $output; my $line; if (@lines) { $line = $lines[0]; } else { $line = "[EOF]"; } printf("%s%s:%-3d %s%s:%-3d %s%s\n", ($output =~ /^$_/) ? $color_ok : $color_bad, $mfile, $line_pat, $pat, $ofile, $line_out, $line, $color_end); } print " => /$_/\n" if $opt_d; print " [$output]\n" if $opt_d; unless ($output =~ s/^$_//) { if ($opt || ($opx && $opt_found)) { printf("%s:%-3d [skipping optional line]\n", $ofile, $line_out) if $opt_v; $line_out--; $opt = 0; } else { if (!$opt_v) { if ($opt_q) { print "[MATCHING FAILED]\n"; } else { print "[MATCHING FAILED, COMPLETE FILE ($ofile) BELOW]\n$all_lines\n[EOF]\n"; } $opt_v = 1; match($mfile, $ofile); } die "$mfile:$line_pat did not match pattern\n"; } } elsif ($opt) { $opt_found = 1; } $opx = 0; } if ($output ne '') { if (!$opt_v) { if ($opt_q) { print "[MATCHING FAILED]\n"; } else { print "[MATCHING FAILED, COMPLETE FILE ($ofile) BELOW]\n$all_lines\n[EOF]\n"; } } # make it a little more print-friendly... $output =~ s/\n/\\n/g; die "line $line_pat: unexpected output: \"$output\"\n"; } } # # snarf -- slurp an entire file into memory # sub snarf { my ($file) = @_; my $fh; open($fh, '<', $file) or die "$file $!\n"; local $/; $_ = <$fh>; close $fh; # check known encodings or die my $decoded; my @encodings = ("UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE"); foreach my $enc (@encodings) { eval { $decoded = decode( $enc, $_, Encode::FB_CROAK ) }; if (!$@) { $decoded =~ s/\R/\n/g; return $decoded; } } die "$Me: ERROR: Unknown file encoding"; } pmdk-1.11.1/src/test/win_signal/0000775000000000000000000000000014123364546015136 5ustar rootrootpmdk-1.11.1/src/test/win_signal/win_signal.vcxproj0000664000000000000000000000643614123364546020716 0ustar rootroot Debug x64 Release x64 {F13108C4-4C86-4D56-A317-A4E5892A8AF7} Win32Proj win_signal 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/win_signal/win_signal.c0000664000000000000000000000072414123364546017437 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * win_signal.c -- test signal related routines */ #include "unittest.h" extern int sys_siglist_size; int main(int argc, char *argv[]) { int sig; START(argc, argv, "win_signal"); for (sig = 0; sig < sys_siglist_size; sig++) { UT_OUT("%d; %s", sig, os_strsignal(sig)); } for (sig = 33; sig < 66; sig++) { UT_OUT("%d; %s", sig, os_strsignal(sig)); } DONE(NULL); } pmdk-1.11.1/src/test/win_signal/win_signal.vcxproj.filters0000664000000000000000000000166614123364546022365 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {fd43f65a-4a91-4191-825a-d7dc98fe5f33} {a517de2c-1baf-4e3e-8774-a652dd45ef4a} Test scripts Match Files Source Files pmdk-1.11.1/src/test/win_signal/out0.log.match0000664000000000000000000000261514123364546017627 0ustar rootrootwin_signal$(nW)TEST0: START: win_signal $(nW)win_signal.exe 0; Unknown signal 0 1; Hangup 2; Interrupt 3; Quit 4; Illegal instruction 5; Trace/breakpoint trap 6; Aborted 7; Bus error 8; Floating point exception 9; Killed 10; User defined signal 1 11; Segmentation fault 12; User defined signal 2 13; Broken pipe 14; Alarm clock 15; Terminated 16; Stack fault 17; Child exited 18; Continued 19; Stopped (signal) 20; Stopped 21; Stopped (tty input) 22; Stopped (tty output) 23; Urgent I/O condition 24; CPU time limit exceeded 25; File size limit exceeded 26; Virtual timer expired 27; Profiling timer expired 28; Window changed 29; I/O possible 30; Power failure 31; Bad system call 32; Unknown signal 32 33; Unknown signal 34; Real-time signal 35; Real-time signal 36; Real-time signal 37; Real-time signal 38; Real-time signal 39; Real-time signal 40; Real-time signal 41; Real-time signal 42; Real-time signal 43; Real-time signal 44; Real-time signal 45; Real-time signal 46; Real-time signal 47; Real-time signal 48; Real-time signal 49; Real-time signal 50; Real-time signal 51; Real-time signal 52; Real-time signal 53; Real-time signal 54; Real-time signal 55; Real-time signal 56; Real-time signal 57; Real-time signal 58; Real-time signal 59; Real-time signal 60; Real-time signal 61; Real-time signal 62; Real-time signal 63; Real-time signal 64; Real-time signal 65; Unknown signal win_signal$(nW)TEST0: DONE pmdk-1.11.1/src/test/win_signal/TEST0.PS10000664000000000000000000000047314123364546016326 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/win_signal/TEST0 -- unit test for windows signal implementation # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\win_signal$Env:EXESUFFIX check pass pmdk-1.11.1/src/test/RUNTESTS.py0000775000000000000000000001471314123364546014656 0ustar rootroot#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation """Main script for unit tests execution. Contains the implementation of the TestRunner class, which is a main test execution manager class and it's also used by TESTS.py scripts if run individually. TestRunner run_tests() method requires special attention as it implements the fundamental test run workflow. """ # modules from unittest directory are visible from this script import sys import os from os import path sys.path.insert(1, path.abspath(path.join(path.dirname(__file__), 'unittest'))) # flake8 issues silenced: # E402 - import statements not at the top of the file because of adding # directory to path import importlib.util as importutil # noqa E402 import subprocess as sp # noqa E402 import futils # noqa E402 from consts import ROOTDIR # noqa E402 from basetest import get_testcases # noqa E402 from configurator import Configurator # noqa E402 from ctx_filter import CtxFilter # noqa E402 class TestRunner: """ Main script utility for managing tests execution. Attributes: testcases (list): BaseTest objects that are test cases to be run during execution. config: config object as returned by Configurator msg (Message) level based logger """ def __init__(self, config, testcases): self.testcases = testcases self.config = config self._check_admin() self.msg = futils.Message(config.unittest_log_level) if self.config.test_sequence: # filter test cases from sequence self.testcases = [t for t in self.testcases if t.testnum in self.config.test_sequence] # sort testcases so their sequence matches provided test sequence self.testcases.sort(key=lambda tc: config.test_sequence.index(tc.testnum)) if not self.testcases: sys.exit('No testcases to run found for selected configuration.') def _check_admin(self): if not self.config.enable_admin_tests: return if sys.platform != 'win32': """This check is valid only for linux OSes""" try: sp.check_output(['sudo', '-n', 'true'], stderr=sp.STDOUT) except sp.CalledProcessError: sys.exit('Enabled "enable_admin_tests" requires ' 'the non-interactive sudo (no password required to ' 'perform the sudo command).') """XXX add a similar check for Windows""" def run_tests(self): """Run selected testcases. Implementation of this method is crucial as a general tests execution workflow. Returns: main script exit code denoting the execution result. """ ret = 0 for tc in self.testcases: # TODO handle test type inside custom decorator if tc.test_type not in self.config.test_type: continue if not tc.enabled: continue cf = CtxFilter(self.config, tc) # The 'c' context has to be initialized before the 'for' loop, # because cf.get_contexts() can return no value ([]) # and in case of the 'futils.Fail' exception # self._test_failed(tc, c, f) will be called # with uninitilized value of the 'c' context. c = None try: for c in cf.get_contexts(): try: t = tc() if t.enabled: self.msg.print('{}: SETUP\t({}/{})' .format(t, t.test_type, c)) t._execute(c) else: continue except futils.Skip as s: self.msg.print_verbose('{}: SKIP: {}'.format(t, s)) except futils.Fail as f: self._test_failed(t, c, f) ret = 1 else: self._test_passed(t) except futils.Skip as s: self.msg.print_verbose('{}: SKIP: {}'.format(tc, s)) except futils.Fail as f: self._test_failed(tc, c, f) ret = 1 return ret def _test_failed(self, tc, ctx, fail): self.msg.print('{}: {}FAILED{}\t({}/{})' .format(tc, futils.Color.RED, futils.Color.END, tc.test_type, ctx)) self.msg.print(fail) if not self.config.keep_going: sys.exit(1) def _test_passed(self, tc): """Print message specific for passed test""" if self.config.tm: tm = '\t\t\t[{:06.3F} s]'.format(tc.elapsed) else: tm = '' self.msg.print('{}: {}PASS{} {}' .format(tc, futils.Color.GREEN, futils.Color.END, tm)) def _import_testfiles(): """ Traverse through "src/test" directory, find all "TESTS.py" files and import them as modules. Set imported module name to file directory path. Importing these files serves two purposes: - makes test classes residing in them visible and usable by the RUNTESTS script. - triggers basetest._TestType metaclass which initializes and registers them as actual test case classes - they are therefore available through basetest.get_testfiles() function """ for root, _, files in os.walk(ROOTDIR): for name in files: if name == 'TESTS.py': testfile = path.join(root, name) module_name = path.dirname(testfile) spec = importutil.spec_from_file_location(module_name, testfile) module = importutil.module_from_spec(spec) spec.loader.exec_module(module) def main(): _import_testfiles() config = Configurator().config testcases = get_testcases() if config.group: # filter selected groups testcases = [t for t in testcases if path.basename(t.__module__) in config.group] if hasattr(config, 'list_testcases'): for t in testcases: print(t.name) sys.exit(0) runner = TestRunner(config, testcases) sys.exit(runner.run_tests()) if __name__ == '__main__': main() pmdk-1.11.1/src/test/unittest/0000775000000000000000000000000014123364546014663 5ustar rootrootpmdk-1.11.1/src/test/unittest/valgrind.py0000664000000000000000000002402014123364546017041 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Valgrind handling tools""" import sys import re import subprocess as sp from enum import Enum, unique from os import path import context as ctx import futils from consts import ROOTDIR DISABLE = -1 ENABLE = 1 AUTO = 0 _IGNORED = ( "WARNING: Serious error when reading debug info", "When reading debug info from ", "Ignoring non-Dwarf2/3/4 block in .debug_info", "Last block truncated in .debug_info; ignoring", "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4", "brk segment overflow", "see section Limitations in user manual", "Warning: set address range perms: large range", "further instances of this message will not be shown", "get_Form_contents: DW_FORM_GNU_strp_alt used, but no alternate .debug_str" ) @unique class _Tool(Enum): """ Enumeration of valid Valgrind tool options. NONE is a virtual tool option denoting that valgrind is not used for test execution. """ MEMCHECK = 1 PMEMCHECK = 2 HELGRIND = 3 DRD = 4 NONE = 5 def __str__(self): return self.name.lower() def __bool__(self): return self != self.NONE TOOLS = tuple(t for t in _Tool if t != _Tool.NONE) MEMCHECK = _Tool.MEMCHECK PMEMCHECK = _Tool.PMEMCHECK HELGRIND = _Tool.HELGRIND DRD = _Tool.DRD NONE = _Tool.NONE class Valgrind: """Valgrind management context element class Attributes: tool (_Tool): selected valgrind tool tool_name (str): tool name as string cwd (str): path to the test cwd (i. e. the directory in which test .py file resides) log_file (str): path to valgrind output log file valgrind_exe (str): path to valgrind command opts (list): list of valgrind command line options """ def __init__(self, tool, cwd, testnum): if sys.platform == 'win32': raise NotImplementedError( 'Valgrind class should not be used on Windows') self.tool = NONE if tool is None else tool self.tool_name = self.tool.name.lower() self.cwd = cwd log_file_name = '{}{}.log'.format(self.tool.name.lower(), testnum) self.log_file = path.join(cwd, log_file_name) if self.tool == NONE: self.valgrind_exe = None else: self.valgrind_exe = self._get_valgrind_exe() if self.valgrind_exe is None: return self.verify() self.opts = [] self.add_suppression('ld.supp') if 'freebsd' in sys.platform: self.add_suppression('freebsd.supp') if tool == MEMCHECK: self.add_suppression('memcheck-libunwind.supp') self.add_suppression('memcheck-ndctl.supp') self.add_suppression('memcheck-dlopen.supp') # Before Skylake, Intel CPUs did not have clflushopt instruction, so # pmem_flush and pmem_persist both translated to clflush. # This means that missing pmem_drain after pmem_flush could only be # detected on Skylake+ CPUs. # This option tells pmemcheck to expect fence (sfence or # VALGRIND_PMC_DO_FENCE client request, used by pmem_drain) after # clflush and makes pmemcheck output the same on pre-Skylake and # post-Skylake CPUs. elif tool == PMEMCHECK: self.add_opt('--expect-fence-after-clflush=yes') elif tool == HELGRIND: self.add_suppression('helgrind-log.supp') elif tool == DRD: self.add_suppression('drd-log.supp') def __str__(self): return self.tool.name.lower() def __bool__(self): return self.tool != NONE @classmethod def filter(cls, config, msg, tc): """ Acquire Valgrind tool for the test to be run with. Takes into account configuration 'force-enable' options, and Valgrind tools enabled or disabled by test requirements. Args: config: configuration as returned by Configurator class msg (Message): level based logger class instance tc (BaseTest): test case, from which the Valgrind requirements are obtained Returns: list of initialized Valgrind tool classes with which the test should be run """ vg_tool, kwargs = ctx.get_requirement(tc, 'enabled_valgrind', NONE) disabled, _ = ctx.get_requirement(tc, 'disabled_valgrind', ()) if config.force_enable: if vg_tool and vg_tool != config.force_enable: raise futils.Skip( "test enables the '{}' Valgrind tool while " "execution configuration forces '{}'" .format(vg_tool, config.force_enable)) elif config.force_enable in disabled: raise futils.Skip( "forced Valgrind tool '{}' is disabled by test" .format(config.force_enable)) else: vg_tool = config.force_enable return [cls(vg_tool, tc.cwd, tc.testnum, **kwargs), ] @property def cmd(self): """ Return Valgrind command with specified arguments as a subprocess compliant list. """ if self.tool == NONE: return [] cmd = [self.valgrind_exe, '--tool={}'.format(self.tool_name), '--log-file={}'.format(self.log_file)] + self.opts return cmd def setup(self, memcheck_check_leaks=True, **kwargs): if self.tool == MEMCHECK and memcheck_check_leaks: self.add_opt('--leak-check=full') def check(self, **kwargs): self.validate_log() def _get_valgrind_exe(self): """ On some systems "valgrind" is a shell script that calls the actual executable "valgrind.bin". The wrapper script does not work well with LD_PRELOAD so we want to call Valgrind directly. """ try: out = sp.check_output('which valgrind', shell=True, universal_newlines=True) except sp.CalledProcessError: raise futils.Skip('Valgrind not found') valgrind_bin = path.join(path.dirname(out), 'valgrind.bin') if path.isfile(valgrind_bin): return valgrind_bin return 'valgrind' def add_opt(self, opt): """Add option to Valgrind command""" self.opts.append(opt) def _get_version(self): """ Get Valgrind version represented as integer with patch version ignored """ out = sp.check_output('{} --version'.format(self.valgrind_exe), shell=True, universal_newlines=True) version = out.split('valgrind-')[1] version_as_int = int(version.rsplit('.', 1)[0].replace('.', '')) return version_as_int def add_suppression(self, f): """ Add suppression file. Provided file path is relative to tests root directory (pmdk/src/test) """ self.opts.append('--suppressions={}' .format(path.join(ROOTDIR, f))) def validate_log(self): """ Check Valgrind test result based on Valgrind log file. Return True if passed, False otherwise """ if self.tool == NONE or sys.platform == 'win32': return True no_ignored = [] # remove ignored warnings from log file with open(self.log_file, 'r+') as f: no_ignored = [ln for ln in f if not any(w in ln for w in _IGNORED)] f.seek(0) f.writelines(no_ignored) f.truncate() if path.isfile(self.log_file + '.match'): # if there is a Valgrind log match file, do nothing - log file # will be checked by 'match' tool return non_zero_errors = 'ERROR SUMMARY: [^0]' errors_found = any(re.search(non_zero_errors, ln) for ln in no_ignored) if any('Bad pmempool' in ln for ln in no_ignored) or errors_found: raise futils.Fail('Valgrind log validation failed') def verify(self): """ Check that Valgrind is viable to be used. """ if self.valgrind_exe is None: raise futils.Skip('Valgrind not found') # verify tool cmd = '{} --tool={} --help'.format(self.valgrind_exe, self.tool_name) try: sp.check_output(cmd, shell=True, stderr=sp.STDOUT) except sp.CalledProcessError: raise futils.Skip("Valgrind tool '{}' was not found" .format(self.tool_name)) def require_valgrind_enabled(valgrind): """ Enable valgrind tool for given test. Used as a test class (tc) decorator. Args: valgrind (str): valgrind tool """ def wrapped(tc): if sys.platform == 'win32': # do not run valgrind tests on windows tc.enabled = False return tc tool = _require_valgrind_common(valgrind) ctx.add_requirement(tc, 'enabled_valgrind', tool) return tc return wrapped def require_valgrind_disabled(*valgrind): """ Require that the test is not executed with selected valgrind tools. Used as a test class (tc) decorator. Args: *valgrind (*str): variable length arguments list of valgrind tools meant to be disabled """ def wrapped(tc): disabled_tools = [_require_valgrind_common(v) for v in valgrind] ctx.add_requirement(tc, 'disabled_valgrind', disabled_tools) return tc return wrapped def _require_valgrind_common(v): """ Validate provided valgrind tool as string and translate it to _Tool enum type. Args: v (str): valgrind tool as string Returns: valgrind tool as _Tool enum type """ valid_tool_names = [str(t) for t in TOOLS] if v not in valid_tool_names: sys.exit('used name {} not in valid valgrind tool names which are: {}' .format(v, valid_tool_names)) str_to_tool = next(t for t in TOOLS if v == str(t)) return str_to_tool pmdk-1.11.1/src/test/unittest/ut_pmem2_map.h0000664000000000000000000000103514123364546017420 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_map.h -- utility helper functions for libpmem2 map tests */ #ifndef UT_PMEM2_MAP_H #define UT_PMEM2_MAP_H 1 /* a pmem2_map_new() that can't return NULL */ #define PMEM2_MAP_NEW(map, cfg, src) \ ut_pmem2_map_new(__FILE__, __LINE__, __func__, map, cfg, src) void ut_pmem2_map_new(const char *file, int line, const char *func, struct pmem2_config *cfg, struct pmem2_source *src, struct pmem2_map **map); #endif /* UT_PMEM2_MAP_H */ pmdk-1.11.1/src/test/unittest/ut_pmem2_source.c0000664000000000000000000000361114123364546020140 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_source.h -- utility helper functions for libpmem2 source tests */ #include #include "unittest.h" #include "ut_pmem2_source.h" #include "ut_pmem2_utils.h" /* * ut_pmem2_source_from_fd -- sets fd (cannot fail) */ void ut_pmem2_source_from_fd(const char *file, int line, const char *func, struct pmem2_source **src, int fd) { int ret = pmem2_source_from_fd(src, fd); ut_pmem2_expect_return(file, line, func, ret, 0); } void ut_pmem2_source_from_fh(const char *file, int line, const char *func, struct pmem2_source **src, struct FHandle *f) { enum file_handle_type type = ut_fh_get_handle_type(f); int ret; if (type == FH_FD) { int fd = ut_fh_get_fd(file, line, func, f); #ifdef _WIN32 ret = pmem2_source_from_handle(src, (HANDLE)_get_osfhandle(fd)); #else ret = pmem2_source_from_fd(src, fd); #endif } else if (type == FH_HANDLE) { #ifdef _WIN32 HANDLE h = ut_fh_get_handle(file, line, func, f); ret = pmem2_source_from_handle(src, h); #else ut_fatal(file, line, func, "FH_HANDLE not supported on !Windows"); #endif } else { ut_fatal(file, line, func, "unknown file handle type"); } ut_pmem2_expect_return(file, line, func, ret, 0); } void ut_pmem2_source_alignment(const char *file, int line, const char *func, struct pmem2_source *src, size_t *al) { int ret = pmem2_source_alignment(src, al); ut_pmem2_expect_return(file, line, func, ret, 0); } void ut_pmem2_source_delete(const char *file, int line, const char *func, struct pmem2_source **src) { int ret = pmem2_source_delete(src); ut_pmem2_expect_return(file, line, func, ret, 0); UT_ASSERTeq(*src, NULL); } void ut_pmem2_source_size(const char *file, int line, const char *func, struct pmem2_source *src, size_t *size) { int ret = pmem2_source_size(src, size); ut_pmem2_expect_return(file, line, func, ret, 0); } pmdk-1.11.1/src/test/unittest/ut_pmem2_utils.h0000664000000000000000000000106014123364546020001 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * ut_pmem2_utils.h -- utility helper functions for libpmem2 tests */ #ifndef UT_PMEM2_UTILS_H #define UT_PMEM2_UTILS_H 1 /* veryfies error code and prints appropriate error message in case of error */ #define UT_PMEM2_EXPECT_RETURN(value, expected) \ ut_pmem2_expect_return(__FILE__, __LINE__, __func__, \ value, expected) void ut_pmem2_expect_return(const char *file, int line, const char *func, int value, int expected); #endif /* UT_PMEM2_UTILS_H */ pmdk-1.11.1/src/test/unittest/ut_pmemset_utils.h0000664000000000000000000000110214123364546020430 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * ut_pmemset_utils.h -- utility helper functions for libpmemset tests */ #ifndef UT_PMEMSET_UTILS_H #define UT_PMEMSET_UTILS_H 1 /* veryfies error code and prints appropriate error message in case of error */ #define UT_PMEMSET_EXPECT_RETURN(value, expected) \ ut_pmemset_expect_return(__FILE__, __LINE__, __func__, \ value, expected) void ut_pmemset_expect_return(const char *file, int line, const char *func, int value, int expected); #endif /* UT_PMEMSET_UTILS_H */ pmdk-1.11.1/src/test/unittest/consts.py0000664000000000000000000000253014123364546016546 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation """Test framework constants.""" from os.path import join, abspath, dirname import sys # List of libraries for logging PMDK debug output LIBS_LIST = ('pmem', 'pmem2', 'pmemobj', 'pmemblk', 'pmemlog', 'pmempool') # Constant paths to repository elements ROOTDIR = abspath(join(dirname(__file__), '..')) WIN_DEBUG_BUILDDIR = abspath(join(ROOTDIR, '..', 'x64', 'Debug')) WIN_DEBUG_EXEDIR = abspath(join(WIN_DEBUG_BUILDDIR, 'tests')) WIN_RELEASE_BUILDDIR = abspath(join(ROOTDIR, '..', 'x64', 'Release')) WIN_RELEASE_EXEDIR = abspath(join(WIN_RELEASE_BUILDDIR, 'tests')) if sys.platform == 'win32': DEBUG_LIBDIR = abspath(join(WIN_DEBUG_BUILDDIR, 'libs')) RELEASE_LIBDIR = abspath(join(WIN_RELEASE_BUILDDIR, 'libs')) else: DEBUG_LIBDIR = abspath(join(ROOTDIR, '..', 'debug')) RELEASE_LIBDIR = abspath(join(ROOTDIR, '..', 'nondebug')) HEADER_SIZE = 4096 # # KiB, MiB, GiB ... -- byte unit prefixes # KiB = 2 ** 10 MiB = 2 ** 20 GiB = 2 ** 30 TiB = 2 ** 40 PiB = 2 ** 50 # platform.machine() used for detecting architectures # gives different values for different systems. # Key is a normalized value of possible returned architecture values. NORMALIZED_ARCHS = { 'x86_64': ('AMD64', 'x86_64'), 'arm64': ('arm64', 'aarch64'), 'ppc64el': ('ppc64el', 'ppc64le') } pmdk-1.11.1/src/test/unittest/unittest.ps10000664000000000000000000011765714123364546017210 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. . "..\testconfig.ps1" function verbose_msg { if ($Env:UNITTEST_LOG_LEVEL -ge "2") { Write-Host $args[0] } } function msg { if ($Env:UNITTEST_LOG_LEVEL -ge "1") { Write-Host $args[0] } } function fatal { throw $args[0] } function touch { out-file -InputObject $null -Encoding ascii -literalpath $args[0] } function epoch { return [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds } function isDir { if (-Not $args[0]) { return $false } return Test-Path $args[0] -PathType Container } # force dir w/wildcard to fail if no match function dirFailOnEmpty { if (0 -eq (Get-ChildItem $args[0]).Count) { throw -Message 'No match: $args[0]' } } function getLineCount { [int64]$numLines = 0 $buff = New-Object IO.StreamReader $args[0] while ($buff.ReadLine() -ne $null){ $numLines++ } $buff.Close() return $numLines } # # convert_to_bytes -- converts the string with K, M, G or T suffixes # to bytes # # example: # "1G" --> "1073741824" # "2T" --> "2199023255552" # "3k" --> "3072" # "1K" --> "1024" # "10" --> "10" # function convert_to_bytes() { param([string]$size) if ($size.ToLower().EndsWith("kib")) { $size = [int64]($size.Substring(0, $size.Length - 3)) * 1kb } elseif ($size.ToLower().EndsWith("mib")) { $size = [int64]($size.Substring(0, $size.Length - 3)) * 1mb } elseif ($size.ToLower().EndsWith("gib")) { $size = [int64]($size.Substring(0, $size.Length - 3)) * 1gb } elseif ($size.ToLower().EndsWith("tib")) { $size = [int64]($size.Substring(0, $size.Length - 3)) * 1tb } elseif ($size.ToLower().EndsWith("pib")) { $size = [int64]($size.Substring(0, $size.Length - 3)) * 1pb } elseif ($size.ToLower().EndsWith("kb")) { $size = [int64]($size.Substring(0, $size.Length - 2)) * 1000 } elseif ($size.ToLower().EndsWith("mb")) { $size = [int64]($size.Substring(0, $size.Length - 2)) * 1000 * 1000 } elseif ($size.ToLower().EndsWith("gb")) { $size = [int64]($size.Substring(0, $size.Length - 2)) * 1000 * 1000 * 1000 } elseif ($size.ToLower().EndsWith("tb")) { $size = [int64]($size.Substring(0, $size.Length - 2)) * 1000 * 1000 * 1000 * 1000 } elseif ($size.ToLower().EndsWith("pb")) { $size = [int64]($size.Substring(0, $size.Length - 2)) * 1000 * 1000 * 1000 * 1000 * 1000 } elseif ($size.ToLower().EndsWith("b")) { $size = [int64]($size.Substring(0, $size.Length - 1)) } elseif ($size.ToLower().EndsWith("k")) { $size = [int64]($size.Substring(0, $size.Length - 1)) * 1kb } elseif ($size.ToLower().EndsWith("m")) { $size = [int64]($size.Substring(0, $size.Length - 1)) * 1mb } elseif ($size.ToLower().EndsWith("g")) { $size = [int64]($size.Substring(0, $size.Length - 1)) * 1gb } elseif ($size.ToLower().EndsWith("t")) { $size = [int64]($size.Substring(0, $size.Length - 1)) * 1tb } elseif ($size.ToLower().EndsWith("p")) { $size = [int64]($size.Substring(0, $size.Length - 1)) * 1pb } elseif (($size -match "^[0-9]*$") -and ([int64]$size -gt 1023)) { # # Because powershell converts 1kb to 1024, and we convert it to 1000, we # catch byte values greater than 1023 to be suspicious that caller might # not be aware of the silent conversion by powershell. If the caller # knows what she is doing, she can always append 'b' to the number. # fatal "Error suspicious byte value to convert_to_bytes" } return [Int64]$size } # # truncate -- shrink or extend a file to the specified size # # A file that does not exist is created (holey). # # XXX: Modify/rename 'sparsefile' to make it work as Linux 'truncate'. # Then, this cmdlet is not needed anymore. # function truncate { [CmdletBinding(PositionalBinding=$true)] Param( [alias("s")][Parameter(Mandatory = $true)][string]$size, [Parameter(Mandatory = $true)][string]$fname ) [int64]$size_in_bytes = (convert_to_bytes $size) if (-Not (Test-Path $fname)) { & $SPARSEFILE -vsl $size_in_bytes $fname 2>&1 1>> $Env:PREP_LOG_FILE if ($Global:LASTEXITCODE -ne 0) { fatal "Error $Global:LASTEXITCODE with sparsefile create" } } else { $file = new-object System.IO.FileStream $fname, Open, ReadWrite $file.SetLength($size_in_bytes) $file.Close() } } # # create_file -- create zeroed out files of a given length # # example, to create two files, each 1GB in size: # create_file 1G testfile1 testfile2 # # Note: this literally fills the file with 0's to make sure its # not a sparse file. Its slow but the fastest method I could find # # Input unit size is in bytes with optional suffixes like k, KB, M, etc. # function create_file { [int64]$size = (convert_to_bytes $args[0]) for ($i=1;$i -lt $args.count;$i++) { $stream = new-object system.IO.StreamWriter($args[$i], "False", [System.Text.Encoding]::Ascii) 1..$size | %{ $stream.Write("0") } $stream.close() Get-ChildItem $args[$i]* >> $Env:PREP_LOG_FILE } } # # create_holey_file -- create holey files of a given length # # example: # create_holey_file 1024k testfile1 testfile2 # create_holey_file 2048M testfile1 testfile2 # create_holey_file 234 testfile1 # create_holey_file 2340b testfile1 # # Input unit size is in bytes with optional suffixes like k, KB, M, etc. # function create_holey_file { [int64]$size = (convert_to_bytes $args[0]) for ($i=1;$i -lt $args.count;$i++) { # need to call out to sparsefile.exe to create a sparse file, note # that initial version of DAX doesn't support sparse $fname = $args[$i] & $SPARSEFILE -nsl $size $fname if ($Global:LASTEXITCODE -ne 0) { fatal "Error $Global:LASTEXITCODE with sparsefile create" } Get-ChildItem $fname >> $Env:PREP_LOG_FILE } } # # create_nonzeroed_file -- create non-zeroed files of a given length # # A given first kilobytes of the file is zeroed out. # # example, to create two files, each 1GB in size, with first 4K zeroed # create_nonzeroed_file 1G 4K testfile1 testfile2 # # Note: from 0 to offset is sparse, after that filled with Z # # Input unit size is in bytes with optional suffixes like k, KB, M, etc. # function create_nonzeroed_file { [int64]$offset = (convert_to_bytes $args[1]) [int64]$size = ((convert_to_bytes $args[0]) - $offset) [int64]$numz = $size / 1024 [string] $z = "Z" * 1024 # using a 1K string to speed up writing for ($i=2;$i -lt $args.count;$i++) { # create sparse file of offset length $file = new-object System.IO.FileStream $args[$i], Create, ReadWrite $file.SetLength($offset) $file.Close() Get-ChildItem $args[$i] >> $Env:PREP_LOG_FILE $stream = new-object system.IO.StreamWriter($args[$i], "True", [System.Text.Encoding]::Ascii) 1..$numz | %{ $stream.Write($Z) } $stream.close() Get-ChildItem $args[$i] >> $Env:PREP_LOG_FILE } } # # create_poolset -- create a dummy pool set # # Creates a pool set file using the provided list of part sizes and paths. # Optionally, it also creates the selected part files (zeroed, partially zeroed # or non-zeroed) with requested size and mode. The actual file size may be # different than the part size in the pool set file. # 'r' or 'R' on the list of arguments indicate the beginning of the next # replica set and 'm' or 'M' the beginning of the next remote replica set. # A remote replica requires two parameters: a target node and a pool set # descriptor. # # Each part argument has the following format: # psize:ppath[:cmd[:fsize[:mode]]] # # where: # psize - part size or AUTO (only for DAX device) # ppath - path # cmd - (optional) can be: # x - do nothing (may be skipped if there's no 'fsize', 'mode') # z - create zeroed (holey) file # n - create non-zeroed file # h - create non-zeroed file, but with zeroed header (first 4KB) # d - create empty directory # fsize - (optional) the actual size of the part file (if 'cmd' is not 'x') # mode - (optional) same format as for 'chmod' command # # Each remote replica argument has the following format: # node:desc # # where: # node - target node # desc - pool set descriptor # # example: # The following command define a pool set consisting of two parts: 16MB # and 32MB, a local replica with only one part of 48MB and a remote replica. # The first part file is not created, the second is zeroed. The only replica # part is non-zeroed. Also, the last file is read-only and its size # does not match the information from pool set file. The last line describes # a remote replica. # # create_poolset .\pool.set 16M:testfile1 32M:testfile2:z \ # R 48M:testfile3:n:11M:0400 \ # M remote_node:remote_pool.set # # function create_poolset { $psfile = $args[0] echo "PMEMPOOLSET" | out-file -encoding utf8 -literalpath $psfile for ($i=1;$i -lt $args.count;$i++) { if ($args[$i] -eq "M" -Or $args[$i] -eq 'm') { # remote replica $i++ $cmd = $args[$i] $fparms = ($cmd.Split("{:}")) $node = $fparms[0] $desc = $fparms[1] echo "REPLICA $node $desc" | out-file -Append -encoding utf8 -literalpath $psfile continue } if ($args[$i] -eq "R" -Or $args[$i] -eq 'r') { echo "REPLICA" | out-file -Append -encoding utf8 -literalpath $psfile continue } if ($args[$i] -eq "O" -Or $args[$i] -eq 'o') { $i++ $opt = $args[$i] echo "OPTION $opt" | out-file -Append -encoding utf8 -literalpath $psfile continue } $cmd = $args[$i] # need to strip out a drive letter if included because we use : # as a delimiter in the argument $driveLetter = "" if ($cmd -match ":([a-zA-Z]):\\") { # for path names in the following format: "C:\foo\bar" $tmp = ($cmd.Split("{:\\}",2,[System.StringSplitOptions]::RemoveEmptyEntries)) $cmd = $tmp[0] + ":" + $tmp[1].SubString(2) $driveLetter = $tmp[1].SubString(0,2) } elseif ($cmd -match ":\\\\\?\\([a-zA-Z]):\\") { # for _long_ path names in the following format: "\\?\C:\foo\bar" $tmp = ($cmd.Split("{:}",2,[System.StringSplitOptions]::RemoveEmptyEntries)) $cmd = $tmp[0] + ":" + $tmp[1].SubString(6) $driveLetter = $tmp[1].SubString(0,6) } $fparms = ($cmd.Split("{:}")) $fsize = $fparms[0] # XXX: unclear how to follow a symlink # like linux "fpath=`readlink -mn ${fparms[1]}`" but I've not tested # that it works with a symlink or shortcut $fpath = $fparms[1] if (-Not $driveLetter -eq "") { $fpath = $driveLetter + $fpath } $cmd = $fparms[2] $asize = $fparms[3] $mode = $fparms[4] if (-not $asize) { $asize = $fsize } switch -regex ($cmd) { # do nothing 'x' { } # zeroed (holey) file 'z' { create_holey_file $asize $fpath } # non-zeroed file 'n' { create_file $asize $fpath } # non-zeroed file, except 4K header 'h' { create_nonzeroed_file $asize 4K $fpath } # create empty directory 'd' { new-item $fpath -force -itemtype directory >> $Env:PREP_LOG_FILE } } # XXX: didn't convert chmod # if [ $mode ]; then # chmod $mode $fpath # fi echo "$fsize $fpath" | out-file -Append -encoding utf8 -literalpath $psfile } # for args } # # dump_last_n_lines -- dumps the last N lines of given log file to stdout # function dump_last_n_lines { if ($Args[0] -And (Test-Path $Args[0])) { sv -Name fname ((Get-Location).path + "\" + $Args[0]) sv -Name ln (getLineCount $fname) if ($ln -gt $UT_DUMP_LINES) { $ln = $UT_DUMP_LINES msg "Last $UT_DUMP_LINES lines of $fname below (whole file has $ln lines)." } else { msg "$fname below." } foreach ($line in Get-Content $fname -Tail $ln) { msg $line } } } # # check_exit_code -- check if $LASTEXITCODE is equal 0 # function check_exit_code { if ($Global:LASTEXITCODE -ne 0) { sv -Name msg "failed with exit code $Global:LASTEXITCODE" if (Test-Path $Env:ERR_LOG_FILE) { if ($Env:UNITTEST_LOG_LEVEL -ge "1") { echo "${Env:UNITTEST_NAME}: $msg. $Env:ERR_LOG_FILE" >> $Env:ERR_LOG_FILE } else { Write-Error "${Env:UNITTEST_NAME}: $msg. $Env:ERR_LOG_FILE" } } else { Write-Error "${Env:UNITTEST_NAME}: $msg" } dump_last_n_lines $Env:PREP_LOG_FLE dump_last_n_lines $Env:TRACE_LOG_FILE dump_last_n_lines $Env:PMEM_LOG_FILE dump_last_n_lines $Env:PMEMOBJ_LOG_FILE dump_last_n_lines $Env:PMEMLOG_LOG_FILE dump_last_n_lines $Env:PMEMBLK_LOG_FILE dump_last_n_lines $Env:PMEMPOOL_LOG_FILE fail "" } } # # expect_normal_exit -- run a given command, expect it to exit 0 # function expect_normal_exit { #XXX: bash sets up LD_PRELOAD and other gcc options here # that we can't do, investigating how to address API hooking... sv -Name command $args[0] $params = New-Object System.Collections.ArrayList foreach ($param in $Args[1 .. $Args.Count]) { if ($param -is [array]) { foreach ($param_entry in $param) { [string]$params += -join(" '", $param_entry, "' ") } } else { [string]$params += -join(" '", $param, "' ") } } # Set $LASTEXITCODE to the value indicating failure. It should be # overwritten with the exit status of the invoked command. # It is to catch the case when the command is not executed (i.e. because # of missing binaries / wrong path / etc.) and $LASTEXITCODE contains the # status of some other command executed before. $Global:LASTEXITCODE = 1 Invoke-Expression "$command $params" check_exit_code } # # expect_abnormal_exit -- run a given command, expect it to exit non-zero # function expect_abnormal_exit { #XXX: bash sets up LD_PRELOAD and other gcc options here # that we can't do, investigating how to address API hooking... sv -Name command $args[0] $params = New-Object System.Collections.ArrayList foreach ($param in $Args[1 .. $Args.Count]) { if ($param -is [array]) { foreach ($param_entry in $param) { [string]$params += -join(" '", $param_entry, "' ") } } else { [string]$params += -join(" '", $param, "' ") } } # Suppress abort window $prev_abort = $Env:PMDK_NO_ABORT_MSG $Env:PMDK_NO_ABORT_MSG = 1 # Set $LASTEXITCODE to the value indicating success. It should be # overwritten with the exit status of the invoked command. # It is to catch the case when the command is not executed (i.e. because # of missing binaries / wrong path / etc.) and $LASTEXITCODE contains the # status of some other command executed before. $Global:LASTEXITCODE = 0 Invoke-Expression "$command $params" $Env:PMDK_NO_ABORT_MSG = $prev_abort if ($Global:LASTEXITCODE -eq 0) { fail "${Env:UNITTEST_NAME}: command succeeded unexpectedly." } } # # check_pool -- run pmempool check on specified pool file # function check_pool { $file = $Args[0] if ($Env:CHECK_POOL -eq "1") { Write-Verbose "$Env:UNITTEST_NAME: checking consistency of pool $file" Invoke-Expression "$PMEMPOOL check $file 2>&1 1>>$Env:CHECK_POOL_LOG_FILE" if ($Global:LASTEXITCODE -ne 0) { fail "error: $PMEMPOOL returned error code ${Global:LASTEXITCODE}" } } } # # check_pools -- run pmempool check on specified pool files # function check_pools { if ($Env:CHECK_POOL -eq "1") { foreach ($arg in $Args[0 .. $Args.Count]) { check_pool $arg } } } # # require_unlimited_vm -- require unlimited virtual memory # # This implies requirements for: # - overcommit_memory enabled (/proc/sys/vm/overcommit_memory is 0 or 1) # - unlimited virtual memory (ulimit -v is unlimited) # function require_unlimited_vm { msg "${Env:UNITTEST_NAME}: SKIP required: overcommit_memory enabled and unlimited virtual memory" exit 0 } # # require_no_superuser -- require user without superuser rights # # XXX: not sure how to translate # function require_no_superuser { msg "${Env:UNITTEST_NAME}: SKIP required: run without superuser rights" exit 0 } # # require_test_type -- only allow script to continue for a certain test type # function require_test_type() { sv -Name req_test_type 1 -Scope Global if ($Env:TYPE -eq 'all') { return } for ($i=0;$i -lt $args.count;$i++) { if ($args[$i] -eq $Env:TYPE) { return } switch ($Env:TYPE) { 'check' { # "check" is a synonym of "short + medium" if ($args[$i] -eq 'short' -Or $args[$i] -eq 'medium') { return } } default { if ($args[$i] -eq $Env:TYPE) { return } } } verbose_msg "${Env:UNITTEST_NAME}: SKIP test-type $Env:TYPE ($* required)" exit 0 } } # # require_build_type -- only allow script to continue for a certain build type # function require_build_type { for ($i=0;$i -lt $args.count;$i++) { if ($args[$i] -eq $Env:BUILD) { return } } verbose_msg "${Env:UNITTEST_NAME}: SKIP build-type $Env:BUILD ($* required)" exit 0 } # # require_pkg -- only allow script to continue if specified package exists # function require_pkg { # XXX: placeholder for checking dependencies if we have a need } # # require_binary -- continue script execution only if the binary has been compiled # # In case of conditional compilation, skip this test. # function require_binary() { # XXX: check if binary provided if (-Not (Test-Path $Args[0])) { msg "${Env:UNITTEST_NAME}: SKIP no binary found" exit 0 } } # # match -- execute match # function match { Invoke-Expression "perl ..\..\..\src\test\match $args" if ($Global:LASTEXITCODE -ne 0) { fail "" } } # # check -- check test results (using .match files) # # note: win32 version slightly different since the caller can't as # easily bail when a cmd fails # function check { # ..\match $(find . -regex "[^0-9]*${UNITTEST_NUM}\.log\.match" | xargs) $perl = Get-Command -Name perl -ErrorAction SilentlyContinue If ($perl -eq $null) { fail "error: Perl is missing, cannot check test results" } # If errX.log.match does not exist, assume errX.log should be empty $ERR_LOG_LEN=0 if (Test-Path $Env:ERR_LOG_FILE) { $ERR_LOG_LEN = (Get-Item $Env:ERR_LOG_FILE).length } if (-not (Test-Path "${Env:ERR_LOG_FILE}.match") -and ($ERR_LOG_LEN -ne 0)) { Write-Error "unexpected output in ${Env:ERR_LOG_FILE}" dump_last_n_lines $Env:ERR_LOG_FILE fail "" } [string]$listing = Get-ChildItem -File | Where-Object {$_.Name -match "[^0-9]${Env:UNITTEST_NUM}.log.match"} if ($listing) { match $listing } # Move logs to build folder $LOGS_DIR="logs\$Env:TYPE\$Global:REAL_FS\$Env:BUILD" If(!(test-path $LOGS_DIR)) { [void](New-Item -path $LOGS_DIR -ItemType Directory) } foreach ($f in $(get_files "[a-zA-Z_]*${Env:UNITTEST_NUM}\.log$")) { Move-Item $f $LOGS_DIR\$f -force } } # # pass -- print message that the test has passed # function pass { if ($Env:TM -eq 1) { $end_time = $script:tm.Elapsed.ToString('ddd\:hh\:mm\:ss\.fff') -Replace "^(000:)","" -Replace "^(00:){1,2}","" $script:tm.reset() } else { sv -Name end_time $null } if ($Env:UNITTEST_LOG_LEVEL -ge "1") { Write-Host -NoNewline ($Env:UNITTEST_NAME + ": ") Write-Host -NoNewline -foregroundcolor green "PASS" if ($end_time) { Write-Host -NoNewline ("`t`t`t" + "[" + $end_time + " s]") } } if ($Env:FS -ne "none") { if (isDir $DIR) { rm -Force -Recurse $DIR } } msg "" } # # fail -- print message that the test has failed # function fail { Write-Error $args[0] Write-Host -NoNewline ($Env:UNITTEST_NAME + ": ") Write-Host -NoNewLine -foregroundcolor red "FAILED" throw "${Env:UNITTEST_NAME}: FAILED" } # # remove_files - removes list of files included in variable # function remove_files { for ($i=0;$i -lt $args.count;$i++) { $arr = $args[$i] -split ' ' ForEach ($file In $arr) { Remove-Item $file -Force -ea si } } } # # check_file -- check if file exists and print error message if not # function check_file { sv -Name fname $Args[0] if (-Not (Test-Path $fname)) { fail "error: Missing File: $fname" } } # # check_files -- check if files exist and print error message if not # function check_files { for ($i=0;$i -lt $args.count;$i++) { check_file $args[$i] } } # # check_no_file -- check if file has been deleted and print error message if not # function check_no_file { sv -Name fname $Args[0] if (Test-Path $fname) { fail "error: Not deleted file: $fname" } } # # check_no_files -- check if files has been deleted and print error message if not # function check_no_files { for ($i=0;$i -lt $args.count;$i++) { check_no_file $args[$i] } } # # get_size -- return size of file # function get_size { if (Test-Path $args[0]) { return (Get-Item $args[0]).length } } # # set_file_mode - set access mode to one or multiple files # parameters: # arg0 - access mode you want to change # arg1 - true or false to admit or deny given mode # # example: # set_file_mode IsReadOnly $true file1 file2 # function set_file_mode { $mode = $args[0] $flag = $args[1] for ($i=2;$i -lt $args.count;$i++) { Set-ItemProperty $args[$i] -name $mode -value $flag } } # # get_mode -- return mode of file # function get_mode { if (Test-Path $args[0]) { return (Get-Item $args[0]).mode } } # # check_size -- validate file size # function check_size { sv -Name size -Scope "Local" $args[0] sv -Name file -Scope "Local" $args[1] sv -Name file_size -Scope "Local" (get_size $file) if ($file_size -ne $size) { fail "error: wrong size $file_size != $size" } } # # check_mode -- validate file mode # function check_mode { sv -Name mode -Scope "Local" $args[0] sv -Name file -Scope "Local" $args[1] $mode = [math]::floor($mode / 100) # get first digit (user/owner permission) $read_only = (gp $file IsReadOnly).IsReadOnly if ($mode -band 2) { if ($read_only -eq $true) { fail "error: wrong file mode" } else { return } } if ($read_only -eq $false) { fail "error: wrong file mode" } else { return } } # # check_signature -- check if file contains specified signature # function check_signature { sv -Name sig -Scope "Local" $args[0] sv -Name file -Scope "Local" ($args[1]) sv -Name file_sig -Scope "Local" "" $stream = [System.IO.File]::OpenRead($file) $buff = New-Object Byte[] $SIG_LEN # you must assign return value otherwise PS will print it to stdout $num = $stream.Read($buff, 0, $SIG_LEN) $file_sig = [System.Text.Encoding]::Ascii.GetString($buff) $stream.Close() if ($file_sig -ne $sig) { fail "error: $file signature doesn't match $file_sig != $sig" } } # # check_signatures -- check if multiple files contain specified signature # function check_signatures { for ($i=1;$i -lt $args.count;$i+=1) { check_signature $args[0] $args[$i] } } # # check_layout -- check if pmemobj pool contains specified layout # function check_layout { sv -Name layout -Scope "Local" $args[0] sv -Name file -Scope "Local" ($args[1]) $stream = [System.IO.File]::OpenRead($file) $stream.Position = $LAYOUT_OFFSET $buff = New-Object Byte[] $LAYOUT_LEN # you must assign return value otherwise PS will print it to stdout $num = $stream.Read($buff, 0, $LAYOUT_LEN) $enc = [System.Text.Encoding]::UTF8.GetString($buff) $stream.Close() if ($enc -ne $layout) { fail "error: layout doesn't match $enc != $layout" } } # # check_arena -- check if file contains specified arena signature # function check_arena { sv -Name file -Scope "Local" ($args[0]) $stream = [System.IO.File]::OpenRead($file) $stream.Position = $ARENA_OFF $buff = New-Object Byte[] $ARENA_SIG_LEN # you must assign return value otherwise PS will print it to stdout $num = $stream.Read($buff, 0, $ARENA_SIG_LEN) $enc = [System.Text.Encoding]::ASCII.GetString($buff) $stream.Close() if ($enc -ne $ARENA_SIG) { fail "error: can't find arena signature" } } # # dump_pool_info -- dump selected pool metadata and/or user data # function dump_pool_info { $params = "" for ($i=0;$i -lt $args.count;$i++) { [string]$params += -join($args[$i], " ") } # ignore selected header fields that differ by definition # this is equivalent of: 'sed -e "/^UUID/,/^Checksum/d"' $print = $True Invoke-Expression "$PMEMPOOL info $params" | % { If ($_ -match '^UUID') { $print = $False } If ($print -eq $True) { $_ } If ($_ -match '^Checksum') { $print = $True } } } # # dump_replica_info -- dump selected pool metadata and/or user data # # Used by compare_replicas() - filters out file paths and sizes. # function dump_replica_info { $params = "" for ($i=0;$i -lt $args.count;$i++) { [string]$params += -join($args[$i], " ") } # ignore selected header fields that differ by definition # this is equivalent of: 'sed -e "/^UUID/,/^Checksum/d"' $print = $True Invoke-Expression "$PMEMPOOL info $params" | % { If ($_ -match '^UUID') { $print = $False } If ($print -eq $True) { # 'sed -e "/^path/d" -e "/^size/d" If (-not ($_ -match '^path' -or $_ -match '^size')) { $_ } } If ($_ -match '^Checksum') { $print = $True } } } # # compare_replicas -- check replicas consistency by comparing `pmempool info` output # function compare_replicas { $count = $args foreach ($param in $Args[0 .. ($Args.Count - 3)]) { if ($param -is [array]) { foreach ($param_entry in $param) { [string]$params += -join(" '", $param_entry, "' ") } } else { [string]$params += -join($param, " ") } } $rep1 = $args[$cnt + 1] $rep2 = $args[$cnt + 2] diff (dump_replica_info $params $rep1) (dump_replica_info $params $rep2) } # # require_fs_type -- only allow script to continue for a certain fs type # function require_fs_type { $Global:req_fs_type = 1 for ($i = 0; $i -lt $args.count; $i++) { $type = $args[$i] # treat 'any' as either 'pmem' or 'non-pmem' if (($type -eq $Env:FS) -or (($type -eq "any") -and ($Env:FS -ne "none") -and $Env:FORCE_FS -eq 1)) { return; } } verbose_msg "${Env:UNITTEST_NAME}: SKIP fs-type $Env:FS (not configured)" exit 0 } # # require_dax_devices -- only allow script to continue for a dax device # function require_dax_devices() { # XXX: no device dax on Windows msg "${Env:UNITTEST_NAME}: SKIP DEVICE_DAX_PATH does not specify enough dax devices" exit 0 } function dax_device_zero() { # XXX: no device dax on Windows } # # require_no_unicode -- require $DIR w/o non-ASCII characters # function require_no_unicode { $Env:SUFFIX = "" $u = [System.Text.Encoding]::UNICODE [string]$DIR_ASCII = [System.Text.Encoding]::Convert([System.Text.Encoding]::UNICODE, [System.Text.Encoding]::ASCII, $u.getbytes($DIR)) [string]$DIR_UTF8 = [System.Text.Encoding]::Convert([System.Text.Encoding]::UNICODE, [System.Text.Encoding]::UTF8, $u.getbytes($DIR)) if ($DIR_UTF8 -ne $DIR_ASCII) { msg "${Env:UNITTEST_NAME}: SKIP required: test directory path without non-ASCII characters" exit 0 } } # # require_short_path -- require $DIR length less than 256 characters # function require_short_path { $Env:DIRSUFFIX = "" if ($DIR.Length -ge 256) { msg "${Env:UNITTEST_NAME}: SKIP required: test directory path below 256 characters" exit 0 } } # # get_files -- returns all files in cwd with given pattern # function get_files { dir |% {$_.Name} | select-string -Pattern $args[0] } # # setup -- print message that test setup is commencing # function setup { $curtestdir = (Get-Item -Path ".\").BaseName # just in case if (-Not $curtestdir) { fatal "curtestdir does not exist" } $curtestdir = "test_" + $curtestdir $Script:DIR = $DIR + "\" + $Env:DIRSUFFIX + "\" + $curtestdir + $Env:UNITTEST_NUM + $Env:SUFFIX # test type must be explicitly specified if ($req_test_type -ne "1") { fatal "error: required test type is not specified" } # fs type "none" must be explicitly enabled if ($Env:FS -eq "none" -and $Global:req_fs_type -ne "1") { exit 0 } # fs type "any" must be explicitly enabled if ($Env:FS -eq "any" -and $Global:req_fs_type -ne "1") { exit 0 } msg "${Env:UNITTEST_NAME}: SETUP ($Env:TYPE\$Global:REAL_FS\$Env:BUILD)" foreach ($f in $(get_files "[a-zA-Z_]*${Env:UNITTEST_NUM}\.log$")) { Remove-Item $f } rm -Force check_pool_${Env:BUILD}_${Env:UNITTEST_NUM}.log -ErrorAction SilentlyContinue if ($Env:FS -ne "none") { if (isDir $DIR) { rm -Force -Recurse $DIR } md -force $DIR > $null } # XXX: do it before setup() is invoked # set console encoding to UTF-8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 if ($Env:TM -eq "1" ) { $script:tm = [system.diagnostics.stopwatch]::startNew() } $DEBUG_DIR = '..\..\x64\Debug' $RELEASE_DIR = '..\..\x64\Release' if ($Env:BUILD -eq 'nondebug') { if (-Not $Env:PMDK_LIB_PATH_NONDEBUG) { $Env:PMDK_LIB_PATH_NONDEBUG = $RELEASE_DIR + '\libs\' } $Env:Path = $Env:PMDK_LIB_PATH_NONDEBUG + ';' + $Env:Path } elseif ($Env:BUILD -eq 'debug') { if (-Not $Env:PMDK_LIB_PATH_DEBUG) { $Env:PMDK_LIB_PATH_DEBUG = $DEBUG_DIR + '\libs\' } $Env:Path = $Env:PMDK_LIB_PATH_DEBUG + ';' + $Env:Path } $Env:PMEMBLK_CONF="fallocate.at_create=0;" $Env:PMEMOBJ_CONF="fallocate.at_create=0;" $Env:PMEMLOG_CONF="fallocate.at_create=0;" } # # cmp -- compare two files # function cmp { $file1 = $Args[0] $file2 = $Args[1] $argc = $Args.Count if($argc -le 2) { # fc does not support / in file path fc.exe /b ([String]$file1).Replace('/','\') ([string]$file2).Replace('/','\') > $null if ($Global:LASTEXITCODE -ne 0) { "$args differ" } return } $limit = $Args[2] $s1 = Get-Content $file1 -totalcount $limit -encoding byte $s2 = Get-Content $file1 -totalcount $limit -encoding byte if ("$s1" -ne "$s2") { "$args differ" } } ####################################################### ####################################################### if (-Not $Env:UNITTEST_NAME) { $CURDIR = (Get-Item -Path ".\").BaseName $SCRIPTNAME = (Get-Item $MyInvocation.ScriptName).BaseName $Env:UNITTEST_NAME = "$CURDIR/$SCRIPTNAME" $Env:UNITTEST_NUM = ($SCRIPTNAME).Replace("TEST", "") } # defaults if (-Not $Env:TYPE) { $Env:TYPE = 'check'} if (-Not $Env:FS) { $Env:FS = 'any'} if (-Not $Env:BUILD) { $Env:BUILD = 'debug'} if (-Not $Env:CHECK_POOL) { $Env:CHECK_POOL = '0'} if (-Not $Env:EXESUFFIX) { $Env:EXESUFFIX = ".exe"} if (-Not $Env:SUFFIX) { $Env:SUFFIX = "😘⠏⠍⠙⠅ɗPMDKӜ⥺🙋"} if (-Not $Env:DIRSUFFIX) { $Env:DIRSUFFIX = ""} if ($Env:BUILD -eq 'nondebug') { if (-Not $Env:PMDK_LIB_PATH_NONDEBUG) { $PMEMPOOL = $RELEASE_DIR + "\libs\pmempool$Env:EXESUFFIX" } else { $PMEMPOOL = "$Env:PMDK_LIB_PATH_NONDEBUG\pmempool$Env:EXESUFFIX" } } elseif ($Env:BUILD -eq 'debug') { if (-Not $Env:PMDK_LIB_PATH_DEBUG) { $PMEMPOOL = $DEBUG_DIR + "\libs\pmempool$Env:EXESUFFIX" } else { $PMEMPOOL = "$Env:PMDK_LIB_PATH_DEBUG\pmempool$Env:EXESUFFIX" } } $PMEMSPOIL="$Env:EXE_DIR\pmemspoil$Env:EXESUFFIX" $PMEMWRITE="$Env:EXE_DIR\pmemwrite$Env:EXESUFFIX" $PMEMALLOC="$Env:EXE_DIR\pmemalloc$Env:EXESUFFIX" $PMEMOBJCLI="$Env:EXE_DIR\pmemobjcli$Env:EXESUFFIX" $DDMAP="$Env:EXE_DIR\ddmap$Env:EXESUFFIX" $BTTCREATE="$Env:EXE_DIR\bttcreate$Env:EXESUFFIX" $SPARSEFILE="$Env:EXE_DIR\sparsefile$Env:EXESUFFIX" $DLLVIEW="$Env:EXE_DIR\dllview$Env:EXESUFFIX" $Global:req_fs_type=0 # # The variable DIR is constructed so the test uses that directory when # constructing test files. DIR is chosen based on the fs-type for # this test, and if the appropriate fs-type doesn't have a directory # defined in testconfig.sh, the test is skipped. if (-Not $Env:UNITTEST_NUM) { fatal "UNITTEST_NUM does not have a value" } if (-Not $Env:UNITTEST_NAME) { fatal "UNITTEST_NAME does not have a value" } $Global:REAL_FS = $Env:FS # choose based on FS env variable switch ($Env:FS) { 'pmem' { # if a variable is set - it must point to a valid directory if (-Not $Env:PMEM_FS_DIR) { fatal "${Env:UNITTEST_NAME}: PMEM_FS_DIR not set" } sv -Name DIR $Env:PMEM_FS_DIR if ($Env:PMEM_FS_DIR_FORCE_PMEM -eq "1") { $Env:PMEM_IS_PMEM_FORCE = "1" } } 'non-pmem' { # if a variable is set - it must point to a valid directory if (-Not $Env:NON_PMEM_FS_DIR) { fatal "${Env:UNITTEST_NAME}: NON_PMEM_FS_DIR not set" } sv -Name DIR $Env:NON_PMEM_FS_DIR } 'any' { if ($Env:PMEM_FS_DIR) { sv -Name DIR ($Env:PMEM_FS_DIR + $tail) $Global:REAL_FS='pmem' if ($Env:PMEM_FS_DIR_FORCE_PMEM -eq "1") { $Env:PMEM_IS_PMEM_FORCE = "1" } } ElseIf ($Env:NON_PMEM_FS_DIR) { sv -Name DIR $Env:NON_PMEM_FS_DIR $Global:REAL_FS='non-pmem' } Else { fatal "${Env:UNITTEST_NAME}: fs-type=any and both env vars are empty" } } 'none' { # don't add long path nor unicode sufix to DIR require_no_unicode require_short_path sv -Name DIR "\nul\not_existing_dir\" } default { fatal "${Env:UNITTEST_NAME}: SKIP fs-type $Env:FS (not configured)" } } # switch # Length of pool file's signature sv -Name SIG_LEN 8 # Offset and length of pmemobj layout sv -Name LAYOUT_OFFSET 4096 sv -Name LAYOUT_LEN 1024 # Length of arena's signature sv -Name ARENA_SIG_LEN 16 # Signature of BTT Arena sv -Name ARENA_SIG "BTT_ARENA_INFO" # Offset to first arena sv -Name ARENA_OFF 8192 # # The default is to turn on library logging to level 3 and save it to local files. # Tests that don't want it on, should override these environment variables. # $Env:PMEM_LOG_LEVEL = 3 $Env:PMEM_LOG_FILE = "pmem${Env:UNITTEST_NUM}.log" $Env:PMEMBLK_LOG_LEVEL=3 $Env:PMEMBLK_LOG_FILE = "pmemblk${Env:UNITTEST_NUM}.log" $Env:PMEMLOG_LOG_LEVEL = 3 $Env:PMEMLOG_LOG_FILE = "pmemlog${Env:UNITTEST_NUM}.log" $Env:PMEMOBJ_LOG_LEVEL = 3 $Env:PMEMOBJ_LOG_FILE= "pmemobj${Env:UNITTEST_NUM}.log" $Env:PMEMPOOL_LOG_LEVEL = 3 $Env:PMEMPOOL_LOG_FILE= "pmempool${Env:UNITTEST_NUM}.log" $Env:TRACE_LOG_FILE = "trace${Env:UNITTEST_NUM}.log" $Env:ERR_LOG_FILE = "err${Env:UNITTEST_NUM}.log" $Env:OUT_LOG_FILE = "out${Env:UNITTEST_NUM}.log" $Env:PREP_LOG_FILE = "prep${Env:UNITTEST_NUM}.log" if (-Not($UT_DUMP_LINES)) { sv -Name "UT_DUMP_LINES" 30 } $Env:CHECK_POOL_LOG_FILE = "check_pool_${Env:BUILD}_${Env:UNITTEST_NUM}.log" # # enable_log_append -- turn on appending to the log files rather than truncating them # It also removes all log files created by tests: out*.log, err*.log and trace*.log # function enable_log_append() { rm -Force -ErrorAction SilentlyContinue $Env:OUT_LOG_FILE rm -Force -ErrorAction SilentlyContinue $Env:ERR_LOG_FILE rm -Force -ErrorAction SilentlyContinue $Env:TRACE_LOG_FILE rm -Force -ErrorAction SilentlyContinue $Env:PREP_LOG_FILE $Env:UNITTEST_LOG_APPEND=1 } # # require_free_space -- check if there is enough free space to run the test # Example, checking if there is 1 GB of free space on disk: # require_free_space 1G # function require_free_space() { $req_free_space = (convert_to_bytes $args[0]) # actually require 5% or 8MB (whichever is higher) more, just in case # file system requires some space for its meta data $pct = 5 * $req_free_space / 100 $abs = (convert_to_bytes 8M) if ($pct -gt $abs) { $req_free_space = $req_free_space + $pct } else { $req_free_space = $req_free_space + $abs } $path = $DIR -replace '\\\\\?\\', '' $device_name = (Get-Item $path).PSDrive.Root $filter = "Name='$($device_name -replace '\\', '\\')'" $free_space = (gwmi Win32_Volume -Filter $filter | select FreeSpace).freespace if ([INT64]$free_space -lt [INT64]$req_free_space) { msg "${Env:UNITTEST_NAME}: SKIP not enough free space ($args required)" exit 0 } } # # require_free_physical_memory -- check if there is enough free physical memory # space to run the test # Example, checking if there is 1 GB of free physical memory space: # require_free_physical_memory 1G # function require_free_physical_memory() { $req_free_physical_memory = (convert_to_bytes $args[0]) $free_physical_memory = (Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty FreePhysicalMemory) * 1024 if ($free_physical_memory -lt $req_free_physical_memory) { msg "${Env:UNITTEST_NAME}: SKIP not enough free physical memory ($args required, free: $free_physical_memory B)" exit 0 } } # # require_automatic_managed_pagefile -- check if system manages the page file size # function require_automatic_managed_pagefile() { $c = Get-WmiObject Win32_computersystem -EnableAllPrivileges if($c.AutomaticManagedPagefile -eq $false) { msg "${Env:UNITTEST_NAME}: SKIP automatic page file management is disabled" exit 0 } } pmdk-1.11.1/src/test/unittest/configurator.py0000664000000000000000000002563614123364546017753 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Parser for user provided test configuration""" import argparse import os import string import sys from datetime import timedelta import builds import context as ctx import granularity import futils import test_types import valgrind as vg try: import testconfig except ImportError: sys.exit('Please add valid testconfig.py file - see testconfig.py.example') class _ConfigFromDict: """ Class fields are created from provided dictionary. Used for creating a final config object. """ def __init__(self, dict_): for k, v in dict_.items(): setattr(self, k, v) # special method triggered if class attribute was not found # https://docs.python.org/3.5/reference/datamodel.html#object.__getattr__ def __getattr__(self, name): if name == 'page_fs_dir': raise futils.Skip('Configuration field "{}" not found. ' 'No page granularity test directory ' 'provided'.format(name)) if name == 'cacheline_fs_dir': raise futils.Skip('Configuration field "{}" not found. ' 'No cache line granularity test ' 'directory provided'.format(name)) if name == 'byte_fs_dir': raise futils.Skip('Configuration field "{}" not found. ' 'No byte granularity test directory ' 'provided'.format(name)) raise AttributeError('Provided test configuration may be ' 'invalid. No "{}" field found in ' 'configuration.' .format(name)) def _str2list(config): """ Convert the string with test sequence to equivalent list. example: _str2list("0-3,6") --> [0, 1, 2, 3, 6] _str2list("1,3-5") --> [1, 3, 4, 5] """ arg = config['test_sequence'] if not arg: # test_sequence not set, do nothing return seq = [] try: for number in arg.split(','): if '-' in number: number = number.split('-') begin = int(number[0]) end = int(number[1]) step = 1 if begin < end else -1 seq.extend(range(begin, end + step, step)) else: seq.append(int(number)) except (ValueError, IndexError): print('Provided test sequence "{}" is invalid'.format(arg)) raise config['test_sequence'] = seq def _str2time(config): """ Convert the string with s, m, h, d suffixes to time format example: _str2time("5s") --> "0:00:05" _str2time("15m") --> "0:15:00" """ string_ = config['timeout'] try: timeout = int(string_[:-1]) except ValueError as e: raise ValueError("invalid timeout argument: {}".format(string_)) from e else: if "d" in string_: timeout = timedelta(days=timeout) elif "m" in string_: timeout = timedelta(minutes=timeout) elif "h" in string_: timeout = timedelta(hours=timeout) elif "s" in string_: timeout = timedelta(seconds=timeout) config['timeout'] = timeout.total_seconds() def _str2ctx(config): """Convert context classes from strings to actual classes""" def class_from_string(name, base): if name == 'all': return base.__subclasses__() try: return next(b for b in base.__subclasses__() if str(b) == name.lower()) except StopIteration: print('Invalid config value: "{}".'.format(name)) raise def convert_internal(key, base): if not isinstance(config[key], list): config[key] = ctx.expand(class_from_string(config[key], base)) else: classes = [class_from_string(cl, base) for cl in config[key]] config[key] = ctx.expand(*classes) convert_internal('build', builds.Build) convert_internal('test_type', test_types._TestType) convert_internal('granularity', granularity.Granularity) if config['force_enable'] is not None: config['force_enable'] = next( t for t in vg.TOOLS if t.name.lower() == config['force_enable']) class Configurator(): """Parser for user test configuration. Configuration is generated from two sources: testconfig.py file and main script (RUNTESTS.py or TESTS.py files) command line arguments. Since these sources cannot change during script execution, the configurator class can be initialized multiple times throughout the implementation and always returns the same configuration result. Values from testconfig.py are overridden by respective values from command line arguments - provided the latter occur. Attributes: config: final test configuration meant to be used by the user """ def __init__(self): self.config = self.parse_config() def parse_config(self): """ Parse and return test execution config object. Final config is composed from 2 config values - values from testconfig.py file and values provided by command line args. """ self.argparser = self._init_argparser() try: args_config = self._get_args_config() # The order of configs addition in 'config' initialization # is relevant - values from each next added config overwrite # values of already existing keys. config = {**testconfig.config, **args_config} self._convert_to_usable_types(config) # Remake dict into class object for convenient fields acquisition config = _ConfigFromDict(config) # device_dax_path may be either a single string with path # or a sequence of paths if sys.platform != 'win32': config.device_dax_path = futils.to_list(config.device_dax_path, str) return config except KeyError as e: print("No config field '{}' found. " "testconfig.py file may be invalid.".format(e.args[0])) raise def _convert_to_usable_types(self, config): """ Converts config values types as parsed from user input into types usable by framework implementation """ _str2ctx(config) _str2list(config) _str2time(config) def _get_args_config(self): """Return config values parsed from command line arguments""" # 'group' positional argument added only if RUNTESTS.py is the # execution entry point from_runtest = os.path.basename(sys.argv[0]) == 'RUNTESTS.py' if from_runtest: self.argparser.add_argument('group', nargs='*', help='Run only tests ' 'from selected groups') # remove possible whitespace and empty args sys.argv = [arg for arg in sys.argv if arg and not arg.isspace()] args = self.argparser.parse_args() if from_runtest: # test_sequence does not make sense if group is not set if args.test_sequence and not args.group: self.argparser.error('"--test_sequence" argument needs ' 'to have "group" arg set') # remove possible path characters added by shell hint args.group = [g.strip(string.punctuation) for g in args.group] # make into dict for type consistency return {k: v for k, v in vars(args).items() if v is not None} def _init_argparser(self): def ctx_choices(cls): return [str(c) for c in cls.__subclasses__()] parser = argparse.ArgumentParser() parser.add_argument('--fs_dir_force_pmem', type=int, help='set PMEM_IS_PMEM_FORCE for tests run on' ' pmem fs') parser.add_argument('-l', '--unittest_log_level', type=int, help='set log level. 0 - silent, 1 - normal, ' '2 - verbose') parser.add_argument('--keep_going', type=bool, help='continue execution despite test fails') parser.add_argument('-b', dest='build', help='run only specified build type', choices=ctx_choices(builds.Build), nargs='*') parser.add_argument('-g', dest='granularity', choices=ctx_choices(granularity.Granularity), nargs='*', help='run tests on a filesystem' ' with specified granularity types.') parser.add_argument('-t', dest='test_type', help='run only specified test type where ' 'check = short + medium', choices=ctx_choices(test_types._TestType), nargs='*') parser.add_argument('-o', dest='timeout', help="set timeout for test execution timeout: " "integer with an optional suffix:''s' for seconds," " 'm' for minutes, 'h' for hours or 'd' for days.") parser.add_argument('-u', dest='test_sequence', help='run only tests from specified test sequence ' 'e.g.: 0-2,5 will execute TEST0, ' 'TEST1, TEST2 and TEST5', default='') parser.add_argument('--list-testcases', dest='list_testcases', action='store_const', const=True, help='List testcases only') parser.add_argument('--fail-on-skip', dest='fail_on_skip', action='store_const', const=True, help='Skipping tests also fail') tracers = parser.add_mutually_exclusive_group() tracers.add_argument('--tracer', dest='tracer', help='run C binary ' 'with provided tracer command. With this option ' 'stdout and stderr are not redirected, enabling ' 'interactive sessions.', default='') tracers.add_argument('--gdb', dest='tracer', action='store_const', const='gdb --args', help='run gdb as a tracer') tracers.add_argument('--cgdb', dest='tracer', action='store_const', const='cgdb --args', help='run cgdb as a tracer') if sys.platform != 'win32': fe_choices = [str(t) for t in vg.TOOLS] parser.add_argument('--force-enable', choices=fe_choices, default=None) return parser pmdk-1.11.1/src/test/unittest/ut_pmemset_utils.c0000664000000000000000000000153614123364546020436 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * ut_pmemset_utils.c -- utility helper functions for libpmemset tests */ #include "unittest.h" #include "ut_pmemset_utils.h" /* * ut_pmemset_expect_return -- verifies error code and prints appropriate * error message in case of error */ void ut_pmemset_expect_return(const char *file, int line, const char *func, int value, int expected) { if (value != expected) { ut_fatal(file, line, func, "unexpected return code (got: %d, expected: %d): %s", value, expected, (value == 0 ? "success" : pmemset_errormsg())); } if (expected) { const char *msg = pmemset_errormsg(); if (!strlen(msg)) ut_fatal(file, line, func, "expected return value is %d, so " "error message should not be empty!", expected); } } pmdk-1.11.1/src/test/unittest/libut.vcxproj.filters0000664000000000000000000000302214123364546021063 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files pmdk-1.11.1/src/test/unittest/context.py0000664000000000000000000005335314123364546016732 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """ Set of classes that represent the context of single test execution as well as functions used for setting test requirements and adding test parameters. The test context is visible to the RUNTESTS main script as well as the test user as a Context class. The context class is constructed with use of 'elements' classes, that are affiliated with test requirements and test parameters. """ import os import shlex import sys import itertools import shutil import subprocess as sp import collections import contextlib from inspect import ismethod import configurator import futils from poolset import _Poolset from tools import Tools from consts import KiB, MiB, HEADER_SIZE try: import testconfig except ImportError: sys.exit('Please add valid testconfig.py file - see testconfig.py.example') config = testconfig.config try: import envconfig envconfig = envconfig.config except ImportError: # if file doesn't exist create dummy object envconfig = {'GLOBAL_LIB_PATH': '', 'PMEM2_AVX512F_ENABLED': ''} def expand(*classes): """Return flatten list of container classes with removed duplications""" return list(set(itertools.chain(*classes))) class ContextBase: """Context basic interface and low-level utilities Main context class responsibility is to manage context elements appended to it (such as Valgrind, filesystem type, etc.), which provide concrete contextualized behavior implementation. Attributes: _elems (list): list of context elements, such as Valgrind tool, filesystem type, etc. cmd_prefix (str): test execution command prefix - utilized by additional test execution tools, such as Valgrind. Defaults to an empty string. build (Build): test build """ def __init__(self, build, **elements): """ Args: build (Build): test execution build type **elements: context elements stored as ContextBase attributes named by keyword argument key. The element is therefore accessible from ContextBase class. Apart from that, below element class methods and attributes are handled (if present) by ContextBase class: env (dict): environment variables set by the element cmd (string): set to cmd_prefix setup, check, clean methods: called by corresponding ContextBase methods which are in turn called in Basetest._execute() """ self._elems = [] self._env = {} self.cmd_prefix = '' self.build = build # for keyword arguments, each kwarg value is set as a # context attribute with its key used as an attribute name. for k, v in elements.items(): self.add_ctx_elem(v) setattr(self, str(k), v) def __getattr__(self, name): """ If context class itself does not have an acquired attribute check if one of its elements has it and return it. """ elems_with_attr = [e for e in self._elems if hasattr(e, name)] # no context elements with requested attribute found if not elems_with_attr: raise AttributeError('Neither context nor any of its elements ' 'have the attribute "{}"'.format(name)) # all found elements have the same attribute value elif all(e == e for e in elems_with_attr): return getattr(elems_with_attr[0], name) # more than one element found and they have different attribute values else: raise AttributeError('Ambiguity while acquiring attribute "{}": ' 'implemented by multiple context elements ' 'with different values' .format(name)) def __str__(self): """ The Context string representation is a concatenation (separated by '/') of all its elements string representations. """ s = '{}/'.format(str(self.build)) for e in self._elems: if e: s = s + str(e) + '/' s = s[:-1] return s def add_ctx_elem(self, elem): """ Add element to the context. Update context environment variables with element's environment variables (if present) """ self._elems.append(elem) # if element has a 'name' attribute, it is accessible from Context # through it, otherwise its attribute name is generated # from its string representation if hasattr(elem, 'name'): setattr(self, elem.name, elem) else: setattr(self, str(elem), elem) if hasattr(elem, 'env'): self.add_env(elem.env) if hasattr(elem, 'cmd'): if self.cmd_prefix: raise ValueError('More than one context element ' 'defines command line prefix') else: self.cmd_prefix = elem.cmd def add_env(self, env): """Add environment variables to those stored by context""" futils.add_env_common(self._env, env) def setup(self, *args, **kwargs): """ run setup() method for each context element. Ignore error if not implemented """ kwargs['tools'] = self.tools for e in self._elems: with contextlib.suppress(AttributeError): e.setup(*args, **kwargs) def check(self, *args, **kwargs): """ run check() method for each context element. Ignore error if not implemented """ kwargs['tools'] = self.tools for e in self._elems: with contextlib.suppress(AttributeError): e.check(*args, **kwargs) def clean(self, *args, **kwargs): """ run clean() method for each context element. Ignore error if not implemented """ kwargs['tools'] = self.tools for e in self._elems: with contextlib.suppress(AttributeError): e.clean(*args, **kwargs) @property def env(self): """Get context environment variables""" return self._env @property def tools(self): """Get test tools""" return Tools(self.env, self.build) def dump_n_lines(self, file, n=-1): """ Prints last n lines of given log file. Number of lines printed can be modified locally by "n" argument or globally by "dump_lines" in testconfig.py file. If none of them are provided, default value is 30. """ if n < 0: n = config.get('dump_lines', 30) file_size = self.get_size(file.name) # if file is small enough, read it whole and find last n lines if file_size < 100 * MiB: lines = list(file) length = len(lines) if n > length: n = length lines = lines[-n:] lines.insert(0, 'Last {} lines of {} below ' '(whole file has {} lines):{}' .format(n, file.name, length, os.linesep)) for line in lines: print(line, end='') else: # if file is really big, read the last 10KiB and forget about lines with open(file.name, 'br') as byte_file: byte_file.seek(file_size - 10 * KiB) print(byte_file.read().decode('iso_8859_1')) def is_devdax(self, path): """Checks if given path points to device dax""" proc = self.tools.pmemdetect('-d', path) if proc.returncode == self.tools.PMEMDETECT_ERROR: futils.fail(proc.stdout) if proc.returncode == self.tools.PMEMDETECT_TRUE: return True if proc.returncode == self.tools.PMEMDETECT_FALSE: return False futils.fail('Unknown value {} returned by pmemdetect' .format(proc.returncode)) def supports_map_sync(self, path): """Checks if MAP_SYNC is supported on a filesystem from given path""" proc = self.tools.pmemdetect('-s', path) if proc.returncode == self.tools.PMEMDETECT_ERROR: futils.fail(proc.stdout) if proc.returncode == self.tools.PMEMDETECT_TRUE: return True if proc.returncode == self.tools.PMEMDETECT_FALSE: return False futils.fail('Unknown value {} returned by pmemdetect' .format(proc.returncode)) def get_size(self, path): """ Returns size of the file or dax device. Value "2**64 - 1" is checked because pmemdetect prints it in case of error. """ proc = self.tools.pmemdetect('-z', path) if int(proc.stdout) != 2**64 - 1: return int(proc.stdout) futils.fail('Could not get size of the file, ' 'it is inaccessible or does not exist') def get_free_space(self, dir="."): """Returns free space for current file system""" _, _, free = shutil.disk_usage(dir) return free class Context(ContextBase): """Manage test execution based on values from context classes""" def __init__(self, *args, **kwargs): self.conf = configurator.Configurator().config self.msg = futils.Message(self.conf.unittest_log_level) ContextBase.__init__(self, *args, **kwargs) def new_poolset(self, path): return _Poolset(path, self) def exec(self, cmd, *args, expected_exitcode=0, stderr_file=None, stdout_file=None): """ Execute binary in the current test context as a separate process. Execution takes place in test cwd and uses environment variables stored in Context 'env' attribute. Timeout for the execution is set based on the execution configuration. Args: cmd (str): command to be executed *args: Variable length command arguments list expected_exitcode (int): if process exit code differs from expected, Fail is thrown. Defaults to 0. Ignored if set to None. stderr_file (str): path to file in which stderr output is stored. Stored in a string if None. Defaults to None. stdout_file (str): path to file in which stdout output is stored. Stored in a string if None. Defaults to None. If neither stderr_file nor stdout_file are set, both outputs are merged into single stdout output and stored in a string. """ tmp = self._env.copy() futils.add_env_common(tmp, os.environ.copy()) # change cmd into list for supbrocess type compliance cmd = [cmd, ] if sys.platform == 'win32': cmd[0] = os.path.join(self.build.exedir, cmd[0]) + '.exe' else: cmd[0] = os.path.join(self.cwd, cmd[0]) + \ self.build.exesuffix if self.valgrind: cmd = self.valgrind.cmd + cmd # cast all provided args to strings (required by subprocess run()) # so that exec() can accept args of any printable type cmd.extend([str(a) for a in args]) if self.conf.tracer: cmd = shlex.split(self.conf.tracer) + cmd # process stdout and stderr are not redirected - this lets running # tracer command in an interactive session proc = sp.run(cmd, env=tmp, cwd=self.cwd) else: if stderr_file: f = open(os.path.join(self.cwd, stderr_file), 'w') # let's create a dictionary of arguments to the run func run_kwargs = { 'env': tmp, 'cwd': self.cwd, 'timeout': self.conf.timeout, 'stdout': sp.PIPE, 'universal_newlines': True, 'stderr': sp.STDOUT if stderr_file is None else f} proc = sp.run(cmd, **run_kwargs) if stderr_file: f.close() if expected_exitcode is not None and \ proc.returncode != expected_exitcode: futils.fail(proc.stdout, exit_code=proc.returncode) if stdout_file is not None: with open(os.path.join(self.cwd, stdout_file), 'w') as f: f.write(proc.stdout) self.msg.print_verbose(proc.stdout) def create_holey_file(self, size, path, mode=None): """ Create a new file in test testdir with the selected size and name. """ filepath = os.path.join(self.testdir, path) with open(filepath, 'w') as f: if size > 0: f.seek(size - 1) f.write('\0') if mode is not None: os.chmod(filepath, mode) return filepath def create_non_zero_file(self, size, path, mode=None): """ Create a new non-zeroed file in test testdir with the selected size and name. """ filepath = os.path.join(self.testdir, path) with open(filepath, 'w') as f: f.write('\132' * size) if mode is not None: os.chmod(filepath, mode) return filepath def create_zeroed_hdr_file(self, size, path, mode=None): """ Create a new non-zeroed file with a zeroed header and the selected size and name. """ filepath = os.path.join(self.testdir, path) with open(filepath, 'w') as f: f.write('\0' * HEADER_SIZE) f.write('\132' * (size - HEADER_SIZE)) if mode is not None: os.chmod(filepath, mode) return filepath def require_free_space(self, space): """ Skip test if not enough free space is available in test testdir. """ if self.get_free_space(self.testdir) < space: futils.skip('Not enough free space ({} MiB required)' .format(space / MiB)) def mkdirs(self, path, mode=None): """ Creates directory in test testdir along with all parent directories required. In the case given path already exists do nothing. """ dirpath = os.path.join(self.testdir, path) if mode is None: os.makedirs(dirpath, exist_ok=True) else: os.makedirs(dirpath, mode, exist_ok=True) class CtxType(type): """ Metaclass for context classes that can stand for multiple classes Attributes: is_preferred (bool): if True, context class is preferred to be chosen in case of Any execution setting. explicit (bool): if True, the context class is executed only if explicitly requested by test implementation, i. e. it is ignored if specified only in external configuration. includes: list of context classes included by this class, e. g. Short and Medium test types are included by Check test type """ def __init__(cls, name, bases, dct): type.__init__(cls, name, bases, dct) # it is supposed that context class has a user defined base class if cls.__base__.__name__ == 'object': return # context class preferred to be used when 'Any' test option is provided if not hasattr(cls, 'preferred'): cls.is_preferred = False # if explicit, run only if the test case explicitly specifies this # context in its own configuration if not hasattr(cls, 'explicit'): cls.explicit = False if hasattr(cls, 'includes'): cls.includes = expand(*cls.includes) else: # class that does not include other classes, includes itself cls.includes = [cls] # set instance (not class) method setattr(cls, '__repr__', lambda cls: cls.__class__.__name__.lower()) def __repr__(cls): return cls.__name__.lower() def __str__(cls): return cls.__name__.lower() def __iter__(cls): for c in cls.includes: yield c def factory(cls, conf, *classes): return [c(conf) for c in expand(*classes)] def filter_contexts(config_ctx, test_ctx): """ Return contexts that should be used in execution based on contexts provided by config and test case. """ if not test_ctx: return [c for c in config_ctx if not c.explicit] return [c for c in config_ctx if c in test_ctx] def str_to_ctx_common(val, ctx_base_type): def class_from_string(name, base): if name == 'all': return base.__subclasses__() try: return next(b for b in base.__subclasses__() if str(b) == name.lower()) except StopIteration: print('Invalid context value: "{}".'.format(name)) raise if isinstance(val, list): classes = [class_from_string(cl, ctx_base_type) for cl in val] return expand(*classes) else: return expand(class_from_string(val, ctx_base_type)) def _req_prefix(attr): """ Add prefix to requirement attribute name. Used to mitigate the risk of name clashes. """ return '_require{}'.format(attr) def add_requirement(tc, attr, value, **kwargs): """ Add requirement to the test Requirements are added to the test as attributes dynamically appended to the test class. Their names are additionally mangled with _req_prefix() function to avoid accidental overwriting of any existing test class attributes as well as unnecessary access by the test user - these attributes are meant to be used directly only by requirements handling functions. Args: tc (BaseTest): test case to which the requirement is added attr (str): attribute name of the requirement. additionally mangled with _req_prefix() function. value: requirement value **kwargs: additional keyword arguments that may be used by requirement implementation """ setattr(tc, _req_prefix(attr), value) setattr(tc, _req_prefix('{}_kwargs'.format(attr)), kwargs) def get_requirement(tc, attr, default): """ Get test requirement added with add_requirement() function with specific attribute name. Args: tc (BaseTest): test case class into which requirements were added attr (str): requirement attribute name - as previously added by add_requirement() function default: default requirement value if not found Returns: requirement value, requirement keyword arguments (as provided by 'kwargs' argument to add_requirement() function) """ ret_val = default ret_kwargs = {} try: ret_val = getattr(tc, _req_prefix(attr)) ret_kwargs = getattr(tc, _req_prefix('{}_kwargs'.format(attr))) except AttributeError: pass return ret_val, ret_kwargs class TestParam: """ TestParam manages single test parameter provided to test with add_params() decorator. Test parameters are added to context class as its elements - therefore the 'value' object may implement interface handled by ContextBase class, such as setup() and clean() """ def __init__(self, name, value): self.name = name self.value = value def __str__(self): return '{}: {}'.format(self.name, self.value) def __call__(self): return self.value def setup(self, **kwargs): if hasattr(self.value, 'setup') and ismethod(self.value.setup): self.value.setup(**kwargs) def check(self, **kwargs): if hasattr(self.value, 'check') and ismethod(self.value.check): self.value.check(**kwargs) def clean(self, **kwargs): if hasattr(self.value, 'clean') and ismethod(self.value.clean): self.value.clean(**kwargs) PARAMS_ATTR = '_params_' def add_params(name, values): """ Add parameters to the test case. Parameters will be accessible from test through context 'name' attribute. The value of single parameter can be accessed by calling this attribute, e.g. for: add_params('param', params_list) single parameter provided within 'params_list' is accessible by calling ctx.param(). """ params = [TestParam(name, v) for v in values] def wrapped(tc): if hasattr(tc, PARAMS_ATTR): getattr(tc, PARAMS_ATTR).update({name: params}) else: setattr(tc, PARAMS_ATTR, {name: params}) return tc return wrapped def get_params(tc): """Get parameters added to test case""" try: return getattr(tc, PARAMS_ATTR) except AttributeError: return {} class Any: """ The test context attribute signifying that specific context value is not relevant for the test outcome and it should be run only once in some viable context """ @classmethod def get(cls, conf_ctx): """Get specific context value to be run""" for c in conf_ctx: if c.is_preferred: # pick preferred if found return c # if no preferred is found, pick the first non-explicit one ret = [c for c in conf_ctx if not c.explicit] if ret: return ret[0] else: config = configurator.Configurator().config msg = futils.Message(config.unittest_log_level) msg.print_verbose('No valid "Any" context found') return None class _NoContext(collections.UserList): """ May be safely returned by context element class 'filter' method if its items are not required during test execution (e. g. no dax devices required by test) """ def __init__(self): self.data = [] self.data.append(False) def __bool__(self): return False NO_CONTEXT = _NoContext() pmdk-1.11.1/src/test/unittest/unittest.h0000664000000000000000000005705714123364546016731 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2014-2020, Intel Corporation */ /* * unittest.h -- the mundane stuff shared by all unit tests * * we want unit tests to be very thorough and check absolutely everything * in order to nail down the test case as precisely as possible and flag * anything at all unexpected. as a result, most unit tests are 90% code * checking stuff that isn't really interesting to what is being tested. * to help address this, the macros defined here include all the boilerplate * error checking which prints information and exits on unexpected errors. * * the result changes this code: * * if ((buf = malloc(size)) == NULL) { * fprintf(stderr, "cannot allocate %d bytes for buf\n", size); * exit(1); * } * * into this code: * * buf = MALLOC(size); * * and the error message includes the calling context information (file:line). * in general, using the all-caps version of a call means you're using the * unittest.h version which does the most common checking for you. so * calling VMEM_CREATE() instead of vmem_create() returns the same * thing, but can never return an error since the unit test library checks for * it. * for routines like vmem_delete() there is no corresponding * VMEM_DELETE() because there's no error to check for. * * all unit tests should use the same initialization: * * START(argc, argv, "brief test description", ...); * * all unit tests should use these exit calls: * * DONE("message", ...); * UT_FATAL("message", ...); * * uniform stderr and stdout messages: * * UT_OUT("message", ...); * UT_ERR("message", ...); * * in all cases above, the message is printf-like, taking variable args. * the message can be NULL. it can start with "!" in which case the "!" is * skipped and the message gets the errno string appended to it, like this: * * if (somesyscall(..) < 0) * UT_FATAL("!my message"); */ #ifndef _UNITTEST_H #define _UNITTEST_H 1 #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __FreeBSD__ #include #endif #include #include #include #include /* XXX: move OS abstraction layer out of common */ #include "os.h" #include "os_thread.h" #include "util.h" int ut_get_uuid_str(char *); #define UT_MAX_ERR_MSG 128 #define UT_POOL_HDR_UUID_STR_LEN 37 /* uuid string length */ #define UT_POOL_HDR_UUID_GEN_FILE "/proc/sys/kernel/random/uuid" /* XXX - fix this temp hack dup'ing util_strerror when we get mock for win */ void ut_strerror(int errnum, char *buff, size_t bufflen); /* XXX - eliminate duplicated definitions in unittest.h and util.h */ #ifdef _WIN32 static inline int ut_util_statW(const wchar_t *path, os_stat_t *st_bufp) { int retVal = _wstat64(path, st_bufp); /* clear unused bits to avoid confusion */ st_bufp->st_mode &= 0600; return retVal; } #endif /* * unit test support... */ void ut_start(const char *file, int line, const char *func, int argc, char * const argv[], const char *fmt, ...) __attribute__((format(printf, 6, 7))); void ut_startW(const char *file, int line, const char *func, int argc, wchar_t * const argv[], const char *fmt, ...) __attribute__((format(printf, 6, 7))); void NORETURN ut_done(const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 4, 5))); void NORETURN ut_fatal(const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 4, 5))); void NORETURN ut_end(const char *file, int line, const char *func, int ret); void ut_out(const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 4, 5))); void ut_err(const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 4, 5))); /* indicate the start of the test */ #ifndef _WIN32 #define START(argc, argv, ...)\ ut_start(__FILE__, __LINE__, __func__, argc, argv, __VA_ARGS__) #else #define START(argc, argv, ...)\ wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc);\ for (int i = 0; i < argc; i++) {\ argv[i] = ut_toUTF8(wargv[i]);\ if (argv[i] == NULL) {\ for (i--; i >= 0; i--)\ free(argv[i]);\ UT_FATAL("Error during arguments conversion\n");\ }\ }\ ut_start(__FILE__, __LINE__, __func__, argc, argv, __VA_ARGS__) #endif /* indicate the start of the test */ #define STARTW(argc, argv, ...)\ ut_startW(__FILE__, __LINE__, __func__, argc, argv, __VA_ARGS__) /* normal exit from test */ #ifndef _WIN32 #define DONE(...)\ ut_done(__FILE__, __LINE__, __func__, __VA_ARGS__) #else #define DONE(...)\ for (int i = argc; i > 0; i--)\ free(argv[i - 1]);\ ut_done(__FILE__, __LINE__, __func__, __VA_ARGS__) #endif #define DONEW(...)\ ut_done(__FILE__, __LINE__, __func__, __VA_ARGS__) #define END(ret, ...)\ ut_end(__FILE__, __LINE__, __func__, ret) /* fatal error detected */ #define UT_FATAL(...)\ ut_fatal(__FILE__, __LINE__, __func__, __VA_ARGS__) /* normal output */ #define UT_OUT(...)\ ut_out(__FILE__, __LINE__, __func__, __VA_ARGS__) /* error output */ #define UT_ERR(...)\ ut_err(__FILE__, __LINE__, __func__, __VA_ARGS__) /* * assertions... */ /* assert a condition is true at runtime */ #define UT_ASSERT_rt(cnd)\ ((void)((cnd) || (ut_fatal(__FILE__, __LINE__, __func__,\ "assertion failure: %s", #cnd), 0))) /* assertion with extra info printed if assertion fails at runtime */ #define UT_ASSERTinfo_rt(cnd, info) \ ((void)((cnd) || (ut_fatal(__FILE__, __LINE__, __func__,\ "assertion failure: %s (%s)", #cnd, info), 0))) /* assert two integer values are equal at runtime */ #define UT_ASSERTeq_rt(lhs, rhs)\ ((void)(((lhs) == (rhs)) || (ut_fatal(__FILE__, __LINE__, __func__,\ "assertion failure: %s (0x%llx) == %s (0x%llx)", #lhs,\ (unsigned long long)(lhs), #rhs, (unsigned long long)(rhs)), 0))) /* assert two integer values are not equal at runtime */ #define UT_ASSERTne_rt(lhs, rhs)\ ((void)(((lhs) != (rhs)) || (ut_fatal(__FILE__, __LINE__, __func__,\ "assertion failure: %s (0x%llx) != %s (0x%llx)", #lhs,\ (unsigned long long)(lhs), #rhs, (unsigned long long)(rhs)), 0))) #if defined(__CHECKER__) #define UT_COMPILE_ERROR_ON(cond) #define UT_ASSERT_COMPILE_ERROR_ON(cond) #elif defined(_MSC_VER) #define UT_COMPILE_ERROR_ON(cond) C_ASSERT(!(cond)) /* XXX - can't be done with C_ASSERT() unless we have __builtin_constant_p() */ #define UT_ASSERT_COMPILE_ERROR_ON(cond) (void)(cond) #else #define UT_COMPILE_ERROR_ON(cond) ((void)sizeof(char[(cond) ? -1 : 1])) #ifndef __cplusplus #define UT_ASSERT_COMPILE_ERROR_ON(cond) UT_COMPILE_ERROR_ON(cond) #else /* __cplusplus */ /* * XXX - workaround for https://github.com/pmem/issues/issues/189 */ #define UT_ASSERT_COMPILE_ERROR_ON(cond) UT_ASSERT_rt(!(cond)) #endif /* __cplusplus */ #endif /* _MSC_VER */ /* assert a condition is true */ #define UT_ASSERT(cnd)\ do {\ /*\ * Detect useless asserts on always true expression. Please use\ * UT_COMPILE_ERROR_ON(!cnd) or UT_ASSERT_rt(cnd) in such\ * cases.\ */\ if (__builtin_constant_p(cnd))\ UT_ASSERT_COMPILE_ERROR_ON(cnd);\ UT_ASSERT_rt(cnd);\ } while (0) /* assertion with extra info printed if assertion fails */ #define UT_ASSERTinfo(cnd, info) \ do {\ /* See comment in UT_ASSERT. */\ if (__builtin_constant_p(cnd))\ UT_ASSERT_COMPILE_ERROR_ON(cnd);\ UT_ASSERTinfo_rt(cnd, info);\ } while (0) /* assert two integer values are equal */ #define UT_ASSERTeq(lhs, rhs)\ do {\ /* See comment in UT_ASSERT. */\ if (__builtin_constant_p(lhs) && __builtin_constant_p(rhs))\ UT_ASSERT_COMPILE_ERROR_ON((lhs) == (rhs));\ UT_ASSERTeq_rt(lhs, rhs);\ } while (0) /* assert two integer values are not equal */ #define UT_ASSERTne(lhs, rhs)\ do {\ /* See comment in UT_ASSERT. */\ if (__builtin_constant_p(lhs) && __builtin_constant_p(rhs))\ UT_ASSERT_COMPILE_ERROR_ON((lhs) != (rhs));\ UT_ASSERTne_rt(lhs, rhs);\ } while (0) /* assert pointer is fits range of [start, start + size) */ #define UT_ASSERTrange(ptr, start, size)\ ((void)(((uintptr_t)(ptr) >= (uintptr_t)(start) &&\ (uintptr_t)(ptr) < (uintptr_t)(start) + (uintptr_t)(size)) ||\ (ut_fatal(__FILE__, __LINE__, __func__,\ "assert failure: %s (%p) is outside range [%s (%p), %s (%p))", #ptr,\ (void *)(ptr), #start, (void *)(start), #start"+"#size,\ (void *)((uintptr_t)(start) + (uintptr_t)(size))), 0))) /* * memory allocation... */ void *ut_malloc(const char *file, int line, const char *func, size_t size); void *ut_calloc(const char *file, int line, const char *func, size_t nmemb, size_t size); void ut_free(const char *file, int line, const char *func, void *ptr); void ut_aligned_free(const char *file, int line, const char *func, void *ptr); void *ut_realloc(const char *file, int line, const char *func, void *ptr, size_t size); char *ut_strdup(const char *file, int line, const char *func, const char *str); void *ut_pagealignmalloc(const char *file, int line, const char *func, size_t size); void *ut_memalign(const char *file, int line, const char *func, size_t alignment, size_t size); void *ut_mmap_anon_aligned(const char *file, int line, const char *func, size_t alignment, size_t size); int ut_munmap_anon_aligned(const char *file, int line, const char *func, void *start, size_t size); /* a malloc() that can't return NULL */ #define MALLOC(size)\ ut_malloc(__FILE__, __LINE__, __func__, size) /* a calloc() that can't return NULL */ #define CALLOC(nmemb, size)\ ut_calloc(__FILE__, __LINE__, __func__, nmemb, size) /* a malloc() of zeroed memory */ #define ZALLOC(size)\ ut_calloc(__FILE__, __LINE__, __func__, 1, size) #define FREE(ptr)\ ut_free(__FILE__, __LINE__, __func__, ptr) #define ALIGNED_FREE(ptr)\ ut_aligned_free(__FILE__, __LINE__, __func__, ptr) /* a realloc() that can't return NULL */ #define REALLOC(ptr, size)\ ut_realloc(__FILE__, __LINE__, __func__, ptr, size) /* a strdup() that can't return NULL */ #define STRDUP(str)\ ut_strdup(__FILE__, __LINE__, __func__, str) /* a malloc() that only returns page aligned memory */ #define PAGEALIGNMALLOC(size)\ ut_pagealignmalloc(__FILE__, __LINE__, __func__, size) /* a malloc() that returns memory with given alignment */ #define MEMALIGN(alignment, size)\ ut_memalign(__FILE__, __LINE__, __func__, alignment, size) /* * A mmap() that returns anonymous memory with given alignment and guard * pages. */ #define MMAP_ANON_ALIGNED(size, alignment)\ ut_mmap_anon_aligned(__FILE__, __LINE__, __func__, alignment, size) #define MUNMAP_ANON_ALIGNED(start, size)\ ut_munmap_anon_aligned(__FILE__, __LINE__, __func__, start, size) /* * file operations */ int ut_open(const char *file, int line, const char *func, const char *path, int flags, ...); int ut_wopen(const char *file, int line, const char *func, const wchar_t *path, int flags, ...); int ut_close(const char *file, int line, const char *func, int fd); FILE *ut_fopen(const char *file, int line, const char *func, const char *path, const char *mode); int ut_fclose(const char *file, int line, const char *func, FILE *stream); int ut_unlink(const char *file, int line, const char *func, const char *path); size_t ut_write(const char *file, int line, const char *func, int fd, const void *buf, size_t len); size_t ut_read(const char *file, int line, const char *func, int fd, void *buf, size_t len); os_off_t ut_lseek(const char *file, int line, const char *func, int fd, os_off_t offset, int whence); int ut_posix_fallocate(const char *file, int line, const char *func, int fd, os_off_t offset, os_off_t len); int ut_stat(const char *file, int line, const char *func, const char *path, os_stat_t *st_bufp); int ut_statW(const char *file, int line, const char *func, const wchar_t *path, os_stat_t *st_bufp); int ut_fstat(const char *file, int line, const char *func, int fd, os_stat_t *st_bufp); void *ut_mmap(const char *file, int line, const char *func, void *addr, size_t length, int prot, int flags, int fd, os_off_t offset); int ut_munmap(const char *file, int line, const char *func, void *addr, size_t length); int ut_mprotect(const char *file, int line, const char *func, void *addr, size_t len, int prot); int ut_ftruncate(const char *file, int line, const char *func, int fd, os_off_t length); void *ut_file_map(const char *file, int line, const char *func, int fd, size_t size); long long ut_strtoll(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); long ut_strtol(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); int ut_strtoi(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); unsigned long long ut_strtoull(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); unsigned long ut_strtoul(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); unsigned ut_strtou(const char *file, int line, const char *func, const char *nptr, char **endptr, int base); int ut_snprintf(const char *file, int line, const char *func, char *str, size_t size, const char *format, ...); /* an open() that can't return < 0 */ #define OPEN(path, ...)\ ut_open(__FILE__, __LINE__, __func__, path, __VA_ARGS__) /* a _wopen() that can't return < 0 */ #define WOPEN(path, ...)\ ut_wopen(__FILE__, __LINE__, __func__, path, __VA_ARGS__) /* a close() that can't return -1 */ #define CLOSE(fd)\ ut_close(__FILE__, __LINE__, __func__, fd) /* an fopen() that can't return != 0 */ #define FOPEN(path, mode)\ ut_fopen(__FILE__, __LINE__, __func__, path, mode) /* a fclose() that can't return != 0 */ #define FCLOSE(stream)\ ut_fclose(__FILE__, __LINE__, __func__, stream) /* an unlink() that can't return -1 */ #define UNLINK(path)\ ut_unlink(__FILE__, __LINE__, __func__, path) /* a write() that can't return -1 */ #define WRITE(fd, buf, len)\ ut_write(__FILE__, __LINE__, __func__, fd, buf, len) /* a read() that can't return -1 */ #define READ(fd, buf, len)\ ut_read(__FILE__, __LINE__, __func__, fd, buf, len) /* a lseek() that can't return -1 */ #define LSEEK(fd, offset, whence)\ ut_lseek(__FILE__, __LINE__, __func__, fd, offset, whence) #define POSIX_FALLOCATE(fd, off, len)\ ut_posix_fallocate(__FILE__, __LINE__, __func__, fd, off, len) #define FSTAT(fd, st_bufp)\ ut_fstat(__FILE__, __LINE__, __func__, fd, st_bufp) /* a mmap() that can't return MAP_FAILED */ #define MMAP(addr, len, prot, flags, fd, offset)\ ut_mmap(__FILE__, __LINE__, __func__, addr, len, prot, flags, fd, offset); /* a munmap() that can't return -1 */ #define MUNMAP(addr, length)\ ut_munmap(__FILE__, __LINE__, __func__, addr, length); /* a mprotect() that can't return -1 */ #define MPROTECT(addr, len, prot)\ ut_mprotect(__FILE__, __LINE__, __func__, addr, len, prot); #define STAT(path, st_bufp)\ ut_stat(__FILE__, __LINE__, __func__, path, st_bufp) #define STATW(path, st_bufp)\ ut_statW(__FILE__, __LINE__, __func__, path, st_bufp) #define FTRUNCATE(fd, length)\ ut_ftruncate(__FILE__, __LINE__, __func__, fd, length) #define FILE_MAP(fd, size)\ ut_file_map(__FILE__, __LINE__, __func__, fd, size); #define ATOU(nptr) STRTOU(nptr, NULL, 10) #define ATOUL(nptr) STRTOUL(nptr, NULL, 10) #define ATOULL(nptr) STRTOULL(nptr, NULL, 10) #define ATOI(nptr) STRTOI(nptr, NULL, 10) #define ATOL(nptr) STRTOL(nptr, NULL, 10) #define ATOLL(nptr) STRTOLL(nptr, NULL, 10) #define STRTOULL(nptr, endptr, base)\ ut_strtoull(__FILE__, __LINE__, __func__, nptr, endptr, base) #define STRTOUL(nptr, endptr, base)\ ut_strtoul(__FILE__, __LINE__, __func__, nptr, endptr, base) #define STRTOL(nptr, endptr, base)\ ut_strtol(__FILE__, __LINE__, __func__, nptr, endptr, base) #define STRTOLL(nptr, endptr, base)\ ut_strtoll(__FILE__, __LINE__, __func__, nptr, endptr, base) #define STRTOU(nptr, endptr, base)\ ut_strtou(__FILE__, __LINE__, __func__, nptr, endptr, base) #define STRTOI(nptr, endptr, base)\ ut_strtoi(__FILE__, __LINE__, __func__, nptr, endptr, base) #define SNPRINTF(str, size, format, ...) \ ut_snprintf(__FILE__, __LINE__, __func__, \ str, size, format, __VA_ARGS__) #ifndef _WIN32 #define ut_jmp_buf_t sigjmp_buf #define ut_siglongjmp(b) siglongjmp(b, 1) #define ut_sigsetjmp(b) sigsetjmp(b, 1) #else #define ut_jmp_buf_t jmp_buf #define ut_siglongjmp(b) longjmp(b, 1) #define ut_sigsetjmp(b) setjmp(b) #endif void ut_suppress_errmsg(void); void ut_unsuppress_errmsg(void); void ut_suppress_crt_assert(void); void ut_unsuppress_crt_assert(void); /* * signals... */ int ut_sigaction(const char *file, int line, const char *func, int signum, struct sigaction *act, struct sigaction *oldact); /* a sigaction() that can't return an error */ #define SIGACTION(signum, act, oldact)\ ut_sigaction(__FILE__, __LINE__, __func__, signum, act, oldact) /* * pthreads... */ int ut_thread_create(const char *file, int line, const char *func, os_thread_t *__restrict thread, const os_thread_attr_t *__restrict attr, void *(*start_routine)(void *), void *__restrict arg); int ut_thread_join(const char *file, int line, const char *func, os_thread_t *thread, void **value_ptr); /* a os_thread_create() that can't return an error */ #define THREAD_CREATE(thread, attr, start_routine, arg)\ ut_thread_create(__FILE__, __LINE__, __func__,\ thread, attr, start_routine, arg) /* a os_thread_join() that can't return an error */ #define THREAD_JOIN(thread, value_ptr)\ ut_thread_join(__FILE__, __LINE__, __func__, thread, value_ptr) /* * processes... */ #ifdef _WIN32 intptr_t ut_spawnv(int argc, const char **argv, ...); #endif /* * mocks... * * NOTE: On Linux, function mocking is implemented using wrapper functions. * See "--wrap" option of the GNU linker. * There is no such feature in VC++, so on Windows we do the mocking at * compile time, by redefining symbol names: * - all the references to are replaced with <__wrap_symbol> * in all the compilation units, except the one where the is * defined and the test source file * - the original definition of is replaced with <__real_symbol> * - a wrapper function <__wrap_symbol> must be defined in the test program * (it may still call the original function via <__real_symbol>) * Such solution seems to be sufficient for the purpose of our tests, even * though it has some limitations. I.e. it does no work well with malloc/free, * so to wrap the system memory allocator functions, we use the built-in * feature of all the PMDK libraries, allowing to override default memory * allocator with the custom one. */ #ifndef _WIN32 #define _FUNC_REAL_DECL(name, ret_type, ...)\ ret_type __real_##name(__VA_ARGS__) __attribute__((unused)); #else #define _FUNC_REAL_DECL(name, ret_type, ...)\ ret_type name(__VA_ARGS__); #endif #ifndef _WIN32 #define _FUNC_REAL(name)\ __real_##name #else #define _FUNC_REAL(name)\ name #endif #define RCOUNTER(name)\ _rcounter##name #define FUNC_MOCK_RCOUNTER_SET(name, val)\ RCOUNTER(name) = val; #define FUNC_MOCK(name, ret_type, ...)\ _FUNC_REAL_DECL(name, ret_type, ##__VA_ARGS__)\ static unsigned RCOUNTER(name);\ ret_type __wrap_##name(__VA_ARGS__);\ ret_type __wrap_##name(__VA_ARGS__) {\ switch (util_fetch_and_add32(&RCOUNTER(name), 1)) { #define FUNC_MOCK_DLLIMPORT(name, ret_type, ...)\ __declspec(dllimport) _FUNC_REAL_DECL(name, ret_type, ##__VA_ARGS__)\ static unsigned RCOUNTER(name);\ ret_type __wrap_##name(__VA_ARGS__);\ ret_type __wrap_##name(__VA_ARGS__) {\ switch (util_fetch_and_add32(&RCOUNTER(name), 1)) { #define FUNC_MOCK_END\ }} #define FUNC_MOCK_RUN(run)\ case run: #define FUNC_MOCK_RUN_DEFAULT\ default: #define FUNC_MOCK_RUN_RET(run, ret)\ case run: return (ret); #define FUNC_MOCK_RUN_RET_DEFAULT_REAL(name, ...)\ default: return _FUNC_REAL(name)(__VA_ARGS__); #define FUNC_MOCK_RUN_RET_DEFAULT(ret)\ default: return (ret); #define FUNC_MOCK_RET_ALWAYS(name, ret_type, ret, ...)\ FUNC_MOCK(name, ret_type, __VA_ARGS__)\ FUNC_MOCK_RUN_RET_DEFAULT(ret);\ FUNC_MOCK_END #define FUNC_MOCK_RET_ALWAYS_VOID(name, ...)\ FUNC_MOCK(name, void, __VA_ARGS__)\ default: return;\ FUNC_MOCK_END extern unsigned long Ut_pagesize; extern unsigned long long Ut_mmap_align; extern os_mutex_t Sigactions_lock; void ut_dump_backtrace(void); void ut_sighandler(int); void ut_register_sighandlers(void); uint16_t ut_checksum(uint8_t *addr, size_t len); char *ut_toUTF8(const wchar_t *wstr); wchar_t *ut_toUTF16(const char *wstr); struct test_case { const char *name; int (*func)(const struct test_case *tc, int argc, char *argv[]); }; /* * get_tc -- return test case of specified name */ static inline const struct test_case * get_tc(const char *name, const struct test_case *test_cases, size_t ntests) { for (size_t i = 0; i < ntests; i++) { if (strcmp(name, test_cases[i].name) == 0) return &test_cases[i]; } return NULL; } static inline void TEST_CASE_PROCESS(int argc, char *argv[], const struct test_case *test_cases, size_t ntests) { if (argc < 2) UT_FATAL("usage: %s []", argv[0]); for (int i = 1; i < argc; i++) { char *str_test = argv[i]; const int args_off = i + 1; const struct test_case *tc = get_tc(str_test, test_cases, ntests); if (!tc) UT_FATAL("unknown test case -- '%s'", str_test); int ret = tc->func(tc, argc - args_off, &argv[args_off]); if (ret < 0) UT_FATAL("test return value cannot be negative"); i += ret; } } #define TEST_CASE_DECLARE(_name)\ int \ _name(const struct test_case *tc, int argc, char *argv[]) #define TEST_CASE(_name)\ {\ .name = #_name,\ .func = (_name),\ } #define STR(x) #x #define ASSERT_ALIGNED_BEGIN(type) do {\ size_t off = 0;\ const char *last = "(none)";\ type t; #define ASSERT_ALIGNED_FIELD(type, field) do {\ if (offsetof(type, field) != off)\ UT_FATAL("%s: padding, missing field or fields not in order between "\ "'%s' and '%s' -- offset %lu, real offset %lu",\ STR(type), last, STR(field), off, offsetof(type, field));\ off += sizeof(t.field);\ last = STR(field);\ } while (0) #define ASSERT_FIELD_SIZE(field, size) do {\ UT_COMPILE_ERROR_ON(size != sizeof(t.field));\ } while (0) #define ASSERT_OFFSET_CHECKPOINT(type, checkpoint) do {\ if (off != checkpoint)\ UT_FATAL("%s: violated offset checkpoint -- "\ "checkpoint %lu, real offset %lu",\ STR(type), checkpoint, off);\ } while (0) #define ASSERT_ALIGNED_CHECK(type)\ if (off != sizeof(type))\ UT_FATAL("%s: missing field or padding after '%s': "\ "sizeof(%s) = %lu, fields size = %lu",\ STR(type), last, STR(type), sizeof(type), off);\ } while (0) /* * AddressSanitizer */ #ifdef __clang__ #if __has_feature(address_sanitizer) #define UT_DEFINE_ASAN_POISON #endif #else #ifdef __SANITIZE_ADDRESS__ #define UT_DEFINE_ASAN_POISON #endif #endif #ifdef UT_DEFINE_ASAN_POISON void __asan_poison_memory_region(void const volatile *addr, size_t size); void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #define ASAN_POISON_MEMORY_REGION(addr, size) \ __asan_poison_memory_region((addr), (size)) #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ __asan_unpoison_memory_region((addr), (size)) #else #define ASAN_POISON_MEMORY_REGION(addr, size) \ ((void)(addr), (void)(size)) #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ ((void)(addr), (void)(size)) #endif #ifdef __cplusplus } #endif #endif /* unittest.h */ pmdk-1.11.1/src/test/unittest/tools.py0000664000000000000000000001306614123364546016403 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation # """External tools integration""" import os import json import sys import subprocess as sp import futils try: import envconfig envconfig = envconfig.config except ImportError: # if file doesn't exist create dummy object envconfig = {'GLOBAL_LIB_PATH': '', 'PMEM2_AVX512F_ENABLED': ''} class Tools: PMEMDETECT_FALSE = 0 PMEMDETECT_TRUE = 1 PMEMDETECT_ERROR = 2 def __init__(self, env, build): self.env = env self.build = build global_lib_path = envconfig['GLOBAL_LIB_PATH'] if sys.platform == 'win32': futils.add_env_common(self.env, {'PATH': global_lib_path}) futils.add_env_common(self.env, {'PATH': build.libdir}) else: futils.add_env_common(self.env, {'LD_LIBRARY_PATH': global_lib_path}) futils.add_env_common(self.env, {'LD_LIBRARY_PATH': build.libdir}) def _run_test_tool(self, name, *args): exe = futils.get_test_tool_path(self.build, name) if sys.platform == 'win32': exe += '.exe' return sp.run([exe, *args], env=self.env, stdout=sp.PIPE, stderr=sp.STDOUT, universal_newlines=True) def pmemdetect(self, *args): return self._run_test_tool('pmemdetect', *args) def gran_detecto(self, *args): return self._run_test_tool('gran_detecto', *args) def cpufd(self): return self._run_test_tool('cpufd') def mapexec(self, *args): return self._run_test_tool('mapexec', *args) class Ndctl: """ndctl CLI handle Attributes: version (str): ndctl version ndctl_list_output (dict): output of 'ndctl list' command decoded from JSON into dictionary """ def __init__(self): self.version = self._get_ndctl_version() self.ndctl_list_output = self._get_ndctl_list_output('list') def _get_ndctl_version(self): """ Get ndctl version. Acquiring the version is simultaneously used as a check whether the ndctl is installed on the system. Returns: ndctl version (str) """ proc = sp.run(['ndctl', '--version'], stdout=sp.PIPE, stderr=sp.STDOUT) if proc.returncode != 0: raise futils.Fail('checking if ndctl exists failed:{}{}' .format(os.linesep, proc.stdout)) version = proc.stdout.strip() return version def _get_ndctl_list_output(self, *args): """ Parse 'ndctl list' command output as JSON into a dictionary and return it. """ proc = sp.run(['ndctl', *args], stdout=sp.PIPE, stderr=sp.STDOUT) if proc.returncode != 0: raise futils.Fail('ndctl list failed:{}{}'.format(os.linesep, proc.stdout)) try: ndctl_list_out = json.loads(proc.stdout) except json.JSONDecodeError: raise futils.Fail('Invalid "ndctl list" output (could ' 'not read as JSON): {}'.format(proc.stdout)) return ndctl_list_out def _get_dev_info(self, dev_path): """ Get ndctl information about the given device. Returns dictionary associated with device. """ dev = None # Possible viable device types as shown with # 'ndctl list' output devtypes = ('blockdev', 'chardev') for d in self._get_ndctl_list_output('list'): for dt in devtypes: if dt in d and os.path.join('/dev', d[dt]) == dev_path: dev = d if not dev: raise futils.Fail('ndctl does not recognize the device: "{}"' .format(dev_path)) return dev # for ndctl v63 we need to parse ndctl list in a different way than for v64 def _get_dev_info_63(self, dev_path): dev = None devtype = 'chardev' daxreg = 'daxregion' for d in self._get_ndctl_list_output('list', '-v'): if daxreg in d: devices = d[daxreg]['devices'] for device in devices: if devtype in device and \ os.path.join('/dev', device[devtype]) == dev_path: # only params from daxreg are interested at this point, # other values are read by _get_dev_info() earlier dev = d[daxreg] if not dev: raise futils.Fail('ndctl does not recognize the device: "{}"' .format(dev_path)) return dev def _get_dev_param(self, dev_path, param): """ Acquire device parameter from 'ndctl list' output. Args: dev_path (str): path of device param (str): parameter """ p = None dev = self._get_dev_info(dev_path) try: p = dev[param] except KeyError: dev = self._get_dev_info_63(dev_path) p = dev[param] return p def get_dev_size(self, dev_path): return int(self._get_dev_param(dev_path, 'size')) def get_dev_alignment(self, dev_path): return int(self._get_dev_param(dev_path, 'align')) def get_dev_mode(self, dev_path): return self._get_dev_param(dev_path, 'mode') def is_devdax(self, dev_path): return self.get_dev_mode(dev_path) == 'devdax' def is_fsdax(self, dev_path): return self.get_dev_mode(dev_path) == 'fsdax' pmdk-1.11.1/src/test/unittest/basetest.py0000664000000000000000000002564314123364546017061 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation """Base tests class and its functionalities. _TestCase metaclass implemented in this module is used to register test case classes. Classes are registered and used as actual test cases only if they fulfill the following requirements: - inherit (directly or indirectly) from BaseTest class - reside in TESTS.py file under pmdk/src/test/ directory - are named by TEST[int] (e.g. TEST0), where integer suffix is a test number (used for selecting test sequences). BaseTest._execute() method requires special attention as a general single test execution workflow. While BaseTest class is the required test case base class, it consist only of the minimal implementation to serve as the test framework handle. In practice, it is the Test class (inheriting from BaseTest) that is most commonly used as a test case direct base class. The Test class implements operations typically used by most of the tests. Test class needs to implement an abstract run(ctx) method, which stands for a test body. setup(ctx) and clean(ctx) methods, which are a part of test execution workflow are optional. Mind that the Test class already provides some implementation of the setup() and clean() - it is crucial to call them while implementing own setup() and clean() methods. Tests for PMDK C code frequently call the Context exec() method (passed as 'ctx' argument to run()), which is a utility for setting up, running and handling the output of C test binaries. Example TESTS.py file with a single test case may look like this: $ cat pmdk/src/test/test_group/TESTS.py !#../env.py import testframework as t class TEST0(t.Test): def run(self, ctx): ctx.exec('test_binary') def setup(self, ctx): # call Test setup super().setup(ctx) # TEST0 setup implementation goes here def clean(self, ctx): super().clean(ctx) # TEST0 clean implementation goes here """ import builtins import subprocess as sp import sys import re import os from datetime import datetime from os import path from configurator import Configurator from consts import LIBS_LIST, ROOTDIR import futils import test_types import shutil # # imported test cases are globally available as a 'builtins' # module 'testcases' variable, which is initialized at first basetest # module import as an empty list # if not hasattr(builtins, 'testcases'): builtins.testcases = [] def get_testcases(): """"Get list of testcases imported from src/test tree""" return builtins.testcases def _test_string_repr(cls): """ Implementation of __str__ method for the test class. Needs to be available both for initialized (as a BaseTest instance method) as well as uninitialized object (as a _TestCase metaclass method) """ return '{}/{}'.format(cls.group, cls.name) class _TestCase(type): """Metaclass for BaseTest that is used for registering imported tests. Attributes: cwd (str): path to the directory of the TESTS.py file containing the class group (str): name of the directory of the TESTS.py file testnum (int): test number tc_dirname (str): name of the directory created for the test in testdir """ def __init__(cls, name, bases, dct): type.__init__(cls, name, bases, dct) # globally register class as test case # only classes whose names start with 'TEST' are meant to be run cls.name = cls.__name__ if cls.__module__ == '__main__': cls.cwd = path.dirname(path.abspath(sys.argv[0])) else: cls.cwd = cls.__module__ cls.group = path.basename(cls.cwd) if cls.name.startswith('TEST'): builtins.testcases.append(cls) try: cls.testnum = int(cls.name.replace('TEST', '')) except ValueError as e: print('Invalid test class name {}, should be "TEST[number]"' .format(cls.name)) raise e cls.tc_dirname = cls.group + '_' + str(cls.testnum) def __str__(cls): return _test_string_repr(cls) class BaseTest(metaclass=_TestCase): """ Framework base test class. Every test case needs to (directly or indirectly) inherit from it. Since this class implements only very abstract test behaviour, it is advised for most test cases to use Test class inheriting from it. Attributes: enabled (bool): True if test is meant to be executed, False otherwise. Defaults to True. ctx (Context): context affiliated with the test """ enabled = True def __init__(self): self.ctx = None def __str__(self): return _test_string_repr(self) def _execute(self, c): """ Implementation of basic single contextualized test execution workflow. Called by the test runner. Args: c (Context): test context """ self.ctx = c try: # pre-execution cleanup self.ctx.clean() self.clean() self.ctx.setup() self.setup(c) start_time = datetime.now() self.run(c) self.elapsed = (datetime.now() - start_time).total_seconds() self.ctx.check() self.check(c) except futils.Fail: self._on_fail() raise except futils.Skip: self.ctx.clean() self.clean() raise except sp.TimeoutExpired: msg = '{}: {}TIMEOUT{}\t({})'.format(self, futils.Color.RED, futils.Color.END, self.ctx) raise futils.Fail(msg) else: self.ctx.clean() self.clean() def setup(self, ctx): """Test setup - not implemented by BaseTest""" pass def run(self, ctx): """ Main test body, run with specific context provided through Context class instance. Needs to be implemented by each test """ raise NotImplementedError('{} does not implement run() method'.format( self.__class__)) def check(self, ctx): """Run additional test checks - not implemented by BaseTest""" pass def clean(self): """Test cleanup - not implemented by BaseTest""" pass def _on_fail(self): """Custom behaviour on test fail - not implemented by BaseTest""" pass class Test(BaseTest): """ Generic implementation of BaseTest scaffolding used by particular test case classes as a base. In practice, most tests need to inherit from this class rather than from Basetest since it implements most commonly used test utilities and actions. Args: test_type (_TestType): test type affiliated with test execution length. Defaults to Medium. match (bool): True if match files will be checked for test, False otherwise. Defaults to True. config (Configurator): test execution configuration msg (Message): message class instance with logging level env (dict): environment variables needed for test execution """ test_type = test_types.Medium match = True def __init__(self): super().__init__() self.config = Configurator().config self.msg = futils.Message(self.config.unittest_log_level) self.log_files = {} def _get_utenv(self): """Get environment variables values used by C test framework""" return { 'UNITTEST_NAME': str(self), 'UNITTEST_LOG_LEVEL': str(self.config.unittest_log_level), 'UNITTEST_NUM': str(self.testnum) } def _debug_log_env(self): """ Return environment variables that enable logging PMDK debug output into log files """ envs = {} for libs in LIBS_LIST: envs['{}_LOG_LEVEL'.format(libs.upper())] = '3' log_file = os.path.join(self.cwd, '{}_{}.log'.format(libs, self.testnum)) envs['{}_LOG_FILE'.format(libs.upper())] = log_file self.log_files[libs] = log_file return envs def get_log_files(self): """ Returns names of all log files for given test """ pattern = r'.*[a-zA-Z_]{}\.log' log_files = [] files = os.scandir(self.cwd) for file in files: match = re.fullmatch(pattern.format(self.testnum), file.name) if match: log = path.abspath(path.join(self.cwd, file.name)) log_files.append(log) return log_files def _print_log_files(self): """ Prints all log files for given test """ log_files = self.get_log_files() for file in log_files: with open(file) as f: self.ctx.dump_n_lines(f) def _move_log_files(self, ctx): """ Move all log files for given tests """ path = "logs" sub_dir = str(ctx).replace(':', '') logs_dir = os.path.join(path, sub_dir) os.makedirs(logs_dir, exist_ok=True) log_files = self.get_log_files() for file in log_files: shutil.copy2(file, logs_dir) def remove_log_files(self): """ Removes log files for given test """ log_files = self.get_log_files() for file in log_files: os.remove(file) def setup(self, ctx): """Test setup""" self.env = {} self.env.update(self._get_utenv()) self.env.update(self._debug_log_env()) self.ctx.add_env(self.env) self.remove_log_files() def _on_fail(self): self._print_log_files() def check(self, ctx): """Run additional test checks""" if self.match: self._run_match() self._move_log_files(ctx) def _run_match(self): """Match log files""" cwd_listdir = [path.join(self.cwd, f) for f in os.listdir(self.cwd)] suffix = '{}.log.match'.format(self.testnum) def is_matchfile(f): """Match file ends with specific suffix and a char before suffix is not a digit""" before_suffix = -len(suffix) - 1 return path.isfile(f) and f.endswith(suffix) and \ not f[before_suffix].isdigit() match_files = filter(is_matchfile, cwd_listdir) prefix = 'perl ' if sys.platform == 'win32' else '' match_cmd = prefix + path.join(ROOTDIR, 'match') for mf in match_files: cmd = '{} {}'.format(match_cmd, mf) proc = sp.run(cmd.split(), stdout=sp.PIPE, cwd=self.cwd, stderr=sp.STDOUT, universal_newlines=True) if proc.returncode != 0: futils.fail(proc.stdout, exit_code=proc.returncode) else: self.msg.print_verbose(proc.stdout) pmdk-1.11.1/src/test/unittest/ut_pthread.c0000664000000000000000000000160514123364546017170 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * ut_pthread.c -- unit test wrappers for pthread routines */ #include "unittest.h" /* * ut_thread_create -- a os_thread_create that cannot return an error */ int ut_thread_create(const char *file, int line, const char *func, os_thread_t *__restrict thread, const os_thread_attr_t *__restrict attr, void *(*start_routine)(void *), void *__restrict arg) { if ((errno = os_thread_create(thread, attr, start_routine, arg)) != 0) ut_fatal(file, line, func, "!os_thread_create"); return 0; } /* * ut_thread_join -- a os_thread_join that cannot return an error */ int ut_thread_join(const char *file, int line, const char *func, os_thread_t *thread, void **value_ptr) { if ((errno = os_thread_join(thread, value_ptr)) != 0) ut_fatal(file, line, func, "!os_thread_join"); return 0; } pmdk-1.11.1/src/test/unittest/ut_pmem2.h0000664000000000000000000000052014123364546016561 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * ut_pmem2.h -- utility helper functions for libpmem tests */ #ifndef UT_PMEM2_H #define UT_PMEM2_H 1 #include "ut_pmem2_config.h" #include "ut_pmem2_map.h" #include "ut_pmem2_source.h" #include "ut_pmem2_utils.h" #endif /* UT_PMEM2_H */ pmdk-1.11.1/src/test/unittest/ut_signal.c0000664000000000000000000000440214123364546017014 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * ut_signal.c -- unit test signal operations */ #include "unittest.h" #ifdef _WIN32 /* * On Windows, Access Violation exception does not raise SIGSEGV signal. * The trick is to catch the exception and... call the signal handler. */ /* * Sigactions[] - allows registering more than one signal/exception handler */ static struct sigaction Sigactions[NSIG]; /* * exception_handler -- called for unhandled exceptions */ static LONG CALLBACK exception_handler(_In_ PEXCEPTION_POINTERS ExceptionInfo) { DWORD excode = ExceptionInfo->ExceptionRecord->ExceptionCode; if (excode == EXCEPTION_ACCESS_VIOLATION) Sigactions[SIGSEGV].sa_handler(SIGSEGV); return EXCEPTION_CONTINUE_EXECUTION; } /* * signal_handler_wrapper -- (internal) wrapper for user-defined signal handler * * Before the specified handler function is executed, signal disposition * is reset to SIG_DFL. This wrapper allows to handle subsequent signals * without the need to set the signal disposition again. */ static void signal_handler_wrapper(int signum) { _crt_signal_t retval = signal(signum, signal_handler_wrapper); if (retval == SIG_ERR) UT_FATAL("!signal: %d", signum); if (Sigactions[signum].sa_handler) Sigactions[signum].sa_handler(signum); else UT_FATAL("handler for signal: %d is not defined", signum); } #endif /* * ut_sigaction -- a sigaction that cannot return < 0 */ int ut_sigaction(const char *file, int line, const char *func, int signum, struct sigaction *act, struct sigaction *oldact) { #ifndef _WIN32 int retval = sigaction(signum, act, oldact); if (retval != 0) ut_fatal(file, line, func, "!sigaction: %s", os_strsignal(signum)); return retval; #else UT_ASSERT(signum < NSIG); os_mutex_lock(&Sigactions_lock); if (oldact) *oldact = Sigactions[signum]; if (act) Sigactions[signum] = *act; os_mutex_unlock(&Sigactions_lock); if (signum == SIGABRT) { ut_suppress_errmsg(); } if (signum == SIGSEGV) { AddVectoredExceptionHandler(0, exception_handler); } _crt_signal_t retval = signal(signum, signal_handler_wrapper); if (retval == SIG_ERR) ut_fatal(file, line, func, "!signal: %d", signum); if (oldact != NULL) oldact->sa_handler = retval; return 0; #endif } pmdk-1.11.1/src/test/unittest/poolset.py0000664000000000000000000001762714123364546016737 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Tools which allows to easily create poolset files""" from enum import Enum, unique import os import futils from consts import KiB, MiB, GiB POOL_MIN_SIZE = 8 * MiB PART_MIN_SIZE = 2 * MiB @unique class CREATE(Enum): """ CREATE allows to create part files during creation of poolset file. When ZEROED, HDR_ZEROED, DATA_ZEROED option is passed user should specify fsize and optionally mode. ZEROED - create a file filled with \0 characters NON_ZEROED - create a file filled with \132 characters HDR_ZEROED - create a file with a zeroed header and rest filled with \132 """ ZEROED = 0 NON_ZEROED = 1 HDR_ZEROED = 2 class _Poolset: """ An interface for easy poolset files creation. To get new Poolset for testcase call ctx.new_poolset(name). Example usage: poolset = ctx.new_poolset('poolset') poolset.set_parts(File('part0.pool', 10*MiB), DDax(ctx, 'daxpath')) poolset.add_replica(File('part0.rep1', 20*MiB), File('part1.rep1', 5*MiB).Create( t.CREATE.ZEROED, 100 * MiB)) poolset.add_replica(Dir('dirpart.rep1', 2*GiB)) poolset.add_remote('poolset.remote', '127.0.0.1') poolset.set_nohdrs() poolset.create() """ def __init__(self, path, ctx): self.path = path self.parts = [] self.replicas = [] self.options = [] self.remote = [] self.ctx = ctx def set_parts(self, *parts): """ Adds a main pool to the poolset file. The function accepts a list of Parts of any length. Should not be called more than once. """ if not self.parts: self.parts = list(parts) else: futils.fail('This function should not be called more than once.') def add_replica(self, *parts): """ Adds local replica to poolset file. The function accepts a list of Parts of any length. Each function call create a new replica. """ self.replicas.append(parts) def add_remote(self, path, node): """ Adds remote poolset file. A path should be relative to the rpmemd poolset-dir. For details please see the rpmemd(1) manual page.Each function call create new remote replica. """ self.remote.append((path, node)) def set_singlehdr(self): """ If called, poolset will be created with SINGLEHDR option. """ self.options.append('SINGLEHDR') def set_nohdrs(self): """ If called, poolset will be created with NOHDRS option. """ self.options.append('NOHDRS') def create(self): """ Create a poolset file with basic space validation. If CREATE arguments ware passed to parts, create parts files as well. """ self._check_pools_size() required_size = self._get_required_size() free_space = self.ctx.get_free_space() if required_size > free_space: futils.fail('Not enough space available to create parts ' 'files. There is {}, and poolset requires {}' .format(free_space, required_size)) for part in self.parts: part._process(self.ctx) for replica in self.replicas: for part in replica: part._process(self.ctx) self.options = list(set(self.options)) poolsetpath = os.path.join(self.ctx.testdir, self.path) with open(poolsetpath, 'w') as poolset: print('PMEMPOOLSET', end='\n\n', file=poolset) for option in self.options: print('OPTION', option, end='\n\n', file=poolset) for part in self.parts: print(part, file=poolset) print(file=poolset) for replica in self.replicas: print("REPLICA", file=poolset) for part in replica: print(part, file=poolset) print(file=poolset) for remote in self.remote: print("REPLICA", remote[1], remote[0], file=poolset) def _check_pools_size(self): """" Validate if pool and replicas have more than 8MiB (minimum pool size). This function does not validate remote replicas sizes. """ size = 0 for part in self.parts: size += part.size if size < POOL_MIN_SIZE: futils.fail('The pool has to have at least 8 MiB') for replica in self.replicas: size = 0 for part in replica: size += part.size if size < POOL_MIN_SIZE: futils.fail('The pool has to have at least 8 MiB') def _get_required_size(self): """ Returns size required to create all part files """ size = 0 for part in self.parts: if part is File and part.create is not None: size += part.size for replica in self.replicas: for part in replica: if part is File and part.create is not None: size += part.size return size class _Part: """ An abstraction for poolset parts """ def __init__(self, path, size): if size < PART_MIN_SIZE: futils.fail('The part should have at least 2 MiB') self.size = size self.path = path def __str__(self): return '{} {}'.format(self._format(self.size), self.path) def _process(self, ctx): """ Should be overridden by classes whose objects need to create files or directories """ pass @staticmethod def _format(number): """ Formats given number and returns equivalent string with size extension """ if number % GiB == 0: return '{}G'.format(int(number / GiB)) elif number % MiB == 0: return '{}M'.format(int(number / MiB)) elif number % KiB == 0: return '{}K'.format(int(number / KiB)) else: return str(number) + 'B' class File(_Part): """ An interface to file parts creations. By default it accepts 2 arguments path and size and does not create a passed file. To force file creation use Create(create, fsize, mode=None) method. Example usage: part0 = File('part0', 10 * MiB) part1 = File('part1', 20 * MiB).Create(CREATE.ZEROED, 20 * MiB, 0o777) part2 = File('part1', 20 * MiB).Create(CREATE.ZEROED, 20 * MiB) """ def __init__(self, path, size): _Part.__init__(self, path, size) self.create = None def Create(self, create, fsize, mode=None): self.fsize = fsize self.mode = mode self.create = create return self def _process(self, ctx): """ Create file adequately to passed 'create' argument """ if self.create == CREATE.ZEROED: ctx.create_holey_file(self.fsize, self.path, self.mode) if self.create == CREATE.NON_ZEROED: ctx.create_non_zero_file(self.fsize, self.path, self.mode) if self.create == CREATE.HDR_ZEROED: ctx.create_zeroed_hdr_file(self.fsize, self.path, self.mode) class DDax(_Part): """ An interface to device dax parts creation """ def __init__(self, ctx, path): if not ctx.is_devdax(path): futils.fail('Part with path "{}" does not point to dax device' .format(path)) _Part.__init__(self, path, ctx.get_size(path)) class Dir(_Part): """ An interface to dir parts creation """ def __init__(self, path, size, mode=None): _Part.__init__(self, path, size) self.mode = mode def _process(self, ctx): ctx.mkdirs(self.path, self.mode) pmdk-1.11.1/src/test/unittest/granularity.py0000664000000000000000000001635614123364546017611 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Granularity context classes and utilities""" import os import shutil from enum import Enum, unique import context as ctx import configurator import futils class Granularity(metaclass=ctx.CtxType): """ Represents file system granularity context element. Attributes: gran_detecto_arg (str): argument of gran_detecto tool that checks test directory for this granularity type compliance config_dir_field (str): name of the field in testconfig that represents the test directory with this granularity type config_force_field (str): name of the field in testconfig that represent the 'force' argument for this granularity type force_env (str): value of PMEM2_FORCE_GRANULARITY environment variable for this granularity type pmem_force_env (str): value for legacy PMEM_IS_PMEM_FORCE environment variable that corresponds to this granularity type """ gran_detecto_arg = None config_dir_field = None config_force_field = None force_env = None pmem_force_env = None def __init__(self, **kwargs): futils.set_kwargs_attrs(self, kwargs) self.config = configurator.Configurator().config dir_ = os.path.abspath(getattr(self.config, self.config_dir_field)) self.testdir = os.path.join(dir_, self.tc_dirname) force = getattr(self.config, self.config_force_field) if force: self.env = { 'PMEM2_FORCE_GRANULARITY': self.force_env, # PMEM2_FORCE_GRANULARITY is implemented only by # libpmem2. Corresponding PMEM_IS_PMEM_FORCE variable # is set to support tests for older PMDK libraries. 'PMEM_IS_PMEM_FORCE': self.pmem_force_env } def setup(self, tools=None): if not os.path.exists(self.testdir): os.makedirs(self.testdir) check_page = tools.gran_detecto(self.testdir, self.gran_detecto_arg) if check_page.returncode != 0: msg = check_page.stdout detect = tools.gran_detecto(self.testdir, '-d') msg = '{}{}{}'.format(os.linesep, msg, detect.stdout) raise futils.Fail('Granularity check for {} failed: {}' .format(self.testdir, msg)) def clean(self, *args, **kwargs): shutil.rmtree(self.testdir, ignore_errors=True) @classmethod def testdir_defined(cls, config): """ Check if test directory used by specific granularity setup is defined by test configuration """ try: if not cls.config_dir_field: return False getattr(config, cls.config_dir_field) except futils.Skip as s: msg = futils.Message(config.unittest_log_level) msg.print_verbose(s) return False else: return True @classmethod def filter(cls, config, msg, tc): """ Initialize granularity classes for the test to be run based on configuration and test requirements. Args: config: configuration as returned by Configurator class msg (Message): level based logger class instance tc (BaseTest): test case, from which the granularity requirements are obtained Returns: list of granularities on which the test should be run """ req_gran, kwargs = ctx.get_requirement(tc, 'granularity', None) # remove granularities if respective test directories in # test config are not defined conf_defined = [c for c in config.granularity if c.testdir_defined(config)] if req_gran == Non: return [Non(**kwargs), ] if req_gran == _CACHELINE_OR_LESS: tmp_req_gran = [Byte, CacheLine] elif req_gran == _PAGE_OR_LESS: tmp_req_gran = [Byte, CacheLine, Page] elif req_gran == [ctx.Any, ]: tmp_req_gran = ctx.Any.get(conf_defined) else: tmp_req_gran = req_gran filtered = ctx.filter_contexts(conf_defined, tmp_req_gran) kwargs['tc_dirname'] = tc.tc_dirname if len(filtered) > 1 and req_gran == _CACHELINE_OR_LESS or \ req_gran == _PAGE_OR_LESS: def order_by_smallest(elem): ordered = [Byte, CacheLine, Page] return ordered.index(elem) # take the smallest available granularity filtered.sort(key=order_by_smallest) filtered = [filtered[0], ] gs = [] for g in filtered: try: gs.append(g(**kwargs)) except futils.Skip as s: msg.print_verbose('{}: SKIP: {}'.format(tc, s)) return gs class Page(Granularity): config_dir_field = 'page_fs_dir' config_force_field = 'force_page' force_env = 'PAGE' pmem_force_env = '0' gran_detecto_arg = '-p' class CacheLine(Granularity): config_dir_field = 'cacheline_fs_dir' config_force_field = 'force_cacheline' force_env = 'CACHE_LINE' pmem_force_env = '1' gran_detecto_arg = '-c' class Byte(Granularity): config_dir_field = 'byte_fs_dir' config_force_field = 'force_byte' force_env = 'BYTE' pmem_force_env = '1' gran_detecto_arg = '-b' class Non(Granularity): """ No filesystem is used - granularity is irrelevant to the test. To ensure that the test indeed does not use any filesystem, accessing some fields of this class is prohibited. """ explicit = True def __init__(self, **kwargs): pass def setup(self, tools=None): pass def cleanup(self, *args, **kwargs): pass def __getattribute__(self, name): if name in ('dir', ): raise AttributeError("'{}' attribute cannot be used if the" " test is meant not to use any " "filesystem" .format(name)) else: return super().__getattribute__(name) # special kind of granularity requirement _CACHELINE_OR_LESS = 'cacheline_or_less' _PAGE_OR_LESS = 'page_or_less' @unique class _Granularity(Enum): PAGE = Page CACHELINE = CacheLine BYTE = Byte CL_OR_LESS = _CACHELINE_OR_LESS PAGE_OR_LESS = _PAGE_OR_LESS ANY = ctx.Any PAGE = _Granularity.PAGE CACHELINE = _Granularity.CACHELINE BYTE = _Granularity.BYTE CL_OR_LESS = _Granularity.CL_OR_LESS PAGE_OR_LESS = _Granularity.PAGE_OR_LESS ANY = _Granularity.ANY def require_granularity(*granularity, **kwargs): for g in granularity: if not isinstance(g, _Granularity): raise ValueError('selected granularity {} is invalid' .format(g)) enum_values = [g.value for g in granularity] def wrapped(tc): ctx.add_requirement(tc, 'granularity', enum_values, **kwargs) return tc return wrapped def no_testdir(**kwargs): def wrapped(tc): ctx.add_requirement(tc, 'granularity', Non, **kwargs) return tc return wrapped pmdk-1.11.1/src/test/unittest/Makefile0000664000000000000000000000512514123364546016326 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # src/test/unittest/Makefile -- build unittest support library # TOP := $(dir $(lastword $(MAKEFILE_LIST)))../../.. include $(TOP)/src/common.inc vpath %.c $(TOP)/src/common vpath %.h $(TOP)/src/common vpath %.c $(TOP)/src/core vpath %.h $(TOP)/src/core TARGET_UT = libut.a OBJS_UT = ut.o ut_alloc.o ut_file.o ut_pthread.o ut_signal.o ut_backtrace.o\ os_posix.o os_thread_posix.o util.o alloc.o rand.o ut_fh.o TARGET_UT_PMEM2 = ut_pmem2.a OBJS_UT_PMEM2 = ut_pmem2_config.o ut_pmem2_utils.o TARGET_UT_PMEMSET = ut_pmemset.a OBJS_UT_PMEMSET = ut_pmemset_utils.o CFLAGS = -I$(TOP)/src/include CFLAGS += -I$(TOP)/src/common CFLAGS += -I$(TOP)/src/core CFLAGS += -I$(TOP)/src/libpmem2 CFLAGS += -I$(TOP)/src/libpmemset CFLAGS += $(OS_INCS) CFLAGS += -std=gnu99 CFLAGS += -ggdb CFLAGS += -Wall CFLAGS += -Werror CFLAGS += -Wmissing-prototypes CFLAGS += -Wpointer-arith CFLAGS += -Wsign-conversion CFLAGS += -Wsign-compare ifeq ($(WCONVERSION_AVAILABLE), y) CFLAGS += -Wconversion endif CFLAGS += -pthread CFLAGS += -fno-common ifeq ($(IS_ICC), n) CFLAGS += -Wunused-macros CFLAGS += -Wmissing-field-initializers endif ifeq ($(WUNREACHABLE_CODE_RETURN_AVAILABLE), y) CFLAGS += -Wunreachable-code-return endif ifeq ($(WMISSING_VARIABLE_DECLARATIONS_AVAILABLE), y) CFLAGS += -Wmissing-variable-declarations endif ifeq ($(WFLOAT_EQUAL_AVAILABLE), y) CFLAGS += -Wfloat-equal endif ifeq ($(WSWITCH_DEFAULT_AVAILABLE), y) CFLAGS += -Wswitch-default endif ifeq ($(WCAST_FUNCTION_TYPE_AVAILABLE), y) CFLAGS += -Wcast-function-type endif ifeq ($(USE_LIBUNWIND),y) CFLAGS += $(shell $(PKG_CONFIG) --cflags libunwind) -DUSE_LIBUNWIND endif ifeq ($(COVERAGE),1) CFLAGS += $(GCOV_CFLAGS) LDFLAGS += $(GCOV_LDFLAGS) LIBS += $(GCOV_LIBS) endif CFLAGS += $(EXTRA_CFLAGS) LIBS += $(LIBUTIL) all test: $(TARGET_UT) $(TARGET_UT_PMEM2) $(TARGET_UT_PMEMSET) $(TARGET_UT): $(OBJS_UT) $(AR) rv $@ $(OBJS_UT) $(TARGET_UT_PMEM2): $(OBJS_UT_PMEM2) $(AR) rv $@ $(OBJS_UT_PMEM2) $(TARGET_UT_PMEMSET): $(OBJS_UT_PMEMSET) $(AR) rv $@ $(OBJS_UT_PMEMSET) ifneq ($(CSTYLEON),0) $(TARGET): unittest.htmp endif objdir=. .c.o: $(call check-cstyle, $<) @mkdir -p .deps $(CC) -MD -c $(CFLAGS) $(INCS) $(COMMONINCS) $(call coverage-path, $<) -o $@ $(create-deps) %.htmp: %.h $(call check-cstyle, $<, $@) clean: $(RM) *.o core a.out unittest.htmp clobber: clean $(RM) $(TARGET_UT) $(TARGET_UT_PMEM2) $(TARGET_UT_PMEMSET) $(RM) -r .deps test check pcheck pycheck: all sparse: $(sparse-c) .PHONY: all test check clean clobber cstyle format pcheck -include .deps/*.P pmdk-1.11.1/src/test/unittest/ut_pmem2_setup_integration.h0000664000000000000000000000133314123364546022407 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_setup_integration.h -- libpmem2 setup functions using public API * (for integration tests) */ #ifndef UT_PMEM2_SETUP_INTEGRATION_H #define UT_PMEM2_SETUP_INTEGRATION_H 1 #include "ut_fh.h" /* a prepare_config() that can't set wrong value */ #define PMEM2_PREPARE_CONFIG_INTEGRATION(cfg, src, fd, g) \ ut_pmem2_prepare_config_integration( \ __FILE__, __LINE__, __func__, cfg, src, fd, g) void ut_pmem2_prepare_config_integration(const char *file, int line, const char *func, struct pmem2_config **cfg, struct pmem2_source **src, int fd, enum pmem2_granularity granularity); #endif /* UT_PMEM2_SETUP_INTEGRATION_H */ pmdk-1.11.1/src/test/unittest/ut_pmem2_setup.c0000664000000000000000000000144514123364546020003 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_setup.h -- libpmem2 setup functions using non-public API * (only for unit tests) */ #include "../../libpmem2/config.h" #include "ut_pmem2_source.h" #include "ut_pmem2_setup.h" #include "unittest.h" /* * ut_pmem2_prepare_config -- fill pmem2_config, this function can not set * the wrong value */ void ut_pmem2_prepare_config(struct pmem2_config *cfg, struct pmem2_source **src, struct FHandle **fh, enum file_handle_type fh_type, const char *file, size_t length, size_t offset, int access) { pmem2_config_init(cfg); cfg->offset = offset; cfg->length = length; cfg->requested_max_granularity = PMEM2_GRANULARITY_PAGE; *fh = UT_FH_OPEN(fh_type, file, access); PMEM2_SOURCE_FROM_FH(src, *fh); } pmdk-1.11.1/src/test/unittest/ut_pmem2_source.h0000664000000000000000000000320614123364546020145 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_source.h -- utility helper functions for libpmem2 source tests */ #ifndef UT_PMEM2_SOURCE_H #define UT_PMEM2_SOURCE_H 1 #include "ut_fh.h" /* a pmem2_config_set_fd() that can't return NULL */ #define PMEM2_SOURCE_FROM_FD(src, fd) \ ut_pmem2_source_from_fd(__FILE__, __LINE__, __func__, src, fd) /* a pmem2_config_set_fd() that can't return NULL */ #define PMEM2_SOURCE_FROM_FH(src, fh) \ ut_pmem2_source_from_fh(__FILE__, __LINE__, __func__, src, fh) /* a pmem2_source_alignment() that can't return an error */ #define PMEM2_SOURCE_ALIGNMENT(src, al) \ ut_pmem2_source_alignment(__FILE__, __LINE__, __func__, src, al) /* a pmem2_source_delete() that can't return NULL */ #define PMEM2_SOURCE_DELETE(src) \ ut_pmem2_source_delete(__FILE__, __LINE__, __func__, src) /* a pmem2_source_source() that can't return NULL */ #define PMEM2_SOURCE_SIZE(src, size) \ ut_pmem2_source_size(__FILE__, __LINE__, __func__, src, size) void ut_pmem2_source_from_fd(const char *file, int line, const char *func, struct pmem2_source **src, int fd); void ut_pmem2_source_from_fh(const char *file, int line, const char *func, struct pmem2_source **src, struct FHandle *fhandle); void ut_pmem2_source_alignment(const char *file, int line, const char *func, struct pmem2_source *src, size_t *alignment); void ut_pmem2_source_delete(const char *file, int line, const char *func, struct pmem2_source **src); void ut_pmem2_source_size(const char *file, int line, const char *func, struct pmem2_source *src, size_t *size); #endif /* UT_PMEM2_SOURCE_H */ pmdk-1.11.1/src/test/unittest/ut_pmem2_config.h0000664000000000000000000000220314123364546020106 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * ut_pmem2_config.h -- utility helper functions for libpmem2 config tests */ #ifndef UT_PMEM2_CONFIG_H #define UT_PMEM2_CONFIG_H 1 #include "ut_fh.h" /* a pmem2_config_new() that can't return NULL */ #define PMEM2_CONFIG_NEW(cfg) \ ut_pmem2_config_new(__FILE__, __LINE__, __func__, cfg) /* a pmem2_config_set_required_store_granularity() doesn't return an error */ #define PMEM2_CONFIG_SET_GRANULARITY(cfg, g) \ ut_pmem2_config_set_required_store_granularity \ (__FILE__, __LINE__, __func__, cfg, g) /* a pmem2_config_delete() that can't return NULL */ #define PMEM2_CONFIG_DELETE(cfg) \ ut_pmem2_config_delete(__FILE__, __LINE__, __func__, cfg) void ut_pmem2_config_new(const char *file, int line, const char *func, struct pmem2_config **cfg); void ut_pmem2_config_set_required_store_granularity(const char *file, int line, const char *func, struct pmem2_config *cfg, enum pmem2_granularity g); void ut_pmem2_config_delete(const char *file, int line, const char *func, struct pmem2_config **cfg); #endif /* UT_PMEM2_CONFIG_H */ pmdk-1.11.1/src/test/unittest/ut_pmem2_utils.c0000664000000000000000000000146214123364546020002 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * ut_pmem2_utils.c -- utility helper functions for libpmem2 tests */ #include "unittest.h" #include "ut_pmem2_utils.h" /* * ut_pmem2_expect_return -- veryfies error code and prints appropriate * error message in case of error */ void ut_pmem2_expect_return(const char *file, int line, const char *func, int value, int expected) { if (value != expected) { ut_fatal(file, line, func, "unexpected return code (got %d, expected: %d): %s", value, expected, (value == 0 ? "success" : pmem2_errormsg())); } if (expected) { const char *msg = pmem2_errormsg(); if (!strlen(msg)) ut_fatal(file, line, func, "expected return value is %d, so " "error message should not be empty!", expected); } } pmdk-1.11.1/src/test/unittest/ut_fh.h0000664000000000000000000000334414123364546016145 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2019-2020, Intel Corporation */ /* * ut_fh.h -- OS-independent file handle / file descriptor interface */ #ifndef UT_FH_H #define UT_FH_H #include "os.h" struct FHandle; enum file_handle_type { FH_FD, FH_HANDLE }; #define FH_ACCMODE (7) #define FH_READ (1 << 0) #define FH_WRITE (1 << 1) #define FH_RDWR (FH_READ | FH_WRITE) #define FH_EXEC (1 << 2) #define FH_CREAT (1 << 3) #define FH_EXCL (1 << 4) #define FH_TRUNC (1 << 5) /* needs directory, on Windows it creates publicly visible file */ #define FH_TMPFILE (1 << 6) #define FH_DIRECTORY (1 << 7) #define UT_FH_OPEN(type, path, flags, ...) \ ut_fh_open(__FILE__, __LINE__, __func__, type, path, \ flags, ##__VA_ARGS__) #define UT_FH_TRUNCATE(fhandle, size) \ ut_fh_truncate(__FILE__, __LINE__, __func__, fhandle, size) #define UT_FH_GET_FD(fhandle) \ ut_fh_get_fd(__FILE__, __LINE__, __func__, fhandle) #ifdef _WIN32 #define UT_FH_GET_HANDLE(fhandle) \ ut_fh_get_handle(__FILE__, __LINE__, __func__, fhandle) #endif #define UT_FH_CLOSE(fhandle) \ ut_fh_close(__FILE__, __LINE__, __func__, fhandle) struct FHandle *ut_fh_open(const char *file, int line, const char *func, enum file_handle_type type, const char *path, int flags, ...); void ut_fh_truncate(const char *file, int line, const char *func, struct FHandle *f, os_off_t length); void ut_fh_close(const char *file, int line, const char *func, struct FHandle *f); enum file_handle_type ut_fh_get_handle_type(struct FHandle *fh); int ut_fh_get_fd(const char *file, int line, const char *func, struct FHandle *f); #ifdef _WIN32 HANDLE ut_fh_get_handle(const char *file, int line, const char *func, struct FHandle *f); #endif #endif pmdk-1.11.1/src/test/unittest/ut_pmem2_setup.h0000664000000000000000000000075114123364546020007 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_setup.h -- libpmem2 setup functions using non-public API * (only for unit tests) */ #ifndef UT_PMEM2_SETUP_H #define UT_PMEM2_SETUP_H 1 #include "ut_fh.h" void ut_pmem2_prepare_config(struct pmem2_config *cfg, struct pmem2_source **src, struct FHandle **fh, enum file_handle_type fh_type, const char *path, size_t length, size_t offset, int access); #endif /* UT_PMEM2_SETUP_H */ pmdk-1.11.1/src/test/unittest/unittest.sh0000664000000000000000000027264614123364546017117 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # set -e # make sure we have a well defined locale for string operations here export LC_ALL="C" #export LC_ALL="en_US.UTF-8" if ! [ -f ../envconfig.sh ]; then echo >&2 "envconfig.sh is missing -- is the tree built?" exit 1 fi . ../testconfig.sh . ../envconfig.sh if [ -t 1 ]; then IS_TERMINAL_STDOUT=YES fi if [ -t 2 ]; then IS_TERMINAL_STDERR=YES fi function is_terminal() { local fd fd=$1 case $(eval "echo \${IS_TERMINAL_${fd}}") in YES) : ;; *) false ;; esac } function interactive_color() { local color fd color=$1 fd=$2 shift 2 if is_terminal ${fd} && command -v tput >/dev/null; then echo "$(tput setaf $color || :)$*$(tput sgr0 || :)" else echo "$*" fi } function interactive_red() { interactive_color 1 "$@" } function interactive_green() { interactive_color 2 "$@" } function verbose_msg() { if [ "$UNITTEST_LOG_LEVEL" -ge 2 ]; then echo "$*" fi } function msg() { if [ "$UNITTEST_LOG_LEVEL" -ge 1 ]; then echo "$*" fi } function fatal() { echo "$*" >&2 exit 1 } if [ -z "${UNITTEST_NAME}" ]; then CURDIR=$(basename $(pwd)) SCRIPTNAME=$(basename $0) export UNITTEST_NAME=$CURDIR/$SCRIPTNAME export UNITTEST_NUM=$(echo $SCRIPTNAME | sed "s/TEST//") fi # defaults [ "$UNITTEST_LOG_LEVEL" ] || UNITTEST_LOG_LEVEL=2 [ "$GREP" ] || GREP="grep -a" [ "$TEST" ] || TEST=check [ "$FS" ] || FS=any [ "$BUILD" ] || BUILD=debug [ "$CHECK_TYPE" ] || CHECK_TYPE=auto [ "$CHECK_POOL" ] || CHECK_POOL=0 [ "$VERBOSE" ] || VERBOSE=0 [ -n "${SUFFIX+x}" ] || SUFFIX="😘⠏⠍⠙⠅ɗPMDKӜ⥺🙋" export UNITTEST_LOG_LEVEL GREP TEST FS BUILD CHECK_TYPE CHECK_POOL VERBOSE SUFFIX TOOLS=../tools LIB_TOOLS="../../tools" # Paths to some useful tools [ "$PMEMPOOL" ] || PMEMPOOL=$LIB_TOOLS/pmempool/pmempool [ "$DAXIO" ] || DAXIO=$LIB_TOOLS/daxio/daxio [ "$PMEMSPOIL" ] || PMEMSPOIL=$TOOLS/pmemspoil/pmemspoil.static-nondebug [ "$BTTCREATE" ] || BTTCREATE=$TOOLS/bttcreate/bttcreate.static-nondebug [ "$PMEMWRITE" ] || PMEMWRITE=$TOOLS/pmemwrite/pmemwrite [ "$PMEMALLOC" ] || PMEMALLOC=$TOOLS/pmemalloc/pmemalloc [ "$PMEMOBJCLI" ] || PMEMOBJCLI=$TOOLS/pmemobjcli/pmemobjcli [ "$PMEMDETECT" ] || PMEMDETECT=$TOOLS/pmemdetect/pmemdetect.static-nondebug [ "$PMREORDER" ] || PMREORDER=$LIB_TOOLS/pmreorder/pmreorder.py [ "$FIP" ] || FIP=$TOOLS/fip/fip [ "$DDMAP" ] || DDMAP=$TOOLS/ddmap/ddmap [ "$CMPMAP" ] || CMPMAP=$TOOLS/cmpmap/cmpmap [ "$EXTENTS" ] || EXTENTS=$TOOLS/extents/extents [ "$FALLOCATE_DETECT" ] || FALLOCATE_DETECT=$TOOLS/fallocate_detect/fallocate_detect.static-nondebug [ "$OBJ_VERIFY" ] || OBJ_VERIFY=$TOOLS/obj_verify/obj_verify [ "$USC_PERMISSION" ] || USC_PERMISSION=$TOOLS/usc_permission_check/usc_permission_check.static-nondebug [ "$ANONYMOUS_MMAP" ] || ANONYMOUS_MMAP=$TOOLS/anonymous_mmap/anonymous_mmap.static-nondebug # force globs to fail if they don't match shopt -s failglob # number of remote nodes required in the current unit test NODES_MAX=-1 # sizes of alignments SIZE_4KB=4096 SIZE_2MB=2097152 readonly PAGE_SIZE=$(getconf PAGESIZE) readonly CACHELINE_SIZE=$(cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size 2>/dev/null || echo 64) # PMEMOBJ limitations PMEMOBJ_MAX_ALLOC_SIZE=17177771968 # SSH and SCP options SSH_OPTS="-o BatchMode=yes" SCP_OPTS="-o BatchMode=yes -r -p" NDCTL_MIN_VERSION="63" # list of common files to be copied to all remote nodes DIR_SRC="../.." FILES_COMMON_DIR="\ $DIR_SRC/test/*.supp \ $DIR_SRC/tools/rpmemd/rpmemd \ $DIR_SRC/tools/pmempool/pmempool \ $DIR_SRC/test/tools/extents/extents \ $DIR_SRC/test/tools/obj_verify/obj_verify \ $DIR_SRC/test/tools/ctrld/ctrld \ $DIR_SRC/test/tools/fip/fip" # Portability VALGRIND_SUPP="--suppressions=../ld.supp \ --suppressions=../memcheck-libunwind.supp \ --suppressions=../memcheck-ndctl.supp" if [ "$(uname -s)" = "FreeBSD" ]; then DATE="gdate" DD="gdd" FALLOCATE="mkfile" VM_OVERCOMMIT="[ $(sysctl vm.overcommit | awk '{print $2}') == 0 ]" RM_ONEFS="-x" STAT_MODE="-f%Lp" STAT_PERM="-f%Sp" STAT_SIZE="-f%z" STRACE="truss" VALGRIND_SUPP="$VALGRIND_SUPP --suppressions=../freebsd.supp" else DATE="date" DD="dd" FALLOCATE="fallocate -l" VM_OVERCOMMIT="[ $(cat /proc/sys/vm/overcommit_memory) != 2 ]" RM_ONEFS="--one-file-system" STAT_MODE="-c%a" STAT_PERM="-c%A" STAT_SIZE="-c%s" STRACE="strace" fi # array of lists of PID files to be cleaned in case of an error NODE_PID_FILES[0]="" case "$BUILD" in debug|static-debug) if [ -z "$PMDK_LIB_PATH_DEBUG" ]; then PMDK_LIB_PATH=../../debug REMOTE_PMDK_LIB_PATH=../debug else PMDK_LIB_PATH=$PMDK_LIB_PATH_DEBUG REMOTE_PMDK_LIB_PATH=$PMDK_LIB_PATH_DEBUG fi ;; nondebug|static-nondebug) if [ -z "$PMDK_LIB_PATH_NONDEBUG" ]; then PMDK_LIB_PATH=../../nondebug REMOTE_PMDK_LIB_PATH=../nondebug else PMDK_LIB_PATH=$PMDK_LIB_PATH_NONDEBUG REMOTE_PMDK_LIB_PATH=$PMDK_LIB_PATH_NONDEBUG fi ;; esac export LD_LIBRARY_PATH=$PMDK_LIB_PATH:$GLOBAL_LIB_PATH:$LD_LIBRARY_PATH export REMOTE_LD_LIBRARY_PATH=$REMOTE_PMDK_LIB_PATH:$GLOBAL_LIB_PATH:\$LD_LIBRARY_PATH export PATH=$GLOBAL_PATH:$PATH export REMOTE_PATH=$GLOBAL_PATH:\$PATH export PKG_CONFIG_PATH=$GLOBAL_PKG_CONFIG_PATH:$PKG_CONFIG_PATH export REMOTE_PKG_CONFIG_PATH=$GLOBAL_PKG_CONFIG_PATH:\$PKG_CONFIG_PATH # # When running static binary tests, append the build type to the binary # case "$BUILD" in static-*) EXESUFFIX=.$BUILD ;; esac # # The variable DIR is constructed so the test uses that directory when # constructing test files. DIR is chosen based on the fs-type for # this test, and if the appropriate fs-type doesn't have a directory # defined in testconfig.sh, the test is skipped. # # This behavior can be overridden by setting DIR. For example: # DIR=/force/test/dir ./TEST0 # curtestdir=`basename $PWD` # just in case if [ ! "$curtestdir" ]; then fatal "curtestdir does not have a value" fi curtestdir=test_$curtestdir if [ ! "$UNITTEST_NUM" ]; then fatal "UNITTEST_NUM does not have a value" fi if [ ! "$UNITTEST_NAME" ]; then fatal "UNITTEST_NAME does not have a value" fi REAL_FS=$FS if [ "$DIR" ]; then DIR=$DIR/$curtestdir$UNITTEST_NUM else case "$FS" in pmem) # if a variable is set - it must point to a valid directory if [ "$PMEM_FS_DIR" == "" ]; then fatal "$UNITTEST_NAME: PMEM_FS_DIR is not set" fi DIR=$PMEM_FS_DIR/$DIRSUFFIX/$curtestdir$UNITTEST_NUM if [ "$PMEM_FS_DIR_FORCE_PMEM" = "1" ] || [ "$PMEM_FS_DIR_FORCE_PMEM" = "2" ]; then export PMEM_IS_PMEM_FORCE=1 fi ;; non-pmem) # if a variable is set - it must point to a valid directory if [ "$NON_PMEM_FS_DIR" == "" ]; then fatal "$UNITTEST_NAME: NON_PMEM_FS_DIR is not set" fi DIR=$NON_PMEM_FS_DIR/$DIRSUFFIX/$curtestdir$UNITTEST_NUM ;; any) if [ "$PMEM_FS_DIR" != "" ]; then DIR=$PMEM_FS_DIR/$DIRSUFFIX/$curtestdir$UNITTEST_NUM REAL_FS=pmem if [ "$PMEM_FS_DIR_FORCE_PMEM" = "1" ] || [ "$PMEM_FS_DIR_FORCE_PMEM" = "2" ]; then export PMEM_IS_PMEM_FORCE=1 fi elif [ "$NON_PMEM_FS_DIR" != "" ]; then DIR=$NON_PMEM_FS_DIR/$DIRSUFFIX/$curtestdir$UNITTEST_NUM REAL_FS=non-pmem else fatal "$UNITTEST_NAME: fs-type=any and both env vars are empty" fi ;; none) DIR=/dev/null/not_existing_dir/$DIRSUFFIX/$curtestdir$UNITTEST_NUM ;; *) verbose_msg "$UNITTEST_NAME: SKIP fs-type $FS (not configured)" exit 0 ;; esac fi # # The default is to turn on library logging to level 3 and save it to local files. # Tests that don't want it on, should override these environment variables. # export PMEM_LOG_LEVEL=3 export PMEM_LOG_FILE=pmem$UNITTEST_NUM.log export PMEMBLK_LOG_LEVEL=3 export PMEMBLK_LOG_FILE=pmemblk$UNITTEST_NUM.log export PMEMLOG_LOG_LEVEL=3 export PMEMLOG_LOG_FILE=pmemlog$UNITTEST_NUM.log export PMEMOBJ_LOG_LEVEL=3 export PMEMOBJ_LOG_FILE=pmemobj$UNITTEST_NUM.log export PMEMPOOL_LOG_LEVEL=3 export PMEMPOOL_LOG_FILE=pmempool$UNITTEST_NUM.log export PMREORDER_LOG_FILE=pmreorder$UNITTEST_NUM.log export OUT_LOG_FILE=out$UNITTEST_NUM.log export ERR_LOG_FILE=err$UNITTEST_NUM.log export TRACE_LOG_FILE=trace$UNITTEST_NUM.log export PREP_LOG_FILE=prep$UNITTEST_NUM.log export VALGRIND_LOG_FILE=${CHECK_TYPE}${UNITTEST_NUM}.log export VALIDATE_VALGRIND_LOG=1 export RPMEM_LOG_LEVEL=3 export RPMEM_LOG_FILE=rpmem$UNITTEST_NUM.log export RPMEMD_LOG_LEVEL=info export RPMEMD_LOG_FILE=rpmemd$UNITTEST_NUM.log export REMOTE_VARS=" RPMEMD_LOG_FILE RPMEMD_LOG_LEVEL RPMEM_LOG_FILE RPMEM_LOG_LEVEL PMEM_LOG_FILE PMEM_LOG_LEVEL PMEMOBJ_LOG_FILE PMEMOBJ_LOG_LEVEL PMEMPOOL_LOG_FILE PMEMPOOL_LOG_LEVEL" [ "$UT_DUMP_LINES" ] || UT_DUMP_LINES=30 export CHECK_POOL_LOG_FILE=check_pool_${BUILD}_${UNITTEST_NUM}.log # In case a lock is required for Device DAXes DEVDAX_LOCK=../devdax.lock # # store_exit_on_error -- store on a stack a sign that reflects the current state # of the 'errexit' shell option # function store_exit_on_error() { if [ "${-#*e}" != "$-" ]; then estack+=- else estack+=+ fi } # # restore_exit_on_error -- restore the state of the 'errexit' shell option # function restore_exit_on_error() { if [ -z $estack ]; then fatal "error: store_exit_on_error function has to be called first" fi eval "set ${estack:${#estack}-1:1}e" estack=${estack%?} } # # disable_exit_on_error -- store the state of the 'errexit' shell option and # disable it # function disable_exit_on_error() { store_exit_on_error set +e } # # get_files -- print list of files in the current directory matching the given regex to stdout # # This function has been implemented to workaround a race condition in # `find`, which fails if any file disappears in the middle of the operation. # # example, to list all *.log files in the current directory # get_files ".*\.log" function get_files() { disable_exit_on_error ls -1 | grep -E "^$*$" restore_exit_on_error } # # get_executables -- print list of executable files in the current directory to stdout # # This function has been implemented to workaround a race condition in # `find`, which fails if any file disappears in the middle of the operation. # function get_executables() { disable_exit_on_error for c in * do if [ -f $c -a -x $c ] then echo "$c" fi done restore_exit_on_error } # # convert_to_bytes -- converts the string with K, M, G or T suffixes # to bytes # # example: # "1G" --> "1073741824" # "2T" --> "2199023255552" # "3k" --> "3072" # "1K" --> "1024" # "10" --> "10" # function convert_to_bytes() { size="$(echo $1 | tr '[:upper:]' '[:lower:]')" if [[ $size == *kib ]] then size=$(($(echo $size | tr -d 'kib') * 1024)) elif [[ $size == *mib ]] then size=$(($(echo $size | tr -d 'mib') * 1024 * 1024)) elif [[ $size == *gib ]] then size=$(($(echo $size | tr -d 'gib') * 1024 * 1024 * 1024)) elif [[ $size == *tib ]] then size=$(($(echo $size | tr -d 'tib') * 1024 * 1024 * 1024 * 1024)) elif [[ $size == *pib ]] then size=$(($(echo $size | tr -d 'pib') * 1024 * 1024 * 1024 * 1024 * 1024)) elif [[ $size == *kb ]] then size=$(($(echo $size | tr -d 'kb') * 1000)) elif [[ $size == *mb ]] then size=$(($(echo $size | tr -d 'mb') * 1000 * 1000)) elif [[ $size == *gb ]] then size=$(($(echo $size | tr -d 'gb') * 1000 * 1000 * 1000)) elif [[ $size == *tb ]] then size=$(($(echo $size | tr -d 'tb') * 1000 * 1000 * 1000 * 1000)) elif [[ $size == *pb ]] then size=$(($(echo $size | tr -d 'pb') * 1000 * 1000 * 1000 * 1000 * 1000)) elif [[ $size == *b ]] then size=$(($(echo $size | tr -d 'b'))) elif [[ $size == *k ]] then size=$(($(echo $size | tr -d 'k') * 1024)) elif [[ $size == *m ]] then size=$(($(echo $size | tr -d 'm') * 1024 * 1024)) elif [[ $size == *g ]] then size=$(($(echo $size | tr -d 'g') * 1024 * 1024 * 1024)) elif [[ $size == *t ]] then size=$(($(echo $size | tr -d 't') * 1024 * 1024 * 1024 * 1024)) elif [[ $size == *p ]] then size=$(($(echo $size | tr -d 'p') * 1024 * 1024 * 1024 * 1024 * 1024)) fi echo "$size" } # # create_file -- create zeroed out files of a given length # # example, to create two files, each 1GB in size: # create_file 1G testfile1 testfile2 # function create_file() { size=$(convert_to_bytes $1) shift for file in $* do $DD if=/dev/zero of=$file bs=1M count=$size iflag=count_bytes status=none >> $PREP_LOG_FILE done } # # create_nonzeroed_file -- create non-zeroed files of a given length # # A given first kilobytes of the file is zeroed out. # # example, to create two files, each 1GB in size, with first 4K zeroed # create_nonzeroed_file 1G 4K testfile1 testfile2 # function create_nonzeroed_file() { offset=$(convert_to_bytes $2) size=$(($(convert_to_bytes $1) - $offset)) shift 2 for file in $* do truncate -s ${offset} $file >> $PREP_LOG_FILE $DD if=/dev/zero bs=1K count=${size} iflag=count_bytes 2>>$PREP_LOG_FILE | tr '\0' '\132' >> $file done } # # create_holey_file -- create holey files of a given length # # examples: # create_holey_file 1024k testfile1 testfile2 # create_holey_file 2048M testfile1 testfile2 # create_holey_file 234 testfile1 # create_holey_file 2340b testfile1 # # Input unit size is in bytes with optional suffixes like k, KB, M, etc. # function create_holey_file() { size=$(convert_to_bytes $1) shift for file in $* do truncate -s ${size} $file >> $PREP_LOG_FILE done } # # create_poolset -- create a dummy pool set # # Creates a pool set file using the provided list of part sizes and paths. # Optionally, it also creates the selected part files (zeroed, partially zeroed # or non-zeroed) with requested size and mode. The actual file size may be # different than the part size in the pool set file. # 'r' or 'R' on the list of arguments indicate the beginning of the next # replica set and 'm' or 'M' the beginning of the next remote replica set. # 'o' or 'O' indicates the next argument is a pool set option. # A remote replica requires two parameters: a target node and a pool set # descriptor. # # Each part argument has the following format: # psize:ppath[:cmd[:fsize[:mode]]] # # where: # psize - part size or AUTO (only for DAX device) # ppath - path # cmd - (optional) can be: # x - do nothing (may be skipped if there's no 'fsize', 'mode') # z - create zeroed (holey) file # n - create non-zeroed file # h - create non-zeroed file, but with zeroed header (first page) # d - create directory # fsize - (optional) the actual size of the part file (if 'cmd' is not 'x') # mode - (optional) same format as for 'chmod' command # # Each remote replica argument has the following format: # node:desc # # where: # node - target node # desc - pool set descriptor # # example: # The following command define a pool set consisting of two parts: 16MB # and 32MB, a local replica with only one part of 48MB and a remote replica. # The first part file is not created, the second is zeroed. The only replica # part is non-zeroed. Also, the last file is read-only and its size # does not match the information from pool set file. The last but one line # describes a remote replica. The SINGLEHDR poolset option is set, so only # the first part in each replica contains a pool header. The remote poolset # also has to have the SINGLEHDR option. # # create_poolset ./pool.set 16M:testfile1 32M:testfile2:z \ # R 48M:testfile3:n:11M:0400 \ # M remote_node:remote_pool.set \ # O SINGLEHDR # function create_poolset() { psfile=$1 shift 1 echo "PMEMPOOLSET" > $psfile while [ "$1" ] do if [ "$1" = "M" ] || [ "$1" = "m" ] # remote replica then shift 1 cmd=$1 shift 1 # extract last ":" separated segment as descriptor # extract everything before last ":" as node address # this extraction method is compatible with IPv6 and IPv4 node=${cmd%:*} desc=${cmd##*:} echo "REPLICA $node $desc" >> $psfile continue fi if [ "$1" = "R" ] || [ "$1" = "r" ] then echo "REPLICA" >> $psfile shift 1 continue fi if [ "$1" = "O" ] || [ "$1" = "o" ] then echo "OPTION $2" >> $psfile shift 2 continue fi cmd=$1 fparms=(${cmd//:/ }) shift 1 fsize=${fparms[0]} fpath=${fparms[1]} cmd=${fparms[2]} asize=${fparms[3]} mode=${fparms[4]} if [ ! $asize ]; then asize=$fsize fi if [ "$asize" != "AUTO" ]; then asize=$(convert_to_bytes $asize) fi case "$cmd" in x) # do nothing ;; z) # zeroed (holey) file truncate -s $asize $fpath >> $PREP_LOG_FILE ;; n) # non-zeroed file $DD if=/dev/zero bs=$asize count=1 2>>$PREP_LOG_FILE | tr '\0' '\132' >> $fpath ;; h) # non-zeroed file, except page size header truncate -s $PAGE_SIZE $fpath >> prep$UNITTEST_NUM.log $DD if=/dev/zero bs=$asize count=1 2>>$PREP_LOG_FILE | tr '\0' '\132' >> $fpath truncate -s $asize $fpath >> $PREP_LOG_FILE ;; d) mkdir -p $fpath ;; esac if [ $mode ]; then chmod $mode $fpath fi echo "$fsize $fpath" >> $psfile done } function dump_last_n_lines() { if [ "$1" != "" -a -f "$1" ]; then ln=`wc -l < $1` if [ $ln -gt $UT_DUMP_LINES ]; then echo -e "Last $UT_DUMP_LINES lines of $1 below (whole file has $ln lines)." >&2 ln=$UT_DUMP_LINES else echo -e "$1 below." >&2 fi paste -d " " <(yes $UNITTEST_NAME $1 | head -n $ln) <(tail -n $ln $1) >&2 echo >&2 fi } # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810295 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780173 # https://bugs.kde.org/show_bug.cgi?id=303877 # # valgrind issues an unsuppressable warning when exceeding # the brk segment, causing matching failures. We can safely # ignore it because malloc() will fallback to mmap() anyway. function valgrind_ignore_warnings() { cat $1 | grep -v \ -e "WARNING: Serious error when reading debug info" \ -e "When reading debug info from " \ -e "Ignoring non-Dwarf2/3/4 block in .debug_info" \ -e "Last block truncated in .debug_info; ignoring" \ -e "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" \ -e "brk segment overflow" \ -e "see section Limitations in user manual" \ -e "Warning: set address range perms: large range"\ -e "further instances of this message will not be shown"\ -e "get_Form_contents: DW_FORM_GNU_strp_alt used, but no alternate .debug_str"\ > $1.tmp mv $1.tmp $1 } # # valgrind_ignore_messages -- cuts off Valgrind messages that are irrelevant # to the correctness of the test, but changes during Valgrind rebase # usage: valgrind_ignore_messages # function valgrind_ignore_messages() { if [ -e "$1.match" ]; then cat $1 | grep -v \ -e "For lists of detected and suppressed errors, rerun with: -s" \ -e "For counts of detected and suppressed errors, rerun with: -v" \ > $1.tmp mv $1.tmp $1 fi } # # get_trace -- return tracing tool command line if applicable # usage: get_trace [] # function get_trace() { if [ "$1" == "none" ]; then echo "$TRACE" return fi local exe=$VALGRINDEXE local check_type=$1 local log_file=$2 local opts="$VALGRIND_OPTS" local node=-1 [ "$#" -eq 3 ] && node=$3 if [ "$check_type" = "memcheck" -a "$MEMCHECK_DONT_CHECK_LEAKS" != "1" ]; then opts="$opts --leak-check=full" fi if [ "$check_type" = "pmemcheck" ]; then # Before Skylake, Intel CPUs did not have clflushopt instruction, so # pmem_flush and pmem_persist both translated to clflush. # This means that missing pmem_drain after pmem_flush could only be # detected on Skylake+ CPUs. # This option tells pmemcheck to expect fence (sfence or # VALGRIND_PMC_DO_FENCE client request, used by pmem_drain) after # clflush and makes pmemcheck output the same on pre-Skylake and # post-Skylake CPUs. opts="$opts --expect-fence-after-clflush=yes" fi opts="$opts $VALGRIND_SUPP" if [ "$node" -ne -1 ]; then exe=${NODE_VALGRINDEXE[$node]} opts="$opts" case "$check_type" in memcheck) opts="$opts --suppressions=../memcheck-libibverbs.supp" ;; helgrind) opts="$opts --suppressions=../helgrind-cxgb4.supp" opts="$opts --suppressions=../helgrind-libfabric.supp" ;; drd) opts="$opts --suppressions=../drd-libfabric.supp" ;; esac fi echo "$exe --tool=$check_type --log-file=$log_file $opts $TRACE" return } # # validate_valgrind_log -- validate valgrind log # usage: validate_valgrind_log # function validate_valgrind_log() { [ "$VALIDATE_VALGRIND_LOG" != "1" ] && return # fail if there are valgrind errors found or # if it detects overlapping chunks if [ ! -e "$1.match" ] && grep \ -e "ERROR SUMMARY: [^0]" \ -e "Bad mempool" \ $1 >/dev/null ; then msg=$(interactive_red STDERR "failed") echo -e "$UNITTEST_NAME $msg with Valgrind. See $1. Last 20 lines below." >&2 paste -d " " <(yes $UNITTEST_NAME $1 | head -n 20) <(tail -n 20 $1) >&2 false fi } # # expect_normal_exit -- run a given command, expect it to exit 0 # # if VALGRIND_DISABLED is not empty valgrind tool will be omitted # function expect_normal_exit() { local VALGRIND_LOG_FILE=${CHECK_TYPE}${UNITTEST_NUM}.log local N=$2 # in case of a remote execution disable valgrind check if valgrind is not # enabled on node local _CHECK_TYPE=$CHECK_TYPE if [ "x$VALGRIND_DISABLED" != "x" ]; then _CHECK_TYPE=none fi if [ "$1" == "run_on_node" -o "$1" == "run_on_node_background" ]; then if [ -z $(is_valgrind_enabled_on_node $N) ]; then _CHECK_TYPE="none" fi else N=-1 fi if [ -n "$TRACE" ]; then case "$1" in *_on_node*) msg "$UNITTEST_NAME: SKIP: TRACE is not supported if test is executed on remote nodes" exit 0 esac fi local trace=$(get_trace $_CHECK_TYPE $VALGRIND_LOG_FILE $N) if [ "$MEMCHECK_DONT_CHECK_LEAKS" = "1" -a "$CHECK_TYPE" = "memcheck" ]; then export OLD_ASAN_OPTIONS="${ASAN_OPTIONS}" export ASAN_OPTIONS="detect_leaks=0 ${ASAN_OPTIONS}" fi if [ "$CHECK_TYPE" = "helgrind" ]; then export VALGRIND_OPTS="--suppressions=../helgrind-log.supp" fi if [ "$CHECK_TYPE" = "memcheck" ]; then export VALGRIND_OPTS="$VALGRIND_OPTS --suppressions=../memcheck-dlopen.supp" fi local REMOTE_VALGRIND_LOG=0 if [ "$CHECK_TYPE" != "none" ]; then case "$1" in run_on_node) REMOTE_VALGRIND_LOG=1 trace="$1 $2 $trace" [ $# -ge 2 ] && shift 2 || shift $# ;; run_on_node_background) trace="$1 $2 $3 $trace" [ $# -ge 3 ] && shift 3 || shift $# ;; wait_on_node|wait_on_node_port|kill_on_node) [ "$1" = "wait_on_node" ] && REMOTE_VALGRIND_LOG=1 trace="$1 $2 $3 $4" [ $# -ge 4 ] && shift 4 || shift $# ;; esac fi if [ "$CHECK_TYPE" = "drd" ]; then export VALGRIND_OPTS="$VALGRIND_OPTS --suppressions=../drd-log.supp" fi disable_exit_on_error eval $ECHO $trace "$*" ret=$? if [ $REMOTE_VALGRIND_LOG -eq 1 ]; then for node in $CHECK_NODES do local new_log_file=node\_$node\_$VALGRIND_LOG_FILE copy_files_from_node $node "." ${NODE_TEST_DIR[$node]}/$VALGRIND_LOG_FILE mv $VALGRIND_LOG_FILE $new_log_file done fi restore_exit_on_error if [ "$ret" -ne "0" ]; then if [ "$ret" -gt "128" ]; then msg="crashed (signal $(($ret - 128)))" else msg="failed with exit code $ret" fi msg=$(interactive_red STDERR $msg) if [ -f $ERR_LOG_FILE ]; then if [ "$UNITTEST_LOG_LEVEL" -ge "1" ]; then echo -e "$UNITTEST_NAME $msg. $ERR_LOG_FILE below." >&2 cat $ERR_LOG_FILE >&2 else echo -e "$UNITTEST_NAME $msg. $ERR_LOG_FILE above." >&2 fi else echo -e "$UNITTEST_NAME $msg." >&2 fi # ignore Ctrl-C if [ $ret != 130 ]; then for f in $(get_files ".*[a-zA-Z_]${UNITTEST_NUM}\.log"); do dump_last_n_lines $f done fi [ $NODES_MAX -ge 0 ] && clean_all_remote_nodes false fi if [ "$CHECK_TYPE" != "none" ]; then if [ $REMOTE_VALGRIND_LOG -eq 1 ]; then for node in $CHECK_NODES do local log_file=node\_$node\_$VALGRIND_LOG_FILE valgrind_ignore_warnings $new_log_file valgrind_ignore_messages $new_log_file validate_valgrind_log $new_log_file done else if [ -f $VALGRIND_LOG_FILE ]; then valgrind_ignore_warnings $VALGRIND_LOG_FILE valgrind_ignore_messages $VALGRIND_LOG_FILE validate_valgrind_log $VALGRIND_LOG_FILE fi fi fi if [ "$MEMCHECK_DONT_CHECK_LEAKS" = "1" -a "$CHECK_TYPE" = "memcheck" ]; then export ASAN_OPTIONS="${OLD_ASAN_OPTIONS}" fi } # # expect_abnormal_exit -- run a given command, expect it to exit non-zero # function expect_abnormal_exit() { if [ -n "$TRACE" ]; then case "$1" in *_on_node*) msg "$UNITTEST_NAME: SKIP: TRACE is not supported if test is executed on remote nodes" exit 0 esac fi if [ "$CHECK_TYPE" = "drd" ]; then export VALGRIND_OPTS="$VALGRIND_OPTS --suppressions=../drd-log.supp" fi disable_exit_on_error eval $ECHO ASAN_OPTIONS="detect_leaks=0 ${ASAN_OPTIONS}" $TRACE "$*" ret=$? restore_exit_on_error if [ "$ret" -eq "0" ]; then msg=$(interactive_red STDERR "succeeded") echo -e "$UNITTEST_NAME command $msg unexpectedly." >&2 [ $NODES_MAX -ge 0 ] && clean_all_remote_nodes false fi } # # check_pool -- run pmempool check on specified pool file # function check_pool() { if [ "$CHECK_POOL" == "1" ] then if [ "$VERBOSE" != "0" ] then echo "$UNITTEST_NAME: checking consistency of pool ${1}" fi ${PMEMPOOL}.static-nondebug check $1 2>&1 1>>$CHECK_POOL_LOG_FILE fi } # # check_pools -- run pmempool check on specified pool files # function check_pools() { if [ "$CHECK_POOL" == "1" ] then for f in $* do check_pool $f done fi } # # require_unlimited_vm -- require unlimited virtual memory # # This implies requirements for: # - overcommit_memory enabled (/proc/sys/vm/overcommit_memory is 0 or 1) # - unlimited virtual memory (ulimit -v is unlimited) # function require_unlimited_vm() { $VM_OVERCOMMIT && [ $(ulimit -v) = "unlimited" ] && return msg "$UNITTEST_NAME: SKIP required: overcommit_memory enabled and unlimited virtual memory" exit 0 } # # require_linked_with_ndctl -- require an executable linked with libndctl # # usage: require_linked_with_ndctl # function require_linked_with_ndctl() { [ "$1" == "" -o ! -x "$1" ] && \ fatal "$UNITTEST_NAME: ERROR: require_linked_with_ndctl() requires one argument - an executable file" local lddndctl=$(ldd $1 | $GREP -ce "libndctl") [ "$lddndctl" == "1" ] && return msg "$UNITTEST_NAME: SKIP required: executable $1 linked with libndctl" exit 0 } # # require_sudo_allowed -- require sudo command is allowed # function require_sudo_allowed() { if [ "$ENABLE_SUDO_TESTS" != "y" ]; then msg "$UNITTEST_NAME: SKIP: tests using 'sudo' are not enabled in testconfig.sh (ENABLE_SUDO_TESTS)" exit 0 fi if ! sh -c "timeout --signal=SIGKILL --kill-after=3s 3s sudo date" >/dev/null 2>&1 then msg "$UNITTEST_NAME: SKIP required: sudo allowed" exit 0 fi } # # require_sudo_allowed_node -- require sudo command on a remote node # # usage: require_sudo_allowed_node # function require_sudo_allowed_node() { if [ "$ENABLE_SUDO_TESTS" != "y" ]; then msg "$UNITTEST_NAME: SKIP: tests using 'sudo' are not enabled in testconfig.sh (ENABLE_SUDO_TESTS)" exit 0 fi if ! run_on_node $1 "timeout --signal=SIGKILL --kill-after=3s 3s sudo date" >/dev/null 2>&1 then msg "$UNITTEST_NAME: SKIP required: sudo allowed on node $1" exit 0 fi } # # require_no_superuser -- require user without superuser rights # function require_no_superuser() { local user_id=$(id -u) [ "$user_id" != "0" ] && return msg "$UNITTEST_NAME: SKIP required: run without superuser rights" exit 0 } # # require_no_freebsd -- Skip test on FreeBSD # function require_no_freebsd() { [ "$(uname -s)" != "FreeBSD" ] && return msg "$UNITTEST_NAME: SKIP: Not supported on FreeBSD" exit 0 } # # require_procfs -- Skip test if /proc is not mounted # function require_procfs() { mount | grep -q "/proc" && return msg "$UNITTEST_NAME: SKIP: /proc not mounted" exit 0 } # # require_arch -- Skip tests if the running platform not matches # any of the input list. # function require_arch() { for i in "$@"; do [[ "$(uname -m)" == "$i" ]] && return done msg "$UNITTEST_NAME: SKIP: Only supported on $1" exit 0 } # # exclude_arch -- Skip tests if the running platform matches # any of the input list. # function exclude_arch() { for i in "$@"; do if [[ "$(uname -m)" == "$i" ]]; then msg "$UNITTEST_NAME: SKIP: Not supported on $1" exit 0 fi done } # # require_x86_64 -- Skip tests if the running platform is not x86_64 # function require_x86_64() { require_arch x86_64 } # # require_ppc64 -- Skip tests if the running platform is not ppc64 or ppc64le # function require_ppc64() { require_arch "ppc64" "ppc64le" "ppc64el" } # # exclude_ppc64 -- Skip tests if the running platform is ppc64 or ppc64le # function exclude_ppc64() { exclude_arch "ppc64" "ppc64le" "ppc64el" } # # require_test_type -- only allow script to continue for a certain test type # function require_test_type() { req_test_type=1 for type in $* do case "$TEST" in all) # "all" is a synonym of "short + medium + long" return ;; check) # "check" is a synonym of "short + medium" [ "$type" = "short" -o "$type" = "medium" ] && return ;; *) [ "$type" = "$TEST" ] && return ;; esac done verbose_msg "$UNITTEST_NAME: SKIP test-type $TEST ($* required)" exit 0 } # # require_dev_dax_region -- check if region id file exist for dev dax # function require_dev_dax_region() { local prefix="$UNITTEST_NAME: SKIP" local cmd="$PMEMDETECT -r" for path in ${DEVICE_DAX_PATH[@]} do disable_exit_on_error out=$($cmd $path 2>&1) ret=$? restore_exit_on_error if [ "$ret" == "0" ]; then continue elif [ "$ret" == "1" ]; then msg "$prefix $out" exit 0 else fatal "$UNITTEST_NAME: pmemdetect: $out" fi done DEVDAX_TO_LOCK=1 } # # lock_devdax -- acquire a lock on Device DAXes # lock_devdax() { exec {DEVDAX_LOCK_FD}> $DEVDAX_LOCK flock $DEVDAX_LOCK_FD } # # unlock_devdax -- release a lock on Device DAXes # unlock_devdax() { flock -u $DEVDAX_LOCK_FD eval "exec ${DEVDAX_LOCK_FD}>&-" } # # require_dev_dax_node -- common function for require_dax_devices and # node_require_dax_device # # usage: require_dev_dax_node [] # function require_dev_dax_node() { req_dax_dev=1 if [ "$req_dax_dev_align" == "1" ]; then fatal "$UNITTEST_NAME: Do not use 'require_(node_)dax_devices' and " "'require_(node_)dax_device_alignments' together. Use the latter instead." fi local min=$1 local node=$2 if [ -n "$node" ]; then local DIR=${NODE_WORKING_DIR[$node]}/$curtestdir local prefix="$UNITTEST_NAME: SKIP NODE $node:" local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) if [ ${#device_dax_path[@]} -lt $min ]; then msg "$prefix NODE_${node}_DEVICE_DAX_PATH does not specify enough dax devices (min: $min)" exit 0 fi local cmd="ssh $SSH_OPTS ${NODE[$node]} cd $DIR && LD_LIBRARY_PATH=$REMOTE_LD_LIBRARY_PATH ../pmemdetect -d" else local prefix="$UNITTEST_NAME: SKIP" if [ ${#DEVICE_DAX_PATH[@]} -lt $min ]; then msg "$prefix DEVICE_DAX_PATH does not specify enough dax devices (min: $min)" exit 0 fi local device_dax_path=${DEVICE_DAX_PATH[@]} local cmd="$PMEMDETECT -d" fi for path in ${device_dax_path[@]} do disable_exit_on_error out=$($cmd $path 2>&1) ret=$? restore_exit_on_error if [ "$ret" == "0" ]; then continue elif [ "$ret" == "1" ]; then msg "$prefix $out" exit 0 else fatal "$UNITTEST_NAME: pmemdetect: $out" fi done DEVDAX_TO_LOCK=1 } # # require_ndctl_enable -- check NDCTL_ENABLE value and skip test if set to 'n' # function require_ndctl_enable() { if ! is_ndctl_enabled $PMEMPOOL$EXE &> /dev/null ; then msg "$UNITTEST_NAME: SKIP: ndctl is disabled - binary not compiled with libndctl" exit 0 fi return 0 } # # require_dax_devices -- only allow script to continue if there is a required # number of Device DAX devices and ndctl is available # function require_dax_devices() { require_ndctl_enable require_pkg libndctl "$NDCTL_MIN_VERSION" REQUIRE_DAX_DEVICES=$1 require_dev_dax_node $1 } # # require_node_dax_device -- only allow script to continue if specified node # has enough Device DAX devices defined in testconfig.sh # function require_node_dax_device() { validate_node_number $1 require_dev_dax_node $2 $1 } # # require_no_unicode -- overwrite unicode suffix to empty string # function require_no_unicode() { export SUFFIX="" } # # get_node_devdax_path -- get path of a Device DAX device on a node # # usage: get_node_devdax_path # get_node_devdax_path() { local node=$1 local device=$2 local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) echo ${device_dax_path[$device]} } # # dax_device_zero -- zero all local dax devices # dax_device_zero() { for path in ${DEVICE_DAX_PATH[@]} do ${PMEMPOOL}.static-debug rm -f $path done } # # node_dax_device_zero -- zero all dax devices on a node # node_dax_device_zero() { local node=$1 local DIR=${NODE_WORKING_DIR[$node]}/$curtestdir local prefix="$UNITTEST_NAME: SKIP NODE $node:" local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) local cmd="ssh $SSH_OPTS ${NODE[$node]} cd $DIR && LD_LIBRARY_PATH=$REMOTE_LD_LIBRARY_PATH ../pmempool rm -f" for path in ${device_dax_path[@]} do disable_exit_on_error out=$($cmd $path 2>&1) ret=$? restore_exit_on_error if [ "$ret" == "0" ]; then continue elif [ "$ret" == "1" ]; then msg "$prefix $out" exit 0 else fatal "$UNITTEST_NAME: pmempool rm: $out" fi done } # # get_devdax_size -- get the size of a device dax # function get_devdax_size() { local device=$1 local path=${DEVICE_DAX_PATH[$device]} local major_hex=$(stat -c "%t" $path) local minor_hex=$(stat -c "%T" $path) local major_dec=$((16#$major_hex)) local minor_dec=$((16#$minor_hex)) cat /sys/dev/char/$major_dec:$minor_dec/size } # # get_node_devdax_size -- get the size of a device dax on a node # function get_node_devdax_size() { local node=$1 local device=$2 local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) local path=${device_dax_path[$device]} local cmd_prefix="ssh $SSH_OPTS ${NODE[$node]} " disable_exit_on_error out=$($cmd_prefix stat -c %t $path 2>&1) ret=$? restore_exit_on_error if [ "$ret" != "0" ]; then fatal "$UNITTEST_NAME: stat on node $node: $out" fi local major=$((16#$out)) disable_exit_on_error out=$($cmd_prefix stat -c %T $path 2>&1) ret=$? restore_exit_on_error if [ "$ret" != "0" ]; then fatal "$UNITTEST_NAME: stat on node $node: $out" fi local minor=$((16#$out)) disable_exit_on_error out=$($cmd_prefix "cat /sys/dev/char/$major:$minor/size" 2>&1) ret=$? restore_exit_on_error if [ "$ret" != "0" ]; then fatal "$UNITTEST_NAME: stat on node $node: $out" fi echo $out } # # require_dax_device_node_alignments -- only allow script to continue if # the internal Device DAX alignments on a remote nodes are as specified. # If necessary, it sorts DEVICE_DAX_PATH entries to match # the requested alignment order. # # usage: require_node_dax_device_alignments [ alignment2 ... ] # function require_node_dax_device_alignments() { req_dax_dev_align=1 if [ "$req_dax_dev" == "$1" ]; then fatal "$UNITTEST_NAME: Do not use 'require_(node_)dax_devices' and " "'require_(node_)dax_device_alignments' together. Use the latter instead." fi local node=$1 shift if [ "$node" == "-1" ]; then local device_dax_path=(${DEVICE_DAX_PATH[@]}) local cmd="$PMEMDETECT -a" else local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) local DIR=${NODE_WORKING_DIR[$node]}/$curtestdir local cmd="ssh $SSH_OPTS ${NODE[$node]} cd $DIR && LD_LIBRARY_PATH=$REMOTE_LD_LIBRARY_PATH ../pmemdetect -a" fi local cnt=${#device_dax_path[@]} local j=0 for alignment in $* do for (( i=j; i&1) ret=$? restore_exit_on_error if [ "$ret" == "0" ]; then if [ $i -ne $j ]; then # swap device paths tmp=${device_dax_path[$j]} device_dax_path[$j]=$path device_dax_path[$i]=$tmp if [ "$node" == "-1" ]; then DEVICE_DAX_PATH=(${device_dax_path[@]}) else NODE_DEVICE_DAX_PATH[$node]=${device_dax_path[@]} fi fi break fi done if [ $i -eq $cnt ]; then if [ "$node" == "-1" ]; then msg "$UNITTEST_NAME: SKIP DEVICE_DAX_PATH"\ "does not specify enough dax devices or they don't have required alignments (min: $#, alignments: $*)" else msg "$UNITTEST_NAME: SKIP NODE $node: NODE_${node}_DEVICE_DAX_PATH"\ "does not specify enough dax devices or they don't have required alignments (min: $#, alignments: $*)" fi exit 0 fi j=$(( j + 1 )) done } # # require_dax_device_alignments -- only allow script to continue if # the internal Device DAX alignments are as specified. # If necessary, it sorts DEVICE_DAX_PATH entries to match # the requested alignment order. # # usage: require_dax_device_alignments alignment1 [ alignment2 ... ] # require_dax_device_alignments() { require_node_dax_device_alignments -1 $* } # # disable_eatmydata -- ensure invalid msyncs fail # # Distros (and people) like to use eatmydata to kill fsync-likes during builds # and testing. This is nice for speed, but we actually rely on msync failing # in some tests. # disable_eatmydata() { export LD_PRELOAD="${LD_PRELOAD/#libeatmydata.so/}" export LD_PRELOAD="${LD_PRELOAD/ libeatmydata.so/}" export LD_PRELOAD="${LD_PRELOAD/:libeatmydata.so/}" } # # require_fs_type -- only allow script to continue for a certain fs type # function require_fs_type() { req_fs_type=1 for type in $* do # treat any as either pmem or non-pmem [ "$type" = "$FS" ] || ([ -n "${FORCE_FS:+x}" ] && [ "$type" = "any" ] && [ "$FS" != "none" ]) && return done verbose_msg "$UNITTEST_NAME: SKIP fs-type $FS ($* required)" exit 0 } # # require_native_fallocate -- verify if filesystem supports fallocate # function require_native_fallocate() { require_fs_type pmem non-pmem set +e $FALLOCATE_DETECT $1 status=$? set -e if [ $status -eq 1 ]; then msg "$UNITTEST_NAME: SKIP: filesystem does not support fallocate" exit 0 elif [ $status -ne 0 ]; then msg "$UNITTEST_NAME: fallocate_detect failed" exit 1 fi } # # require_usc_permission -- verify if usc can be read with current permissions # function require_usc_permission() { set +e $USC_PERMISSION $1 2> $DIR/usc_permission.txt status=$? set -e # check if there were any messages printed to stderr, skip test if there were usc_stderr=$(cat $DIR/usc_permission.txt | wc -c) rm -f $DIR/usc_permission.txt if [ $status -eq 1 ] || [ $usc_stderr -ne 0 ]; then msg "$UNITTEST_NAME: SKIP: missing permissions to read usc" exit 0 elif [ $status -ne 0 ]; then msg "$UNITTEST_NAME: usc_permission_check failed" exit 1 fi } # # require_fs_name -- verify if the $DIR is on the required file system # # Must be AFTER setup() because $DIR must exist # function require_fs_name() { fsname=`df $DIR -PT | awk '{if (NR == 2) print $2}'` for name in $* do if [ "$name" == "$fsname" ]; then return fi done msg "$UNITTEST_NAME: SKIP file system $fsname ($* required)" exit 0 } # # require_build_type -- only allow script to continue for a certain build type # function require_build_type() { for type in $* do [ "$type" = "$BUILD" ] && return done verbose_msg "$UNITTEST_NAME: SKIP build-type $BUILD ($* required)" exit 0 } # # require_command -- only allow script to continue if specified command exists # function require_command() { if ! which $1 >/dev/null 2>&1; then msg "$UNITTEST_NAME: SKIP: '$1' command required" exit 0 fi } # # require_command_node -- only allow script to continue if specified command exists on a remote node # # usage: require_command_node # function require_command_node() { if ! run_on_node $1 "which $2 >/dev/null 2>&1"; then msg "$UNITTEST_NAME: SKIP: node $1: '$2' command required" exit 0 fi } # # require_kernel_module -- only allow script to continue if specified kernel module exists # # usage: require_kernel_module [path_to_modinfo] # function require_kernel_module() { MODULE=$1 MODINFO=$2 if [ "$MODINFO" == "" ]; then set +e [ "$MODINFO" == "" ] && \ MODINFO=$(which modinfo 2>/dev/null) set -e [ "$MODINFO" == "" ] && \ [ -x /usr/sbin/modinfo ] && MODINFO=/usr/sbin/modinfo [ "$MODINFO" == "" ] && \ [ -x /sbin/modinfo ] && MODINFO=/sbin/modinfo [ "$MODINFO" == "" ] && \ msg "$UNITTEST_NAME: SKIP: modinfo command required" && \ exit 0 else [ ! -x $MODINFO ] && \ msg "$UNITTEST_NAME: SKIP: modinfo command required" && \ exit 0 fi $MODINFO -F name $MODULE &>/dev/null && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP: '$MODULE' kernel module required" exit 0 fi } # # require_kernel_module_node -- only allow script to continue if specified kernel module exists on a remote node # # usage: require_kernel_module_node [path_to_modinfo] # function require_kernel_module_node() { NODE_N=$1 MODULE=$2 MODINFO=$3 if [ "$MODINFO" == "" ]; then set +e [ "$MODINFO" == "" ] && \ MODINFO=$(run_on_node $NODE_N which modinfo 2>/dev/null) set -e [ "$MODINFO" == "" ] && \ run_on_node $NODE_N "test -x /usr/sbin/modinfo" && MODINFO=/usr/sbin/modinfo [ "$MODINFO" == "" ] && \ run_on_node $NODE_N "test -x /sbin/modinfo" && MODINFO=/sbin/modinfo [ "$MODINFO" == "" ] && \ msg "$UNITTEST_NAME: SKIP: node $NODE_N: modinfo command required" && \ exit 0 else run_on_node $NODE_N "test ! -x $MODINFO" && \ msg "$UNITTEST_NAME: SKIP: node $NODE_N: modinfo command required" && \ exit 0 fi run_on_node $NODE_N "$MODINFO -F name $MODULE &>/dev/null" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP: node $NODE_N: '$MODULE' kernel module required" exit 0 fi } # # require_pkg -- only allow script to continue if specified package exists # usage: require_pkg [] # function require_pkg() { if ! command -v pkg-config 1>/dev/null then msg "$UNITTEST_NAME: SKIP pkg-config required" exit 0 fi local COMMAND="pkg-config $1" local MSG="$UNITTEST_NAME: SKIP '$1' package" if [ "$#" -eq "2" ]; then COMMAND="$COMMAND --atleast-version $2" MSG="$MSG (version >= $2)" fi MSG="$MSG required" if ! $COMMAND then msg "$MSG" exit 0 fi } # # require_node_pkg -- only allow script to continue if specified package exists # on specified node # usage: require_node_pkg [] # function require_node_pkg() { validate_node_number $1 local N=$1 shift local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir local COMMAND="${NODE_ENV[$N]}" if [ -n "${NODE_LD_LIBRARY_PATH[$N]}" ]; then local PKG_CONFIG_PATH=${NODE_LD_LIBRARY_PATH[$N]//:/\/pkgconfig:}/pkgconfig COMMAND="$COMMAND PKG_CONFIG_PATH=\$PKG_CONFIG_PATH:$PKG_CONFIG_PATH" fi COMMAND="$COMMAND PKG_CONFIG_PATH=$REMOTE_PKG_CONFIG_PATH" COMMAND="$COMMAND pkg-config $1" MSG="$UNITTEST_NAME: SKIP NODE $N: '$1' package" if [ "$#" -eq "2" ]; then COMMAND="$COMMAND --atleast-version $2" MSG="$MSG (version >= $2)" fi MSG="$MSG required" disable_exit_on_error run_command ssh $SSH_OPTS ${NODE[$N]} "$COMMAND" 2>&1 ret=$? restore_exit_on_error if [ "$ret" == 1 ]; then msg "$MSG" exit 0 fi } # # configure_valgrind -- only allow script to continue when settings match # function configure_valgrind() { case "$1" in memcheck|pmemcheck|helgrind|drd|force-disable) ;; *) usage "bad test-type: $1" ;; esac if [ "$CHECK_TYPE" == "none" ]; then if [ "$1" == "force-disable" ]; then msg "$UNITTEST_NAME: all valgrind tests disabled" elif [ "$2" = "force-enable" ]; then CHECK_TYPE="$1" require_valgrind_tool $1 $3 elif [ "$2" = "force-disable" ]; then CHECK_TYPE=none else fatal "invalid parameter" fi else if [ "$1" == "force-disable" ]; then msg "$UNITTEST_NAME: SKIP RUNTESTS script parameter $CHECK_TYPE tries to enable valgrind test when all valgrind tests are disabled in TEST" exit 0 elif [ "$CHECK_TYPE" != "$1" -a "$2" == "force-enable" ]; then msg "$UNITTEST_NAME: SKIP RUNTESTS script parameter $CHECK_TYPE tries to enable different valgrind test than one defined in TEST" exit 0 elif [ "$CHECK_TYPE" == "$1" -a "$2" == "force-disable" ]; then msg "$UNITTEST_NAME: SKIP RUNTESTS script parameter $CHECK_TYPE tries to enable test defined in TEST as force-disable" exit 0 fi require_valgrind_tool $CHECK_TYPE $3 fi if [ "$UT_VALGRIND_SKIP_PRINT_MISMATCHED" == 1 ]; then export UT_SKIP_PRINT_MISMATCHED=1 fi } # # valgrind_version_no_check -- returns Valgrind version without checking # for valgrind first # function valgrind_version_no_check() { $VALGRINDEXE --version | sed "s/valgrind-\([0-9]*\)\.\([0-9]*\).*/\1*100+\2/" | bc } # # require_valgrind -- continue script execution only if # valgrind package is installed # function require_valgrind() { # bc is used inside valgrind_version_no_check require_command bc require_no_asan disable_exit_on_error VALGRINDEXE=`which valgrind 2>/dev/null` local ret=$? restore_exit_on_error if [ $ret -ne 0 ]; then msg "$UNITTEST_NAME: SKIP valgrind required" exit 0 fi [ $NODES_MAX -lt 0 ] && return; if [ ! -z "$1" ]; then available=$(valgrind_version_no_check) required=`echo $1 | sed "s/\([0-9]*\)\.\([0-9]*\).*/\1*100+\2/" | bc` if [ $available -lt $required ]; then msg "$UNITTEST_NAME: SKIP valgrind required (ver $1 or later)" exit 0 fi fi for N in $NODES_SEQ; do if [ "${NODE_VALGRINDEXE[$N]}" = "" ]; then disable_exit_on_error NODE_VALGRINDEXE[$N]=$(ssh $SSH_OPTS ${NODE[$N]} "which valgrind 2>/dev/null") ret=$? restore_exit_on_error if [ $ret -ne 0 ]; then msg "$UNITTEST_NAME: SKIP valgrind required on remote node #$N" exit 0 fi fi done } # # valgrind_version -- returns Valgrind version # function valgrind_version() { require_valgrind valgrind_version_no_check } # # require_valgrind_tool -- continue script execution only if valgrind with # specified tool is installed # # usage: require_valgrind_tool [] # function require_valgrind_tool() { require_valgrind local tool=$1 local binary=$2 local dir=. [ -d "$2" ] && dir="$2" && binary= pushd "$dir" > /dev/null [ -n "$binary" ] || binary=$(get_executables) if [ -z "$binary" ]; then fatal "require_valgrind_tool: error: no binary found" fi strings ${binary} 2>&1 | \ grep -q "compiled with support for Valgrind $tool" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP not compiled with support for Valgrind $tool" exit 0 fi if [ "$tool" == "helgrind" ]; then valgrind --tool=$tool --help 2>&1 | \ grep -qi "$tool is Copyright (c)" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP Valgrind with $tool required" exit 0; fi fi if [ "$tool" == "pmemcheck" ]; then out=`valgrind --tool=$tool --help 2>&1` && true echo "$out" | grep -qi "$tool is Copyright (c)" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP Valgrind with $tool required" exit 0; fi echo "$out" | grep -qi "expect-fence-after-clflush" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP pmemcheck does not support --expect-fence-after-clflush option. Please update it to the latest version." exit 0; fi fi popd > /dev/null return 0 } # # set_valgrind_exe_name -- set the actual Valgrind executable name # # On some systems (Ubuntu), "valgrind" is a shell script that calls # the actual executable "valgrind.bin". # The wrapper script doesn't work well with LD_PRELOAD, so we want # to call Valgrind directly. # function set_valgrind_exe_name() { if [ "$VALGRINDEXE" = "" ]; then fatal "set_valgrind_exe_name: error: valgrind is not set up" fi local VALGRINDDIR=`dirname $VALGRINDEXE` if [ -x $VALGRINDDIR/valgrind.bin ]; then VALGRINDEXE=$VALGRINDDIR/valgrind.bin fi [ $NODES_MAX -lt 0 ] && return; for N in $NODES_SEQ; do local COMMAND="\ [ -x $(dirname ${NODE_VALGRINDEXE[$N]})/valgrind.bin ] && \ echo $(dirname ${NODE_VALGRINDEXE[$N]})/valgrind.bin || \ echo ${NODE_VALGRINDEXE[$N]}" NODE_VALGRINDEXE[$N]=$(ssh $SSH_OPTS ${NODE[$N]} $COMMAND) if [ $? -ne 0 ]; then fatal ${NODE_VALGRINDEXE[$N]} fi done } # # require_no_asan_for - continue script execution only if passed binary does # NOT require libasan # function require_no_asan_for() { disable_exit_on_error nm $1 | grep -q __asan_ ASAN_ENABLED=$? restore_exit_on_error if [ "$ASAN_ENABLED" == "0" ]; then msg "$UNITTEST_NAME: SKIP: ASAN enabled" exit 0 fi } # # require_cxx11 -- continue script execution only if C++11 supporting compiler # is installed # function require_cxx11() { [ "$CXX" ] || CXX=c++ CXX11_AVAILABLE=`echo "int main(){return 0;}" |\ $CXX -std=c++11 -x c++ -o /dev/null - 2>/dev/null &&\ echo y || echo n` if [ "$CXX11_AVAILABLE" == "n" ]; then msg "$UNITTEST_NAME: SKIP: C++11 required" exit 0 fi } # # require_no_asan - continue script execution only if libpmem does NOT require # libasan # function require_no_asan() { case "$BUILD" in debug) require_no_asan_for ../../debug/libpmem.so ;; nondebug) require_no_asan_for ../../nondebug/libpmem.so ;; static-debug) require_no_asan_for ../../debug/libpmem.a ;; static-nondebug) require_no_asan_for ../../nondebug/libpmem.a ;; esac } # # require_tty - continue script execution only if standard output is a terminal # function require_tty() { if ! tty >/dev/null; then msg "$UNITTEST_NAME: SKIP no terminal" exit 0 fi } # # require_binary -- continue script execution only if the binary has been compiled # # In case of conditional compilation, skip this test. # function require_binary() { if [ -z "$1" ]; then fatal "require_binary: error: binary not provided" fi if [ ! -x "$1" ]; then msg "$UNITTEST_NAME: SKIP no binary found" exit 0 fi return } # # require_sds -- continue script execution only if binary is compiled with # shutdown state support # # usage: require_sds # function require_sds() { local binary=$1 local dir=. if [ -z "$binary" ]; then fatal "require_sds: error: no binary found" fi strings ${binary} 2>&1 | \ grep -q "compiled with support for shutdown state" && true if [ $? -ne 0 ]; then msg "$UNITTEST_NAME: SKIP not compiled with support for shutdown state" exit 0 fi return 0 } # # require_no_sds -- continue script execution only if binary is NOT compiled with # shutdown state support # # usage: require_no_sds # function require_no_sds() { local binary=$1 local dir=. if [ -z "$binary" ]; then fatal "require_sds: error: no binary found" fi set +e found=$(strings ${binary} 2>&1 | \ grep -c "compiled with support for shutdown state") set -e if [ "$found" -ne "0" ]; then msg "$UNITTEST_NAME: SKIP compiled with support for shutdown state" exit 0 fi return 0 } # # is_ndctl_enabled -- check if binary is compiled with libndctl # # usage: is_ndctl_enabled # function is_ndctl_enabled() { local binary=$1 local dir=. if [ -z "$binary" ]; then fatal "is_ndctl_enabled: error: no binary found" fi strings ${binary} 2>&1 | \ grep -q "compiled with libndctl" && true return $? } # # require_bb_enabled_by_default -- check if the binary has bad block # checking feature enabled by default # # usage: require_bb_enabled_by_default # function require_bb_enabled_by_default() { if ! is_ndctl_enabled $1 &> /dev/null ; then msg "$UNITTEST_NAME: SKIP bad block checking feature disabled by default" exit 0 fi return 0 } # # require_bb_disabled_by_default -- check if the binary does not have bad # block checking feature enabled by default # # usage: require_bb_disabled_by_default # function require_bb_disabled_by_default() { if is_ndctl_enabled $1 &> /dev/null ; then msg "$UNITTEST_NAME: SKIP bad block checking feature enabled by default" exit 0 fi return 0 } # # check_absolute_path -- continue script execution only if $DIR path is # an absolute path; do not resolve symlinks # function check_absolute_path() { if [ "${DIR:0:1}" != "/" ]; then fatal "Directory \$DIR has to be an absolute path. $DIR was given." fi } # # run_command -- run a command in a verbose or quiet way # function run_command() { local COMMAND="$*" if [ "$VERBOSE" != "0" ]; then echo "$ $COMMAND" $COMMAND else $COMMAND fi } # # validate_node_number -- validate a node number # function validate_node_number() { [ $1 -gt $NODES_MAX ] \ && fatal "error: node number ($1) greater than maximum allowed node number ($NODES_MAX)" return 0 } # # clean_remote_node -- usage: clean_remote_node # function clean_remote_node() { validate_node_number $1 local N=$1 shift local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir # register the list of PID files to be cleaned in case of an error NODE_PID_FILES[$N]="${NODE_PID_FILES[$N]} $*" # clean the remote node disable_exit_on_error for pidfile in ${NODE_PID_FILES[$N]}; do require_ctrld_err $N $pidfile run_command ssh $SSH_OPTS ${NODE[$N]} "\ cd $DIR && [ -f $pidfile ] && \ ../ctrld $pidfile kill SIGINT && \ ../ctrld $pidfile wait 1 ; \ rm -f $pidfile" done; restore_exit_on_error return 0 } # # clean_all_remote_nodes -- clean all remote nodes in case of an error # function clean_all_remote_nodes() { msg "$UNITTEST_NAME: CLEAN (cleaning processes on remote nodes)" local N=0 disable_exit_on_error for N in $NODES_SEQ; do local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir for pidfile in ${NODE_PID_FILES[$N]}; do run_command ssh $SSH_OPTS ${NODE[$N]} "\ cd $DIR && [ -f $pidfile ] && \ ../ctrld $pidfile kill SIGINT && \ ../ctrld $pidfile wait 1 ; \ rm -f $pidfile" done done restore_exit_on_error return 0 } # # export_vars_node -- export specified variables on specified node # function export_vars_node() { local N=$1 shift validate_node_number $N for var in "$@"; do NODE_ENV[$N]="${NODE_ENV[$N]} $var=${!var}" done } # # require_nodes_libfabric -- only allow script to continue if libfabric with # optionally specified provider is available on # specified node # usage: require_nodes_libfabric [] # function require_node_libfabric() { validate_node_number $1 local N=$1 local provider=$2 # Minimal required version of libfabric. # Keep in sync with requirements in src/common.inc. local version=${3:-1.4.2} require_pkg libfabric "$version" # fi_info can be found in libfabric-bin require_command fi_info require_node_pkg $N libfabric "$version" require_command_node $N fi_info if [ "$RPMEM_PROVIDER" == "verbs" ]; then if ! fi_info --list | grep -q verbs; then msg "$UNITTEST_NAME: SKIP libfabric not compiled with verbs provider" exit 0 fi if ! run_on_node $N "fi_info --list | grep -q verbs"; then msg "$UNITTEST_NAME: SKIP libfabric on node $N not compiled with verbs provider" exit 0 fi fi local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir local COMMAND="$COMMAND ${NODE_ENV[$N]}" COMMAND="$COMMAND LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[$N]}:$REMOTE_LD_LIBRARY_PATH" COMMAND="$COMMAND ../fip ${NODE_ADDR[$N]} $provider" disable_exit_on_error fip_out=$(ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && $COMMAND" 2>&1) ret=$? restore_exit_on_error if [ "$ret" == "0" ]; then return elif [ "$ret" == "1" ]; then msg "$UNITTEST_NAME: SKIP NODE $N: $fip_out" exit 0 else fatal "NODE $N: require_libfabric $provider: $fip_out" fi } # # check_if_node_is_reachable -- check if the $1 node is reachable # function check_if_node_is_reachable() { disable_exit_on_error run_command ssh $SSH_OPTS ${NODE[$1]} exit local ret=$? restore_exit_on_error return $ret } # # require_nodes -- only allow script to continue for a certain number # of defined and reachable nodes # # Input arguments: # NODE[] - (required) array of nodes' addresses # NODE_WORKING_DIR[] - (required) array of nodes' working directories # function require_nodes() { local N_NODES=${#NODE[@]} local N=$1 [ -z "$N" ] \ && fatal "require_nodes: missing reguired parameter: number of nodes" # if it has already been called, check if number of required nodes is bigger than previously [ -n "$NODES_MAX" ] \ && [ $(($N - 1)) -le $NODES_MAX ] && return [ $N -gt $N_NODES ] \ && msg "$UNITTEST_NAME: SKIP: requires $N node(s), but $N_NODES node(s) provided" \ && exit 0 NODES_MAX=$(($N - 1)) NODES_SEQ=$(seq -s' ' 0 $NODES_MAX) # check if all required nodes are reachable for N in $NODES_SEQ; do # validate node's address [ "${NODE[$N]}" = "" ] \ && msg "$UNITTEST_NAME: SKIP: address of node #$N is not provided" \ && exit 0 # validate the working directory [ "${NODE_WORKING_DIR[$N]}" = "" ] \ && fatal "error: working directory for node #$N (${NODE[$N]}) is not provided" # check if the node is reachable check_if_node_is_reachable $N [ $? -ne 0 ] \ && fatal "error: node #$N (${NODE[$N]}) is unreachable" # clear the list of PID files for each node NODE_PID_FILES[$N]="" NODE_TEST_DIR[$N]=${NODE_WORKING_DIR[$N]}/$curtestdir NODE_DIR[$N]=${NODE_WORKING_DIR[$N]}/$curtestdir/data/ require_node_log_files $N $ERR_LOG_FILE $OUT_LOG_FILE $TRACE_LOG_FILE if [ "$CHECK_TYPE" != "none" -a "${NODE_VALGRINDEXE[$N]}" = "" ]; then disable_exit_on_error NODE_VALGRINDEXE[$N]=$(ssh $SSH_OPTS ${NODE[$N]} "which valgrind 2>/dev/null") local ret=$? restore_exit_on_error if [ $ret -ne 0 ]; then msg "$UNITTEST_NAME: SKIP valgrind required on remote node #$N" exit 0 fi fi done # remove all log files of the current unit test from the required nodes # and export the 'log' variables to these nodes for N in $NODES_SEQ; do for f in $(get_files "node_${N}.*${UNITTEST_NUM}\.log"); do rm -f $f done export_vars_node $N $REMOTE_VARS done # register function to clean all remote nodes in case of an error or SIGINT trap clean_all_remote_nodes ERR SIGINT return 0 } # # check_files_on_node -- check if specified files exist on given node # function check_files_on_node() { validate_node_number $1 local N=$1 shift local REMOTE_DIR=${NODE_DIR[$N]} run_command ssh $SSH_OPTS ${NODE[$N]} "for f in $*; do if [ ! -f $REMOTE_DIR/\$f ]; then echo \"Missing file \$f on node #$N\" 1>&2; exit 1; fi; done" } # # check_no_files_on_node -- check if specified files does not exist on given node # function check_no_files_on_node() { validate_node_number $1 local N=$1 shift local REMOTE_DIR=${NODE_DIR[$N]} run_command ssh $SSH_OPTS ${NODE[$N]} "for f in $*; do if [ -f $REMOTE_DIR/\$f ]; then echo \"Not deleted file \$f on node #$N\" 1>&2; exit 1; fi; done" } # # copy_files_to_node -- copy all required files to the given remote node # usage: copy_files_to_node [] ... # function copy_files_to_node() { validate_node_number $1 local N=$1 local DEST_DIR=$2 shift 2 [ $# -eq 0 ] &&\ fatal "error: copy_files_to_node(): no files provided" # copy all required files run_command scp $SCP_OPTS $@ ${NODE[$N]}:$DEST_DIR > /dev/null return 0 } # # copy_files_from_node -- copy all required files from the given remote node # usage: copy_files_from_node [] ... # function copy_files_from_node() { validate_node_number $1 local N=$1 local DEST_DIR=$2 [ ! -d $DEST_DIR ] &&\ fatal "error: destination directory $DEST_DIR does not exist" shift 2 [ $# -eq 0 ] &&\ fatal "error: copy_files_from_node(): no files provided" # compress required files, copy and extract local temp_file=node_${N}_temp_file.tar files="" dir_name="" files=$(basename -a $@) dir_name=$(dirname $1) run_command ssh $SSH_OPTS ${NODE[$N]} "cd $dir_name && tar -czf $temp_file $files" run_command scp $SCP_OPTS ${NODE[$N]}:$dir_name/$temp_file $DEST_DIR > /dev/null cd $DEST_DIR \ && tar -xzf $temp_file \ && rm $temp_file \ && cd - > /dev/null return 0 } # # copy_log_files -- copy log files from remote node # function copy_log_files() { local NODE_SCP_LOG_FILES[0]="" for N in $NODES_SEQ; do local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir for file in ${NODE_LOG_FILES[$N]}; do NODE_SCP_LOG_FILES[$N]="${NODE_SCP_LOG_FILES[$N]} ${NODE[$N]}:$DIR/${file}" done [ "${NODE_SCP_LOG_FILES[$N]}" ] && run_command scp $SCP_OPTS ${NODE_SCP_LOG_FILES[$N]} . &>> $PREP_LOG_FILE for file in ${NODE_LOG_FILES[$N]}; do [ -f $file ] && mv $file node_${N}_${file} done done } # # rm_files_from_node -- removes all listed files from the given remote node # usage: rm_files_from_node [] ... # function rm_files_from_node() { validate_node_number $1 local N=$1 shift [ $# -eq 0 ] &&\ fatal "error: rm_files_from_node(): no files provided" run_command ssh $SSH_OPTS ${NODE[$N]} "rm -f $@" return 0 } # # # require_node_log_files -- store log files which must be copied from # specified node on failure # function require_node_log_files() { validate_node_number $1 local N=$1 shift NODE_LOG_FILES[$N]="${NODE_LOG_FILES[$N]} $*" } # # require_ctrld_err -- store ctrld's log files to copy from specified # node on failure # function require_ctrld_err() { local N=$1 local PID_FILE=$2 local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir for cmd in run wait kill wait_port; do NODE_LOG_FILES[$N]="${NODE_LOG_FILES[$N]} $PID_FILE.$cmd.ctrld.log" done } # # run_on_node -- usage: run_on_node # # Run the in background on the remote . # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n] # function run_on_node() { validate_node_number $1 local N=$1 shift local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir local COMMAND="UNITTEST_NUM=$UNITTEST_NUM UNITTEST_NAME=$UNITTEST_NAME" COMMAND="$COMMAND UNITTEST_LOG_LEVEL=1" COMMAND="$COMMAND ${NODE_ENV[$N]}" COMMAND="$COMMAND PATH=$REMOTE_PATH" COMMAND="$COMMAND LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[$N]}:$REMOTE_LD_LIBRARY_PATH $*" run_command ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && $COMMAND" ret=$? if [ "$ret" -ne "0" ]; then copy_log_files fi return $ret } # # run_on_node_background -- usage: # run_on_node_background # # Run the in background on the remote # and create a for this process. # LD_LIBRARY_PATH for the n-th remote node # can be provided in the array NODE_LD_LIBRARY_PATH[n] # function run_on_node_background() { validate_node_number $1 local N=$1 local PID_FILE=$2 shift shift local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir local COMMAND="UNITTEST_NUM=$UNITTEST_NUM UNITTEST_NAME=$UNITTEST_NAME" COMMAND="$COMMAND UNITTEST_LOG_LEVEL=1" COMMAND="$COMMAND ${NODE_ENV[$N]}" COMMAND="$COMMAND PATH=$REMOTE_PATH" COMMAND="$COMMAND LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[$N]}:$REMOTE_LD_LIBRARY_PATH" COMMAND="$COMMAND ../ctrld $PID_FILE run $RUNTEST_TIMEOUT $*" # register the PID file to be cleaned in case of an error NODE_PID_FILES[$N]="${NODE_PID_FILES[$N]} $PID_FILE" run_command ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && $COMMAND" ret=$? if [ "$ret" -ne "0" ]; then copy_log_files fi return $ret } # # wait_on_node -- usage: wait_on_node [] # # Wait until the process with the on the # exits or expires. # function wait_on_node() { validate_node_number $1 local N=$1 local PID_FILE=$2 local TIMEOUT=$3 local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir run_command ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && ../ctrld $PID_FILE wait $TIMEOUT" ret=$? if [ "$ret" -ne "0" ]; then copy_log_files fi return $ret } # # wait_on_node_port -- usage: wait_on_node_port # # Wait until the process with the on the # opens the port . # function wait_on_node_port() { validate_node_number $1 local N=$1 local PID_FILE=$2 local PORTNO=$3 local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir run_command ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && ../ctrld $PID_FILE wait_port $PORTNO" ret=$? if [ "$ret" -ne "0" ]; then copy_log_files fi return $ret } # # kill_on_node -- usage: kill_on_node # # Send the signal to the process with the # on the . # function kill_on_node() { validate_node_number $1 local N=$1 local PID_FILE=$2 local SIGNO=$3 local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir run_command ssh $SSH_OPTS ${NODE[$N]} "cd $DIR && ../ctrld $PID_FILE kill $SIGNO" ret=$? if [ "$ret" -ne "0" ]; then copy_log_files fi return $ret } # # obj_pool_desc_size -- returns the obj_pool_desc_size macro value # in bytes which is two times the actual pagesize. # # This should be use to calculate the minimum zero size for pool # creation on some tests. # function obj_pool_desc_size() { echo "$(expr $(getconf PAGESIZE) \* 2)" } # # log_pool_desc_size -- returns the minimum size of pool header # in bytes which is two times the actual pagesize. # # This should be use to calculate the minimum zero size for pool # creation on some tests. # function log_pool_desc_size() { echo "$(expr $(getconf PAGESIZE) \* 2)" } # # blk_pool_desc_size -- returns the minimum size of pool header # in bytes which is two times the actual pagesize. # # This should be use to calculate the minimum zero size for pool # creation on some tests. # function blk_pool_desc_size() { echo "$(expr $(getconf PAGESIZE) \* 2)" } # # create_holey_file_on_node -- create holey files of a given length # usage: create_holey_file_on_node # # example, to create two files, each 1GB in size on node 0: # create_holey_file_on_node 0 1G testfile1 testfile2 # # Input unit size is in bytes with optional suffixes like k, KB, M, etc. # function create_holey_file_on_node() { validate_node_number $1 local N=$1 size=$(convert_to_bytes $2) shift 2 for file in $* do run_on_node $N truncate -s ${size} $file >> $PREP_LOG_FILE done } # # require_mmap_under_valgrind -- only allow script to continue if mapping is # possible under Valgrind with required length # (sum of required DAX devices size). # This function is being called internally in # setup() function. # function require_mmap_under_valgrind() { local FILE_MAX_DAX_DEVICES="../tools/anonymous_mmap/max_dax_devices" if [ -z "$REQUIRE_DAX_DEVICES" ]; then return fi if [ ! -f "$FILE_MAX_DAX_DEVICES" ]; then fatal "$FILE_MAX_DAX_DEVICES not found. Run make test." fi if [ "$REQUIRE_DAX_DEVICES" -gt "$(< $FILE_MAX_DAX_DEVICES)" ]; then msg "$UNITTEST_NAME: SKIP: anonymous mmap under Valgrind not possible for $REQUIRE_DAX_DEVICES DAX device(s)." exit 0 fi } # # setup -- print message that test setup is commencing # function setup() { DIR=$DIR$SUFFIX # writes test working directory to temporary file # that allows read location of data after test failure if [ -f "$TEMP_LOC" ]; then echo "$DIR" > $TEMP_LOC fi # test type must be explicitly specified if [ "$req_test_type" != "1" ]; then fatal "error: required test type is not specified" fi # fs type "none" must be explicitly enabled if [ "$FS" = "none" -a "$req_fs_type" != "1" ]; then exit 0 fi # fs type "any" must be explicitly enabled if [ "$FS" = "any" -a "$req_fs_type" != "1" ]; then exit 0 fi if [ "$CHECK_TYPE" != "none" ]; then require_valgrind # detect possible Valgrind mmap issues and skip uncertain tests require_mmap_under_valgrind export VALGRIND_LOG_FILE=$CHECK_TYPE${UNITTEST_NUM}.log MCSTR="/$CHECK_TYPE" else MCSTR="" fi [ -n "$RPMEM_PROVIDER" ] && PROV="/$RPMEM_PROVIDER" [ -n "$RPMEM_PM" ] && PM="/$RPMEM_PM" msg "$UNITTEST_NAME: SETUP ($TEST/$REAL_FS/$BUILD$MCSTR$PROV$PM)" for f in $(get_files ".*[a-zA-Z_]${UNITTEST_NUM}\.log"); do rm -f $f done # $DIR has to be an absolute path check_absolute_path if [ "$FS" != "none" ]; then if [ -d "$DIR" ]; then rm $RM_ONEFS -rf -- $DIR fi mkdir -p $DIR fi if [ "$TM" = "1" ]; then start_time=$($DATE +%s.%N) fi if [ "$DEVDAX_TO_LOCK" == 1 ]; then lock_devdax fi export PMEMBLK_CONF="fallocate.at_create=0;" export PMEMOBJ_CONF="fallocate.at_create=0;" export PMEMLOG_CONF="fallocate.at_create=0;" } # # check_log_empty -- if match file does not exist, assume log should be empty # function check_log_empty() { if [ ! -f ${1}.match ] && [ $(get_size $1) -ne 0 ]; then echo "unexpected output in $1" dump_last_n_lines $1 exit 1 fi } # # check_local -- check local test results (using .match files) # function check_local() { if [ "$UT_SKIP_PRINT_MISMATCHED" == 1 ]; then option=-q fi check_log_empty $ERR_LOG_FILE FILES=$(get_files "[^0-9w]*${UNITTEST_NUM}\.log\.match") if [ -n "$FILES" ]; then ../match $option $FILES fi } # # match -- execute match # function match() { ../match $@ } # # check -- check local or remote test results (using .match files) # function check() { if [ $NODES_MAX -lt 0 ]; then check_local else FILES=$(get_files "node_[0-9]+_[^0-9w]*${UNITTEST_NUM}\.log\.match") local NODE_MATCH_FILES[0]="" local NODE_SCP_MATCH_FILES[0]="" for file in $FILES; do local N=`echo $file | cut -d"_" -f2` local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir local FILE=`echo $file | cut -d"_" -f3 | sed "s/\.match$//g"` validate_node_number $N NODE_MATCH_FILES[$N]="${NODE_MATCH_FILES[$N]} $FILE" NODE_SCP_MATCH_FILES[$N]="${NODE_SCP_MATCH_FILES[$N]} ${NODE[$N]}:$DIR/$FILE" done for N in $NODES_SEQ; do [ "${NODE_SCP_MATCH_FILES[$N]}" ] && run_command scp $SCP_OPTS ${NODE_SCP_MATCH_FILES[$N]} . > /dev/null for file in ${NODE_MATCH_FILES[$N]}; do mv $file node_${N}_${file} done done if [ "$UT_SKIP_PRINT_MISMATCHED" == 1 ]; then option=-q fi for N in $NODES_SEQ; do check_log_empty node_${N}_${ERR_LOG_FILE} done if [ -n "$FILES" ]; then match $option $FILES fi fi # Move logs to build folder LOG_DIR=logs/$TEST/$REAL_FS/$BUILD$MCSTR$PROV$PM if [ ! -d $LOG_DIR ]; then mkdir --parents $LOG_DIR; fi for f in $(get_files ".*[a-zA-Z_]${UNITTEST_NUM}\.log"); do mv -f $f $LOG_DIR/$f done } # # pass -- print message that the test has passed # function pass() { if [ "$DEVDAX_TO_LOCK" == 1 ]; then unlock_devdax fi if [ "$TM" = "1" ]; then end_time=$($DATE +%s.%N) start_time_sec=$($DATE -d "0 $start_time sec" +%s) end_time_sec=$($DATE -d "0 $end_time sec" +%s) days=$(((end_time_sec - start_time_sec) / (24*3600))) days=$(printf "%03d" $days) tm=$($DATE -d "0 $end_time sec - $start_time sec" +%H:%M:%S.%N) tm=$(echo "$days:$tm" | sed -e "s/^000://g" -e "s/^00://g" -e "s/^00://g" -e "s/\([0-9]*\)\.\([0-9][0-9][0-9]\).*/\1.\2/") tm="\t\t\t[$tm s]" else tm="" fi msg=$(interactive_green STDOUT "PASS") if [ "$UNITTEST_LOG_LEVEL" -ge 1 ]; then echo -e "$UNITTEST_NAME: $msg$tm" fi if [ "$FS" != "none" ]; then rm $RM_ONEFS -rf -- $DIR fi } # Length of pool file's signature SIG_LEN=8 # Offset and length of pmemobj layout LAYOUT_OFFSET=$(getconf PAGE_SIZE) LAYOUT_LEN=1024 # Length of arena's signature ARENA_SIG_LEN=16 # Signature of BTT Arena ARENA_SIG="BTT_ARENA_INFO" # Offset to first arena ARENA_OFF=$(($(getconf PAGE_SIZE) * 2)) # # check_file -- check if file exists and print error message if not # check_file() { if [ ! -f $1 ] then fatal "Missing file: ${1}" fi } # # check_files -- check if files exist and print error message if not # check_files() { for file in $* do check_file $file done } # # check_no_file -- check if file has been deleted and print error message if not # check_no_file() { if [ -f $1 ] then fatal "Not deleted file: ${1}" fi } # # check_no_files -- check if files has been deleted and print error message if not # check_no_files() { for file in $* do check_no_file $file done } # # get_size -- return size of file (0 if file does not exist) # get_size() { if [ ! -f $1 ]; then echo "0" else stat $STAT_SIZE $1 fi } # # get_mode -- return mode of file # get_mode() { stat $STAT_MODE $1 } # # check_size -- validate file size # check_size() { local size=$1 local file=$2 local file_size=$(get_size $file) if [[ $size != $file_size ]] then fatal "error: wrong size ${file_size} != ${size}" fi } # # check_mode -- validate file mode # check_mode() { local mode=$1 local file=$2 local file_mode=$(get_mode $file) if [[ $mode != $file_mode ]] then fatal "error: wrong mode ${file_mode} != ${mode}" fi } # # check_signature -- check if file contains specified signature # check_signature() { local sig=$1 local file=$2 local file_sig=$($DD if=$file bs=1 count=$SIG_LEN 2>/dev/null | tr -d \\0) if [[ $sig != $file_sig ]] then fatal "error: $file: signature doesn't match ${file_sig} != ${sig}" fi } # # check_signatures -- check if multiple files contain specified signature # check_signatures() { local sig=$1 shift 1 for file in $* do check_signature $sig $file done } # # check_layout -- check if pmemobj pool contains specified layout # check_layout() { local layout=$1 local file=$2 local file_layout=$($DD if=$file bs=1\ skip=$LAYOUT_OFFSET count=$LAYOUT_LEN 2>/dev/null | tr -d \\0) if [[ $layout != $file_layout ]] then fatal "error: layout doesn't match ${file_layout} != ${layout}" fi } # # check_arena -- check if file contains specified arena signature # check_arena() { local file=$1 local sig=$($DD if=$file bs=1 skip=$ARENA_OFF count=$ARENA_SIG_LEN 2>/dev/null | tr -d \\0) if [[ $sig != $ARENA_SIG ]] then fatal "error: can't find arena signature" fi } # # dump_pool_info -- dump selected pool metadata and/or user data # function dump_pool_info() { # ignore selected header fields that differ by definition ${PMEMPOOL}.static-nondebug info $* | sed -e "/^UUID/,/^Checksum/d" } # # compare_replicas -- check replicas consistency by comparing `pmempool info` output # function compare_replicas() { disable_exit_on_error diff <(dump_pool_info $1 $2) <(dump_pool_info $1 $3) -I "^path" -I "^size" restore_exit_on_error } # # get_node_dir -- returns node dir for current test # usage: get_node_dir # function get_node_dir() { validate_node_number $1 echo ${NODE_WORKING_DIR[$1]}/$curtestdir } # # init_rpmem_on_node -- prepare rpmem environment variables on node # usage: init_rpmem_on_node [ ...] # # example: # The following command initialize rpmem environment variables on the node 1 # to perform replication to node 0, node 2 and node 3. # Additionally: # - on node 2 rpmemd pid will be stored in file.pid # - on node 3 no pid file will be created (SKIP) and rpmemd will use # file.conf config file # # init_rpmem_on_node 1 0 2:file.pid 3:SKIP:file.conf # function init_rpmem_on_node() { local master=$1 shift validate_node_number $master case "$RPMEM_PM" in APM|GPSPM) ;; *) msg "$UNITTEST_NAME: SKIP required: RPMEM_PM is invalid or empty" exit 0 ;; esac # Workaround for SIGSEGV in the infinipath-psm during abort # The infinipath-psm is registering a signal handler and do not unregister # it when rpmem handle is dlclosed. SIGABRT (potentially any other signal) # would try to call the signal handler which does not exist after dlclose. # Issue require a fix in the infinipath-psm or the libfabric. IPATH_NO_BACKTRACE=1 export_vars_node $master IPATH_NO_BACKTRACE RPMEM_CMD="" local SEPARATOR="|" for slave in "$@" do slave=(${slave//:/ }) conf=${slave[2]} pid=${slave[1]} slave=${slave[0]} validate_node_number $slave local poolset_dir=${NODE_DIR[$slave]} if [ -n "${RPMEM_POOLSET_DIR[$slave]}" ]; then poolset_dir=${RPMEM_POOLSET_DIR[$slave]} fi local trace= if [ -n "$(is_valgrind_enabled_on_node $slave)" ]; then log_file=${CHECK_TYPE}${UNITTEST_NUM}.log trace=$(get_trace $CHECK_TYPE $log_file $slave) fi if [ -n "$pid" -a "$pid" != "SKIP" ]; then trace="$trace ../ctrld $pid exe" fi if [ -n ${UNITTEST_DO_NOT_CHECK_OPEN_FILES+x} ]; then export_vars_node $slave UNITTEST_DO_NOT_CHECK_OPEN_FILES fi if [ -n ${IPATH_NO_BACKTRACE+x} ]; then export_vars_node $slave IPATH_NO_BACKTRACE fi CMD="cd ${NODE_TEST_DIR[$slave]} && " # Force pmem for APM. Otherwise in case of lack of a pmem rpmemd will # silently fallback to GPSPM. [ "$RPMEM_PM" == "APM" ] && CMD="$CMD PMEM_IS_PMEM_FORCE=1" CMD="$CMD ${NODE_ENV[$slave]}" CMD="$CMD PATH=$REMOTE_PATH" CMD="$CMD LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[$slave]}:$REMOTE_LD_LIBRARY_PATH" CMD="$CMD $trace ../rpmemd" CMD="$CMD --log-file=$RPMEMD_LOG_FILE" CMD="$CMD --log-level=$RPMEMD_LOG_LEVEL" CMD="$CMD --poolset-dir=$poolset_dir" if [ -n "$conf" ]; then CMD="$CMD --config=$conf" fi if [ "$RPMEM_PM" == "APM" ]; then CMD="$CMD --persist-apm" fi if [ "$RPMEM_CMD" ]; then RPMEM_CMD="$RPMEM_CMD$SEPARATOR$CMD" else RPMEM_CMD=$CMD fi require_node_log_files $slave rpmemd$UNITTEST_NUM.log done RPMEM_CMD="\"$RPMEM_CMD\"" RPMEM_ENABLE_SOCKETS=0 RPMEM_ENABLE_VERBS=0 case "$RPMEM_PROVIDER" in sockets) RPMEM_ENABLE_SOCKETS=1 ;; verbs) RPMEM_ENABLE_VERBS=1 ;; *) msg "$UNITTEST_NAME: SKIP required: RPMEM_PROVIDER is invalid or empty" exit 0 ;; esac export_vars_node $master RPMEM_CMD export_vars_node $master RPMEM_ENABLE_SOCKETS export_vars_node $master RPMEM_ENABLE_VERBS if [ -n ${UNITTEST_DO_NOT_CHECK_OPEN_FILES+x} ]; then export_vars_node $master UNITTEST_DO_NOT_CHECK_OPEN_FILES fi if [ -n ${PMEMOBJ_NLANES+x} ]; then export_vars_node $master PMEMOBJ_NLANES fi if [ -n ${RPMEM_MAX_NLANES+x} ]; then export_vars_node $master RPMEM_MAX_NLANES fi require_node_log_files $master rpmem$UNITTEST_NUM.log require_node_log_files $master $PMEMOBJ_LOG_FILE } # # init_valgrind_on_node -- prepare valgrind on nodes # usage: init_valgrind_on_node # function init_valgrind_on_node() { # When librpmem is preloaded libfabric does not close all opened files # before list of opened files is checked. local UNITTEST_DO_NOT_CHECK_OPEN_FILES=1 local LD_PRELOAD=../$BUILD/librpmem.so CHECK_NODES="" for node in "$@" do validate_node_number $node export_vars_node $node LD_PRELOAD export_vars_node $node UNITTEST_DO_NOT_CHECK_OPEN_FILES CHECK_NODES="$CHECK_NODES $node" done } # # is_valgrind_enabled_on_node -- echo the node number if the node has # initialized valgrind environment by calling # init_valgrind_on_node # usage: is_valgrind_enabled_on_node # function is_valgrind_enabled_on_node() { for node in $CHECK_NODES do if [ "$node" -eq "$1" ]; then echo $1 return fi done return } # # pack_all_libs -- put all libraries and their links to one tarball # function pack_all_libs() { local LIBS_TAR_DIR=$(pwd)/$1 cd $DIR_SRC tar -cf $LIBS_TAR_DIR ./debug/*.so* ./nondebug/*.so* cd - > /dev/null } # # copy_common_to_remote_nodes -- copy common files to all remote nodes # function copy_common_to_remote_nodes() { local NODES_ALL_MAX=$((${#NODE[@]} - 1)) local NODES_ALL_SEQ=$(seq -s' ' 0 $NODES_ALL_MAX) DIR_SYNC=$1 if [ "$DIR_SYNC" != "" ]; then [ ! -d $DIR_SYNC ] \ && fatal "error: $DIR_SYNC does not exist or is not a directory" fi # add all libraries to the 'to-copy' list local LIBS_TAR=libs.tar pack_all_libs $LIBS_TAR if [ "$DIR_SYNC" != "" -a "$(ls $DIR_SYNC)" != "" ]; then FILES_COMMON_DIR="$DIR_SYNC/* $LIBS_TAR" else FILES_COMMON_DIR="$FILES_COMMON_DIR $LIBS_TAR" fi for N in $NODES_ALL_SEQ; do # validate node's address [ "${NODE[$N]}" = "" ] \ && fatal "error: address of node #$N is not provided" check_if_node_is_reachable $N [ $? -ne 0 ] \ && msg "warning: node #$N (${NODE[$N]}) is unreachable, skipping..." \ && continue # validate the working directory [ "${NODE_WORKING_DIR[$N]}" = "" ] \ && msg ": warning: working directory for node #$N (${NODE[$N]}) is not provided, skipping..." \ && continue # create the working dir if it does not exist run_command ssh $SSH_OPTS ${NODE[$N]} "mkdir -p ${NODE_WORKING_DIR[$N]}" # copy all common files run_command scp $SCP_OPTS $FILES_COMMON_DIR ${NODE[$N]}:${NODE_WORKING_DIR[$N]} > /dev/null # unpack libraries run_command ssh $SSH_OPTS ${NODE[$N]} "cd ${NODE_WORKING_DIR[$N]} \ && tar -xf $LIBS_TAR && rm -f $LIBS_TAR" done rm -f $LIBS_TAR } # # copy_test_to_remote_nodes -- copy all unit test binaries to all remote nodes # function copy_test_to_remote_nodes() { local NODES_ALL_MAX=$((${#NODE[@]} - 1)) local NODES_ALL_SEQ=$(seq -s' ' 0 $NODES_ALL_MAX) for N in $NODES_ALL_SEQ; do # validate node's address [ "${NODE[$N]}" = "" ] \ && fatal "error: address of node #$N is not provided" check_if_node_is_reachable $N [ $? -ne 0 ] \ && msg "warning: node #$N (${NODE[$N]}) is unreachable, skipping..." \ && continue # validate the working directory [ "${NODE_WORKING_DIR[$N]}" = "" ] \ && msg ": warning: working directory for node #$N (${NODE[$N]}) is not provided, skipping..." \ && continue local DIR=${NODE_WORKING_DIR[$N]}/$curtestdir # create a new test dir run_command ssh $SSH_OPTS ${NODE[$N]} "rm -rf $DIR && mkdir -p $DIR" # create the working data dir run_command ssh $SSH_OPTS ${NODE[$N]} "mkdir -p \ ${DIR}/data" # copy all required files [ $# -gt 0 ] && run_command scp $SCP_OPTS $* ${NODE[$N]}:$DIR > /dev/null done return 0 } # # enable_log_append -- turn on appending to the log files rather than truncating them # It also removes all log files created by tests: out*.log, err*.log and trace*.log # function enable_log_append() { rm -f $OUT_LOG_FILE rm -f $ERR_LOG_FILE rm -f $TRACE_LOG_FILE export UNITTEST_LOG_APPEND=1 } # clean data directory on all remote # nodes if remote test failed if [ "$CLEAN_FAILED_REMOTE" == "y" ]; then NODES_ALL=$((${#NODE[@]} - 1)) MYPID=$$ for ((i=0;i<=$NODES_ALL;i++)); do if [[ -z "${NODE_WORKING_DIR[$i]}" || -z "$curtestdir" ]]; then echo "Invalid path to tests data: ${NODE_WORKING_DIR[$i]}/$curtestdir/data/" exit 1 fi N[$i]=${NODE_WORKING_DIR[$i]}/$curtestdir/data/ run_command ssh $SSH_OPTS ${NODE[$i]} "rm -rf ${N[$i]}; mkdir ${N[$i]}" if [ $? -eq 0 ]; then verbose_msg "Removed data from: ${NODE[$i]}:${N[$i]}" fi done exit 0 fi # calculate the minimum of two or more numbers minimum() { local min=$1 shift for val in $*; do if [[ "$val" < "$min" ]]; then min=$val fi done echo $min } # # count_lines - count number of lines that match pattern $1 in file $2 # function count_lines() { # grep returns 1 on no match disable_exit_on_error $GREP -ce "$1" $2 restore_exit_on_error } # # get_pmemcheck_version() - return pmemcheck API major or minor version # usage: get_pmemcheck_version <0|1> # function get_pmemcheck_version() { PMEMCHECK_VERSION=$($VALGRINDEXE --tool=pmemcheck true 2>&1 \ | head -n 1 | sed "s/.*-\([0-9.]*\),.*/\1/") OIFS=$IFS IFS="." PMEMCHECK_MAJ_MIN=($PMEMCHECK_VERSION) IFS=$OIFS PMEMCHECK_VERSION_PART=${PMEMCHECK_MAJ_MIN[$1]} echo "$PMEMCHECK_VERSION_PART" } # # require_pmemcheck_version_ge - check if pmemcheck API # version is greater or equal to required value # usage: require_pmemcheck_version_ge [binary] # function require_pmemcheck_version_ge() { require_valgrind_tool pmemcheck $3 REQUIRE_MAJOR=$1 REQUIRE_MINOR=$2 PMEMCHECK_MAJOR=$(get_pmemcheck_version 0) PMEMCHECK_MINOR=$(get_pmemcheck_version 1) # compare MAJOR if [ $PMEMCHECK_MAJOR -gt $REQUIRE_MAJOR ]; then return 0 fi # compare MINOR if [ $PMEMCHECK_MAJOR -eq $REQUIRE_MAJOR ]; then if [ $PMEMCHECK_MINOR -ge $REQUIRE_MINOR ]; then return 0 fi fi msg "$UNITTEST_NAME: SKIP pmemcheck API version:" \ "$PMEMCHECK_MAJOR.$PMEMCHECK_MINOR" \ "is less than required" \ "$REQUIRE_MAJOR.$REQUIRE_MINOR" exit 0 } # # require_pmemcheck_version_lt - check if pmemcheck API # version is less than required value # usage: require_pmemcheck_version_lt [binary] # function require_pmemcheck_version_lt() { require_valgrind_tool pmemcheck $3 REQUIRE_MAJOR=$1 REQUIRE_MINOR=$2 PMEMCHECK_MAJOR=$(get_pmemcheck_version 0) PMEMCHECK_MINOR=$(get_pmemcheck_version 1) # compare MAJOR if [ $PMEMCHECK_MAJOR -lt $REQUIRE_MAJOR ]; then return 0 fi # compare MINOR if [ $PMEMCHECK_MAJOR -eq $REQUIRE_MAJOR ]; then if [ $PMEMCHECK_MINOR -lt $REQUIRE_MINOR ]; then return 0 fi fi msg "$UNITTEST_NAME: SKIP pmemcheck API version:" \ "$PMEMCHECK_MAJOR.$PMEMCHECK_MINOR" \ "is greater or equal than" \ "$REQUIRE_MAJOR.$REQUIRE_MINOR" exit 0 } # # require_python_3 -- check if python3 is available # function require_python3() { if hash python3 &>/dev/null; then PYTHON_EXE=python3 else PYTHON_EXE=python fi case "$($PYTHON_EXE --version 2>&1)" in *" 3."*) return ;; *) msg "$UNITTEST_NAME: SKIP: required python version 3" exit 0 ;; esac } # # require_pmreorder -- check all necessary conditions to run pmreorder # usage: require_pmreorder [binary] # function require_pmreorder() { # python3 and valgrind are necessary require_python3 # pmemcheck is required to generate store_log configure_valgrind pmemcheck force-enable $1 # pmreorder tool does not support unicode yet require_no_unicode } # # pmreorder_run_tool -- run pmreorder with parameters and return exit status # # 1 - reorder engine type [nochecker|full|noreorder|partial|accumulative] # 2 - marker-engine pairs in format: MARKER=ENGINE,MARKER1=ENGINE1 or # config file in json format: { "MARKER":"ENGINE","MARKER1":"ENGINE1" } # 3 - the path to the checker binary/library and remaining parameters which # will be passed to the consistency checker binary. # If you are using a library checker, prepend '-n funcname' # function pmreorder_run_tool() { rm -f pmreorder$UNITTEST_NUM.log disable_exit_on_error $PYTHON_EXE $PMREORDER \ -l store_log$UNITTEST_NUM.log \ -o pmreorder$UNITTEST_NUM.log \ -r $1 \ -x $2 \ -p "$3" ret=$? restore_exit_on_error echo $ret } # # pmreorder_expect_success -- run pmreoreder with forwarded parameters, # expect it to exit zero # function pmreorder_expect_success() { ret=$(pmreorder_run_tool "$@" | tail -n1) if [ "$ret" -ne "0" ]; then msg=$(interactive_red STDERR "failed with exit code $ret") # exit code 130 - script terminated by user (Control-C) if [ "$ret" -ne "130" ]; then echo -e "$UNITTEST_NAME $msg." >&2 dump_last_n_lines $PMREORDER_LOG_FILE fi false fi } # # pmreorder_expect_failure -- run pmreoreder with forwarded parameters, # expect it to exit non zero # function pmreorder_expect_failure() { ret=$(pmreorder_run_tool "$@" | tail -n1) if [ "$ret" -eq "0" ]; then msg=$(interactive_red STDERR "succeeded") echo -e "$UNITTEST_NAME command $msg unexpectedly." >&2 false fi } # # pmreorder_create_store_log -- perform a reordering test # # This function expects 5 additional parameters. They are in order: # 1 - the pool file to be tested # 2 - the application and necessary parameters to run pmemcheck logging # function pmreorder_create_store_log() { #copy original file and perform store logging cp $1 "$1.pmr" rm -f store_log$UNITTEST_NUM.log $VALGRINDEXE \ --tool=pmemcheck -q \ --log-stores=yes \ --print-summary=no \ --log-file=store_log$UNITTEST_NUM.log \ --log-stores-stacktraces=yes \ --log-stores-stacktraces-depth=2 \ --expect-fence-after-clflush=yes \ $2 # uncomment this line for debug purposes # mv $1 "$1.bak" mv "$1.pmr" $1 } # # require_free_space -- check if there is enough free space to run the test # Example, checking if there is 1 GB of free space on disk: # require_free_space 1G # function require_free_space() { req_free_space=$(convert_to_bytes $1) # actually require 5% or 8MB (whichever is higher) more, just in case # file system requires some space for its meta data pct=$((5 * $req_free_space / 100)) abs=$(convert_to_bytes 8M) if [ $pct -gt $abs ]; then req_free_space=$(($req_free_space + $pct)) else req_free_space=$(($req_free_space + $abs)) fi output=$(df -k $DIR) found=false i=1 for elem in $(echo "$output" | head -1); do if [ ${elem:0:5} == "Avail" ]; then found=true break else let "i+=1" fi done if [ $found = true ]; then row=$(echo "$output" | tail -1) free_space=$(( $(echo $row | awk "{print \$$i}")*1024 )) else msg "$UNITTEST_NAME: SKIP: unable to check free space" exit 0 fi if [ $free_space -lt $req_free_space ]; then msg "$UNITTEST_NAME: SKIP: not enough free space ($1 required)" exit 0 fi } # # require_max_devdax_size -- checks that dev dax is smaller than requested # # usage: require_max_devdax_size # function require_max_devdax_size() { cur_sz=$(get_devdax_size 0) max_size=$2 if [ $cur_sz -ge $max_size ]; then msg "$UNITTEST_NAME: SKIP: DevDAX $1 is too big for this test (max $2 required)" exit 0 fi } # # require_max_block_size -- checks that block size is smaller or equal than requested # # usage: require_max_block_size # function require_max_block_size() { cur_sz=$(stat --file-system --format=%S $1) max_size=$2 if [ $cur_sz -gt $max_size ]; then msg "$UNITTEST_NAME: SKIP: block size of $1 is too big for this test (max $2 required)" exit 0 fi } # # require_badblock_tests_enabled - check if tests for bad block support are not enabled # Input arguments: # 1) test device type # function require_badblock_tests_enabled() { require_sudo_allowed require_command ndctl require_bb_enabled_by_default $PMEMPOOL$EXESUFFIX if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then require_kernel_module nfit_test # nfit_test dax device is created by the test and is # used directly - no device dax path is needed to be provided by the # user. Some tests though may use an additional filesystem for the # pool replica - hence 'any' filesystem is required. if [ $1 == "dax_device" ]; then require_fs_type any # nfit_test block device is created by the test and mounted on # a filesystem of any type provided by the user elif [ $1 == "block_device" ]; then require_fs_type any fi elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then if [ $1 == "dax_device" ]; then require_fs_type any require_dax_devices 1 require_binary $DAXIO$EXESUFFIX elif [ $1 == "block_device" ]; then require_fs_type pmem fi else msg "$UNITTEST_NAME: SKIP: bad block tests are not enabled in testconfig.sh" exit 0 fi } # # require_badblock_tests_enabled_node - check if tests for bad block support are not enabled # on given remote node # function require_badblock_tests_enabled_node() { require_sudo_allowed_node $1 require_command_node $1 ndctl require_bb_enabled_by_default $PMEMPOOL$EXESUFFIX if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then require_kernel_module_node $1 nfit_test elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then : else msg "$UNITTEST_NAME: SKIP: bad block tests are not enabled in testconfig.sh" exit 0 fi require_sudo_allowed require_kernel_module nfit_test require_command ndctl } # # create_recovery_file - create bad block recovery file # # Usage: create_recovery_file [ ...] # # Offsets and length should be in page sizes. # function create_recovery_file() { [ $# -lt 1 ] && fatal "create_recovery_file(): not enough parameters: $*" FILE=$1 shift rm -f $FILE while [ $# -ge 2 ]; do OFFSET=$1 LENGTH=$2 shift 2 echo "$(($OFFSET * $PAGE_SIZE)) $(($LENGTH * $PAGE_SIZE))" >> $FILE done # write the finish flag echo "0 0" >> $FILE } # # create_recovery_file_absolute - create bad block recovery file # # Usage: create_recovery_file_absolute [ ...] # # Offsets and length should be in bytes. # function create_recovery_file_absolute() { [ $# -lt 1 ] && fatal "create_recovery_file(): not enough parameters: $*" FILE=$1 shift rm -f $FILE while [ $# -ge 2 ]; do OFFSET=$1 LENGTH=$2 shift 2 echo "$OFFSET $LENGTH" >> $FILE done # write the finish flag echo "0 0" >> $FILE } # # zero_blocks - zero blocks in a file # # Usage: zero_blocks # # Offsets and length should be in page sizes. # function zero_blocks() { [ $# -lt 3 ] && fatal "zero_blocks(): not enough parameters: $*" FILE=$1 shift while [ $# -ge 2 ]; do OFFSET=$1 LENGTH=$2 shift 2 dd if=/dev/zero of=$FILE bs=$PAGE_SIZE seek=$OFFSET count=$LENGTH conv=notrunc status=none done } # # turn_on_checking_bad_blocks -- set the compat_feature POOL_FEAT_CHECK_BAD_BLOCKS on # function turn_on_checking_bad_blocks() { FILE=$1 expect_normal_exit "$PMEMPOOL feature -e CHECK_BAD_BLOCKS $FILE &>> $PREP_LOG_FILE" } # # turn_on_checking_bad_blocks_node -- set the compat_feature POOL_FEAT_CHECK_BAD_BLOCKS on # function turn_on_checking_bad_blocks_node() { FILE=$2 expect_normal_exit run_on_node $1 "../pmempool feature -e CHECK_BAD_BLOCKS $FILE &>> $PREP_LOG_FILE" } pmdk-1.11.1/src/test/unittest/ut_alloc.c0000664000000000000000000001021614123364546016631 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * ut_alloc.c -- unit test memory allocation routines */ #include "unittest.h" /* * ut_malloc -- a malloc that cannot return NULL */ void * ut_malloc(const char *file, int line, const char *func, size_t size) { void *retval = malloc(size); if (retval == NULL) ut_fatal(file, line, func, "cannot malloc %zu bytes", size); return retval; } /* * ut_calloc -- a calloc that cannot return NULL */ void * ut_calloc(const char *file, int line, const char *func, size_t nmemb, size_t size) { void *retval = calloc(nmemb, size); if (retval == NULL) ut_fatal(file, line, func, "cannot calloc %zu bytes", size); return retval; } /* * ut_free -- wrapper for free * * technically we don't need to wrap free since there's no return to * check. using this wrapper to add memory allocation tracking later. */ void ut_free(const char *file, int line, const char *func, void *ptr) { free(ptr); } /* * ut_aligned_free -- wrapper for aligned memory free */ void ut_aligned_free(const char *file, int line, const char *func, void *ptr) { #ifndef _WIN32 free(ptr); #else _aligned_free(ptr); #endif } /* * ut_realloc -- a realloc that cannot return NULL */ void * ut_realloc(const char *file, int line, const char *func, void *ptr, size_t size) { void *retval = realloc(ptr, size); if (retval == NULL) ut_fatal(file, line, func, "cannot realloc %zu bytes", size); return retval; } /* * ut_strdup -- a strdup that cannot return NULL */ char * ut_strdup(const char *file, int line, const char *func, const char *str) { char *retval = strdup(str); if (retval == NULL) ut_fatal(file, line, func, "cannot strdup %zu bytes", strlen(str)); return retval; } /* * ut_memalign -- like malloc but page-aligned memory */ void * ut_memalign(const char *file, int line, const char *func, size_t alignment, size_t size) { void *retval; #ifndef _WIN32 if ((errno = posix_memalign(&retval, alignment, size)) != 0) ut_fatal(file, line, func, "!memalign %zu bytes (%zu alignment)", size, alignment); #else retval = _aligned_malloc(size, alignment); if (!retval) { ut_fatal(file, line, func, "!memalign %zu bytes (%zu alignment)", size, alignment); } #endif return retval; } /* * ut_pagealignmalloc -- like malloc but page-aligned memory */ void * ut_pagealignmalloc(const char *file, int line, const char *func, size_t size) { return ut_memalign(file, line, func, (size_t)Ut_pagesize, size); } /* * ut_mmap_anon_aligned -- mmaps anonymous memory with specified (power of two, * multiple of page size) alignment and adds guard * pages around it */ void * ut_mmap_anon_aligned(const char *file, int line, const char *func, size_t alignment, size_t size) { char *d, *d_aligned; uintptr_t di, di_aligned; size_t sz; if (alignment == 0) alignment = Ut_mmap_align; /* alignment must be a multiple of page size */ if (alignment & (Ut_mmap_align - 1)) return NULL; /* power of two */ if (alignment & (alignment - 1)) return NULL; d = ut_mmap(file, line, func, NULL, size + 2 * alignment, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); di = (uintptr_t)d; di_aligned = (di + alignment - 1) & ~(alignment - 1); if (di == di_aligned) di_aligned += alignment; d_aligned = (void *)di_aligned; sz = di_aligned - di; if (sz - Ut_mmap_align) ut_munmap(file, line, func, d, sz - Ut_mmap_align); /* guard page before */ ut_mprotect(file, line, func, d_aligned - Ut_mmap_align, Ut_mmap_align, PROT_NONE); /* guard page after */ ut_mprotect(file, line, func, d_aligned + size, Ut_mmap_align, PROT_NONE); sz = di + size + 2 * alignment - (di_aligned + size) - Ut_mmap_align; if (sz) ut_munmap(file, line, func, d_aligned + size + Ut_mmap_align, sz); return d_aligned; } /* * ut_munmap_anon_aligned -- unmaps anonymous memory allocated by * ut_mmap_anon_aligned */ int ut_munmap_anon_aligned(const char *file, int line, const char *func, void *start, size_t size) { return ut_munmap(file, line, func, (char *)start - Ut_mmap_align, size + 2 * Ut_mmap_align); } pmdk-1.11.1/src/test/unittest/ut_backtrace.c0000664000000000000000000000751314123364546017464 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * ut_backtrace.c -- backtrace reporting routines */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "unittest.h" #ifdef USE_LIBUNWIND #define UNW_LOCAL_ONLY #include #include #define PROCNAMELEN 256 /* * ut_dump_backtrace -- dump stacktrace to error log using libunwind */ void ut_dump_backtrace(void) { unw_context_t context; unw_proc_info_t pip; pip.unwind_info = NULL; int ret = unw_getcontext(&context); if (ret) { UT_ERR("unw_getcontext: %s [%d]", unw_strerror(ret), ret); return; } unw_cursor_t cursor; ret = unw_init_local(&cursor, &context); if (ret) { UT_ERR("unw_init_local: %s [%d]", unw_strerror(ret), ret); return; } ret = unw_step(&cursor); char procname[PROCNAMELEN]; unsigned i = 0; while (ret > 0) { ret = unw_get_proc_info(&cursor, &pip); if (ret) { UT_ERR("unw_get_proc_info: %s [%d]", unw_strerror(ret), ret); break; } unw_word_t off; ret = unw_get_proc_name(&cursor, procname, PROCNAMELEN, &off); if (ret && ret != -UNW_ENOMEM) { if (ret != -UNW_EUNSPEC) { UT_ERR("unw_get_proc_name: %s [%d]", unw_strerror(ret), ret); } strcpy(procname, "?"); } void *ptr = (void *)(pip.start_ip + off); Dl_info dlinfo; const char *fname = "?"; uintptr_t in_object_offset = 0; if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname && *dlinfo.dli_fname) { fname = dlinfo.dli_fname; uintptr_t base = (uintptr_t)dlinfo.dli_fbase; if ((uintptr_t)ptr >= base) in_object_offset = (uintptr_t)ptr - base; } UT_ERR("%u: %s (%s%s+0x%lx) [%p] [0x%" PRIxPTR "]", i++, fname, procname, ret == -UNW_ENOMEM ? "..." : "", off, ptr, in_object_offset); ret = unw_step(&cursor); if (ret < 0) UT_ERR("unw_step: %s [%d]", unw_strerror(ret), ret); } } #else /* USE_LIBUNWIND */ #define SIZE 100 #ifndef _WIN32 #include /* * ut_dump_backtrace -- dump stacktrace to error log using libc's backtrace */ void ut_dump_backtrace(void) { int j, nptrs; void *buffer[SIZE]; char **strings; nptrs = backtrace(buffer, SIZE); strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { UT_ERR("!backtrace_symbols"); return; } for (j = 0; j < nptrs; j++) UT_ERR("%u: %s", j, strings[j]); free(strings); } #else /* _WIN32 */ #include /* * ut_dump_backtrace -- dump stacktrace to error log */ void ut_dump_backtrace(void) { void *buffer[SIZE]; unsigned nptrs; SYMBOL_INFO *symbol; HANDLE proc_hndl = GetCurrentProcess(); SymInitialize(proc_hndl, NULL, TRUE); nptrs = CaptureStackBackTrace(0, SIZE, buffer, NULL); symbol = CALLOC(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR), 1); symbol->MaxNameLen = MAX_SYM_NAME - 1; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); for (unsigned i = 0; i < nptrs; i++) { if (SymFromAddr(proc_hndl, (DWORD64)buffer[i], 0, symbol)) { UT_ERR("%u: %s [%p]", nptrs - i - 1, symbol->Name, buffer[i]); } else { UT_ERR("%u: [%p]", nptrs - i - 1, buffer[i]); } } FREE(symbol); } #endif /* _WIN32 */ #endif /* USE_LIBUNWIND */ /* * ut_sighandler -- fatal signal handler */ void ut_sighandler(int sig) { /* * Usually SIGABRT is a result of ASSERT() or FATAL(). * We don't need backtrace, as the reason of the failure * is logged in debug traces. */ if (sig != SIGABRT) { UT_ERR("\n"); UT_ERR("Signal %d, backtrace:", sig); ut_dump_backtrace(); UT_ERR("\n"); } exit(128 + sig); } /* * ut_register_sighandlers -- register signal handlers for various fatal signals */ void ut_register_sighandlers(void) { signal(SIGSEGV, ut_sighandler); signal(SIGABRT, ut_sighandler); signal(SIGILL, ut_sighandler); signal(SIGFPE, ut_sighandler); signal(SIGINT, ut_sighandler); #ifndef _WIN32 signal(SIGQUIT, ut_sighandler); signal(SIGBUS, ut_sighandler); #endif } pmdk-1.11.1/src/test/unittest/.gitignore0000664000000000000000000000001014123364546016642 0ustar rootrootlibut.a pmdk-1.11.1/src/test/unittest/requirements.py0000664000000000000000000000620414123364546017762 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # """Various requirements""" import subprocess as sp import ctypes import sys import os import configurator as conf import context as ctx import futils NDCTL_MIN_VERSION = '63' class Requirements: """Various requirements""" def __init__(self): self.cfg = conf.Configurator().config def _check_pkgconfig(self, pkg, min_ver): """ Run pkg-config to check if a package is installed """ proc = sp.run(['pkg-config', pkg, '--atleast-version', min_ver], stdout=sp.PIPE, stderr=sp.STDOUT) return proc.returncode == 0 def _is_ndctl_enabled(self): path = futils.get_tool_path(ctx, "pmempool") s = sp.check_output(["strings", path]) if "compiled with libndctl" in str(s): return True return False def _check_is_admin(self): if sys.platform == 'win32': return ctypes.windll.shell32.IsUserAnAdmin() != 0 else: return os.getuid() == 0 def check_ndctl(self): is_ndctl = self._check_pkgconfig('libndctl', NDCTL_MIN_VERSION) if not is_ndctl: raise futils.Skip('libndctl (>=v{}) is not installed' .format(NDCTL_MIN_VERSION)) def check_ndctl_enable(self): if self._is_ndctl_enabled() is False: raise futils.Skip('ndctl is disabled - binary not ' 'compiled with libndctl') def _check_ndctl_req_is_met(self, tc): """ Check if all conditions for the ndctl requirement are met """ require_ndctl, _ = ctx.get_requirement(tc, 'require_ndctl', ()) if not require_ndctl: return True self.check_ndctl_enable() self.check_ndctl() return True def _check_admin_req_is_met(self, tc): """ Check if all conditions for the admin requirement are met """ require_admin, _ = ctx.get_requirement(tc, 'require_admin', ()) if not require_admin: # admin is not required return True if not self.cfg.enable_admin_tests: raise futils.Skip('admin tests are not enabled in config ' '(enable_admin_tests)') if not self._check_is_admin(): raise futils.Fail('Error: admin tests are enabled in config, ' 'but the user does not have administrative ' 'privileges') # user is admin return True def check_if_all_requirements_are_met(self, tc): if not self._check_ndctl_req_is_met(tc): return False if not self._check_admin_req_is_met(tc): return False """More requirements can be checked here""" return True def require_ndctl(tc): """Enable test only if ndctl is installed""" ctx.add_requirement(tc, 'require_ndctl', True) return tc def require_admin(tc): """ Disable test if "enable_admin_tests" configuration is not set """ ctx.add_requirement(tc, 'require_admin', True) return tc pmdk-1.11.1/src/test/unittest/ut_pmem2_setup_integration.c0000664000000000000000000000144414123364546022405 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_setup_integration.h -- libpmem2 setup functions using public API * (for integration tests) */ #include #include "ut_pmem2_config.h" #include "ut_pmem2_setup_integration.h" #include "ut_pmem2_source.h" #include "unittest.h" /* * ut_pmem2_prepare_config_integration -- fill pmem2_config in minimal scope */ void ut_pmem2_prepare_config_integration(const char *file, int line, const char *func, struct pmem2_config **cfg, struct pmem2_source **src, int fd, enum pmem2_granularity granularity) { ut_pmem2_config_new(file, line, func, cfg); ut_pmem2_config_set_required_store_granularity(file, line, func, *cfg, granularity); ut_pmem2_source_from_fd(file, line, func, src, fd); } pmdk-1.11.1/src/test/unittest/README0000664000000000000000000000335014123364546015544 0ustar rootrootPersistent Memory Development Kit This is src/test/unittest/README. This directory contains the unit test framework used by the Persistent Memory Development Kit unit tests. This framework provides a support for mock objects. To mock an interface use FUNC_MOCK_RET_ALWAYS or FUNC_MOCK macros in the test code. The FUNC_MOCK_RET_ALWAYS is quite straightforward, it simply takes a function name and a value that the given function has to return. For example: FUNC_MOCK_RET_ALWAYS(malloc, NULL) This declaration causes all malloc calls to return NULL and thus facilitates error path tests. The rest of FUNC_MOCK set of macros is used in more complicated cases. It allows to implement replacement logic for different runs of the given function. For example: FUNC_MOCK(malloc, void *, size_t size) FUNC_MOCK_RUN_RET_DEFAULT_REAL(malloc, size) FUNC_MOCK_RUN(2) { UT_ASSERTeq(size, 8); return NULL; } FUNC_MOCK_END This declaration causes the third malloc call to return NULL and also verifies if the size argument is of expected size. All other mallocs fallback to the real implementation. Those macros can be used on all non-static functions that are in a different compilation unit than the test itself. Because the mocking framework uses the linker to wrap the functions, all tests have to add appropriate linker flags. For convenience, there is a makefile function 'extract_funcs' which parses the source file looking for the FUNC_MOCK_RET_ALWAYS or FUNC_MOCK and adds the wrap flag for all the encountered functions. Test makefile that wishes to use this functionality should contain following line: LDFLAGS += $(call extract_funcs, [test_name].c) And after that no changes in makefile is required at all when adding new mocks. pmdk-1.11.1/src/test/unittest/test_types.py0000664000000000000000000000060014123364546017434 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Test type context classes""" import context as ctx class _TestType(metaclass=ctx.CtxType): """Base class for a test duration.""" class Short(_TestType): pass class Medium(_TestType): pass class Long(_TestType): pass class Check(_TestType): includes = [Short, Medium] pmdk-1.11.1/src/test/unittest/builds.py0000664000000000000000000000406214123364546016521 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Build context classes""" import sys import context as ctx import futils import consts as c class Build(metaclass=ctx.CtxType): """Base and factory class for standard build classes""" exesuffix = '' def set_env_common(self): if sys.platform == 'win32': self.env = {'PATH': self.libdir} else: self.env = {'LD_LIBRARY_PATH': self.libdir} @classmethod def filter(cls, config, msg, tc): req_builds, kwargs = ctx.get_requirement(tc, 'build', None) builds = [] for b in ctx.filter_contexts(config.build, req_builds): try: builds.append(b(**kwargs)) except futils.Skip as s: msg.print_verbose('{}: SKIP: {}'.format(tc, s)) return builds class Debug(Build): """Set this context for a debug build""" is_preferred = True def __init__(self): if sys.platform == 'win32': self.exedir = c.WIN_DEBUG_EXEDIR self.libdir = c.DEBUG_LIBDIR self.set_env_common() class Release(Build): """Set this context for a release build""" is_preferred = True def __init__(self): if sys.platform == 'win32': self.exedir = c.WIN_RELEASE_EXEDIR self.libdir = c.RELEASE_LIBDIR self.set_env_common() # Build types not available on Windows if sys.platform != 'win32': class Static_Debug(Build): """Set this context for a static_debug build""" def __init__(self): self.exesuffix = '.static-debug' self.libdir = c.DEBUG_LIBDIR class Static_Release(Build): """Set this context for a static_release build""" def __init__(self): self.exesuffix = '.static-nondebug' self.libdir = c.RELEASE_LIBDIR def require_build(build, **kwargs): def wrapped(tc): builds = ctx.str_to_ctx_common(build, Build) ctx.add_requirement(tc, 'build', builds, **kwargs) return tc return wrapped pmdk-1.11.1/src/test/unittest/ut_fh.c0000664000000000000000000001706614123364546016146 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * ut_fh.c -- implementation of OS-independent file handle / file descriptor * interface */ /* for O_TMPFILE */ #define _GNU_SOURCE #include #include "ut_fh.h" #include "unittest.h" struct FHandle { int fd; #ifdef _WIN32 HANDLE h; #endif enum file_handle_type type; }; #ifdef _WIN32 #define HIDWORD(x) ((DWORD)((x) >> 32)) #define LODWORD(x) ((DWORD)((x) & 0xFFFFFFFF)) #endif static void check_invalid_flags(const char *file, int line, const char *func, int flags) { if ((flags & FH_EXCL) && !(flags & FH_CREAT)) { ut_fatal(file, line, func, "FH_EXCL without FH_CREAT is meaningless"); } if ((flags & FH_TRUNC) && (flags & FH_CREAT)) { /* because Windows doesn't support both */ ut_fatal(file, line, func, "FH_TRUNC with FH_CREAT is forbidden"); } } static int ut_fh_open_fd(const char *file, int line, const char *func, const char *path, int flags, mode_t mode) { int sflags = 0; check_invalid_flags(file, line, func, flags); if ((flags & (FH_CREAT | FH_EXCL)) == (FH_CREAT | FH_EXCL)) { flags &= ~(FH_CREAT | FH_EXCL); sflags |= O_CREAT | O_EXCL; } else if (flags & FH_CREAT) { flags &= ~FH_CREAT; sflags |= O_CREAT; /* Windows version doesn't support both O_TRUNC and O_CREAT */ } else if (flags & FH_TRUNC) { flags &= ~FH_TRUNC; sflags |= O_TRUNC; } int acc = flags & FH_ACCMODE; /* Linux version does not have FH_EXEC equivalent */ if ((acc & FH_WRITE) && (acc & FH_READ)) sflags |= O_RDWR; else if (acc & FH_WRITE) sflags |= O_WRONLY; else if (acc & FH_READ) sflags |= O_RDONLY; else ut_fatal(file, line, func, "unknown access mode %d", acc); flags &= ~FH_ACCMODE; if (flags & FH_DIRECTORY) { #ifdef _WIN32 ut_fatal(file, line, func, "FH_DIRECTORY is not supported on Windows using FD interface"); #else flags &= ~FH_DIRECTORY; sflags |= O_DIRECTORY; #endif } if (flags & FH_TMPFILE) { #ifdef O_TMPFILE flags &= ~FH_TMPFILE; sflags |= O_TMPFILE; #else ut_fatal(file, line, func, "FH_TMPFILE is not supported on this system for file descriptors"); #endif } if (flags) ut_fatal(file, line, func, "unsupported flag(s) 0%o", flags); return ut_open(file, line, func, path, sflags, mode); } #ifdef _WIN32 static HANDLE ut_fh_open_handle(const char *file, int line, const char *func, const char *path, int flags, mode_t mode) { DWORD dwDesiredAccess; /* do not allow delete, read or write from another process */ DWORD dwShareMode = 0; LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; DWORD dwCreationDisposition; DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; HANDLE hTemplateFile = NULL; /* XXX sometimes doesn't work, ERROR_ACCESS_DENIED on AppVeyor */ #if 0 /* * FILE_FLAG_DELETE_ON_CLOSE needs a real file (FH_CREAT) * If it already exists refuse to use it (FH_EXCL), because this means * something weird is going on (either there's another process with * the same file opened or FILE_FLAG_DELETE_ON_CLOSE didn't actually * delete the file on close) */ if (flags & FH_TMPFILE) flags |= FH_CREAT | FH_EXCL; #else if (flags & FH_TMPFILE) ut_fatal(file, line, func, "FH_TMPFILE is not supported for file handles"); #endif check_invalid_flags(file, line, func, flags); /* only write permission can be taken out on Windows */ if (!(mode & _S_IWRITE)) dwFlagsAndAttributes |= FILE_ATTRIBUTE_READONLY; if ((flags & (FH_CREAT | FH_EXCL)) == (FH_CREAT | FH_EXCL)) { flags &= ~(FH_CREAT | FH_EXCL); dwCreationDisposition = CREATE_NEW; } else if (flags & FH_CREAT) { flags &= ~FH_CREAT; dwCreationDisposition = OPEN_ALWAYS; } else if (flags & FH_TRUNC) { flags &= ~FH_TRUNC; dwCreationDisposition = TRUNCATE_EXISTING; } else { dwCreationDisposition = OPEN_EXISTING; } int acc = flags & FH_ACCMODE; dwDesiredAccess = 0; if (acc & FH_READ) { dwDesiredAccess |= GENERIC_READ; acc &= ~FH_READ; } if (acc & FH_WRITE) { dwDesiredAccess |= GENERIC_WRITE; acc &= ~FH_WRITE; } if (acc & FH_EXEC) { dwDesiredAccess |= GENERIC_EXECUTE; acc &= ~FH_EXEC; } if (acc) ut_fatal(file, line, func, "unknown access mode %d", acc); flags &= ~FH_ACCMODE; if (flags & FH_DIRECTORY) { flags &= ~FH_DIRECTORY; /* GJ MS */ dwFlagsAndAttributes |= FILE_FLAG_BACKUP_SEMANTICS; } char *full_path = NULL; if (flags & FH_TMPFILE) { flags &= ~FH_TMPFILE; dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; /* * FILE_FLAG_DELETE_ON_CLOSE needs a real file, * not a directory */ full_path = MALLOC(strlen(path) + 1 + strlen("UT_FH_TMPFILE") + 1); sprintf(full_path, "%s\\UT_FH_TMPFILE", path); path = full_path; } if (flags) ut_fatal(file, line, func, "unsupported flag(s) 0%o", flags); wchar_t *wpath = util_toUTF16(path); if (wpath == NULL) ut_fatal(file, line, func, "conversion to utf16 failed"); HANDLE h = CreateFileW(wpath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); util_free_UTF16(wpath); if (h == INVALID_HANDLE_VALUE) { ut_fatal(file, line, func, "opening file %s failed: %d", path, GetLastError()); } if (full_path) free(full_path); return h; } #endif struct FHandle * ut_fh_open(const char *file, int line, const char *func, enum file_handle_type type, const char *path, int flags, ...) { struct FHandle *f = MALLOC(sizeof(*f)); mode_t mode = 0; va_list ap; va_start(ap, flags); if ((flags & FH_CREAT) || (flags & FH_TMPFILE)) mode = va_arg(ap, mode_t); va_end(ap); f->type = type; if (type == FH_FD) { f->fd = ut_fh_open_fd(file, line, func, path, flags, mode); } else if (type == FH_HANDLE) { #ifdef _WIN32 f->h = ut_fh_open_handle(file, line, func, path, flags, mode); #else ut_fatal(file, line, func, "FH_HANDLE not supported on !Windows"); #endif } else { ut_fatal(file, line, func, "unknown type value %d", type); } return f; } void ut_fh_truncate(const char *file, int line, const char *func, struct FHandle *f, os_off_t length) { if (f->type == FH_FD) { ut_ftruncate(file, line, func, f->fd, length); } else if (f->type == FH_HANDLE) { #ifdef _WIN32 LONG low = LODWORD(length); LONG high = HIDWORD(length); if (SetFilePointer(f->h, low, &high, FILE_BEGIN) == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS) { ut_fatal(file, line, func, "SetFilePointer failed: %d", GetLastError()); } if (SetEndOfFile(f->h) == 0) { ut_fatal(file, line, func, "SetEndOfFile failed: %d", GetLastError()); } #else ut_fatal(file, line, func, "FH_HANDLE not supported on !Windows"); #endif } else { ut_fatal(file, line, func, "unknown type value %d", f->type); } } void ut_fh_close(const char *file, int line, const char *func, struct FHandle *f) { if (f->type == FH_FD) { CLOSE(f->fd); } else if (f->type == FH_HANDLE) { #ifdef _WIN32 CloseHandle(f->h); #else ut_fatal(file, line, func, "FH_HANDLE not supported on !Windows"); #endif } else { ut_fatal(file, line, func, "unknown type value %d", f->type); } memset(f, 0, sizeof(*f)); FREE(f); } int ut_fh_get_fd(const char *file, int line, const char *func, struct FHandle *f) { if (f->type == FH_FD) return f->fd; ut_fatal(file, line, func, "requested file descriptor on FHandle that doesn't contain it"); } #ifdef _WIN32 HANDLE ut_fh_get_handle(const char *file, int line, const char *func, struct FHandle *f) { if (f->type == FH_HANDLE) return f->h; ut_fatal(file, line, func, "requested file handle on FHandle that doesn't contain it"); } #endif enum file_handle_type ut_fh_get_handle_type(struct FHandle *fh) { return fh->type; } pmdk-1.11.1/src/test/unittest/ctx_filter.py0000664000000000000000000000602514123364546017403 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation """ Functionalities for acquiring (through 'filtering' execution configuration and test specification) set of context parameters with which the test will be run. """ import sys import itertools import builds import futils import granularity import devdax import context as ctx import valgrind as vg import requirements as req if sys.platform != 'win32': CTX_TYPES = (vg.Valgrind, granularity.Granularity, devdax.DevDaxes) else: CTX_TYPES = (granularity.Granularity, ) class CtxFilter: """ Generates contexts based on provided configuration and test requirements. Attributes: tc (BaseTest): test using the context config: configuration class msg (Message): level based logger """ def __init__(self, config, tc): self.tc = tc self.config = config self.msg = futils.Message(config.unittest_log_level) def _get_builds(self): return builds.Build.filter(self.config, self.msg, self.tc) def get_contexts(self): """ Generate a list of contexts based on configuration and test requirements """ reqs = req.Requirements() if not reqs.check_if_all_requirements_are_met(self.tc): return [] conf_params = self._get_configured_params() common_params = self._get_common_params() ctx_elem_names = list(conf_params.keys()) + list(common_params.keys()) builds = self._get_builds() # Generate cartesian product of builds and context elements. # Each element of the product serves as a base for the separate # context in which the test is run ctx_params = itertools.product(builds, *conf_params.values(), *common_params.values()) ctxs = [] for cp in ctx_params: build = cp[0] ctx_elems = dict(zip(ctx_elem_names, cp[1:])) c = ctx.Context(build, **ctx_elems) c.cwd = self.tc.cwd ctxs.append(c) return ctxs def _get_configured_params(self): """ Get special test parameters, like file system or Valgrind tool which final content depends on test requirements, and user configuration. This content is obtained through its static filter() method. """ # TODO: instead of using a hard-coded CTX_TYPES list, # detect configured parameters based on whether they # implement the filter() method. # Configured parameter therefore becomes # the specific case of common parameter # and may be implemented ad-hoc by the test developer params = {} for param in CTX_TYPES: params[param.__name__.lower()] = \ param.filter(self.config, self.msg, self.tc) return params def _get_common_params(self): """ Get generic test params, added through ctx.add_params() function """ return ctx.get_params(self.tc) pmdk-1.11.1/src/test/unittest/utils.py0000664000000000000000000000417214123364546016401 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation """Utilities for tests. Meant to be used by test user.""" import sys import platform import consts as c def require_architectures(*archs): """Enable test only for specified architectures""" def wrapped(tc): this_arch = platform.machine() # normalize this_arch value for normalized, possible in c.NORMALIZED_ARCHS.items(): if this_arch in possible: this_arch = normalized if this_arch not in archs: tc.enabled = False return tc return wrapped def _os_only(tc, os_name): """ Disable test case (TEST[number] class) if NOT run on selected OS. Otherwise, the test is not re-enabled if it was already disabled elsewhere. Internal helper function. """ if not sys.platform.startswith(os_name): tc.enabled = False return tc def _os_exclude(tc, os_name): """ Disable test case (TEST[number] class) on selected OS. Internal helper function. """ if sys.platform.startswith(os_name): tc.enabled = False return tc def windows_only(tc): """ Disable test case (TEST[number] class) if NOT run on Windows. Use it as a class decorator. """ return _os_only(tc, 'win32') def linux_only(tc): """ Disable test case (TEST[number] class) if NOT run on Linux. Use it as a class decorator. """ return _os_only(tc, 'linux') def freebsd_only(tc): """ Disable test case (TEST[number] class) if NOT run on FreeBSD. Use it as a class decorator. """ return _os_only(tc, 'freebsd') def windows_exclude(tc): """ Disable test case (TEST[number] class) on Windows. Use it as a class decorator. """ return _os_exclude(tc, 'win32') def linux_exclude(tc): """ Disable test case (TEST[number] class) on Linux. Use it as a class decorator. """ return _os_exclude(tc, 'linux') def freebsd_exclude(tc): """ Disable test case (TEST[number] class) on FreeBSD. Use it as a class decorator. """ return _os_exclude(tc, 'freebsd') pmdk-1.11.1/src/test/unittest/libut.vcxproj0000664000000000000000000001350214123364546017420 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {CE3F2DFB-8470-4802-AD37-21CAF6CB2681} Win32Proj libut 10.0.17134.0 StaticLibrary true v140 NotSet StaticLibrary true v140 NotSet true .lib $(SolutionDir)\core;$(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(IncludePath) true .lib $(SolutionDir)\core;$(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(IncludePath) NotUsing Level3 PMDK_UTF8_API; NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) platform.h CompileAsC MultiThreadedDebugDLL true Console true ole32.lib;ntdll.lib false NotUsing Level3 PMDK_UTF8_API; NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) platform.h CompileAsC MultiThreadedDLL MaxSpeed Default ProgramDatabase true Console true ole32.lib;ntdll.lib false pmdk-1.11.1/src/test/unittest/devdax.py0000664000000000000000000001553614123364546016522 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # """Device dax context classes and utilities""" import copy import itertools import os import sys import context as ctx import futils import requirements as req import tools class DevDax(): """ Class representing dax device and its parameters. Attributes: name (str): name of the DevDax object by which it is accessible from DaxDevices class path (str): path to device _req_alignment (int): required dax device alignment _req_min_size (int): required dax device minimal size _req_max_size (int): required dax device maximal size assigned (bool): True, if object was successfully assigned to real dax device that fulfills its requirements, False otherwise """ def __init__(self, name, alignment=None, min_size=None, max_size=None): self.name = name self.path = None self._req_alignment = alignment self._req_min_size = min_size self._req_max_size = max_size self.assigned = False def __str__(self): return self.name def try_assign(self, path): """ Try assigning to real dax device, identified by its path, provided it meets defined requirements. In case of success, set DevDax object attributes (like size and/or alignment) to the real dax device values and return True. Return False otherwise. """ ndctl = tools.Ndctl() p_size = ndctl.get_dev_size(path) p_align = ndctl.get_dev_alignment(path) if self._req_min_size and p_size < self._req_min_size: return False if self._req_max_size and p_size > self._req_max_size: return False if self._req_alignment and p_align != self._req_alignment: return False self.path = path self.size = p_size self.alignment = p_align self.assigned = True return True class DevDaxes(): """ Dax device context element class representing a set of dax devices required for the test. Attributes: dax_devices (tuple): set of dax devices (DevDax objects) which are required by the test. Each DevDax is accessible from DaxDevices as an attribute through its name """ check_fs_exec = False def __init__(self, *dax_devices): self.dax_devices = tuple(dax_devices) for dd in dax_devices: setattr(self, dd.name, dd) def setup(self, **kwargs): # DevDax tests always require ndctl req.Requirements().check_ndctl_enable() req.Requirements().check_ndctl() tools = kwargs['tools'] for dd in self.dax_devices: proc = tools.pmemdetect('-d', dd.path) if proc.returncode != 0: raise futils.Fail('checking {} with pmemdetect failed:{}{}' .format(dd.path, os.linesep, proc.stdout)) if self.check_fs_exec: exec_allowed = tools.mapexec(dd.path) if exec_allowed.returncode != 1: raise futils.Skip('dax device {} has no exec rights for' ' mmap'.format(dd.path)) def __str__(self): return 'devdax' @classmethod def filter(cls, config, msg, tc): """ Initialize DevDaxes class for the test to be run based on configuration and test requirements. Args: config: configuration as returned by Configurator class msg (Message): level based logger class instance tc (BaseTest): test case, from which the dax device run requirements are obtained Returns: Initialized DevDaxes class as single element list for type compliance """ dax_devices, _ = ctx.get_requirement(tc, 'devdax', ()) cls.check_fs_exec, kwargs = ctx.get_requirement(tc, 'require_fs_exec', None) if not dax_devices: return ctx.NO_CONTEXT elif sys.platform == 'win32' and tc.enabled: raise futils.Fail('dax device functionality required by "{}" is ' 'not available on Windows. Please disable the ' 'test for this platform'.format(tc)) if not config.device_dax_path: raise futils.Skip('No dax devices defined in testconfig') if len(dax_devices) > len(config.device_dax_path): raise futils.Skip('Not enough dax devices defined in testconfig ' '({} needed)'.format(len(dax_devices))) ndctl = tools.Ndctl() for c in config.device_dax_path: if not ndctl.is_devdax(c): raise futils.Fail('{} is not a dax device'.format(c)) assigned = _try_assign_by_requirements(config.device_dax_path, dax_devices) if not assigned: raise futils.Skip('Dax devices in test configuration do not ' 'meet test requirements') return [DevDaxes(*assigned)] def _try_assign_by_requirements(configured, required): """ Try assigning dax devices defined as paths in test configuration to dax device objects taking their requirements into account. Return a sequence of all requirement objects if they were successfully assigned to existing dax, otherwise return None. Since the order in which requirement objects are tried to be assigned may affect the final outcome, all permutations are checked. """ permutations = itertools.permutations(required) for p in permutations: conf_copy = configured[:] req_copy = copy.deepcopy(p) for dd in req_copy: for i, c in enumerate(conf_copy): if dd.try_assign(c): conf_copy.pop(i) break if not dd.assigned: # at least one device dax requirement cannot be assigned # to any of devices defined in the configuration, # try another permutation break if all(dd.assigned for dd in req_copy): return req_copy return None def require_devdax(*dax_devices, **kwargs): """ Add requirement to run test on specified dax devices. Used as a test class decorator. Args: dax_devices: variable length list of initialized DevDax objects kwargs: optional keyword arguments """ def wrapped(tc): ctx.add_requirement(tc, 'devdax', tuple(dax_devices), **kwargs) return tc return wrapped def require_fs_exec(tc): """ Disable test if exec acess for device is not permitted """ ctx.add_requirement(tc, 'require_fs_exec', True) return tc pmdk-1.11.1/src/test/unittest/ut.c0000664000000000000000000006535514123364546015475 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2021, Intel Corporation */ /* * ut.c -- unit test support routines * * some of these functions look at errno, but none of them * change errno -- it is preserved across these calls. * * ut_done() and ut_fatal() never return. */ #include "unittest.h" #ifndef _WIN32 #ifdef __FreeBSD__ #include int ut_get_uuid_str(char *uu) { uuid_t uuid; uuid_generate(uuid); uuid_unparse(uuid, uu); return 0; } #else int ut_get_uuid_str(char *uu) { int fd = OPEN(UT_POOL_HDR_UUID_GEN_FILE, O_RDONLY); size_t num = READ(fd, uu, UT_POOL_HDR_UUID_STR_LEN); UT_ASSERTeq(num, UT_POOL_HDR_UUID_STR_LEN); uu[UT_POOL_HDR_UUID_STR_LEN - 1] = '\0'; CLOSE(fd); return 0; } #endif /* RHEL5 seems to be missing decls, even though libc supports them */ extern DIR *fdopendir(int fd); extern ssize_t readlinkat(int, const char *restrict, char *__restrict, size_t); void ut_strerror(int errnum, char *buff, size_t bufflen) { strerror_r(errnum, buff, bufflen); } void ut_suppress_errmsg(void) {} void ut_unsuppress_errmsg(void) {} void ut_suppress_crt_assert(void) {} void ut_unsuppress_crt_assert(void) {} #else #include #pragma comment(lib, "rpcrt4.lib") static DWORD ErrMode; static BOOL Err_suppressed = FALSE; static UINT AbortBehave; void ut_suppress_errmsg(void) { ErrMode = GetErrorMode(); SetErrorMode(ErrMode | SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); AbortBehave = _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); Err_suppressed = TRUE; } void ut_unsuppress_errmsg(void) { if (Err_suppressed) { SetErrorMode(ErrMode); _set_abort_behavior(AbortBehave, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); Err_suppressed = FALSE; } } static _invalid_parameter_handler OldHandler; static BOOL Crt_suppressed = FALSE; static int Old_crt_assert_mode; /* * empty_parameter_handler -- empty, non aborting invalid parameter handler */ static void empty_parameter_handler(const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned line, uintptr_t pReserved) { } /* * ut_suppress_crt_assert -- suppress crt raport message box */ void ut_suppress_crt_assert(void) { OldHandler = _set_invalid_parameter_handler(empty_parameter_handler); Old_crt_assert_mode = _CrtSetReportMode(_CRT_ASSERT, 0); Crt_suppressed = TRUE; } /* * ut_suppress_crt_assert -- unsuppress crt raport message box */ void ut_unsuppress_crt_assert(void) { if (Crt_suppressed) { _set_invalid_parameter_handler(OldHandler); _CrtSetReportMode(_CRT_ASSERT, Old_crt_assert_mode); Crt_suppressed = FALSE; } } int ut_get_uuid_str(char *uuid_str) { UUID uuid; char *buff; if (UuidCreate(&uuid) == 0) if (UuidToStringA(&uuid, &buff) == RPC_S_OK) { strcpy_s(uuid_str, UT_POOL_HDR_UUID_STR_LEN, buff); return 0; } return -1; } /* XXX - fix this temp hack dup'ing util_strerror when we get mock for win */ #define ENOTSUP_STR "Operation not supported" #define UNMAPPED_STR "Unmapped error" void ut_strerror(int errnum, char *buff, size_t bufflen) { switch (errnum) { case ENOTSUP: strcpy_s(buff, bufflen, ENOTSUP_STR); break; default: if (strerror_s(buff, bufflen, errnum)) strcpy_s(buff, bufflen, UNMAPPED_STR); } } /* * ut_spawnv -- creates and executes new synchronous process, * ... are additional parameters to new process, * the last argument must be a NULL * * XXX: argc/argv are ignored actually, as we need to use the unmodified * UTF16-encoded command line args. */ intptr_t ut_spawnv(int argc, const char **argv, ...) { int va_count = 0; int wargc; wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); va_list ap; va_start(ap, argv); while (va_arg(ap, char *)) { va_count++; } va_end(ap); /* 1 for terminating NULL */ wchar_t **wargv2 = calloc(wargc + va_count + 1, sizeof(wchar_t *)); if (wargv2 == NULL) { UT_ERR("Cannot calloc memory for new array"); return -1; } memcpy(wargv2, wargv, wargc * sizeof(wchar_t *)); va_start(ap, argv); for (int i = 0; i < va_count; i++) { char *a = va_arg(ap, char *); wargv2[wargc + i] = ut_toUTF16(a); } va_end(ap); intptr_t ret = _wspawnv(_P_WAIT, wargv2[0], wargv2); for (int i = 0; i < va_count; i++) { free(wargv2[wargc + i]); } free(wargv2); return ret; } #endif #define MAXLOGFILENAME 100 /* maximum expected .log file name length */ #define MAXPRINT 8192 /* maximum expected single print length */ /* * output gets replicated to these files */ static FILE *Outfp; static FILE *Errfp; static FILE *Tracefp; static int LogLevel; /* set by UNITTEST_LOG_LEVEL env variable */ static int Force_quiet; /* set by UNITTEST_FORCE_QUIET env variable */ static char *Testname; /* set by UNITTEST_NAME env variable */ /* set by UNITTEST_CHECK_OPEN_FILES_IGNORE_BADBLOCKS env variable */ static int Ignore_bb; unsigned long Ut_pagesize; unsigned long long Ut_mmap_align; os_mutex_t Sigactions_lock; static char Buff_out[MAXPRINT]; static char Buff_err[MAXPRINT]; static char Buff_trace[MAXPRINT]; static char Buff_stdout[MAXPRINT]; /* * flags that control output */ #define OF_NONL 1 /* do not append newline */ #define OF_ERR 2 /* output is error output */ #define OF_TRACE 4 /* output to trace file only */ #define OF_NAME 16 /* include Testname in the output */ /* * vout -- common output code, all output happens here */ static void vout(int flags, const char *prepend, const char *fmt, va_list ap) { char buf[MAXPRINT]; unsigned cc = 0; int sn; const char *sep = ""; char errstr[UT_MAX_ERR_MSG] = ""; const char *nl = "\n"; if (Force_quiet) return; if (flags & OF_NONL) nl = ""; if (flags & OF_NAME && Testname) { sn = util_snprintf(&buf[cc], MAXPRINT - cc, "%s: ", Testname); if (sn < 0) abort(); cc += (unsigned)sn; } if (prepend) { const char *colon = ""; if (fmt) colon = ": "; sn = util_snprintf(&buf[cc], MAXPRINT - cc, "%s%s", prepend, colon); if (sn < 0) abort(); cc += (unsigned)sn; } if (fmt) { if (*fmt == '!') { fmt++; sep = ": "; ut_strerror(errno, errstr, UT_MAX_ERR_MSG); } sn = vsnprintf(&buf[cc], MAXPRINT - cc, fmt, ap); if (sn < 0) abort(); cc += (unsigned)sn; } int ret = util_snprintf(&buf[cc], MAXPRINT - cc, "%s%s%s", sep, errstr, nl); if (ret < 0) UT_FATAL("snprintf: %d", errno); /* buf has the fully-baked output, send it everywhere it goes... */ fputs(buf, Tracefp); if (flags & OF_ERR) { fputs(buf, Errfp); if (LogLevel >= 2) fputs(buf, stderr); } else if ((flags & OF_TRACE) == 0) { fputs(buf, Outfp); if (LogLevel >= 2) fputs(buf, stdout); } } /* * out -- printf-like output controlled by flags */ static void out(int flags, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vout(flags, NULL, fmt, ap); va_end(ap); } /* * prefix -- emit the trace line prefix */ static void prefix(const char *file, int line, const char *func, int flags) { out(OF_NONL|OF_TRACE|flags, "{%s:%d %s} ", file, line, func); } /* * lookup table for open files */ static struct fd_lut { struct fd_lut *left; struct fd_lut *right; int fdnum; char *fdfile; } *Fd_lut; static int Fd_errcount; /* * open_file_add -- add an open file to the lut */ static struct fd_lut * open_file_add(struct fd_lut *root, int fdnum, const char *fdfile) { if (root == NULL) { root = ZALLOC(sizeof(*root)); root->fdnum = fdnum; root->fdfile = STRDUP(fdfile); } else if (root->fdnum == fdnum) UT_FATAL("duplicate fdnum: %d", fdnum); else if (root->fdnum < fdnum) root->left = open_file_add(root->left, fdnum, fdfile); else root->right = open_file_add(root->right, fdnum, fdfile); return root; } /* * open_file_remove -- find exact match & remove it from lut * * prints error if exact match not found, increments Fd_errcount */ static void open_file_remove(struct fd_lut *root, int fdnum, const char *fdfile) { if (root == NULL) { if (!Ignore_bb || strstr(fdfile, "badblocks") == NULL) { UT_ERR("unexpected open file: fd %d => \"%s\"", fdnum, fdfile); Fd_errcount++; } } else if (root->fdnum == fdnum) { if (root->fdfile == NULL) { UT_ERR("open file dup: fd %d => \"%s\"", fdnum, fdfile); Fd_errcount++; } else if (strcmp(root->fdfile, fdfile) == 0) { /* found exact match */ FREE(root->fdfile); root->fdfile = NULL; } else { UT_ERR("open file changed: fd %d was \"%s\" now \"%s\"", fdnum, root->fdfile, fdfile); #ifdef __FreeBSD__ /* * XXX Pathname list not definitive on FreeBSD, * so treat as warning */ FREE(root->fdfile); root->fdfile = NULL; #else Fd_errcount++; #endif } } else if (root->fdnum < fdnum) open_file_remove(root->left, fdnum, fdfile); else open_file_remove(root->right, fdnum, fdfile); } /* * open_file_walk -- walk lut for any left-overs * * prints error if any found, increments Fd_errcount */ static void open_file_walk(struct fd_lut *root) { if (root) { open_file_walk(root->left); if (root->fdfile) { UT_ERR("open file missing: fd %d => \"%s\"", root->fdnum, root->fdfile); Fd_errcount++; } open_file_walk(root->right); } } /* * open_file_free -- free the lut */ static void open_file_free(struct fd_lut *root) { if (root) { open_file_free(root->left); open_file_free(root->right); if (root->fdfile) FREE(root->fdfile); FREE(root); } } /* * close_output_files -- close opened output files */ static void close_output_files(void) { if (Outfp != NULL) fclose(Outfp); if (Errfp != NULL) fclose(Errfp); if (Tracefp != NULL) fclose(Tracefp); } #ifndef _WIN32 #ifdef __FreeBSD__ /* XXX Note: Pathname retrieval is not really supported in FreeBSD */ #include #include /* * record_open_files -- make a list of open files (used at START() time) */ static void record_open_files(void) { int numfds, i; struct kinfo_file *fip, *f; if ((fip = kinfo_getfile(getpid(), &numfds)) == NULL) { UT_FATAL("!kinfo_getfile"); } for (i = 0, f = fip; i < numfds; i++, f++) { if (f->kf_fd >= 0) { Fd_lut = open_file_add(Fd_lut, f->kf_fd, f->kf_path); } } free(fip); } /* * check_open_files -- verify open files match recorded open files */ static void check_open_files(void) { int numfds, i; struct kinfo_file *fip, *f; if ((fip = kinfo_getfile(getpid(), &numfds)) == NULL) { UT_FATAL("!kinfo_getfile"); } for (i = 0, f = fip; i < numfds; i++, f++) { if (f->kf_fd >= 0) { open_file_remove(Fd_lut, f->kf_fd, f->kf_path); } } open_file_walk(Fd_lut); if (Fd_errcount) { if (os_getenv("UNITTEST_DO_NOT_FAIL_OPEN_FILES")) UT_OUT( "open file list changed between START() and DONE()"); else UT_FATAL( "open file list changed between START() and DONE()"); } open_file_free(Fd_lut); free(fip); } #else /* !__FreeBSD__ */ /* * record_open_files -- make a list of open files (used at START() time) */ static void record_open_files(void) { int dirfd; DIR *dirp = NULL; struct dirent *dp; if ((dirfd = os_open("/proc/self/fd", O_RDONLY)) < 0 || (dirp = fdopendir(dirfd)) == NULL) UT_FATAL("!/proc/self/fd"); while ((dp = readdir(dirp)) != NULL) { int fdnum; char fdfile[PATH_MAX]; ssize_t cc; if (*dp->d_name == '.') continue; if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0) UT_FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name); fdfile[cc] = '\0'; fdnum = atoi(dp->d_name); if (dirfd == fdnum) continue; Fd_lut = open_file_add(Fd_lut, fdnum, fdfile); } closedir(dirp); } /* * check_open_files -- verify open files match recorded open files */ static void check_open_files(void) { int dirfd; DIR *dirp = NULL; struct dirent *dp; if ((dirfd = os_open("/proc/self/fd", O_RDONLY)) < 0 || (dirp = fdopendir(dirfd)) == NULL) UT_FATAL("!/proc/self/fd"); while ((dp = readdir(dirp)) != NULL) { int fdnum; char fdfile[PATH_MAX]; ssize_t cc; if (*dp->d_name == '.') continue; if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0) UT_FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name); fdfile[cc] = '\0'; fdnum = atoi(dp->d_name); if (dirfd == fdnum) continue; open_file_remove(Fd_lut, fdnum, fdfile); } closedir(dirp); open_file_walk(Fd_lut); if (Fd_errcount) { if (os_getenv("UNITTEST_DO_NOT_FAIL_OPEN_FILES")) UT_OUT( "open file list changed between START() and DONE()"); else UT_FATAL( "open file list changed between START() and DONE()"); } open_file_free(Fd_lut); } #endif /* __FreeBSD__ */ #else /* _WIN32 */ #include #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 #define ObjectTypeInformation 2 #define SystemExtendedHandleInformation 64 typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX { PVOID Object; HANDLE UniqueProcessId; HANDLE HandleValue; ULONG GrantedAccess; USHORT CreatorBackTraceIndex; USHORT ObjectTypeIndex; ULONG HandleAttributes; ULONG Reserved; } SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX; typedef struct _SYSTEM_HANDLE_INFORMATION_EX { ULONG_PTR NumberOfHandles; ULONG_PTR Reserved; SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; } SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; typedef enum _POOL_TYPE { NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS } POOL_TYPE, *PPOOL_TYPE; typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING Name; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG TotalPagedPoolUsage; ULONG TotalNonPagedPoolUsage; ULONG TotalNamePoolUsage; ULONG TotalHandleTableUsage; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; ULONG HighWaterPagedPoolUsage; ULONG HighWaterNonPagedPoolUsage; ULONG HighWaterNamePoolUsage; ULONG HighWaterHandleTableUsage; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccess; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; USHORT MaintainTypeList; POOL_TYPE PoolType; ULONG PagedPoolUsage; ULONG NonPagedPoolUsage; } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; /* * enum_handles -- (internal) record or check a list of open handles */ static void enum_handles(int op) { ULONG hi_size = 0x200000; /* default size */ ULONG req_size = 0; PSYSTEM_HANDLE_INFORMATION_EX hndl_info = (PSYSTEM_HANDLE_INFORMATION_EX)MALLOC(hi_size); /* if it fails with the default info size, realloc and try again */ NTSTATUS status; while ((status = NtQuerySystemInformation( SystemExtendedHandleInformation, hndl_info, hi_size, &req_size)) == STATUS_INFO_LENGTH_MISMATCH) { hi_size = req_size + 4096; hndl_info = (PSYSTEM_HANDLE_INFORMATION_EX)REALLOC(hndl_info, hi_size); } UT_ASSERT(status >= 0); DWORD pid = GetProcessId(GetCurrentProcess()); DWORD ti_size = 4096; /* initial size */ POBJECT_TYPE_INFORMATION type_info = (POBJECT_TYPE_INFORMATION)MALLOC(ti_size); DWORD ni_size = 4096; /* initial size */ PVOID name_info = MALLOC(ni_size); for (ULONG i = 0; i < hndl_info->NumberOfHandles; i++) { SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = hndl_info->Handles[i]; char name[MAX_PATH]; /* ignore handles not owned by current process */ if ((ULONGLONG)handle.UniqueProcessId != pid) continue; /* query the object type */ status = NtQueryObject(handle.HandleValue, ObjectTypeInformation, type_info, ti_size, NULL); if (status < 0) continue; /* if handle can't be queried, ignore it */ /* * Register/verify only handles of selected types. * Do not rely on type numbers - check type name instead. */ if (wcscmp(type_info->Name.Buffer, L"Directory") && wcscmp(type_info->Name.Buffer, L"Mutant") && wcscmp(type_info->Name.Buffer, L"Semaphore") && wcscmp(type_info->Name.Buffer, L"File")) { /* does not match any of the above types */ continue; } /* * Skip handles with access 0x0012019f. NtQueryObject() may * hang on querying the handles pointing to named pipes. */ if (handle.GrantedAccess == 0x0012019f) continue; int ret = snprintf(name, MAX_PATH, "%.*S", type_info->Name.Length / 2, type_info->Name.Buffer); if (ret < 0 || ret >= MAX_PATH) UT_FATAL("snprintf: %d", ret); int fd = (int)(ULONGLONG)handle.HandleValue; if (op == 0) Fd_lut = open_file_add(Fd_lut, fd, name); else open_file_remove(Fd_lut, fd, name); } FREE(type_info); FREE(name_info); FREE(hndl_info); } /* * record_open_files -- record a number of open handles (used at START() time) * * On Windows, it records not only file handles, but some other handle types * as well. * XXX: We can't register all the handles, as spawning new process in the test * may result in opening new handles of some types (i.e. registry keys). */ static void record_open_files() { /* * XXX: Dummy call to CoCreateGuid() to ignore files/handles open * by this function. They won't be closed until process termination. */ GUID uuid; HRESULT res = CoCreateGuid(&uuid); enum_handles(0); } /* * check_open_files -- verify open handles match recorded open handles */ static void check_open_files() { enum_handles(1); open_file_walk(Fd_lut); if (Fd_errcount) { if (os_getenv("UNITTEST_DO_NOT_FAIL_OPEN_FILES")) UT_OUT( "open file list changed between START() and DONE()"); else UT_FATAL( "open file list changed between START() and DONE()"); } open_file_free(Fd_lut); } #endif /* _WIN32 */ /* * ut_start_common -- (internal) initialize unit test framework, * indicate test started */ static void ut_start_common(const char *file, int line, const char *func, const char *fmt, va_list ap) { int saveerrno = errno; char logname[MAXLOGFILENAME]; char *logsuffix; long long sc = sysconf(_SC_PAGESIZE); if (sc < 0) abort(); Ut_pagesize = (unsigned long)sc; #ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); Ut_mmap_align = si.dwAllocationGranularity; if (os_getenv("PMDK_NO_ABORT_MSG") != NULL) { /* disable windows error message boxes */ ut_suppress_errmsg(); } os_mutex_init(&Sigactions_lock); #else Ut_mmap_align = Ut_pagesize; char *ignore_bb = os_getenv("UNITTEST_CHECK_OPEN_FILES_IGNORE_BADBLOCKS"); if (ignore_bb && *ignore_bb) Ignore_bb = 1; #endif if (os_getenv("UNITTEST_NO_SIGHANDLERS") == NULL) ut_register_sighandlers(); if (os_getenv("UNITTEST_LOG_LEVEL") != NULL) LogLevel = atoi(os_getenv("UNITTEST_LOG_LEVEL")); else LogLevel = 2; if (os_getenv("UNITTEST_FORCE_QUIET") != NULL) Force_quiet++; Testname = os_getenv("UNITTEST_NAME"); if ((logsuffix = os_getenv("UNITTEST_NUM")) == NULL) logsuffix = ""; const char *fmode = "w"; if (os_getenv("UNITTEST_LOG_APPEND") != NULL) fmode = "a"; int ret = util_snprintf(logname, MAXLOGFILENAME, "out%s.log", logsuffix); if (ret < 0) UT_FATAL("snprintf: %d", errno); if ((Outfp = os_fopen(logname, fmode)) == NULL) { perror(logname); exit(1); } ret = util_snprintf(logname, MAXLOGFILENAME, "err%s.log", logsuffix); if (ret < 0) UT_FATAL("snprintf: %d", errno); if ((Errfp = os_fopen(logname, fmode)) == NULL) { perror(logname); exit(1); } ret = util_snprintf(logname, MAXLOGFILENAME, "trace%s.log", logsuffix); if (ret < 0) UT_FATAL("snprintf: %d", errno); if ((Tracefp = os_fopen(logname, fmode)) == NULL) { perror(logname); exit(1); } setvbuf(Outfp, Buff_out, _IOLBF, MAXPRINT); setvbuf(Errfp, Buff_err, _IOLBF, MAXPRINT); setvbuf(Tracefp, Buff_trace, _IOLBF, MAXPRINT); setvbuf(stdout, Buff_stdout, _IOLBF, MAXPRINT); prefix(file, line, func, 0); vout(OF_NAME, "START", fmt, ap); #ifdef _WIN32 /* * XXX To generate error string Windows will silently load * KernelBase.dll.mui. To prevent counting it as an opened file, it is * loaded here by force. */ char buff[1000]; util_strwinerror(1, buff, 1000); /* * It creates KsecDD file before recording open files. * This prevents inconsistencies in the list of open * files after the test. */ unsigned rnd; os_rand_r(&rnd); #elif __FreeBSD__ /* XXX Record the fd that will be leaked by uuid_generate */ uuid_t u; uuid_generate(u); #endif record_open_files(); errno = saveerrno; } /* * ut_start -- initialize unit test framework, indicate test started */ void ut_start(const char *file, int line, const char *func, int argc, char * const argv[], const char *fmt, ...) { va_list ap; va_start(ap, fmt); ut_start_common(file, line, func, fmt, ap); out(OF_NONL, 0, " args:"); for (int i = 0; i < argc; i++) out(OF_NONL, " %s", argv[i]); out(0, NULL); va_end(ap); } #ifdef _WIN32 /* * ut_startW -- initialize unit test framework, indicate test started */ void ut_startW(const char *file, int line, const char *func, int argc, wchar_t * const argv[], const char *fmt, ...) { va_list ap; va_start(ap, fmt); ut_start_common(file, line, func, fmt, ap); out(OF_NONL, 0, " args:"); for (int i = 0; i < argc; i++) { char *str = ut_toUTF8(argv[i]); UT_ASSERTne(str, NULL); out(OF_NONL, " %s", str); free(str); } out(0, NULL); va_end(ap); } #endif /* * ut_end -- indicate test is done, exit program with specified value */ void ut_end(const char *file, int line, const char *func, int ret) { #ifdef _WIN32 os_mutex_destroy(&Sigactions_lock); #endif if (!os_getenv("UNITTEST_DO_NOT_CHECK_OPEN_FILES")) check_open_files(); prefix(file, line, func, 0); out(OF_NAME, "END %d", ret); close_output_files(); exit(ret); } /* * ut_done -- indicate test is done, exit program */ void ut_done(const char *file, int line, const char *func, const char *fmt, ...) { #ifdef _WIN32 os_mutex_destroy(&Sigactions_lock); #endif if (!os_getenv("UNITTEST_DO_NOT_CHECK_OPEN_FILES")) check_open_files(); va_list ap; va_start(ap, fmt); prefix(file, line, func, 0); vout(OF_NAME, "DONE", fmt, ap); va_end(ap); close_output_files(); exit(0); } /* * ut_fatal -- indicate fatal error, exit program */ void ut_fatal(const char *file, int line, const char *func, const char *fmt, ...) { va_list ap; va_start(ap, fmt); prefix(file, line, func, OF_ERR); vout(OF_ERR|OF_NAME, "Error", fmt, ap); va_end(ap); abort(); } /* * ut_out -- output to stdout */ void ut_out(const char *file, int line, const char *func, const char *fmt, ...) { va_list ap; int saveerrno = errno; va_start(ap, fmt); prefix(file, line, func, 0); vout(0, NULL, fmt, ap); va_end(ap); errno = saveerrno; } /* * ut_err -- output to stderr */ void ut_err(const char *file, int line, const char *func, const char *fmt, ...) { va_list ap; int saveerrno = errno; va_start(ap, fmt); prefix(file, line, func, OF_ERR); vout(OF_ERR|OF_NAME, NULL, fmt, ap); va_end(ap); errno = saveerrno; } /* * ut_checksum -- compute checksum using Fletcher16 algorithm */ uint16_t ut_checksum(uint8_t *addr, size_t len) { uint16_t sum1 = 0; uint16_t sum2 = 0; for (size_t i = 0; i < len; ++i) { sum1 = (uint16_t)(sum1 + addr[i]) % 255; sum2 = (uint16_t)(sum2 + sum1) % 255; } return (uint16_t)((sum2 << 8) | sum1); } #ifdef _WIN32 /* * ut_toUTF8 -- convert WCS to UTF-8 string */ char * ut_toUTF8(const wchar_t *wstr) { int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, NULL, 0, NULL, NULL); if (size == 0) { UT_FATAL("!ut_toUTF8"); } char *str = malloc(size * sizeof(char)); if (str == NULL) { UT_FATAL("!ut_toUTF8"); } if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, str, size, NULL, NULL) == 0) { UT_FATAL("!ut_toUTF8"); } return str; } /* * ut_toUTF16 -- convert UTF-8 to WCS string */ wchar_t * ut_toUTF16(const char *wstr) { int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, wstr, -1, NULL, 0); if (size == 0) { UT_FATAL("!ut_toUTF16"); } wchar_t *str = malloc(size * sizeof(wchar_t)); if (str == NULL) { UT_FATAL("!ut_toUTF16"); } if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, wstr, -1, str, size) == 0) { UT_FATAL("!ut_toUTF16"); } return str; } #endif /* * ut_strtoi -- a strtoi call that cannot return error */ int ut_strtoi(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { long ret = ut_strtol(file, line, func, nptr, endptr, base); if (ret > INT_MAX || ret < INT_MIN) ut_fatal(file, line, func, "!strtoi: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); return (int)ret; } /* * ut_strtou -- a strtou call that cannot return error */ unsigned ut_strtou(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { unsigned long ret = ut_strtoul(file, line, func, nptr, endptr, base); if (ret > UINT_MAX) ut_fatal(file, line, func, "!strtou: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); return (unsigned)ret; } /* * ut_strtol -- a strtol call that cannot return error */ long ut_strtol(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { long long ret = ut_strtoll(file, line, func, nptr, endptr, base); if (ret > LONG_MAX || ret < LONG_MIN) ut_fatal(file, line, func, "!strtol: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); return (long)ret; } /* * ut_strtoul -- a strtou call that cannot return error */ unsigned long ut_strtoul(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { unsigned long long ret = ut_strtoull(file, line, func, nptr, endptr, base); if (ret > ULONG_MAX) ut_fatal(file, line, func, "!strtoul: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); return (unsigned long)ret; } /* * ut_strtoull -- a strtoul call that cannot return error */ unsigned long long ut_strtoull(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { unsigned long long retval; errno = 0; if (*nptr == '\0') { errno = EINVAL; goto fatal; } if (endptr != NULL) { retval = strtoull(nptr, endptr, base); } else { char *end; retval = strtoull(nptr, &end, base); if (*end != '\0') goto fatal; } if (errno != 0) goto fatal; return retval; fatal: ut_fatal(file, line, func, "!strtoull: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); } /* * ut_strtoll -- a strtol call that cannot return error */ long long ut_strtoll(const char *file, int line, const char *func, const char *nptr, char **endptr, int base) { long long retval; errno = 0; if (*nptr == '\0') { errno = EINVAL; goto fatal; } if (endptr != NULL) { retval = strtoll(nptr, endptr, base); } else { char *end; retval = strtoll(nptr, &end, base); if (*end != '\0') goto fatal; } if (errno != 0) goto fatal; return retval; fatal: ut_fatal(file, line, func, "!strtoll: nptr=%s, endptr=%s, base=%d", nptr, endptr ? *endptr : "NULL", base); } int ut_snprintf(const char *file, int line, const char *func, char *str, size_t size, const char *format, ...) { va_list ap; va_start(ap, format); int ret = vsnprintf(str, size, format, ap); va_end(ap); if (ret < 0) { if (!errno) errno = EIO; ut_fatal(file, line, func, "!snprintf"); } else if ((size_t)ret >= size) { errno = ENOBUFS; ut_fatal(file, line, func, "!snprintf"); } return ret; } pmdk-1.11.1/src/test/unittest/ut_pmem2_config.c0000664000000000000000000000223514123364546020106 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * ut_pmem2_config.h -- utility helper functions for libpmem2 config tests */ #include #include "unittest.h" #include "ut_pmem2_config.h" #include "ut_pmem2_utils.h" /* * ut_pmem2_config_new -- allocates cfg (cannot fail) */ void ut_pmem2_config_new(const char *file, int line, const char *func, struct pmem2_config **cfg) { int ret = pmem2_config_new(cfg); ut_pmem2_expect_return(file, line, func, ret, 0); UT_ASSERTne(*cfg, NULL); } /* * pmem2_config_set_required_store_granularity -- sets granularity */ void ut_pmem2_config_set_required_store_granularity(const char *file, int line, const char *func, struct pmem2_config *cfg, enum pmem2_granularity g) { int ret = pmem2_config_set_required_store_granularity(cfg, g); ut_pmem2_expect_return(file, line, func, ret, 0); } /* * ut_pmem2_config_delete -- deallocates cfg (cannot fail) */ void ut_pmem2_config_delete(const char *file, int line, const char *func, struct pmem2_config **cfg) { int ret = pmem2_config_delete(cfg); ut_pmem2_expect_return(file, line, func, ret, 0); UT_ASSERTeq(*cfg, NULL); } pmdk-1.11.1/src/test/unittest/ut_pmem2_map.c0000664000000000000000000000110414123364546017410 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * ut_pmem2_map.h -- utility helper functions for libpmem2 map tests */ #include #include "unittest.h" #include "ut_pmem2_map.h" #include "ut_pmem2_utils.h" /* * ut_pmem2_map -- allocates map (cannot fail) */ void ut_pmem2_map_new(const char *file, int line, const char *func, struct pmem2_config *cfg, struct pmem2_source *src, struct pmem2_map **map) { int ret = pmem2_map_new(map, cfg, src); ut_pmem2_expect_return(file, line, func, ret, 0); UT_ASSERTne(*map, NULL); } pmdk-1.11.1/src/test/unittest/futils.py0000664000000000000000000001124514123364546016546 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation """Test framework utilities.""" from os.path import join, abspath import os import sys import consts as c import configurator def get_tool_path(ctx, name): if sys.platform == 'win32': if str(ctx.build) == 'debug': return abspath(join(c.WIN_DEBUG_BUILDDIR, 'libs', name)) else: return abspath(join(c.WIN_RELEASE_BUILDDIR, 'libs', name)) else: return abspath(join(c.ROOTDIR, '..', 'tools', name, name)) def get_test_tool_path(build, name): if sys.platform == 'win32': if str(build) == 'debug': return abspath(join(c.WIN_DEBUG_BUILDDIR, 'tests', name)) else: return abspath(join(c.WIN_RELEASE_BUILDDIR, 'tests', name)) else: return abspath(join(c.ROOTDIR, 'tools', name, name)) def get_lib_dir(ctx): if str(ctx.build) == 'debug': return c.DEBUG_LIBDIR else: return c.RELEASE_LIBDIR def get_example_path(ctx, libname, name): """ Get the path to the example binary. Paths to examples differ on Windows and Unix systems. On Windows, the example binaries have a specific name: ex_libname_name. On Unix systems, the example binaries are located in the catalog "lib + libname/name" and have the same name as .c file. """ if sys.platform == 'win32': binname = '_'.join(['ex', libname, name]) if str(ctx.build) == 'debug': return abspath(join(c.WIN_DEBUG_BUILDDIR, 'examples', binname)) else: return abspath(join(c.WIN_RELEASE_BUILDDIR, 'examples', binname)) else: return abspath(join(c.ROOTDIR, '..', 'examples', 'lib' + libname, name, name)) def tail(file, n): """ Replace the file content with the n last lines from the existing file. The original file is saved under the name with ".old" suffix. """ with open(file, 'r') as f: lines = f.readlines() last_lines = lines[-n:] os.rename(file, file + ".old") with open(file, 'w') as f: for line in last_lines: f.write(line) def count(file, substring): """ Count the number of occurrences of a string in the given file. """ with open(file, 'r') as f: content = f.read() return content.count(substring) class Color: """ Set the font color. This functionality relies on ANSI escape sequences and is currently disabled for Windows. """ if sys.platform != 'win32': RED = '\33[91m' GREEN = '\33[92m' END = '\33[0m' else: RED, GREEN, END = '', '', '' class Message: """Simple level based logger.""" def __init__(self, level): self.level = level def print(self, msg): if self.level >= 1: print(msg) def print_verbose(self, msg): if self.level >= 2: print(msg) class Fail(Exception): """Thrown when the test fails.""" def __init__(self, msg): super().__init__(msg) self.messages = [] self.messages.append(msg) def __str__(self): ret = '\n'.join(self.messages) return ret def fail(msg, exit_code=None): if exit_code is not None: msg = '{}{}Error {}'.format(msg, os.linesep, exit_code) raise Fail(msg) class Skip(Exception): """Thrown when the test should be skipped.""" def __init__(self, msg): super().__init__(msg) config = configurator.Configurator().config if config.fail_on_skip: raise Fail(msg) self.messages = [] self.messages.append(msg) def __str__(self): ret = '\n'.join(self.messages) return ret def skip(msg): raise Skip(msg) def set_kwargs_attrs(cls, kwargs): """ Translate provided keyword arguments into class attributes. """ for k, v in kwargs.items(): setattr(cls, '{}'.format(k), v) def add_env_common(src, added): """ A common implementation of adding an environment variable to the 'src' environment variables dictionary - taking into account that the variable may or may be not already defined. """ for k, v in added.items(): if k in src: src[k] = v + os.pathsep + src[k] else: src.update({k: v}) def to_list(var, *types): """ Some variables may be provided by the user either as a single instance of a type or a sequence of instances (e. g. a string or list of strings). To be conveniently treated by the framework code, their types should be unified - casted to lists. """ if isinstance(var, tuple(types)): return [var, ] else: return var pmdk-1.11.1/src/test/unittest/ut_file.c0000664000000000000000000001677614123364546016477 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2020, Intel Corporation */ /* * ut_file.c -- unit test file operations */ #include "unittest.h" /* * ut_open -- an open that cannot return < 0 */ int ut_open(const char *file, int line, const char *func, const char *path, int flags, ...) { va_list ap; int mode; va_start(ap, flags); mode = va_arg(ap, int); int retval = os_open(path, flags, mode); va_end(ap); if (retval < 0) ut_fatal(file, line, func, "!open: %s", path); return retval; } #ifdef _WIN32 /* * ut_wopen -- a _wopen that cannot return < 0 */ int ut_wopen(const char *file, int line, const char *func, const wchar_t *path, int flags, ...) { va_list ap; int mode; va_start(ap, flags); mode = va_arg(ap, int); int retval = _wopen(path, flags, mode); va_end(ap); if (retval < 0) ut_fatal(file, line, func, "!wopen: %s", ut_toUTF8(path)); return retval; } #endif /* * ut_close -- a close that cannot return -1 */ int ut_close(const char *file, int line, const char *func, int fd) { int retval = os_close(fd); if (retval != 0) ut_fatal(file, line, func, "!close: %d", fd); return retval; } /* * ut_fopen --an fopen that cannot return != 0 */ FILE * ut_fopen(const char *file, int line, const char *func, const char *path, const char *mode) { FILE *retval = os_fopen(path, mode); if (retval == NULL) ut_fatal(file, line, func, "!fopen: %s", path); return retval; } /* * ut_fclose -- a fclose that cannot return != 0 */ int ut_fclose(const char *file, int line, const char *func, FILE *stream) { int retval = os_fclose(stream); if (retval != 0) { ut_fatal(file, line, func, "!fclose: 0x%llx", (unsigned long long)stream); } return retval; } /* * ut_unlink -- an unlink that cannot return -1 */ int ut_unlink(const char *file, int line, const char *func, const char *path) { int retval = os_unlink(path); if (retval != 0) ut_fatal(file, line, func, "!unlink: %s", path); return retval; } /* * ut_posix_fallocate -- a posix_fallocate that cannot return -1 */ int ut_posix_fallocate(const char *file, int line, const char *func, int fd, os_off_t offset, os_off_t len) { int retval = os_posix_fallocate(fd, offset, len); if (retval != 0) { errno = retval; ut_fatal(file, line, func, "!fallocate: fd %d offset 0x%llx len %llu", fd, (unsigned long long)offset, (unsigned long long)len); } return retval; } /* * ut_write -- a write that can't return -1 */ size_t ut_write(const char *file, int line, const char *func, int fd, const void *buf, size_t count) { #ifndef _WIN32 ssize_t retval = write(fd, buf, count); #else /* * XXX - do multiple write() calls in a loop? * Or just use native Windows API? */ if (count > UINT_MAX) ut_fatal(file, line, func, "read: count > UINT_MAX (%zu > %u)", count, UINT_MAX); ssize_t retval = _write(fd, buf, (unsigned)count); #endif if (retval < 0) ut_fatal(file, line, func, "!write: %d", fd); return (size_t)retval; } /* * ut_read -- a read that can't return -1 */ size_t ut_read(const char *file, int line, const char *func, int fd, void *buf, size_t count) { #ifndef _WIN32 ssize_t retval = read(fd, buf, count); #else /* * XXX - do multiple read() calls in a loop? * Or just use native Windows API? */ if (count > UINT_MAX) ut_fatal(file, line, func, "read: count > UINT_MAX (%zu > %u)", count, UINT_MAX); ssize_t retval = read(fd, buf, (unsigned)count); #endif if (retval < 0) ut_fatal(file, line, func, "!read: %d", fd); return (size_t)retval; } /* * ut_lseek -- an lseek that can't return -1 */ os_off_t ut_lseek(const char *file, int line, const char *func, int fd, os_off_t offset, int whence) { os_off_t retval = os_lseek(fd, offset, whence); if (retval == -1) ut_fatal(file, line, func, "!lseek: %d", fd); return retval; } /* * ut_fstat -- a fstat that cannot return -1 */ int ut_fstat(const char *file, int line, const char *func, int fd, os_stat_t *st_bufp) { int retval = os_fstat(fd, st_bufp); if (retval < 0) ut_fatal(file, line, func, "!fstat: %d", fd); #ifdef _WIN32 /* clear unused bits to avoid confusion */ st_bufp->st_mode &= 0600; #endif return retval; } /* * ut_stat -- a stat that cannot return -1 */ int ut_stat(const char *file, int line, const char *func, const char *path, os_stat_t *st_bufp) { int retval = os_stat(path, st_bufp); if (retval < 0) ut_fatal(file, line, func, "!stat: %s", path); #ifdef _WIN32 /* clear unused bits to avoid confusion */ st_bufp->st_mode &= 0600; #endif return retval; } #ifdef _WIN32 /* * ut_statW -- a stat that cannot return -1 */ int ut_statW(const char *file, int line, const char *func, const wchar_t *path, os_stat_t *st_bufp) { int retval = ut_util_statW(path, st_bufp); if (retval < 0) ut_fatal(file, line, func, "!stat: %S", path); #ifdef _WIN32 /* clear unused bits to avoid confusion */ st_bufp->st_mode &= 0600; #endif return retval; } #endif /* * ut_mmap -- a mmap call that cannot return MAP_FAILED */ void * ut_mmap(const char *file, int line, const char *func, void *addr, size_t length, int prot, int flags, int fd, os_off_t offset) { void *ret_addr = mmap(addr, length, prot, flags, fd, offset); if (ret_addr == MAP_FAILED) { const char *error = ""; #ifdef _WIN32 /* * XXX: on Windows mmap is implemented and exported by libpmem */ error = pmem_errormsg(); #endif ut_fatal(file, line, func, "!mmap: addr=0x%llx length=0x%zx prot=%d flags=%d fd=%d offset=0x%llx %s", (unsigned long long)addr, length, prot, flags, fd, (unsigned long long)offset, error); } return ret_addr; } /* * ut_munmap -- a munmap call that cannot return -1 */ int ut_munmap(const char *file, int line, const char *func, void *addr, size_t length) { int retval = munmap(addr, length); if (retval < 0) ut_fatal(file, line, func, "!munmap: addr=0x%llx length=0x%zx", (unsigned long long)addr, length); return retval; } /* * ut_mprotect -- a mprotect call that cannot return -1 */ int ut_mprotect(const char *file, int line, const char *func, void *addr, size_t len, int prot) { int retval = mprotect(addr, len, prot); if (retval < 0) ut_fatal(file, line, func, "!mprotect: addr=0x%llx length=0x%zx prot=0x%x", (unsigned long long)addr, len, prot); return retval; } /* * ut_ftruncate -- a ftruncate that cannot return -1 */ int ut_ftruncate(const char *file, int line, const char *func, int fd, os_off_t length) { int retval = os_ftruncate(fd, length); if (retval < 0) ut_fatal(file, line, func, "!ftruncate: %d %llu", fd, (unsigned long long)length); return retval; } #ifdef _WIN32 /* * file_map -- map file without using pmdk api */ void * ut_file_map(const char *file, int line, const char *func, int fd, size_t size) { void *addr = NULL; HANDLE handle = (HANDLE)_get_osfhandle(fd); UT_ASSERTne(handle, INVALID_HANDLE_VALUE); HANDLE mh = CreateFileMapping(handle, NULL, PAGE_READWRITE, size >> 32, size & 0xFFFFFFFF, NULL); if (mh == INVALID_HANDLE_VALUE) ut_fatal(file, line, func, "!!CreateFileMapping"); addr = MapViewOfFileEx(mh, FILE_MAP_ALL_ACCESS, 0, 0, size, NULL); if (addr == NULL) ut_fatal(file, line, func, "!!CreateFileMapping"); if (CloseHandle(mh) == 0) ut_fatal(file, line, func, "!!CloseHandle"); return addr; } #else /* * file_map -- map file without using pmdk api */ void * ut_file_map(const char *file, int line, const char *func, int fd, size_t size) { void *addr = NULL; ut_mmap(file, line, func, addr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); return addr; } #endif pmdk-1.11.1/src/test/util_vec/0000775000000000000000000000000014123364546014616 5ustar rootrootpmdk-1.11.1/src/test/util_vec/util_vec.c0000664000000000000000000000214314123364546016574 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2019, Intel Corporation */ /* * util_vec.c -- unit test for vec implementation */ #include "unittest.h" #include "vec.h" struct test { int foo; int bar; }; static void vec_test() { VEC(testvec, struct test) v = VEC_INITIALIZER; UT_ASSERTeq(VEC_SIZE(&v), 0); struct test t = {1, 2}; struct test t2 = {3, 4}; VEC_PUSH_BACK(&v, t); VEC_PUSH_BACK(&v, t2); UT_ASSERTeq(VEC_ARR(&v)[0].foo, 1); UT_ASSERTeq(VEC_GET(&v, 1)->foo, 3); UT_ASSERTeq(VEC_SIZE(&v), 2); int n = 0; VEC_FOREACH(t, &v) { switch (n) { case 0: UT_ASSERTeq(t.foo, 1); UT_ASSERTeq(t.bar, 2); break; case 1: UT_ASSERTeq(t.foo, 3); UT_ASSERTeq(t.bar, 4); break; } n++; } UT_ASSERTeq(n, 2); UT_ASSERTeq(VEC_SIZE(&v), n); VEC_POP_BACK(&v); n = 0; VEC_FOREACH(t, &v) { UT_ASSERTeq(t.foo, 1); UT_ASSERTeq(t.bar, 2); n++; } UT_ASSERTeq(n, 1); UT_ASSERTeq(VEC_SIZE(&v), n); VEC_CLEAR(&v); UT_ASSERTeq(VEC_SIZE(&v), 0); VEC_DELETE(&v); } int main(int argc, char *argv[]) { START(argc, argv, "util_vec"); vec_test(); DONE(NULL); } pmdk-1.11.1/src/test/util_vec/TEST00000775000000000000000000000045014123364546015402 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_vec/TEST0 -- unit test for vec implementation # . ../unittest/unittest.sh require_test_type short require_fs_type none setup expect_normal_exit ./util_vec$EXESUFFIX pass pmdk-1.11.1/src/test/util_vec/Makefile0000664000000000000000000000033514123364546016257 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # src/test/util_vec/Makefile -- build util_vec unit test # TARGET = util_vec OBJS = util_vec.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_vec/TEST0.PS10000664000000000000000000000044514123364546016005 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_vec/TEST0 -- unit test for vec implementation # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_vec$Env:EXESUFFIX pass pmdk-1.11.1/src/test/util_vec/util_vec.vcxproj.filters0000664000000000000000000000133714123364546021520 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {cb0140fc-b255-4ef9-a417-11f1a13525ba} Source Files Test Scripts pmdk-1.11.1/src/test/util_vec/.gitignore0000664000000000000000000000001114123364546016576 0ustar rootrootutil_vec pmdk-1.11.1/src/test/util_vec/util_vec.vcxproj0000664000000000000000000000702514123364546020051 0ustar rootroot Debug x64 Release x64 {FD726AA3-D4FA-4597-B435-08CC7752888C} Win32Proj util_vec 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_memcpy/0000775000000000000000000000000014123364546015376 5ustar rootrootpmdk-1.11.1/src/test/pmem2_memcpy/pmem2_memcpy.c0000664000000000000000000000477714123364546020153 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmem2_memcpy.c -- test for doing a memcpy from libpmem2 * * usage: pmem2_memcpy file destoff srcoff length * */ #include "unittest.h" #include "file.h" #include "ut_pmem2.h" #include "memcpy_common.h" /* * do_memcpy_variants -- do_memcpy wrapper that tests multiple variants * of memcpy functions */ static void do_memcpy_variants(int fd, char *dest, int dest_off, char *src, int src_off, size_t bytes, size_t mapped_len, const char *file_name, persist_fn p, memcpy_fn fn) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memcpy(fd, dest, dest_off, src, src_off, bytes, mapped_len, file_name, fn, Flags[i], p, NULL, NULL, NULL); } } int main(int argc, char *argv[]) { int fd; char *dest; char *src; char *src_orig; size_t mapped_len; struct pmem2_config *cfg; struct pmem2_source *psrc; struct pmem2_map *map; if (argc != 5) UT_FATAL("usage: %s file destoff srcoff length", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_memcpy %s %s %s %s %savx %savx512f", argv[2], argv[3], argv[4], thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); util_init(); fd = OPEN(argv[1], O_RDWR); UT_ASSERT(fd != -1); int dest_off = atoi(argv[2]); int src_off = atoi(argv[3]); size_t bytes = strtoul(argv[4], NULL, 0); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&psrc, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, psrc); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); /* src > dst */ mapped_len = pmem2_map_get_size(map); dest = pmem2_map_get_address(map); if (dest == NULL) UT_FATAL("!could not map file: %s", argv[1]); src_orig = src = dest + mapped_len / 2; UT_ASSERT(src > dest); pmem2_persist_fn persist = pmem2_get_persist_fn(map); memset(dest, 0, (2 * bytes)); persist(dest, 2 * bytes); memset(src, 0, (2 * bytes)); persist(src, 2 * bytes); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); do_memcpy_variants(fd, dest, dest_off, src, src_off, bytes, 0, argv[1], persist, memcpy_fn); src = dest; dest = src_orig; if (dest <= src) UT_FATAL("cannot map files in memory order"); do_memcpy_variants(fd, dest, dest_off, src, src_off, bytes, mapped_len, argv[1], persist, memcpy_fn); ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_memcpy/pmem2_memcpy.vcxproj.filters0000664000000000000000000000264314123364546023061 0ustar rootroot {4200f836-ad76-482e-9962-43243397298a} {efd29bfb-c8ff-4cee-989b-4edf4e3af894} {23a70f8d-0265-4412-a8f0-b4b1a8bc8c73} Test Scripts Source Files Source Files Source Files Source Files Source Files Header files Header files pmdk-1.11.1/src/test/pmem2_memcpy/Makefile0000664000000000000000000000057514123364546017045 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_memcpy/Makefile -- build pmem2_memcpy test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_memcpy OBJS += pmem2_memcpy.o\ memcpy_common.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_memcpy/TESTS.py0000775000000000000000000000341214123364546016655 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # from collections import namedtuple import testframework as t TC = namedtuple('TC', ['dest', 'src', 'length']) class Pmem2Memcpy(t.Test): test_type = t.Short filesize = 4 * t.MiB envs0 = () envs1 = () test_cases = ( # aligned everything TC(dest=0, src=0, length=4096), # unaligned dest TC(dest=7, src=0, length=4096), # unaligned dest, unaligned src TC(dest=7, src=9, length=4096), # aligned dest, unaligned src TC(dest=0, src=9, length=4096) ) def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' for env in self.envs1: ctx.env[env] = '1' if ctx.wc_workaround() == 'on': ctx.env['PMEM_WC_WORKAROUND'] = '1' elif ctx.wc_workaround() == 'off': ctx.env['PMEM_WC_WORKAROUND'] = '0' for tc in self.test_cases: filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmem2_memcpy', filepath, tc.dest, tc.src, tc.length) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST0(Pmem2Memcpy): pass @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST1(Pmem2Memcpy): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST2(Pmem2Memcpy): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) @t.add_params('wc_workaround', ['default']) class TEST3(Pmem2Memcpy): envs1 = ("PMEM_NO_MOVNT",) @t.add_params('wc_workaround', ['default']) class TEST4(Pmem2Memcpy): envs1 = ("PMEM_NO_MOVNT", "PMEM_NO_GENERIC_MEMCPY") pmdk-1.11.1/src/test/pmem2_memcpy/pmem2_memcpy.vcxproj0000664000000000000000000000755614123364546021422 0ustar rootroot Debug x64 Release x64 {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {D43FCFB6-97D2-44B2-8577-94B43B97D7CA} Win32Proj pmem2_memcpy 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem2_memcpy/.gitignore0000664000000000000000000000001514123364546017362 0ustar rootrootpmem2_memcpy pmdk-1.11.1/src/test/pmem2_memcpy/memcpy_common.c0000664000000000000000000000620514123364546020407 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * memcpy_common.c -- common part for tests doing a persistent memcpy */ #include "unittest.h" #include "memcpy_common.h" #include "valgrind_internal.h" /* * do_persist - performs selected persist function */ static void do_persist(struct pmemset *set, set_persist_fn sp, persist_fn p, char *ptr, size_t len) { if (set) sp(set, ptr, len); else p(ptr, len); } /* * do_memcpy_s - performs selected memcpy function */ static void * do_memcpy_s(struct pmemset *set, set_memcpy_fn sm, memcpy_fn m, char *ptr1, char *ptr2, size_t len, unsigned flags) { if (set) return sm(set, ptr1, ptr2, len, flags); else return m(ptr1, ptr2, len, flags); } /* * do_memcpy: Worker function for memcpy * * Always work within the boundary of bytes. Fill in 1/2 of the src * memory with the pattern we want to write. This allows us to check * that we did not overwrite anything we were not supposed to in the * dest. Use the non pmem version of the memset/memcpy commands * so as not to introduce any possible side affects. */ void do_memcpy(int fd, char *dest, int dest_off, char *src, int src_off, size_t bytes, size_t mapped_len, const char *file_name, memcpy_fn fn, unsigned flags, persist_fn persist, struct pmemset *set, set_persist_fn sp, set_memcpy_fn sm) { void *ret; char *buf = MALLOC(bytes); memset(buf, 0, bytes); memset(dest, 0, bytes); do_persist(set, sp, persist, dest, bytes); memset(src, 0, bytes); do_persist(set, sp, persist, src, bytes); memset(src, 0x5A, bytes / 4); do_persist(set, sp, persist, src, bytes / 4); memset(src + bytes / 4, 0x46, bytes / 4); do_persist(set, sp, persist, src + bytes / 4, bytes / 4); /* dest == src */ ret = do_memcpy_s(set, sm, fn, dest + dest_off, dest + dest_off, bytes / 2, flags); UT_ASSERTeq(ret, dest + dest_off); UT_ASSERTeq(*(char *)(dest + dest_off), 0); /* len == 0 */ ret = do_memcpy_s(set, sm, fn, dest + dest_off, src, 0, flags); UT_ASSERTeq(ret, dest + dest_off); UT_ASSERTeq(*(char *)(dest + dest_off), 0); ret = do_memcpy_s(set, sm, fn, dest + dest_off, src + src_off, bytes / 2, flags); if (flags & PMEM2_F_MEM_NOFLUSH) VALGRIND_DO_PERSIST((dest + dest_off), bytes / 2); UT_ASSERTeq(ret, dest + dest_off); /* memcmp will validate that what I expect in memory. */ if (memcmp(src + src_off, dest + dest_off, bytes / 2)) UT_FATAL("%s: first %zu bytes do not match", file_name, bytes / 2); /* Now validate the contents of the file */ LSEEK(fd, dest_off + (os_off_t)(mapped_len) / 2, SEEK_SET); if (READ(fd, buf, bytes / 2) == bytes / 2) { if (memcmp(src + src_off, buf, bytes / 2)) UT_FATAL("%s: first %zu bytes do not match", file_name, bytes / 2); } FREE(buf); } unsigned Flags[] = { 0, PMEM_F_MEM_NODRAIN, PMEM_F_MEM_NONTEMPORAL, PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_NODRAIN, PMEM_F_MEM_WC, PMEM_F_MEM_WB, PMEM_F_MEM_NOFLUSH, /* all possible flags */ PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB, }; pmdk-1.11.1/src/test/pmem2_memcpy/memcpy_common.h0000664000000000000000000000154214123364546020413 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020-2021, Intel Corporation */ /* * memcpy_common.h -- header file for common memcpy utilities */ #ifndef MEMCPY_COMMON_H #define MEMCPY_COMMON_H 1 #include "unittest.h" #include "file.h" typedef void *(*memcpy_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*set_memcpy_fn)(struct pmemset *set, void *pmemdest, void *src, size_t len, unsigned flags); typedef void (*persist_fn)(const void *ptr, size_t len); typedef int (*set_persist_fn)(struct pmemset *set, void *ptr, size_t len); extern unsigned Flags[10]; void do_memcpy(int fd, char *dest, int dest_off, char *src, int src_off, size_t bytes, size_t mapped_len, const char *file_name, memcpy_fn fn, unsigned flags, persist_fn p, struct pmemset *set, set_persist_fn sp, set_memcpy_fn sm); #endif pmdk-1.11.1/src/test/log_recovery/0000775000000000000000000000000014123364546015503 5ustar rootrootpmdk-1.11.1/src/test/log_recovery/TEST1.PS10000664000000000000000000000072514123364546016674 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_recovery/TEST0 -- unit test for pmemlog recovery # pmemlog_appendv() is used to append data # . ..\unittest\unittest.ps1 require_test_type medium require_build_type nondebug static-nondebug setup touch $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_recovery$Env:EXESUFFIX $DIR\testfile1 v check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_recovery/log_recovery.vcxproj.filters0000664000000000000000000000213214123364546023264 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {437e7d4f-a209-47b8-943f-147c14440289} {6b78c1c2-2ce7-48cd-b99d-14c814115646} Source Files Test Scripts Test Scripts Match Files Match Files pmdk-1.11.1/src/test/log_recovery/TEST00000775000000000000000000000127114123364546016271 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_recovery/TEST0 -- unit test for pmemlog recovery # pmemlog_append() is used to append data # . ../unittest/unittest.sh require_test_type medium require_build_type nondebug static-nondebug # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable configure_valgrind pmemcheck force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 touch $DIR/testfile1 expect_normal_exit ./log_recovery$EXESUFFIX $DIR/testfile1 a check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_recovery/log_recovery.vcxproj0000664000000000000000000001003114123364546021612 0ustar rootroot Debug x64 Release x64 {E901B756-EA72-4B8D-967F-85F109D0D1DE} Win32Proj log_recovery 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\libpmemlog;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\libpmemlog;%(AdditionalIncludeDirectories) {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/log_recovery/Makefile0000664000000000000000000000040714123364546017144 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_recovery/Makefile -- build log_recovery unit test # TARGET = log_recovery OBJS = log_recovery.o LIBPMEMLOG=y include ../Makefile.inc CFLAGS += -I../../libpmemlog pmdk-1.11.1/src/test/log_recovery/log_recovery.c0000664000000000000000000001030214123364546020342 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2018, Intel Corporation */ /* * log_recovery.c -- unit test for pmemlog recovery * * usage: log_recovery file operation:... * * operation has to be 'a' or 'v' * */ #include #include "unittest.h" #include "log.h" /* * do_append -- call pmemlog_append() & print result */ static void do_append(PMEMlogpool *plp) { const char *str[6] = { "1st append string\n", "2nd append string\n", "3rd append string\n", "4th append string\n", "5th append string\n", "6th append string\n" }; for (int i = 0; i < 6; ++i) { int rv = pmemlog_append(plp, str[i], strlen(str[i])); switch (rv) { case 0: UT_OUT("append str[%i] %s", i, str[i]); break; case -1: UT_OUT("!append str[%i] %s", i, str[i]); break; default: UT_OUT("!append: wrong return value"); break; } } } /* * do_appendv -- call pmemlog_appendv() & print result */ static void do_appendv(PMEMlogpool *plp) { struct iovec iov[9] = { { .iov_base = "1st appendv string\n", .iov_len = 19 }, { .iov_base = "2nd appendv string\n", .iov_len = 19 }, { .iov_base = "3rd appendv string\n", .iov_len = 19 }, { .iov_base = "4th appendv string\n", .iov_len = 19 }, { .iov_base = "5th appendv string\n", .iov_len = 19 }, { .iov_base = "6th appendv string\n", .iov_len = 19 }, { .iov_base = "7th appendv string\n", .iov_len = 19 }, { .iov_base = "8th appendv string\n", .iov_len = 19 }, { .iov_base = "9th appendv string\n", .iov_len = 19 } }; int rv = pmemlog_appendv(plp, iov, 9); switch (rv) { case 0: UT_OUT("appendv"); break; case -1: UT_OUT("!appendv"); break; default: UT_OUT("!appendv: wrong return value"); break; } } /* * do_tell -- call pmemlog_tell() & print result */ static void do_tell(PMEMlogpool *plp) { os_off_t tell = pmemlog_tell(plp); UT_OUT("tell %zu", tell); } /* * printit -- print out the 'buf' of length 'len'. * * It is a walker function for pmemlog_walk */ static int printit(const void *buf, size_t len, void *arg) { char *str = MALLOC(len + 1); strncpy(str, buf, len); str[len] = '\0'; UT_OUT("%s", str); FREE(str); return 0; } /* * do_walk -- call pmemlog_walk() & print result */ static void do_walk(PMEMlogpool *plp) { pmemlog_walk(plp, 0, printit, NULL); UT_OUT("walk all at once"); } static ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { UT_OUT("signal: %s", os_strsignal(sig)); ut_siglongjmp(Jmp); } int main(int argc, char *argv[]) { PMEMlogpool *plp; int result; START(argc, argv, "log_recovery"); if (argc != 3) UT_FATAL("usage: %s file-name op:a|v", argv[0]); if (strchr("av", argv[2][0]) == NULL || argv[2][1] != '\0') UT_FATAL("op must be a or v"); const char *path = argv[1]; int fd = OPEN(path, O_RDWR); /* pre-allocate 2MB of persistent memory */ POSIX_FALLOCATE(fd, (os_off_t)0, (size_t)(2 * 1024 * 1024)); CLOSE(fd); if ((plp = pmemlog_create(path, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemlog_create: %s", path); /* append some data */ if (argv[2][0] == 'a') do_append(plp); else do_appendv(plp); /* print out current write point */ do_tell(plp); size_t len = roundup(sizeof(*plp), LOG_FORMAT_DATA_ALIGN); UT_OUT("write-protecting the metadata, length %zu", len); MPROTECT(plp, len, PROT_READ); /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); if (!ut_sigsetjmp(Jmp)) { /* try to append more data */ if (argv[2][0] == 'a') do_append(plp); else do_appendv(plp); } MPROTECT(plp, len, PROT_READ | PROT_WRITE); pmemlog_close(plp); /* check consistency */ result = pmemlog_check(path); if (result < 0) UT_OUT("!%s: pmemlog_check", path); else if (result == 0) UT_OUT("%s: pmemlog_check: not consistent", path); else UT_OUT("%s: consistent", path); /* map again to print out whole log */ if ((plp = pmemlog_open(path)) == NULL) UT_FATAL("!pmemlog_open: %s", path); /* print out current write point */ do_tell(plp); /* print out whole log */ do_walk(plp); pmemlog_close(plp); DONE(NULL); } pmdk-1.11.1/src/test/log_recovery/out0.log.match0000664000000000000000000000115614123364546020173 0ustar rootrootlog_recovery$(nW)TEST0: START: log_recovery $(nW)log_recovery$(nW) $(nW)testfile1 a append str[0] 1st append string append str[1] 2nd append string append str[2] 3rd append string append str[3] 4th append string append str[4] 5th append string append str[5] 6th append string tell 108 $(OPT)write-protecting the metadata, length 8192 $(OPX)write-protecting the metadata, length 131072 signal: Segmentation fault $(nW)testfile1: consistent tell 108 1st append string 2nd append string 3rd append string 4th append string 5th append string 6th append string walk all at once log_recovery$(nW)TEST0: DONE pmdk-1.11.1/src/test/log_recovery/TEST0.PS10000664000000000000000000000072414123364546016672 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_recovery/TEST0 -- unit test for pmemlog recovery # pmemlog_append() is used to append data # . ..\unittest\unittest.ps1 require_test_type medium require_build_type nondebug static-nondebug setup touch $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_recovery$Env:EXESUFFIX $DIR\testfile1 a check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_recovery/.gitignore0000664000000000000000000000001514123364546017467 0ustar rootrootlog_recovery pmdk-1.11.1/src/test/log_recovery/README0000664000000000000000000000156014123364546016365 0ustar rootrootPersistent Memory Development Kit This is src/test/log_recovery/README. This directory contains a unit test for pmemlog recovery. It works only in non-debug mode. The program in log_recovery.c takes a file name and an operation as arguments. An operation is encoded as a character 'a' or 'v'. The first one means that pmemlog_append() will be used to append data and the second one means that pmemlog_appendv() will be used to do that. For example: ./log_recovery file1 a this will call pmemlog_open() on file1, call pmemlog_append() to append six strings to the log and pmemlog_tell() to check the current write point, then it will change the memory protection on the metadata area to read-only. Next, pmemlog_append() is called again and SIGSEGV is caught and reported. Finally, pmemblk_check() and pmemlog_tell() are called to make sure there are no partial log entries. pmdk-1.11.1/src/test/log_recovery/TEST10000775000000000000000000000127214123364546016273 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_recovery/TEST0 -- unit test for pmemlog recovery # pmemlog_appendv() is used to append data # . ../unittest/unittest.sh require_test_type medium require_build_type nondebug static-nondebug # exits with locked mutexes configure_valgrind helgrind force-disable configure_valgrind drd force-disable configure_valgrind pmemcheck force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 touch $DIR/testfile1 expect_normal_exit ./log_recovery$EXESUFFIX $DIR/testfile1 v check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_recovery/out1.log.match0000664000000000000000000000074314123364546020175 0ustar rootrootlog_recovery$(nW)TEST1: START: log_recovery $(nW)log_recovery$(nW) $(nW)testfile1 v appendv tell 171 $(OPT)write-protecting the metadata, length 8192 $(OPX)write-protecting the metadata, length 131072 signal: Segmentation fault $(nW)testfile1: consistent tell 171 1st appendv string 2nd appendv string 3rd appendv string 4th appendv string 5th appendv string 6th appendv string 7th appendv string 8th appendv string 9th appendv string walk all at once log_recovery$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_ctl_config/0000775000000000000000000000000014123364546015745 5ustar rootrootpmdk-1.11.1/src/test/obj_ctl_config/TEST1.PS10000664000000000000000000000100014123364546017121 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_config/TEST1 -- unit test for ctl configuration # $Env:UNITTEST_NAME = "obj_ctl_config/TEST1" $Env:UNITTEST_NUM = "100" # TEST0 poses as different test numbers . ..\unittest\unittest.ps1 require_test_type short setup expect_normal_exit $PMEMPOOL create --layout obj_ctl_config obj $DIR\testfile $Env:PMEMOBJ_CONF_FILE = "" expect_normal_exit $Env:EXE_DIR\obj_ctl_config$Env:EXESUFFIX $DIR\testfile pass pmdk-1.11.1/src/test/obj_ctl_config/config40000664000000000000000000000007514123364546017223 0ustar rootroot#comment prefault #comment .at _ open = 1; #comment #comment pmdk-1.11.1/src/test/obj_ctl_config/obj_ctl_config.vcxproj.filters0000664000000000000000000000425714123364546024002 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {410b2da7-b0a0-4cde-9074-fe5a2223083e} match {e0bdbab6-d3b6-4139-8bf0-5f4b9de0df8b} ps1 Source Files Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_ctl_config/obj_ctl_config.vcxproj0000664000000000000000000001020714123364546022323 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {AEAA72CD-E060-417C-9CA1-49B4738384E0} Win32Proj obj_ctl_config 10.0.17134.0 Application true v140 Application false v140 NotUsing CompileAsCpp NotUsing CompileAsCpp pmdk-1.11.1/src/test/obj_ctl_config/TEST00000775000000000000000000000134614123364546016536 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short setup CONFIG_ID=0 expect_normal_exit $PMEMPOOL$EXESUFFIX\ create --layout obj_ctl_config obj $DIR/testfile0 while true do UNITTEST_NUM=$CONFIG_ID CONFIG_FILE=config$CONFIG_ID if [ ! -f $CONFIG_FILE ]; then break fi # skip configs that include comments for env variable test if ! grep -q '#' $CONFIG_FILE ; then PMEMOBJ_CONF=`cat $CONFIG_FILE`\ expect_normal_exit\ ./obj_ctl_config$EXESUFFIX $DIR/testfile0 check fi PMEMOBJ_CONF_FILE=$CONFIG_FILE\ expect_normal_exit\ ./obj_ctl_config$EXESUFFIX $DIR/testfile0 check CONFIG_ID=$(($CONFIG_ID+1)) done pass pmdk-1.11.1/src/test/obj_ctl_config/config80000664000000000000000000000005014123364546017220 0ustar rootrootprefault.at_open=1;prefault.at_create=1 pmdk-1.11.1/src/test/obj_ctl_config/Makefile0000664000000000000000000000035514123364546017410 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_config/Makefile -- build obj_ctl_config test # TARGET = obj_ctl_config OBJS = obj_ctl_config.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_ctl_config/config30000664000000000000000000000002514123364546017215 0ustar rootrootprefault.at_create=1 pmdk-1.11.1/src/test/obj_ctl_config/out7.log.match0000664000000000000000000000016314123364546020441 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 0 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/out0.log.match0000664000000000000000000000016314123364546020432 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 1 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/TEST0.PS10000664000000000000000000000155614123364546017140 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_ctl_config/TEST0 -- unit test for ctl configuration # . ..\unittest\unittest.ps1 require_test_type short setup expect_normal_exit $PMEMPOOL create --layout obj_ctl_config obj $DIR\testfile $CONFIG_ID = 0 Do { $Env:UNITTEST_NUM = $CONFIG_ID $CONFIG_FILE = "config" + $CONFIG_ID if (!(Test-Path $CONFIG_FILE -PathType Leaf)) { break } if (!(Get-Content $CONFIG_FILE | Select-String "#" -quiet)) { $Env:PMEMOBJ_CONF = Get-Content $CONFIG_FILE -Raw expect_normal_exit $Env:EXE_DIR\obj_ctl_config$Env:EXESUFFIX $DIR\testfile $Env:PMEMOBJ_CONF = "" check } $Env:PMEMOBJ_CONF_FILE = $CONFIG_FILE expect_normal_exit $Env:EXE_DIR\obj_ctl_config$Env:EXESUFFIX $DIR\testfile $Env:PMEMOBJ_CONF_FILE = "" check $CONFIG_ID = $CONFIG_ID + 1 } While ($true) pass pmdk-1.11.1/src/test/obj_ctl_config/config00000664000000000000000000000002314123364546017210 0ustar rootrootprefault.at_open=1 pmdk-1.11.1/src/test/obj_ctl_config/.gitignore0000664000000000000000000000001714123364546017733 0ustar rootrootobj_ctl_config pmdk-1.11.1/src/test/obj_ctl_config/config70000664000000000000000000000010414123364546017217 0ustar rootroot# łabędź prefault.at_open=0; # żołądź prefault.at_create=0; pmdk-1.11.1/src/test/obj_ctl_config/TEST10000775000000000000000000000070014123364546016530 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation export UNITTEST_NAME=obj_ctl_config/TEST1 export UNITTEST_NUM=100 # TEST0 poses as different test numbers . ../unittest/unittest.sh require_test_type short setup expect_normal_exit $PMEMPOOL$EXESUFFIX\ create --layout obj_ctl_config obj $DIR/testfile PMEMOBJ_CONF_FILE=""\ expect_normal_exit ./obj_ctl_config$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/obj_ctl_config/config60000664000000000000000000000040714123364546017224 0ustar rootroot######################### # My pmemobj configuration ######################### # # Global settings: prefault. # modify the behavior of pre-faulting at_open = 1; # prefault when the pool is opened prefault. at_create = 0; # but don't prefault when it's created pmdk-1.11.1/src/test/obj_ctl_config/out6.log.match0000664000000000000000000000016314123364546020440 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 1 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/config20000664000000000000000000000003614123364546017216 0ustar rootroot# empty config with a comment pmdk-1.11.1/src/test/obj_ctl_config/config10000664000000000000000000000000014123364546017204 0ustar rootrootpmdk-1.11.1/src/test/obj_ctl_config/config50000664000000000000000000000010014123364546017211 0ustar rootroot# comment # comment 2 prefault.at_open=1; prefault.at_create=1; pmdk-1.11.1/src/test/obj_ctl_config/out1.log.match0000664000000000000000000000016314123364546020433 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 0 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/out5.log.match0000664000000000000000000000016314123364546020437 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 1 1 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/out3.log.match0000664000000000000000000000016314123364546020435 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 0 1 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/out4.log.match0000664000000000000000000000016314123364546020436 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 1 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/obj_ctl_config.c0000664000000000000000000000133714123364546021056 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * obj_ctl_config.c -- tests for ctl configuration */ #include "unittest.h" #include "out.h" #define LAYOUT "obj_ctl_config" int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_config"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = pmemobj_open(path, LAYOUT); if (pop == NULL) UT_FATAL("!pmemobj_open: %s", path); /* dump all available ctl read entry points */ int result; pmemobj_ctl_get(pop, "prefault.at_open", &result); UT_OUT("%d", result); pmemobj_ctl_get(pop, "prefault.at_create", &result); UT_OUT("%d", result); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_ctl_config/out8.log.match0000664000000000000000000000016314123364546020442 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 1 1 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_ctl_config/out2.log.match0000664000000000000000000000016314123364546020434 0ustar rootrootobj_ctl_config$(nW)TEST0: START: obj_ctl_config $(nW)obj_ctl_config$(nW) $(nW) 0 0 obj_ctl_config$(nW)TEST0: DONE pmdk-1.11.1/src/test/pmem2_badblock_mocks/0000775000000000000000000000000014123364546017041 5ustar rootrootpmdk-1.11.1/src/test/pmem2_badblock_mocks/pmem2_badblock_mocks.c0000664000000000000000000002015014123364546023240 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_badblock_mocks.c -- unit test for pmem2_badblock_*() */ #include #include "unittest.h" #include "out.h" #include "ut_pmem2_utils.h" #include "source.h" #include "badblocks.h" #include "pmem2_badblock_mocks.h" #define BAD_BLOCKS_NUMBER 10 #define EXTENTS_NUMBER 8 #define MAX_BB_SET_STR "4" #define MAX_BB_SET 4 #define DEFAULT_BB_SET 1 #define USAGE_MSG \ "Usage: pmem2_badblock_mocks [bad_blocks_set]\n"\ "Possible values of arguments:\n"\ " test_case : test_basic, test_read_clear_bb \n"\ " file_type : reg_file, chr_dev\n"\ " mode : no_device, namespace, region\n"\ " bad_blocks_set : 1-"MAX_BB_SET_STR"\n\n" /* indexes of arguments */ enum args_t { ARG_TEST_CASE = 1, ARG_FILE_TYPE, ARG_MODE, ARG_BB_SET, /* it always has to be the last one */ ARG_NUMBER, /* number of arguments */ }; typedef void test_fn(struct pmem2_source *src); typedef struct badblock bad_blocks_array[BAD_BLOCKS_NUMBER]; /* HW bad blocks expressed in 512b sectors */ static bad_blocks_array hw_bad_blocks[] = { /* test #1 - no bad blocks */ { {0, 0} }, /* test #2 - 1 HW bad block */ { {1, 1}, {0, 0} }, /* test #3 - 6 HW bad blocks */ { {4, 10}, {16, 10}, {28, 2}, {32, 4}, {40, 4}, {50, 2}, {0, 0} }, /* test #4 - 7 HW bad blocks */ { {2, 4}, {8, 2}, {12, 6}, {20, 2}, {24, 10}, {38, 4}, {46, 2}, \ {0, 0} }, }; /* file's bad blocks expressed in 512b sectors */ static bad_blocks_array file_bad_blocks[] = { /* test #1 - no bad blocks */ { {0, 0} }, /* test #2 - 1 file bad block */ { {0, 2}, {0, 0} }, /* test #3 - 9 file bad blocks */ { {4, 2}, {8, 2}, {12, 2}, {16, 2}, {20, 2}, {24, 2}, {28, 2}, \ {32, 2}, {40, 2}, {0, 0} }, /* test #4 - 9 file bad blocks */ { {4, 2}, {8, 2}, {12, 2}, {16, 2}, {20, 2}, {24, 2}, {28, 2}, \ {32, 2}, {40, 2}, {0, 0} }, }; /* file's extents expressed in 512b sectors */ static struct extent files_extents[][EXTENTS_NUMBER] = { /* test #1 - no extents */ { {0, 0, 0} }, /* test #2 - 1 extent */ { {0, 0, 2}, {0, 0, 0} }, /* test #3 - 7 extents */ { {2, 2, 4}, {8, 8, 2}, {12, 12, 6}, {20, 20, 2}, {24, 24, 10}, \ {38, 38, 4}, {46, 46, 2}, {0, 0, 0} }, /* test #4 - 6 extents */ { {4, 4, 10}, {16, 16, 10}, {28, 28, 2}, {32, 32, 4}, {40, 40, 4}, \ {50, 50, 2}, {0, 0, 0} }, }; /* * map_test_to_set -- map number of a test to an index of bad blocks' set */ static inline unsigned map_test_to_set(unsigned test) { return test & MASK_TEST; } /* * get_nth_typed_badblock -- get next typed badblock */ static struct badblock * get_nth_typed_badblock(unsigned test, unsigned *i_bb, bad_blocks_array bad_blocks[]) { unsigned set = map_test_to_set(test); struct badblock *bb = &bad_blocks[set][*i_bb]; if (bb->offset == 0 && bb->len == 0) bb = NULL; /* no more bad blocks */ else (*i_bb)++; return bb; } /* * get_nth_hw_badblock -- get next HW badblock */ struct badblock * get_nth_hw_badblock(unsigned test, unsigned *i_bb) { return get_nth_typed_badblock(test, i_bb, hw_bad_blocks); } /* * get_nth_file_badblock -- get next file's badblock */ static struct badblock * get_nth_file_badblock(unsigned test, unsigned *i_bb) { return get_nth_typed_badblock(test, i_bb, file_bad_blocks); } /* * get_nth_badblock -- get next badblock */ static struct badblock * get_nth_badblock(int fd, unsigned *i_bb) { UT_ASSERT(fd >= 0); if ((fd & MASK_MODE) == MODE_NO_DEVICE) /* no matching device found */ return NULL; switch (fd & MASK_DEVICE) { case FD_REG_FILE: /* regular file */ return get_nth_file_badblock((unsigned)fd, i_bb); case FD_CHR_DEV: /* character device */ return get_nth_hw_badblock((unsigned)fd, i_bb); case FD_DIRECTORY: case FD_BLK_DEV: break; } /* no bad blocks found */ return NULL; } /* * get_extents -- get file's extents */ int get_extents(int fd, struct extents **exts) { unsigned set = map_test_to_set((unsigned)fd); *exts = ZALLOC(sizeof(struct extents)); struct extents *pexts = *exts; /* set block size */ pexts->blksize = BLK_SIZE_1KB; if ((fd & MASK_DEVICE) != FD_REG_FILE) { /* not a regular file */ return 0; } /* count extents (length > 0) */ while (files_extents[set][pexts->extents_count].length) pexts->extents_count++; /* * It will be freed internally by libpmem2 * (pmem2_badblock_context_delete) */ pexts->extents = MALLOC(pexts->extents_count * sizeof(struct extent)); for (int i = 0; i < pexts->extents_count; i++) { struct extent ext = files_extents[set][i]; uint64_t off_phy = ext.offset_physical; uint64_t off_log = ext.offset_logical; uint64_t len = ext.length; /* check alignment */ UT_ASSERTeq(SEC2B(off_phy) % pexts->blksize, 0); UT_ASSERTeq(SEC2B(off_log) % pexts->blksize, 0); UT_ASSERTeq(SEC2B(len) % pexts->blksize, 0); pexts->extents[i].offset_physical = SEC2B(off_phy); pexts->extents[i].offset_logical = SEC2B(off_log); pexts->extents[i].length = SEC2B(len); } return 0; } /* * test_basic -- basic test */ static void test_basic(struct pmem2_source *src) { UT_OUT("TEST: test_basic: 0x%x", src->value.fd); struct pmem2_badblock_context *bbctx; struct pmem2_badblock bb; int ret; ret = pmem2_badblock_context_new(&bbctx, src); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_badblock_next(bbctx, &bb); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_NO_BAD_BLOCK_FOUND); pmem2_badblock_context_delete(&bbctx); } /* * test_read_clear_bb -- test reading and clearing bad blocks */ static void test_read_clear_bb(struct pmem2_source *src) { UT_OUT("TEST: test_read_clear_bb: 0x%x", src->value.fd); struct pmem2_badblock_context *bbctx; struct pmem2_badblock bb; struct badblock *bb2; unsigned i_bb; int ret; ret = pmem2_badblock_context_new(&bbctx, src); UT_PMEM2_EXPECT_RETURN(ret, 0); i_bb = 0; while ((ret = pmem2_badblock_next(bbctx, &bb)) == 0) { bb2 = get_nth_badblock(src->value.fd, &i_bb); UT_ASSERTne(bb2, NULL); UT_ASSERTeq(bb.offset, SEC2B(bb2->offset)); UT_ASSERTeq(bb.length, SEC2B(bb2->len)); ret = pmem2_badblock_clear(bbctx, &bb); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_NO_BAD_BLOCK_FOUND); if (ret) goto exit_free; } bb2 = get_nth_badblock(src->value.fd, &i_bb); UT_ASSERTeq(bb2, NULL); exit_free: pmem2_badblock_context_delete(&bbctx); } static void parse_arguments(int argc, char *argv[], int *test, enum pmem2_file_type *ftype, test_fn **test_func) { if (argc < (ARG_NUMBER - 1) || argc > ARG_NUMBER) { UT_OUT(USAGE_MSG); if (argc > ARG_NUMBER) UT_FATAL("too many arguments"); else UT_FATAL("missing required argument(s)"); } char *test_case = argv[ARG_TEST_CASE]; char *file_type = argv[ARG_FILE_TYPE]; char *mode = argv[ARG_MODE]; *test = 0; *test_func = NULL; if (strcmp(test_case, "test_basic") == 0) { *test_func = test_basic; } else if (strcmp(test_case, "test_read_clear_bb") == 0) { *test_func = test_read_clear_bb; } else { UT_OUT(USAGE_MSG); UT_FATAL("wrong test case: %s", test_case); } if (strcmp(file_type, "reg_file") == 0) { *test |= FD_REG_FILE; *ftype = PMEM2_FTYPE_REG; } else if (strcmp(file_type, "chr_dev") == 0) { *test |= FD_CHR_DEV; *ftype = PMEM2_FTYPE_DEVDAX; } else { UT_OUT(USAGE_MSG); UT_FATAL("wrong file type: %s", file_type); } if (strcmp(mode, "no_device") == 0) { *test |= MODE_NO_DEVICE; } else if (strcmp(mode, "namespace") == 0) { *test |= MODE_NAMESPACE; } else if (strcmp(mode, "region") == 0) { *test |= MODE_REGION; } else { UT_OUT(USAGE_MSG); UT_FATAL("wrong mode: %s", mode); } int bad_blocks_set = (argc == 5) ? atoi(argv[ARG_BB_SET]) : DEFAULT_BB_SET; if (bad_blocks_set >= 1 && bad_blocks_set <= MAX_BB_SET) { *test |= (bad_blocks_set - 1); } else { UT_OUT(USAGE_MSG); UT_FATAL("wrong bad_blocks_set: %i", bad_blocks_set); } } int main(int argc, char *argv[]) { START(argc, argv, "pmem2_badblock_mocks"); /* sanity check of defines */ UT_ASSERTeq(atoi(MAX_BB_SET_STR), MAX_BB_SET); struct pmem2_source src; test_fn *test_func; src.type = PMEM2_SOURCE_FD; parse_arguments(argc, argv, &src.value.fd, &src.value.ftype, &test_func); src.value.st_rdev = (dev_t)src.value.fd; DONE(NULL); } pmdk-1.11.1/src/test/pmem2_badblock_mocks/mocks_pmem2.c0000664000000000000000000000237714123364546021432 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * mocks_pmem2.c -- mocked pmem2 functions used * indirectly in pmem2_badblock_mocks.c */ #include #include "unittest.h" #include "out.h" #include "extent.h" #include "source.h" #include "pmem2_utils.h" #include "pmem2_badblock_mocks.h" /* * pmem2_region_namespace - mock pmem2_region_namespace */ FUNC_MOCK(pmem2_region_namespace, int, struct ndctl_ctx *ctx, const struct pmem2_source *src, struct ndctl_region **pregion, struct ndctl_namespace **pndns) FUNC_MOCK_RUN_DEFAULT { UT_ASSERTne(pregion, NULL); dev_t st_rdev = src->value.st_rdev; *pregion = (void *)st_rdev; if (pndns == NULL) return 0; UT_ASSERT(src->value.ftype == PMEM2_FTYPE_REG || src->value.ftype == PMEM2_FTYPE_DEVDAX); if (IS_MODE_NO_DEVICE(st_rdev)) { /* did not found any matching device */ *pndns = NULL; return 0; } *pndns = (void *)st_rdev; return 0; } FUNC_MOCK_END /* * pmem2_extents_create_get -- allocate extents structure and get extents * of the given file */ FUNC_MOCK(pmem2_extents_create_get, int, int fd, struct extents **exts) FUNC_MOCK_RUN_DEFAULT { return get_extents(fd, exts); } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem2_badblock_mocks/mocks_other.c0000664000000000000000000000125114123364546021521 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * mocks_other.c -- mocked various functions used * indirectly in pmem2_badblock_mocks.c */ #include #include "unittest.h" #include "out.h" #include "pmem2_badblock_mocks.h" /* * fallocate -- mock fallocate */ FUNC_MOCK(fallocate, int, int fd, int mode, __off_t offset, __off_t len) FUNC_MOCK_RUN_DEFAULT { UT_OUT("fallocate(%i, %i, %lu, %lu)", fd, mode, offset, len); return 0; } FUNC_MOCK_END /* * fcntl -- mock fcntl */ FUNC_MOCK(fcntl, int, int fildes, int cmd) FUNC_MOCK_RUN_DEFAULT { UT_ASSERTeq(cmd, F_GETFL); return O_RDWR; } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem2_badblock_mocks/Makefile0000664000000000000000000000104314123364546020477 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_badblock_mocks/Makefile -- # -- build pmem2_badblock_mocks test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmem2_badblock_mocks OBJS += pmem2_badblock_mocks.o\ mocks_ndctl.o\ mocks_pmem2.o\ mocks_other.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, mocks_ndctl.c) LDFLAGS += $(call extract_funcs, mocks_pmem2.c) LDFLAGS += $(call extract_funcs, mocks_other.c) pmdk-1.11.1/src/test/pmem2_badblock_mocks/mocks_ndctl.c0000664000000000000000000001341414123364546021510 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * mocks_ndctl.c -- mocked ndctl functions used * indirectly in pmem2_badblock_mocks.c */ #include #include #include "unittest.h" #include "pmem2_badblock_mocks.h" #define RESOURCE_ADDRESS 0x1000 /* any non-zero value */ #define UINT(ptr) (unsigned)((uintptr_t)ptr) /* index of bad blocks */ static unsigned i_bb; /* * ndctl_namespace_get_mode - mock ndctl_namespace_get_mode */ FUNC_MOCK(ndctl_namespace_get_mode, enum ndctl_namespace_mode, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { if (IS_MODE_NAMESPACE((uintptr_t)ndns)) /* namespace mode */ return NDCTL_NS_MODE_FSDAX; /* raw mode */ return NDCTL_NS_MODE_RAW; } FUNC_MOCK_END /* * ndctl_namespace_get_pfn - mock ndctl_namespace_get_pfn */ FUNC_MOCK(ndctl_namespace_get_pfn, struct ndctl_pfn *, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { if (IS_MODE_NAMESPACE((uintptr_t)ndns)) /* namespace mode */ return (struct ndctl_pfn *)ndns; return NULL; } FUNC_MOCK_END /* * ndctl_namespace_get_dax - mock ndctl_namespace_get_dax */ FUNC_MOCK(ndctl_namespace_get_dax, struct ndctl_dax *, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { if (IS_MODE_REGION((uintptr_t)ndns)) /* region mode */ return (struct ndctl_dax *)ndns; return NULL; } FUNC_MOCK_END /* * ndctl_pfn_get_resource - mock ndctl_pfn_get_resource */ FUNC_MOCK(ndctl_pfn_get_resource, unsigned long long, struct ndctl_pfn *pfn) FUNC_MOCK_RUN_DEFAULT { return RESOURCE_ADDRESS; } FUNC_MOCK_END /* * ndctl_pfn_get_size - mock ndctl_pfn_get_size */ FUNC_MOCK(ndctl_pfn_get_size, unsigned long long, struct ndctl_pfn *pfn) FUNC_MOCK_RUN_DEFAULT { return DEV_SIZE_1GB; /* 1 GiB */ } FUNC_MOCK_END /* * ndctl_dax_get_resource - mock ndctl_dax_get_resource */ FUNC_MOCK(ndctl_dax_get_resource, unsigned long long, struct ndctl_dax *dax) FUNC_MOCK_RUN_DEFAULT { return RESOURCE_ADDRESS; } FUNC_MOCK_END /* * ndctl_dax_get_size - mock ndctl_dax_get_size */ FUNC_MOCK(ndctl_dax_get_size, unsigned long long, struct ndctl_dax *dax) FUNC_MOCK_RUN_DEFAULT { return DEV_SIZE_1GB; /* 1 GiB */ } FUNC_MOCK_END /* * ndctl_namespace_get_resource - mock ndctl_namespace_get_resource */ FUNC_MOCK(ndctl_namespace_get_resource, unsigned long long, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { return RESOURCE_ADDRESS; } FUNC_MOCK_END /* * ndctl_namespace_get_size - mock ndctl_namespace_get_size */ FUNC_MOCK(ndctl_namespace_get_size, unsigned long long, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { return DEV_SIZE_1GB; /* 1 GiB */ } FUNC_MOCK_END /* * ndctl_region_get_resource - mock ndctl_region_get_resource */ FUNC_MOCK(ndctl_region_get_resource, unsigned long long, struct ndctl_region *region) FUNC_MOCK_RUN_DEFAULT { return RESOURCE_ADDRESS; } FUNC_MOCK_END /* * ndctl_region_get_bus - mock ndctl_region_get_bus */ FUNC_MOCK(ndctl_region_get_bus, struct ndctl_bus *, struct ndctl_region *region) FUNC_MOCK_RUN_DEFAULT { return (struct ndctl_bus *)region; } FUNC_MOCK_END /* * ndctl_namespace_get_first_badblock - mock ndctl_namespace_get_first_badblock */ FUNC_MOCK(ndctl_namespace_get_first_badblock, struct badblock *, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { i_bb = 0; return get_nth_hw_badblock(UINT(ndns), &i_bb); } FUNC_MOCK_END /* * ndctl_namespace_get_next_badblock - mock ndctl_namespace_get_next_badblock */ FUNC_MOCK(ndctl_namespace_get_next_badblock, struct badblock *, struct ndctl_namespace *ndns) FUNC_MOCK_RUN_DEFAULT { return get_nth_hw_badblock(UINT(ndns), &i_bb); } FUNC_MOCK_END /* * ndctl_region_get_first_badblock - mock ndctl_region_get_first_badblock */ FUNC_MOCK(ndctl_region_get_first_badblock, struct badblock *, struct ndctl_region *region) FUNC_MOCK_RUN_DEFAULT { i_bb = 0; return get_nth_hw_badblock(UINT(region), &i_bb); } FUNC_MOCK_END /* * ndctl_region_get_next_badblock - mock ndctl_region_get_next_badblock */ FUNC_MOCK(ndctl_region_get_next_badblock, struct badblock *, struct ndctl_region *region) FUNC_MOCK_RUN_DEFAULT { return get_nth_hw_badblock(UINT(region), &i_bb); } FUNC_MOCK_END static struct ndctl_data { uintptr_t bus; unsigned long long address; unsigned long long length; } data; /* * ndctl_bus_cmd_new_ars_cap - mock ndctl_bus_cmd_new_ars_cap */ FUNC_MOCK(ndctl_bus_cmd_new_ars_cap, struct ndctl_cmd *, struct ndctl_bus *bus, unsigned long long address, unsigned long long len) FUNC_MOCK_RUN_DEFAULT { data.bus = (uintptr_t)bus; data.address = address; data.length = len; return (struct ndctl_cmd *)&data; } FUNC_MOCK_END /* * ndctl_cmd_submit - mock ndctl_cmd_submit */ FUNC_MOCK(ndctl_cmd_submit, int, struct ndctl_cmd *cmd) FUNC_MOCK_RUN_DEFAULT { return 0; } FUNC_MOCK_END /* * ndctl_cmd_ars_cap_get_range - mock ndctl_cmd_ars_cap_get_range */ FUNC_MOCK(ndctl_cmd_ars_cap_get_range, int, struct ndctl_cmd *ars_cap, struct ndctl_range *range) FUNC_MOCK_RUN_DEFAULT { return 0; } FUNC_MOCK_END /* * ndctl_bus_cmd_new_clear_error - mock ndctl_bus_cmd_new_clear_error */ FUNC_MOCK(ndctl_bus_cmd_new_clear_error, struct ndctl_cmd *, unsigned long long address, unsigned long long len, struct ndctl_cmd *ars_cap) FUNC_MOCK_RUN_DEFAULT { return ars_cap; } FUNC_MOCK_END /* * ndctl_cmd_clear_error_get_cleared - mock ndctl_cmd_clear_error_get_cleared */ FUNC_MOCK(ndctl_cmd_clear_error_get_cleared, unsigned long long, struct ndctl_cmd *clear_err) FUNC_MOCK_RUN_DEFAULT { struct ndctl_data *pdata = (struct ndctl_data *)clear_err; UT_OUT("ndctl_clear_error(%lu, %llu, %llu)", pdata->bus, pdata->address, pdata->length); return pdata->length; } FUNC_MOCK_END /* * ndctl_cmd_unref - mock ndctl_cmd_unref */ FUNC_MOCK(ndctl_cmd_unref, void, struct ndctl_cmd *cmd) FUNC_MOCK_RUN_DEFAULT { } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem2_badblock_mocks/TESTS.py0000775000000000000000000000306714123364546020326 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t @t.linux_only @t.require_ndctl class BB_MOCKS_BASIC(t.Test): """PART #1 - basic tests""" def run(self, ctx): test = 'test_basic' ctx.exec('pmem2_badblock_mocks', test, ctx.file_type(), ctx.mode()) @t.add_params('file_type', ['reg_file', 'chr_dev']) @t.add_params('mode', ['no_device']) class TEST0(BB_MOCKS_BASIC): """did not found any matching device""" """regular file / character device""" pass @t.add_params('file_type', ['reg_file']) @t.add_params('mode', ['namespace', 'region']) class TEST1(BB_MOCKS_BASIC): """regular file, namespace mode / region mode""" pass @t.add_params('file_type', ['chr_dev']) @t.add_params('mode', ['region']) class TEST2(BB_MOCKS_BASIC): """character device, region mode""" pass @t.linux_only @t.require_ndctl class BB_MOCKS_READ_CLEAR(t.Test): """PART #2 - test reading and clearing bad blocks""" def run(self, ctx): test = 'test_read_clear_bb' ctx.exec('pmem2_badblock_mocks', test, ctx.file_type(), ctx.mode(), ctx.bb()) @t.add_params('file_type', ['reg_file']) @t.add_params('mode', ['namespace', 'region']) @t.add_params('bb', [1, 2, 3, 4]) class TEST3(BB_MOCKS_READ_CLEAR): """regular file, namespace mode / region mode""" pass @t.add_params('file_type', ['chr_dev']) @t.add_params('mode', ['region']) @t.add_params('bb', [1, 2, 3, 4]) class TEST4(BB_MOCKS_READ_CLEAR): """character device, region mode""" pass pmdk-1.11.1/src/test/pmem2_badblock_mocks/.gitignore0000664000000000000000000000002514123364546021026 0ustar rootrootpmem2_badblock_mocks pmdk-1.11.1/src/test/pmem2_badblock_mocks/pmem2_badblock_mocks.h0000664000000000000000000000241514123364546023251 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * pmem2_badblock_mocks.h -- definitions for pmem2_badblock_mocks test */ #include "extent.h" /* fd bits 6-8: type of device */ #define FD_REG_FILE (1 << 6) /* regular file */ #define FD_CHR_DEV (2 << 6) /* character device */ #define FD_DIRECTORY (3 << 6) /* directory */ #define FD_BLK_DEV (4 << 6) /* block device */ /* fd bits 4-5: ndctl mode */ #define MODE_NO_DEVICE (1 << 4) /* did not found any matching device */ #define MODE_NAMESPACE (2 << 4) /* namespace mode */ #define MODE_REGION (3 << 4) /* region mode */ /* fd bits 0-3: number of test */ /* masks */ #define MASK_DEVICE 0b0111000000 /* bits 6-8: device mask */ #define MASK_MODE 0b0000110000 /* bits 4-5: mode mask */ #define MASK_TEST 0b0000001111 /* bits 0-3: test mask */ /* checks */ #define IS_MODE_NO_DEVICE(x) ((x & MASK_MODE) == MODE_NO_DEVICE) #define IS_MODE_NAMESPACE(x) ((x & MASK_MODE) == MODE_NAMESPACE) #define IS_MODE_REGION(x) ((x & MASK_MODE) == MODE_REGION) /* default block size: 1kB */ #define BLK_SIZE_1KB 1024 /* default size of device: 1 GiB */ #define DEV_SIZE_1GB (1024 * 1024 * 1024) struct badblock *get_nth_hw_badblock(unsigned test, unsigned *i_bb); int get_extents(int fd, struct extents **exts); pmdk-1.11.1/src/test/drd-log.supp0000664000000000000000000000117214123364546015246 0ustar rootroot{ drd:ConflictingAccess fun:*mem*cpy ... fun:_IO_file_xsputn@@GLIBC* ... fun:out_print_func fun:out_common fun:out_log } { drd:ConflictingAccess fun:*memmove ... fun:_IO_file_xsputn@@GLIBC* ... fun:out_print_func fun:out_common fun:out_log } { drd:ConflictingAccess fun:*mem*cpy fun:_IO_file_xsputn@@GLIBC* fun:fputs ... fun:ut_out } { drd:ConflictingAccess fun:*memmove fun:_IO_file_xsputn@@GLIBC* fun:fputs ... fun:ut_out } pmdk-1.11.1/src/test/ctl_prefault/0000775000000000000000000000000014123364546015470 5ustar rootrootpmdk-1.11.1/src/test/ctl_prefault/ctl_prefault.c0000664000000000000000000001034614123364546020324 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * ctl_prefault.c -- tests for the ctl entry points: prefault */ #include #include #include #include "unittest.h" #define OBJ_STR "obj" #define BLK_STR "blk" #define LOG_STR "log" #define BSIZE 20 #define LAYOUT "obj_ctl_prefault" #ifdef __FreeBSD__ typedef char vec_t; #else typedef unsigned char vec_t; #endif typedef int (*fun)(void *, const char *, void *); /* * prefault_fun -- function ctl_get/set testing */ static void prefault_fun(int prefault, fun get_func, fun set_func) { int ret; int arg; int arg_read; if (prefault == 1) { /* prefault at open */ arg_read = -1; ret = get_func(NULL, "prefault.at_open", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); arg = 1; ret = set_func(NULL, "prefault.at_open", &arg); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg, 1); arg_read = -1; ret = get_func(NULL, "prefault.at_open", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 1); } else if (prefault == 2) { /* prefault at create */ arg_read = -1; ret = get_func(NULL, "prefault.at_create", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); arg = 1; ret = set_func(NULL, "prefault.at_create", &arg); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg, 1); arg_read = -1; ret = get_func(NULL, "prefault.at_create", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 1); } } /* * count_resident_pages -- count resident_pages */ static size_t count_resident_pages(void *pool, size_t length) { size_t arr_len = (length + Ut_pagesize - 1) / Ut_pagesize; vec_t *vec = MALLOC(sizeof(*vec) * arr_len); int ret = mincore(pool, length, vec); UT_ASSERTeq(ret, 0); size_t resident_pages = 0; for (size_t i = 0; i < arr_len; ++i) resident_pages += vec[i] & 0x1; FREE(vec); return resident_pages; } /* * test_obj -- open/create PMEMobjpool */ static void test_obj(const char *path, int open) { PMEMobjpool *pop; if (open) { if ((pop = pmemobj_open(path, LAYOUT)) == NULL) UT_FATAL("!pmemobj_open: %s", path); } else { if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); } size_t resident_pages = count_resident_pages(pop, PMEMOBJ_MIN_POOL); pmemobj_close(pop); UT_OUT("%ld", resident_pages); } /* * test_blk -- open/create PMEMblkpool */ static void test_blk(const char *path, int open) { PMEMblkpool *pbp; if (open) { if ((pbp = pmemblk_open(path, BSIZE)) == NULL) UT_FATAL("!pmemblk_open: %s", path); } else { if ((pbp = pmemblk_create(path, BSIZE, PMEMBLK_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemblk_create: %s", path); } size_t resident_pages = count_resident_pages(pbp, PMEMBLK_MIN_POOL); pmemblk_close(pbp); UT_OUT("%ld", resident_pages); } /* * test_log -- open/create PMEMlogpool */ static void test_log(const char *path, int open) { PMEMlogpool *plp; /* * To test prefaulting, pool must have size at least equal to 2 pages. * If 2MB huge pages are used this is at least 4MB. */ size_t pool_size = 2 * PMEMLOG_MIN_POOL; if (open) { if ((plp = pmemlog_open(path)) == NULL) UT_FATAL("!pmemlog_open: %s", path); } else { if ((plp = pmemlog_create(path, pool_size, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemlog_create: %s", path); } size_t resident_pages = count_resident_pages(plp, pool_size); pmemlog_close(plp); UT_OUT("%ld", resident_pages); } #define USAGE() do {\ UT_FATAL("usage: %s file-name type(obj/blk/log) prefault(0/1/2) "\ "open(0/1)", argv[0]);\ } while (0) int main(int argc, char *argv[]) { START(argc, argv, "ctl_prefault"); if (argc != 5) USAGE(); char *type = argv[1]; const char *path = argv[2]; int prefault = atoi(argv[3]); int open = atoi(argv[4]); if (strcmp(type, OBJ_STR) == 0) { prefault_fun(prefault, (fun)pmemobj_ctl_get, (fun)pmemobj_ctl_set); test_obj(path, open); } else if (strcmp(type, BLK_STR) == 0) { prefault_fun(prefault, (fun)pmemblk_ctl_get, (fun)pmemblk_ctl_set); test_blk(path, open); } else if (strcmp(type, LOG_STR) == 0) { prefault_fun(prefault, (fun)pmemlog_ctl_get, (fun)pmemlog_ctl_set); test_log(path, open); } else USAGE(); DONE(NULL); } pmdk-1.11.1/src/test/ctl_prefault/TEST00000775000000000000000000000244314123364546016260 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short setup # without fallocate, creating pool causes writes to each block and # number of page faults is the same no matter if prefaulting is enabled require_native_fallocate $DIR/testfile1 # create, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX obj $DIR/testfile1 0 0 pagefault_create_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX obj $DIR/testfile1 0 1 pagefault_open_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 # create, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX obj $DIR/testfile1 2 0 pagefault_create_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX obj $DIR/testfile1 1 1 pagefault_open_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 if [ ${pagefault_create_baseline} -ge ${pagefault_create_prefault} ]; then fatal "create: ${pagefault_create_baseline} >= ${pagefault_create_prefault} " fi if [ ${pagefault_open_baseline} -ge ${pagefault_open_prefault} ]; then fatal "open: ${pagefault_open_baseline} >= ${pagefault_open_prefault}" fi pass pmdk-1.11.1/src/test/ctl_prefault/Makefile0000664000000000000000000000037714123364546017137 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/ctl_prefault/Makefile -- build ctl_prefault test # TARGET = ctl_prefault OBJS = ctl_prefault.o LIBPMEMBLK=y LIBPMEMLOG=y LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/ctl_prefault/.gitignore0000664000000000000000000000001514123364546017454 0ustar rootrootctl_prefault pmdk-1.11.1/src/test/ctl_prefault/TEST10000775000000000000000000000244314123364546016261 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short setup # without fallocate, creating pool causes writes to each block and # number of page faults is the same no matter if prefaulting is enabled require_native_fallocate $DIR/testfile1 # create, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX blk $DIR/testfile1 0 0 pagefault_create_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX blk $DIR/testfile1 0 1 pagefault_open_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 # create, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX blk $DIR/testfile1 2 0 pagefault_create_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX blk $DIR/testfile1 1 1 pagefault_open_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 if [ ${pagefault_create_baseline} -ge ${pagefault_create_prefault} ]; then fatal "create: ${pagefault_create_baseline} >= ${pagefault_create_prefault} " fi if [ ${pagefault_open_baseline} -ge ${pagefault_open_prefault} ]; then fatal "open: ${pagefault_open_baseline} >= ${pagefault_open_prefault}" fi pass pmdk-1.11.1/src/test/ctl_prefault/TEST20000775000000000000000000000244314123364546016262 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short setup # without fallocate, creating pool causes writes to each block and # number of page faults is the same no matter if prefaulting is enabled require_native_fallocate $DIR/testfile1 # create, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX log $DIR/testfile1 0 0 pagefault_create_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, don't prefault expect_normal_exit ./ctl_prefault$EXESUFFIX log $DIR/testfile1 0 1 pagefault_open_baseline=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 # create, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX log $DIR/testfile1 2 0 pagefault_create_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` # open, prefault expect_normal_exit ./ctl_prefault$EXESUFFIX log $DIR/testfile1 1 1 pagefault_open_prefault=`cat out$UNITTEST_NUM.log | sed -n '3p'` rm -f $DIR/testfile1 if [ ${pagefault_create_baseline} -ge ${pagefault_create_prefault} ]; then fatal "create: ${pagefault_create_baseline} >= ${pagefault_create_prefault} " fi if [ ${pagefault_open_baseline} -ge ${pagefault_open_prefault} ]; then fatal "open: ${pagefault_open_baseline} >= ${pagefault_open_prefault}" fi pass pmdk-1.11.1/src/test/util_pool_hdr/0000775000000000000000000000000014123364546015647 5ustar rootrootpmdk-1.11.1/src/test/util_pool_hdr/util_pool_hdr.c0000664000000000000000000001063414123364546020662 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2020, Intel Corporation */ /* * util_pool_hdr.c -- unit test for pool_hdr layout and default values * * This test should be modified after every layout change. It's here to prevent * any accidental layout changes. */ #include "util.h" #include "unittest.h" #include "set.h" #include "pool_hdr.h" #define POOL_HDR_SIG_LEN_V1 (8) #define POOL_HDR_UNUSED_LEN_V1 (1904) #define POOL_HDR_UNUSED2_LEN_V1 (1976) #define POOL_HDR_2K_CHECKPOINT (2048UL) #define FEATURES_T_SIZE_V1 (12) #define ARCH_FLAGS_SIZE_V1 (16) #define ARCH_FLAGS_RESERVED_LEN_V1 (4) #define SHUTDOWN_STATE_SIZE_V1 (64) #define SHUTDOWN_STATE_RESERVED_LEN_V1 (39) /* * test_layout -- test pool_hdr layout */ static void test_layout() { ASSERT_ALIGNED_BEGIN(struct pool_hdr); ASSERT_ALIGNED_FIELD(struct pool_hdr, signature); ASSERT_FIELD_SIZE(signature, POOL_HDR_SIG_LEN_V1); ASSERT_ALIGNED_FIELD(struct pool_hdr, major); ASSERT_ALIGNED_FIELD(struct pool_hdr, features); ASSERT_ALIGNED_FIELD(struct pool_hdr, poolset_uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, prev_part_uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, next_part_uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, prev_repl_uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, next_repl_uuid); ASSERT_ALIGNED_FIELD(struct pool_hdr, crtime); ASSERT_ALIGNED_FIELD(struct pool_hdr, arch_flags); ASSERT_ALIGNED_FIELD(struct pool_hdr, unused); ASSERT_FIELD_SIZE(unused, POOL_HDR_UNUSED_LEN_V1); ASSERT_OFFSET_CHECKPOINT(struct pool_hdr, POOL_HDR_2K_CHECKPOINT); ASSERT_ALIGNED_FIELD(struct pool_hdr, unused2); ASSERT_FIELD_SIZE(unused2, POOL_HDR_UNUSED2_LEN_V1); ASSERT_ALIGNED_FIELD(struct pool_hdr, sds); ASSERT_ALIGNED_FIELD(struct pool_hdr, checksum); #if PMEM_PAGESIZE > 4096 ASSERT_ALIGNED_FIELD(struct pool_hdr, align_pad); #endif ASSERT_ALIGNED_CHECK(struct pool_hdr); ASSERT_ALIGNED_BEGIN(features_t); ASSERT_ALIGNED_FIELD(features_t, compat); ASSERT_ALIGNED_FIELD(features_t, incompat); ASSERT_ALIGNED_FIELD(features_t, ro_compat); ASSERT_ALIGNED_CHECK(features_t); UT_COMPILE_ERROR_ON(sizeof(features_t) != FEATURES_T_SIZE_V1); ASSERT_ALIGNED_BEGIN(struct arch_flags); ASSERT_ALIGNED_FIELD(struct arch_flags, alignment_desc); ASSERT_ALIGNED_FIELD(struct arch_flags, machine_class); ASSERT_ALIGNED_FIELD(struct arch_flags, data); ASSERT_ALIGNED_FIELD(struct arch_flags, reserved); ASSERT_FIELD_SIZE(reserved, ARCH_FLAGS_RESERVED_LEN_V1); ASSERT_ALIGNED_FIELD(struct arch_flags, machine); ASSERT_ALIGNED_CHECK(struct arch_flags); UT_COMPILE_ERROR_ON(sizeof(struct arch_flags) != ARCH_FLAGS_SIZE_V1); ASSERT_ALIGNED_BEGIN(struct shutdown_state); ASSERT_ALIGNED_FIELD(struct shutdown_state, usc); ASSERT_ALIGNED_FIELD(struct shutdown_state, uuid); ASSERT_ALIGNED_FIELD(struct shutdown_state, dirty); ASSERT_ALIGNED_FIELD(struct shutdown_state, reserved); ASSERT_FIELD_SIZE(reserved, SHUTDOWN_STATE_RESERVED_LEN_V1); ASSERT_ALIGNED_FIELD(struct shutdown_state, checksum); ASSERT_ALIGNED_CHECK(struct shutdown_state); UT_COMPILE_ERROR_ON(sizeof(struct shutdown_state) != SHUTDOWN_STATE_SIZE_V1); } /* incompat features - final values */ #define POOL_FEAT_SINGLEHDR_FINAL 0x0001U #define POOL_FEAT_CKSUM_2K_FINAL 0x0002U #define POOL_FEAT_SDS_FINAL 0x0004U /* incompat features effective values */ #if defined(_WIN32) || NDCTL_ENABLED #ifdef SDS_ENABLED #define POOL_E_FEAT_SDS_FINAL POOL_FEAT_SDS_FINAL #else #define POOL_E_FEAT_SDS_FINAL 0x0000U /* empty */ #endif #else /* * shutdown state support on Linux requires root access on kernel < 4.20 with * ndctl < 63 so it is disabled by default */ #define POOL_E_FEAT_SDS_FINAL 0x0000U /* empty */ #endif #define POOL_FEAT_INCOMPAT_DEFAULT_V1 \ (POOL_FEAT_CKSUM_2K_FINAL | POOL_E_FEAT_SDS_FINAL) #ifdef _WIN32 #define SDS_AT_CREATE_EXPECTED 1 #else #define SDS_AT_CREATE_EXPECTED 0 #endif /* * test_default_values -- test default values */ static void test_default_values() { UT_COMPILE_ERROR_ON(POOL_FEAT_SINGLEHDR != POOL_FEAT_SINGLEHDR_FINAL); UT_COMPILE_ERROR_ON(POOL_FEAT_CKSUM_2K != POOL_FEAT_CKSUM_2K_FINAL); UT_COMPILE_ERROR_ON(POOL_FEAT_SDS != POOL_FEAT_SDS_FINAL); UT_COMPILE_ERROR_ON(SDS_at_create != SDS_AT_CREATE_EXPECTED); UT_COMPILE_ERROR_ON(POOL_FEAT_INCOMPAT_DEFAULT != POOL_FEAT_INCOMPAT_DEFAULT_V1); } int main(int argc, char *argv[]) { START(argc, argv, "util_pool_hdr"); test_layout(); test_default_values(); DONE(NULL); } pmdk-1.11.1/src/test/util_pool_hdr/TEST00000775000000000000000000000046214123364546016436 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/util_pool_hdr/TEST0 -- unit test for pool_hdr layout # and default values # . ../unittest/unittest.sh require_test_type short setup expect_normal_exit ./util_pool_hdr$EXESUFFIX pass pmdk-1.11.1/src/test/util_pool_hdr/Makefile0000664000000000000000000000035414123364546017311 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/util_pool_hdr/Makefile -- build util_pool_hdr unit test # TARGET = util_pool_hdr OBJS = util_pool_hdr.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_pool_hdr/.gitignore0000664000000000000000000000001614123364546017634 0ustar rootrootutil_pool_hdr pmdk-1.11.1/src/test/pmem2_mem_ext/0000775000000000000000000000000014123364546015542 5ustar rootrootpmdk-1.11.1/src/test/pmem2_mem_ext/pmem2_mem_ext.vcxproj.filters0000664000000000000000000000173714123364546023374 0ustar rootroot {4200f836-ad76-482e-9962-43243397298a} {23a70f8d-0265-4412-a8f0-b4b1a8bc8c73} Test Scripts Source Files Source Files Source Files Source Files pmdk-1.11.1/src/test/pmem2_mem_ext/Makefile0000664000000000000000000000055714123364546017211 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_mem_ext/Makefile -- build pmem2_mem_ext test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_mem_ext OBJS += pmem2_mem_ext.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_mem_ext/TESTS.py0000775000000000000000000002063714123364546017031 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020-2021, Intel Corporation # import testframework as t from testframework import granularity as g from testframework import tools from testframework import futils import sys NO_FLAGS = 0 PMEM_F_MEM_NONTEMPORAL = 1 PMEM_F_MEM_TEMPORAL = 2 PMEM_F_MEM_NONTEMPORAL_v_PMEM_F_MEM_TEMPORAL = 3 PMEM_F_MEM_WC = 4 PMEM_F_MEM_WB = 5 PMEM_F_MEM_NOFLUSH = 6 ''' ALL_FLAGS = PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB ''' ALL_FLAGS = 7 # This match is valid for all cases with a BYTE # granularity and small (<256) data size. MATCH_BYTE_SMALL = \ ( (NO_FLAGS, 128, "t"), (PMEM_F_MEM_NONTEMPORAL, 128, "nt"), (PMEM_F_MEM_TEMPORAL, 128, "t"), (PMEM_F_MEM_NONTEMPORAL_v_PMEM_F_MEM_TEMPORAL, 128, "nt"), (PMEM_F_MEM_WC, 128, "t"), (PMEM_F_MEM_WB, 128, "t"), (PMEM_F_MEM_NOFLUSH, 128, "t"), (ALL_FLAGS, 128, "t") ) # This match is valid for all cases with a BYTE # granularity and big (>256) data size. MATCH_BYTE_BIG = \ ( (NO_FLAGS, 1024, "t"), (PMEM_F_MEM_NONTEMPORAL, 1024, "nt"), (PMEM_F_MEM_TEMPORAL, 1024, "t"), (PMEM_F_MEM_NONTEMPORAL_v_PMEM_F_MEM_TEMPORAL, 1024, "nt"), (PMEM_F_MEM_WC, 1024, "t"), (PMEM_F_MEM_WB, 1024, "t"), (PMEM_F_MEM_NOFLUSH, 1024, "t"), (ALL_FLAGS, 1024, "t") ) # This match is valid for all cases with a PAGE/CACHELINE # granularity and small (<256) data size. MATCH_PAGE_CACHELINE_SMALL = \ ( (NO_FLAGS, 128, "t"), (PMEM_F_MEM_NONTEMPORAL, 128, "nt"), (PMEM_F_MEM_TEMPORAL, 128, "t"), (PMEM_F_MEM_NONTEMPORAL_v_PMEM_F_MEM_TEMPORAL, 128, "nt"), (PMEM_F_MEM_WC, 128, "nt"), (PMEM_F_MEM_WB, 128, "t"), (PMEM_F_MEM_NOFLUSH, 128, "t"), (ALL_FLAGS, 128, "t") ) # This match is valid for all cases with a PAGE/CACHELINE # granularity and big (>256) data size. MATCH_PAGE_CACHELINE_BIG = \ ( (NO_FLAGS, 1024, "nt"), (PMEM_F_MEM_NONTEMPORAL, 1024, "nt"), (PMEM_F_MEM_TEMPORAL, 1024, "t"), (PMEM_F_MEM_NONTEMPORAL_v_PMEM_F_MEM_TEMPORAL, 1024, "nt"), (PMEM_F_MEM_WC, 1024, "nt"), (PMEM_F_MEM_WB, 1024, "t"), (PMEM_F_MEM_NOFLUSH, 1024, "t"), (ALL_FLAGS, 1024, "t") ) SSE2 = 1 AVX = 2 AVX512 = 3 VARIANT_LIBC = 'libc' VARIANT_GENERIC = 'generic' VARIANT_SSE2 = 'sse2' VARIANT_AVX = 'avx' VARIANT_AVX512F = 'avx512f' @t.require_build('debug') @t.require_architectures('x86_64') class Pmem2MemExt(t.Test): test_type = t.Short filesize = 4 * t.MiB available_arch = SSE2 variant = VARIANT_SSE2 # By default data size is 128 - this is smaller than threshold value (256) # to predict usage of temporal stores. This value is overridden in some # tests to values bigger than 256. data_size = 128 oper = ("C", "M", "S") def setup(self, ctx): super().setup(ctx) ret = tools.Tools(ctx.env, ctx.build).cpufd() self.check_arch(ctx.variant(), ret.returncode) def check_arch(self, variant, available_arch): if variant == VARIANT_AVX512F: if available_arch < AVX512: raise futils.Skip("SKIP: AVX512F unavailable") # remove this when MSVC we use will support AVX512F if sys.platform.startswith('win32'): raise futils.Skip("SKIP: AVX512F not supported by MSVC") is_avx512f_enabled = tools.envconfig['PMEM2_AVX512F_ENABLED'] if is_avx512f_enabled == "0": raise futils.Skip("SKIP: AVX512F disabled at build time") if variant == VARIANT_AVX and available_arch < AVX: raise futils.Skip("SKIP: AVX unavailable") def check_log(self, ctx, match, type, flag): with open(self.log_files['pmem2'], 'r') as f: str_val = f.read() # count function match, only one log should occur at the time count = str_val.count(match) if count != 1: raise futils.Fail( "Pattern: {} occurs {} times. One expected. " "Type: {} Flag id: {}" .format(match, count, type, flag)) def create_match(self, variant, oper, store_type): match = "" if variant == VARIANT_LIBC: if oper == "C" or oper == "M": match = "memmove_nodrain_libc" elif oper == "S": match = "memset_nodrain_libc" return match if variant == VARIANT_GENERIC: if oper == "C" or oper == "M": match = "memmove_nodrain_generic" elif oper == "S": match = "memset_nodrain_generic" return match if oper in ("C", "M"): match += "memmove_mov" elif oper == "S": match += "memset_mov" else: raise futils.Fail( "Operation: {} not supported.".format(oper)) if store_type == "nt": match += store_type if variant == VARIANT_SSE2: match += "_sse2" elif variant == VARIANT_AVX: match += "_avx" else: match += "_avx512f" return match def run(self, ctx): ctx.env['PMEM2_LOG_LEVEL'] = '15' if ctx.wc_workaround() == 'on': ctx.env['PMEM_WC_WORKAROUND'] = '1' elif ctx.wc_workaround() == 'off': ctx.env['PMEM_WC_WORKAROUND'] = '0' if ctx.variant() == VARIANT_LIBC: ctx.env['PMEM_NO_MOVNT'] = '1' ctx.env['PMEM_NO_GENERIC_MEMCPY'] = '1' elif ctx.variant() == VARIANT_GENERIC: ctx.env['PMEM_NO_MOVNT'] = '1' elif ctx.variant() == VARIANT_SSE2: ctx.env['PMEM_AVX'] = '0' ctx.env['PMEM_AVX512F'] = '0' elif ctx.variant() == VARIANT_AVX: ctx.env['PMEM_AVX'] = '1' ctx.env['PMEM_AVX512F'] = '0' elif ctx.variant() == VARIANT_AVX512F: ctx.env['PMEM_AVX'] = '0' ctx.env['PMEM_AVX512F'] = '1' filepath = ctx.create_holey_file(self.filesize, 'testfile',) for tc in self.test_case: for o in self.oper: flag_id = tc[0] size = tc[1] store_type = tc[2] match = self.create_match(ctx.variant(), o, store_type) ctx.exec('pmem2_mem_ext', filepath, o, size, flag_id) self.check_log(ctx, match, o, flag_id) @t.add_params('variant', [VARIANT_LIBC, VARIANT_GENERIC]) @t.add_params('wc_workaround', ['default']) class TEST0(Pmem2MemExt): test_case = [(NO_FLAGS, 1024, "")] @g.require_granularity(g.PAGE, g.CACHELINE) @t.add_params('variant', [VARIANT_SSE2, VARIANT_AVX, VARIANT_AVX512F]) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST1(Pmem2MemExt): test_case = MATCH_PAGE_CACHELINE_SMALL @g.require_granularity(g.BYTE) @t.add_params('variant', [VARIANT_SSE2, VARIANT_AVX, VARIANT_AVX512F]) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST2(Pmem2MemExt): test_case = MATCH_BYTE_SMALL @g.require_granularity(g.PAGE, g.CACHELINE) @t.add_params('variant', [VARIANT_SSE2, VARIANT_AVX, VARIANT_AVX512F]) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST3(Pmem2MemExt): test_case = MATCH_PAGE_CACHELINE_BIG @g.require_granularity(g.BYTE) @t.add_params('variant', [VARIANT_SSE2, VARIANT_AVX, VARIANT_AVX512F]) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST4(Pmem2MemExt): test_case = MATCH_BYTE_BIG pmdk-1.11.1/src/test/pmem2_mem_ext/.gitignore0000664000000000000000000000001614123364546017527 0ustar rootrootpmem2_mem_ext pmdk-1.11.1/src/test/pmem2_mem_ext/pmem2_mem_ext.vcxproj0000664000000000000000000000731014123364546021716 0ustar rootroot Debug x64 Release x64 {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {5632B41F-19DD-4BA7-A6EB-74F9E8A7EF8A} Win32Proj pmem2_mem_ext 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem2_mem_ext/pmem2_mem_ext.c0000664000000000000000000000643614123364546020455 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_mem_ext.c -- test for low level functions from libpmem2 */ #include "unittest.h" #include "file.h" #include "ut_pmem2.h" #include "valgrind_internal.h" typedef void *(*memmove_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*memcpy_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*memset_fn)(void *pmemdest, int c, size_t len, unsigned flags); static unsigned Flags[] = { 0, PMEM_F_MEM_NONTEMPORAL, PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_WC, PMEM_F_MEM_WB, PMEM_F_MEM_NOFLUSH, PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB, }; /* * do_memcpy_with_flag -- pmem2 memcpy with specified flag amd size */ static void do_memcpy_with_flag(char *addr, size_t data_size, memcpy_fn cpy_fn, int flag) { char *addr2 = addr + data_size; cpy_fn(addr2, addr, data_size, Flags[flag]); } /* * do_memmove_with_flag -- pmem2 memmove with specified flag and size */ static void do_memmove_with_flag(char *addr, size_t data_size, memmove_fn mov_fn, int flag) { char *addr2 = addr + data_size; mov_fn(addr2, addr, data_size, Flags[flag]); } /* * do_memset_with_flag -- pmem2 memset with specified flag and size */ static void do_memset_with_flag(char *addr, size_t data_size, memset_fn set_fn, int flag) { set_fn(addr, 1, data_size, Flags[flag]); if (Flags[flag] & PMEM2_F_MEM_NOFLUSH) VALGRIND_DO_PERSIST(addr, data_size); } int main(int argc, char *argv[]) { int fd; char *addr; size_t mapped_len; struct pmem2_config *cfg; struct pmem2_source *src; struct pmem2_map *map; if (argc != 5) UT_FATAL("usage: %s file type size flag", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_mem_ext %s %savx %savx512f", thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); util_init(); char type = argv[2][0]; size_t data_size = strtoul(argv[3], NULL, 0); int flag = atoi(argv[4]); UT_ASSERT(flag < ARRAY_SIZE(Flags)); fd = OPEN(argv[1], O_RDWR); UT_ASSERT(fd != -1); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&src, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); PMEM2_SOURCE_DELETE(&src); mapped_len = pmem2_map_get_size(map); UT_ASSERT(data_size * 2 < mapped_len); addr = pmem2_map_get_address(map); if (addr == NULL) UT_FATAL("!could not map file: %s", argv[1]); switch (type) { case 'C': { pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); do_memcpy_with_flag(addr, data_size, memcpy_fn, flag); break; } case 'S': { pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); do_memset_with_flag(addr, data_size, memset_fn, flag); break; } case 'M': { pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); do_memmove_with_flag(addr, data_size, memmove_fn, flag); break; } default: UT_FATAL("!wrong type of test %c", type); break; } ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/helgrind-libfabric.supp0000664000000000000000000000026614123364546017430 0ustar rootroot{ Helgrind:Misc ... fun:pthread_spin_destroy fun:fastlock_destroy fun:fi_ibv_eq_close ... } pmdk-1.11.1/src/test/util_ctl/0000775000000000000000000000000014123364546014623 5ustar rootrootpmdk-1.11.1/src/test/util_ctl/TEST00000775000000000000000000000034114123364546015406 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short setup expect_normal_exit\ ./util_ctl$EXESUFFIX $DIR/testconfig pass pmdk-1.11.1/src/test/util_ctl/util_ctl.vcxproj.filters0000664000000000000000000000140114123364546021522 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {64a1f08f-887d-4caa-ad50-5b6c8fd653e2} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/util_ctl/Makefile0000664000000000000000000000033014123364546016257 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_ctl/Makefile -- build util_ctl test # TARGET = util_ctl OBJS = util_ctl.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_ctl/TEST0.PS10000664000000000000000000000043614123364546016012 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/util_ctl/TEST0 -- unit test for util_ctl interface # . ..\unittest\unittest.ps1 require_test_type short setup expect_normal_exit $Env:EXE_DIR\util_ctl$Env:EXESUFFIX $DIR\testconfig pass pmdk-1.11.1/src/test/util_ctl/.gitignore0000664000000000000000000000001114123364546016603 0ustar rootrootutil_ctl pmdk-1.11.1/src/test/util_ctl/util_ctl.c0000664000000000000000000004206314123364546016613 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * util_ctl.c -- tests for the control module */ #include "unittest.h" #include "ctl.h" #include "out.h" #include "pmemcommon.h" #include "fault_injection.h" #define LOG_PREFIX "ut" #define LOG_LEVEL_VAR "TEST_LOG_LEVEL" #define LOG_FILE_VAR "TEST_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 struct pool { struct ctl *ctl; }; static char *testconfig_path; static int test_config_written; static int CTL_READ_HANDLER(test_rw)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_PROGRAMMATIC); int *arg_rw = arg; *arg_rw = 0; return 0; } static int CTL_WRITE_HANDLER(test_rw)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { int *arg_rw = arg; *arg_rw = 1; test_config_written++; return 0; } static struct ctl_argument CTL_ARG(test_rw) = CTL_ARG_INT; static int CTL_WRITE_HANDLER(test_wo)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { int *arg_wo = arg; *arg_wo = 1; test_config_written++; return 0; } static struct ctl_argument CTL_ARG(test_wo) = CTL_ARG_INT; #define TEST_CONFIG_VALUE "abcd" static int CTL_WRITE_HANDLER(test_config)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_CONFIG_INPUT); char *config_value = arg; UT_ASSERTeq(strcmp(config_value, TEST_CONFIG_VALUE), 0); test_config_written++; return 0; } static struct ctl_argument CTL_ARG(test_config) = CTL_ARG_STRING(8); struct complex_arg { int a; char b[5]; long long c; int d; }; #define COMPLEX_ARG_TEST_A 12345 #define COMPLEX_ARG_TEST_B "abcd" #define COMPLEX_ARG_TEST_C 3147483647 #define COMPLEX_ARG_TEST_D 1 static int CTL_WRITE_HANDLER(test_config_complex_arg)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_CONFIG_INPUT); struct complex_arg *c = arg; UT_ASSERTeq(c->a, COMPLEX_ARG_TEST_A); UT_ASSERT(strcmp(COMPLEX_ARG_TEST_B, c->b) == 0); UT_ASSERTeq(c->c, COMPLEX_ARG_TEST_C); UT_ASSERTeq(c->d, COMPLEX_ARG_TEST_D); test_config_written++; return 0; } static struct ctl_argument CTL_ARG(test_config_complex_arg) = { .dest_size = sizeof(struct complex_arg), .parsers = { CTL_ARG_PARSER_STRUCT(struct complex_arg, a, ctl_arg_integer), CTL_ARG_PARSER_STRUCT(struct complex_arg, b, ctl_arg_string), CTL_ARG_PARSER_STRUCT(struct complex_arg, c, ctl_arg_integer), CTL_ARG_PARSER_STRUCT(struct complex_arg, d, ctl_arg_boolean), CTL_ARG_PARSER_END } }; static int CTL_READ_HANDLER(test_ro)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_PROGRAMMATIC); int *arg_ro = arg; *arg_ro = 0; return 0; } static int CTL_READ_HANDLER(index_value)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_PROGRAMMATIC); long *index_value = arg; struct ctl_index *idx = PMDK_SLIST_FIRST(indexes); UT_ASSERT(strcmp(idx->name, "test_index") == 0); *index_value = idx->value; return 0; } static int CTL_RUNNABLE_HANDLER(test_runnable)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_PROGRAMMATIC); int *arg_runnable = arg; *arg_runnable = 0; return 0; } static const struct ctl_node CTL_NODE(test_index)[] = { CTL_LEAF_RO(index_value), CTL_NODE_END }; static const struct ctl_node CTL_NODE(debug)[] = { CTL_LEAF_RO(test_ro), CTL_LEAF_WO(test_wo), CTL_LEAF_RUNNABLE(test_runnable), CTL_LEAF_RW(test_rw), CTL_INDEXED(test_index), CTL_LEAF_WO(test_config), CTL_LEAF_WO(test_config_complex_arg), CTL_NODE_END }; static int CTL_WRITE_HANDLER(gtest_config)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_CONFIG_INPUT); char *config_value = arg; UT_ASSERTeq(strcmp(config_value, TEST_CONFIG_VALUE), 0); test_config_written = 1; return 0; } static struct ctl_argument CTL_ARG(gtest_config) = CTL_ARG_STRING(8); static int CTL_READ_HANDLER(gtest_ro)(void *ctx, enum ctl_query_source source, void *arg, struct ctl_indexes *indexes) { UT_ASSERTeq(source, CTL_QUERY_PROGRAMMATIC); int *arg_ro = arg; *arg_ro = 0; return 0; } static const struct ctl_node CTL_NODE(global_debug)[] = { CTL_LEAF_RO(gtest_ro), CTL_LEAF_WO(gtest_config), CTL_NODE_END }; static int util_ctl_get(struct pool *pop, const char *name, void *arg) { LOG(3, "pop %p name %s arg %p", pop, name, arg); return ctl_query(pop ? pop->ctl : NULL, pop, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_READ, arg); } static int util_ctl_set(struct pool *pop, const char *name, void *arg) { LOG(3, "pop %p name %s arg %p", pop, name, arg); return ctl_query(pop ? pop->ctl : NULL, pop, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_WRITE, arg); } static int util_ctl_exec(struct pool *pop, const char *name, void *arg) { LOG(3, "pop %p name %s arg %p", pop, name, arg); return ctl_query(pop ? pop->ctl : NULL, pop, CTL_QUERY_PROGRAMMATIC, name, CTL_QUERY_RUNNABLE, arg); } static void test_ctl_parser(struct pool *pop) { errno = 0; int ret; ret = util_ctl_get(pop, NULL, NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "a.b.c.d", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, ".", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "..", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "1.2.3.4", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.1.", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.1.invalid", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); /* test methods set read to 0 and write to 1 if successful */ int arg_read = 1; int arg_write = 0; errno = 0; /* correct name, wrong args */ ret = util_ctl_get(pop, "debug.test_rw", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_set(pop, "debug.test_rw", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.test_wo", &arg_read); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.test_wo", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_set(pop, "debug.test_ro", &arg_write); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_set(pop, "debug.test_ro", NULL); UT_ASSERTne(ret, 0); UT_ASSERTne(errno, 0); errno = 0; ret = util_ctl_get(pop, "debug.test_rw", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); UT_ASSERTeq(arg_write, 0); UT_ASSERTeq(errno, 0); ret = util_ctl_set(pop, "debug.test_rw", &arg_write); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); UT_ASSERTeq(arg_write, 1); arg_read = 1; arg_write = 0; ret = util_ctl_get(pop, "debug.test_ro", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); UT_ASSERTeq(arg_write, 0); arg_read = 1; arg_write = 0; ret = util_ctl_set(pop, "debug.test_wo", &arg_write); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 1); UT_ASSERTeq(arg_write, 1); long index_value = 0; ret = util_ctl_get(pop, "debug.5.index_value", &index_value); UT_ASSERTeq(ret, 0); UT_ASSERTeq(index_value, 5); ret = util_ctl_get(pop, "debug.10.index_value", &index_value); UT_ASSERTeq(ret, 0); UT_ASSERTeq(index_value, 10); arg_read = 1; arg_write = 1; int arg_runnable = 1; ret = util_ctl_exec(pop, "debug.test_runnable", &arg_runnable); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 1); UT_ASSERTeq(arg_write, 1); UT_ASSERTeq(arg_runnable, 0); } static void test_string_config(struct pool *pop) { UT_ASSERTne(pop, NULL); int ret; test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, ""); UT_ASSERTeq(ret, 0); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, ";;"); UT_ASSERTeq(ret, 0); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, ";=;"); UT_ASSERTeq(ret, -1); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "="); UT_ASSERTeq(ret, -1); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "debug.test_wo="); UT_ASSERTeq(ret, -1); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "=b"); UT_ASSERTeq(ret, -1); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "debug.test_wo=111=222"); UT_ASSERTeq(ret, -1); UT_ASSERTeq(test_config_written, 0); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "debug.test_wo=333;debug.test_rw=444;"); UT_ASSERTeq(ret, 0); UT_ASSERTeq(test_config_written, 2); test_config_written = 0; ret = ctl_load_config_from_string(pop->ctl, pop, "debug.test_config="TEST_CONFIG_VALUE";"); UT_ASSERTeq(ret, 0); UT_ASSERTeq(test_config_written, 1); } static void config_file_create(const char *buf) { /* the test script will take care of removing this file for us */ FILE *f = os_fopen(testconfig_path, "w+"); fwrite(buf, sizeof(char), strlen(buf), f); fclose(f); } static void create_and_test_file_config(struct pool *pop, const char *buf, int ret, int result) { config_file_create(buf); test_config_written = 0; int r = ctl_load_config_from_file(pop ? pop->ctl : NULL, pop, testconfig_path); UT_ASSERTeq(r, ret); UT_ASSERTeq(test_config_written, result); } static void test_too_large_file(struct pool *pop) { char *too_large_buf = calloc(1, 1 << 21); UT_ASSERTne(too_large_buf, NULL); memset(too_large_buf, 0xc, (1 << 21) - 1); config_file_create(too_large_buf); int ret = ctl_load_config_from_file(pop->ctl, pop, testconfig_path); UT_ASSERTne(ret, 0); free(too_large_buf); } static void test_file_config(struct pool *pop) { create_and_test_file_config(pop, "debug.test_config="TEST_CONFIG_VALUE";", 0, 1); create_and_test_file_config(pop, "debug.test_config="TEST_CONFIG_VALUE";" "debug.test_config="TEST_CONFIG_VALUE";", 0, 2); create_and_test_file_config(pop, "#this is a comment\n" "debug.test_config="TEST_CONFIG_VALUE";", 0, 1); create_and_test_file_config(pop, "debug.#this is a comment\n" "test_config#this is a comment\n" "="TEST_CONFIG_VALUE";", 0, 1); create_and_test_file_config(pop, "debug.test_config="TEST_CONFIG_VALUE";#this is a comment", 0, 1); create_and_test_file_config(pop, "\n\n\ndebug\n.\ntest\t_\tconfig="TEST_CONFIG_VALUE";\n", 0, 1); create_and_test_file_config(pop, " d e b u g . t e s t _ c o n f i g = "TEST_CONFIG_VALUE";", 0, 1); create_and_test_file_config(pop, "#debug.test_config="TEST_CONFIG_VALUE";", 0, 0); create_and_test_file_config(pop, "debug.#this is a comment\n" "test_config#this is a not properly terminated comment" "="TEST_CONFIG_VALUE";", -1, 0); create_and_test_file_config(pop, "invalid", -1, 0); create_and_test_file_config(pop, "", 0, 0); create_and_test_file_config(pop, "debug.test_config_complex_arg=;", -1, 0); create_and_test_file_config(pop, "debug.test_config_complex_arg=1,2,3;", -1, 0); create_and_test_file_config(pop, "debug.test_config_complex_arg=12345,abcd,,1;", -1, 0); create_and_test_file_config(pop, "debug.test_config_complex_arg=12345,abcd,3147483647,1;", 0, 1); create_and_test_file_config(NULL, "global_debug.gtest_config="TEST_CONFIG_VALUE";", 0, 1); create_and_test_file_config(NULL, "private.missing.query=1;" "global_debug.gtest_config="TEST_CONFIG_VALUE";", 0, 1); test_too_large_file(pop); int ret = ctl_load_config_from_file(pop->ctl, pop, "does_not_exist"); UT_ASSERTne(ret, 0); } static void test_ctl_global_namespace(struct pool *pop) { int arg_read = 1; int ret = util_ctl_get(pop, "global_debug.gtest_ro", &arg_read); UT_ASSERTeq(ret, 0); UT_ASSERTeq(arg_read, 0); } static void test_ctl_arg_parsers() { char *input; input = ""; int boolean = -1; int ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(boolean, -1); input = "abcdefgh"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(boolean, -1); input = "-999"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(boolean, -1); input = "N"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 0); input = "0"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 0); input = "yes"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 1); input = "Yes"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 1); input = "1"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 1); input = "1234"; boolean = -1; ret = ctl_arg_boolean(input, &boolean, sizeof(int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(boolean, 1); input = ""; int small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "abcd"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "12345678901234567890"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "-12345678901234567890"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "2147483648"; /* INT_MAX + 1 */ small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "-2147483649"; /* INT_MIN - 2 */ small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(small_int, -1); input = "0"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(small_int, 0); input = "500"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(small_int, 500); input = "-500"; small_int = -1; ret = ctl_arg_integer(input, &small_int, sizeof(small_int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(small_int, -500); input = ""; long long ll_int = -1; ret = ctl_arg_integer(input, &ll_int, sizeof(ll_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(ll_int, -1); input = "12345678901234567890"; ll_int = -1; ret = ctl_arg_integer(input, &ll_int, sizeof(ll_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(ll_int, -1); input = "-12345678901234567890"; ll_int = -1; ret = ctl_arg_integer(input, &ll_int, sizeof(ll_int)); UT_ASSERTeq(ret, -1); UT_ASSERTeq(ll_int, -1); input = "2147483648"; ll_int = -1; ret = ctl_arg_integer(input, &ll_int, sizeof(ll_int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(ll_int, 2147483648); input = "-2147483649"; ll_int = -1; ret = ctl_arg_integer(input, &ll_int, sizeof(ll_int)); UT_ASSERTeq(ret, 0); UT_ASSERTeq(ll_int, -2147483649LL); input = ""; char string[1000] = {0}; ret = ctl_arg_string(input, string, 0); UT_ASSERTeq(ret, -1); input = "abcd"; ret = ctl_arg_string(input, string, 3); UT_ASSERTeq(ret, -1); input = "abcdefg"; ret = ctl_arg_string(input, string, 3); UT_ASSERTeq(ret, -1); input = "abcd"; ret = ctl_arg_string(input, string, 4); UT_ASSERTeq(ret, -1); input = "abc"; ret = ctl_arg_string(input, string, 4); UT_ASSERTeq(ret, 0); UT_ASSERT(strcmp(input, string) == 0); } static void test_fault_injection(struct pool *pop) { if (!core_fault_injection_enabled()) return; UT_ASSERTne(pop, NULL); core_inject_fault_at(PMEM_MALLOC, 1, "ctl_parse_args"); test_config_written = 0; int ret = ctl_load_config_from_string(pop->ctl, pop, "debug.test_wo=333;debug.test_rw=444;"); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); } int main(int argc, char *argv[]) { START(argc, argv, "util_ctl"); common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); if (argc != 2) UT_FATAL("usage: %s testconfig", argv[0]); testconfig_path = argv[1]; CTL_REGISTER_MODULE(NULL, global_debug); test_ctl_global_namespace(NULL); struct pool pop; pop.ctl = ctl_new(); test_ctl_global_namespace(NULL); CTL_REGISTER_MODULE(pop.ctl, debug); test_ctl_global_namespace(&pop); test_fault_injection(&pop); test_ctl_parser(&pop); test_string_config(&pop); test_file_config(&pop); test_ctl_arg_parsers(); ctl_delete(pop.ctl); common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/util_ctl/TEST10000775000000000000000000000041414123364546015410 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-enable setup expect_normal_exit\ ./util_ctl$EXESUFFIX $DIR/testconfig pass pmdk-1.11.1/src/test/util_ctl/util_ctl.vcxproj0000664000000000000000000000746714123364546020075 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {E796AA20-D664-4D05-ABD9-C93A4FBE3E5C} Win32Proj util_ctl 10.0.17134.0 Application true v140 Application false v140 true NotUsing Disabled $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) NotUsing MaxSpeed $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/rpmem_addr_ext/0000775000000000000000000000000014123364546015776 5ustar rootrootpmdk-1.11.1/src/test/rpmem_addr_ext/TEST00000775000000000000000000000124214123364546016562 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/rpmem_addr_ext/TEST0 -- advanced unittest for invalid target formats # . ../unittest/unittest.sh require_test_type short # matching logs works only with the debug version require_build_type debug require_nodes 2 # libfabric version < 1.4.3 does not handle this test properly require_node_libfabric 0 $RPMEM_PROVIDER 1.4.3 require_node_libfabric 1 $RPMEM_PROVIDER 1.4.3 setup init_rpmem_on_node 1 0 TARGETS=targets.in copy_files_to_node 1 ${NODE_TEST_DIR[1]} $TARGETS expect_normal_exit run_on_node 1 ./rpmem_addr_ext$EXESUFFIX $TARGETS check pass pmdk-1.11.1/src/test/rpmem_addr_ext/Makefile0000664000000000000000000000072014123364546017435 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2020, Intel Corporation # # src/test/rpmem_addr_ext/Makefile -- build rpmem_addr_ext test # include ../../common.inc vpath %.c ../../rpmem_common ifeq ($(BUILD_RPMEM), y) SCP_TO_REMOTE_NODES = y TARGET = rpmem_addr_ext OBJS = rpmem_addr_ext.o LIBRPMEM=y endif include ../Makefile.inc ifeq ($(BUILD_RPMEM), y) LIBS += $(LIBFABRIC_LIBS) CFLAGS += $(LIBFABRIC_CFLAGS) INCS += -I../../rpmem_common endif pmdk-1.11.1/src/test/rpmem_addr_ext/targets.in0000664000000000000000000000036614123364546020004 0ustar rootrootuser 192.168.0.182 22 user:192.168.0.182::22 user::192.168.0.182:22 user@192.168.0.18222 user@192.168.0.182@22 user:192.168.0.182:22 user|192.168.0.182:22 user@192.168.0.182|22 user@.192.168.0.182:22 user@:192.168.0.182:22 user@@192.168.0.182:22 pmdk-1.11.1/src/test/rpmem_addr_ext/.gitignore0000664000000000000000000000001714123364546017764 0ustar rootrootrpmem_addr_ext pmdk-1.11.1/src/test/rpmem_addr_ext/node_1_rpmem0.log.match0000664000000000000000000002174714123364546022234 0ustar rootroot: <1> [$(*)] $(*) : <1> [$(*)] librpmem version $(nW) : <1> [$(*)] src version: $(nW) $(OPT): <1> [$(*)] compiled with support for Valgrind pmemcheck $(OPT): <1> [$(*)] compiled with support for Valgrind helgrind $(OPT): <1> [$(*)] compiled with support for Valgrind memcheck $(OPT): <1> [$(*)] compiled with support for Valgrind drd $(OPT): <1> [$(*)] compiled with support for shutdown state $(OPT): <1> [$(*)] compiled with libndctl 63+ : <3> [$(*)] $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user 192.168.0.182 22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user 192.168.0.182 22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user:192.168.0.182::22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user:192.168.0.182::22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user::192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user::192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@192.168.0.18222 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@192.168.0.18222 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@192.168.0.182@22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@192.168.0.182@22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user:192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user:192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user|192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user|192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@192.168.0.182|22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@192.168.0.182|22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@.192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@.192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@:192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@:192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] create request: : <3> [$(*)] target: user@@192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <3> [$(*)] open request: : <3> [$(*)] target: user@@192.168.0.182:22 : <3> [$(*)] pool set: invalid.poolset : <3> [$(*)] nlanes: 32 $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) $(OPT): <3> [$(*)] $(*) : <1> [$(*)] cannot find provider : <3> [$(*)]$(W) pmdk-1.11.1/src/test/rpmem_addr_ext/config.sh0000664000000000000000000000044114123364546017576 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # rpmem_addr_ext/config.sh -- test configuration file # CONF_GLOBAL_FS_TYPE=any CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=sockets CONF_GLOBAL_RPMEM_PMETHOD=GPSPM pmdk-1.11.1/src/test/rpmem_addr_ext/rpmem_addr_ext.c0000664000000000000000000000405114123364546021134 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * rpmem_addr_ext.c -- advanced unittest for invalid target formats */ #include "unittest.h" #include "librpmem.h" #include "pool_hdr.h" #include "set.h" #include "util.h" #include "out.h" #include "rpmem_common.h" #include "rpmem_fip_common.h" #define POOL_SIZE (8 * 1024 * 1024) /* 8 MiB */ #define NLANES 32 #define MAX_TARGET_LENGTH 256 /* * test_prepare -- prepare test environment */ static void test_prepare() { /* * Till fix introduced to libfabric in pull request * https://github.com/ofiwg/libfabric/pull/2551 misuse of errno value * lead to SIGSEGV. */ errno = 0; } /* * test_create -- test case for creating remote pool */ static int test_create(const char *target, void *pool) { const char *pool_set = "invalid.poolset"; unsigned nlanes = NLANES; struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); RPMEMpool *rpp = rpmem_create(target, pool_set, pool, POOL_SIZE, &nlanes, &pool_attr); UT_ASSERTeq(rpp, NULL); return 0; } /* * test_open -- test case for opening remote pool */ static int test_open(const char *target, void *pool) { const char *pool_set = "invalid.poolset"; unsigned nlanes = NLANES; struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); RPMEMpool *rpp = rpmem_open(target, pool_set, pool, POOL_SIZE, &nlanes, &pool_attr); UT_ASSERTeq(rpp, NULL); return 0; } int main(int argc, char *argv[]) { START(argc, argv, "rpmem_addr_ext"); if (argc < 2) UT_FATAL("usage: rpmem_addr_ext "); const char *targets_file_name = argv[1]; char target[MAX_TARGET_LENGTH]; void *pool = PAGEALIGNMALLOC(POOL_SIZE); FILE *targets_file = FOPEN(targets_file_name, "r"); while (fgets(target, sizeof(target), targets_file)) { /* assume each target has new line at the end and remove it */ target[strlen(target) - 1] = '\0'; test_prepare(); test_create(target, pool); test_prepare(); test_open(target, pool); } FCLOSE(targets_file); FREE(pool); DONE(NULL); } pmdk-1.11.1/src/test/ctl_cow/0000775000000000000000000000000014123364546014436 5ustar rootrootpmdk-1.11.1/src/test/ctl_cow/err3.log.match0000664000000000000000000000014314123364546017105 0ustar rootroot{ctl_cow.c:$(N) test_dax} ctl_cow/TEST3: Error: cannot open $(nW)/dax.set: Operation not supported pmdk-1.11.1/src/test/ctl_cow/TEST30000775000000000000000000000145614123364546015234 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/TEST3 -- unit test which checks if opening pool located # on Device DAX when copy_on_write.at_open=1 fails # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 dax_device_zero setup POOL="$DIR/testfile" POOLSET_DAX="$DIR/dax.set" create_poolset $POOLSET_DAX AUTO:${DEVICE_DAX_PATH[0]} O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOLSET_DAX expect_normal_exit $PMEMPOOL$EXESUFFIX create -s 32MB obj $POOL PMEMOBJ_CONF="copy_on_write.at_open=1;" # check if opening non-dax pool does not fail expect_normal_exit ./ctl_cow$EXESUFFIX $POOL dax # check if opening dax pool fails expect_abnormal_exit ./ctl_cow$EXESUFFIX $POOLSET_DAX dax check pass pmdk-1.11.1/src/test/ctl_cow/ctl_cow.c0000664000000000000000000000557314123364546016246 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * ctl_cow.c -- unit tests for copy on write feature which check * if changes are reverted after pool close when copy_on_write.at_open = 1 */ #include #include "unittest.h" #include struct test_st { int x; }; POBJ_LAYOUT_BEGIN(test_layout); POBJ_LAYOUT_ROOT(test_layout, struct my_root); POBJ_LAYOUT_TOID(test_layout, struct test_st); POBJ_LAYOUT_END(test_layout); struct my_root { TOID(struct test_st) x; TOID(struct test_st) y; TOID(struct test_st) z; }; static void test_obj(const char *path) { PMEMobjpool *pop = pmemobj_open(path, NULL); if (pop == NULL) UT_FATAL("!%s: pmemobj_open", path); TOID(struct my_root) root = POBJ_ROOT(pop, struct my_root); TX_BEGIN(pop) { TX_ADD(root); TOID(struct test_st) x = TX_NEW(struct test_st); TOID(struct test_st) y = TX_NEW(struct test_st); TOID(struct test_st) z = TX_NEW(struct test_st); D_RW(x)->x = 5; D_RW(y)->x = 10; D_RW(z)->x = 15; D_RW(root)->x = x; D_RW(root)->y = y; D_RW(root)->z = z; } TX_ONABORT { abort(); } TX_END TX_BEGIN(pop) { TX_ADD(root); TX_FREE(D_RW(root)->x); D_RW(root)->x = TOID_NULL(struct test_st); TX_ADD(D_RW(root)->y); TOID(struct test_st) y = D_RO(root)->y; D_RW(y)->x = 100; } TX_ONABORT { abort(); } TX_END pmemobj_close(pop); } static void test_blk(const char *path) { PMEMblkpool *pbp = pmemblk_open(path, 512); if (pbp == NULL) UT_FATAL("!cannot open %s", path); char x[512] = "Test blk x"; char y[512] = "Test blk y"; if (pmemblk_write(pbp, &x, 1) < 0) UT_FATAL("cannot write to %s", path); if (pmemblk_write(pbp, &y, 2) < 0) UT_FATAL("cannot write to %s", path); if (pmemblk_set_zero(pbp, 2) < 0) UT_FATAL("cannot write to %s", path); pmemblk_close(pbp); } static void test_log(const char *path) { PMEMlogpool *plp = pmemlog_open(path); if (plp == NULL) UT_FATAL("!cannot open %s", path); char buf[] = "pmemlog test"; char buf_2[] = "pmemlog test 2"; if (pmemlog_append(plp, buf, strlen(buf)) < 0) UT_FATAL("cannot append to %s", path); if (pmemlog_append(plp, buf_2, strlen(buf_2)) < 0) UT_FATAL("cannot append to %s", path); pmemlog_close(plp); } static void test_dax(const char *path) { PMEMobjpool *pop = pmemobj_open(path, NULL); if (pop == NULL) UT_FATAL("!cannot open %s", path); else pmemobj_close(pop); } int main(int argc, char *argv[]) { START(argc, argv, "ctl_cow"); if (argc < 3) UT_FATAL("usage: %s filename obj|log|blk|dax", argv[0]); const char *path = argv[1]; const char *action = argv[2]; if (strcmp(action, "obj") == 0) { test_obj(path); } else if (strcmp(action, "blk") == 0) { test_blk(path); } else if (strcmp(action, "log") == 0) { test_log(path); } else if (strcmp(action, "dax") == 0) { test_dax(path); } else { UT_FATAL("%s is not a valid action", action); } DONE(NULL); } pmdk-1.11.1/src/test/ctl_cow/TEST00000775000000000000000000000164214123364546015226 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/TEST0 -- unit test which checks copy on write feature # for obj pool # . ../unittest/unittest.sh require_test_type medium require_command md5sum setup POOLSET="testset_local" POOL="testfile" REPLICA="testfile_replica" create_poolset $DIR/$POOLSET 32M:$DIR/$POOL:z \ R 32M:$DIR/$REPLICA:z expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/$POOLSET POOL_BEFORE=`md5sum -b $DIR/$POOL` REPLICA_BEFORE=`md5sum -b $DIR/$REPLICA` PMEMOBJ_CONF="${PMEMOBJ_CONF}copy_on_write.at_open=1" expect_normal_exit ./ctl_cow$EXESUFFIX $DIR/$POOLSET obj POOL_AFTER=`md5sum -b $DIR/$POOL` REPLICA_AFTER=`md5sum -b $DIR/$REPLICA` if [ "$POOL_BEFORE" != "$POOL_AFTER" ] || [ "$REPLICA_BEFORE" != "$REPLICA_AFTER" ] then fatal "$POOL_BEFORE != $POOL_AFTER or $REPLICA_BEFORE != $REPLICA_AFTER" fi check pass pmdk-1.11.1/src/test/ctl_cow/Makefile0000664000000000000000000000034614123364546016101 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/Makefile -- build ctl_cow test # TARGET = ctl_cow OBJS = ctl_cow.o LIBPMEMBLK=y LIBPMEMLOG=y LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/ctl_cow/TEST0.PS10000664000000000000000000000166014123364546015625 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/TEST0 -- unit test which check copy on write feature # for obj pools . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\testfile" $REPLICA="$DIR\testfile_replica" $POOLSET="$DIR\pool0.set" create_poolset $POOLSET ` 32M:$DIR\testfile:z ` R ` 32M:$DIR\testfile_replica:z expect_normal_exit $PMEMPOOL create obj $POOLSET $POOL_BEFORE = $(Get-FileHash $POOL).hash $REPLICA_BEFORE = $(Get-FileHash $REPLICA).hash $Env:PMEMOBJ_CONF += "copy_on_write.at_open=1" expect_normal_exit $Env:EXE_DIR\ctl_cow$Env:EXESUFFIX $POOLSET obj $POOL_AFTER = $(Get-FileHash $POOL).hash $REPLICA_AFTER = $(Get-FileHash $REPLICA).hash if ($POOLSET_BEFORE -ne $POOLSET_AFTER -Or $REPLICA_BEFORE -ne $REPLICA_AFTER) { fatal '$POOLSET_BEFORE -ne $POOLSET_AFTER -or $REPLICA_BEFORE -ne $REPLICA_AFTER' } check pass pmdk-1.11.1/src/test/ctl_cow/.gitignore0000664000000000000000000000001014123364546016415 0ustar rootrootctl_cow pmdk-1.11.1/src/test/ctl_cow/TEST10000775000000000000000000000120114123364546015216 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/TEST1 -- unit test which checks copy on writ feature # for log pool # . ../unittest/unittest.sh require_test_type medium require_command md5sum setup POOL="testfile.log" expect_normal_exit $PMEMPOOL$EXESUFFIX create -s 32MB log $DIR/$POOL POOL_BEFORE=`md5sum -b $DIR/$POOL` PMEMLOG_CONF="${PMEMLOG_CONF}copy_on_write.at_open=1" expect_normal_exit ./ctl_cow$EXESUFFIX $DIR/$POOL log POOL_AFTER=`md5sum -b $DIR/$POOL` if [ "$POOL_BEFORE" != "$POOL_AFTER" ] then fatal "$POOL_BEFORE != $POOL_AFTER" fi check pass pmdk-1.11.1/src/test/ctl_cow/ctl_cow.vcxproj0000664000000000000000000000766414123364546017522 0ustar rootroot Debug x64 Release x64 {46B82069-10BE-432A-8D93-F4D995148555} Win32Proj obj_cow 10.0.17134.0 Application true v140 Application false v140 true Disabled CompileAsCpp MaxSpeed CompileAsCpp {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/ctl_cow/ctl_cow.vcxproj.filters0000664000000000000000000000133614123364546021157 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {244ffb2d-f113-414d-87ac-b65de5ad9d3d} Test scripts Source Files pmdk-1.11.1/src/test/ctl_cow/TEST20000775000000000000000000000120514123364546015223 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ctl_cow/TEST2 -- unit test which checks copy on writ feature # for blk pool # . ../unittest/unittest.sh require_test_type medium require_command md5sum setup POOL="testfile.blk" expect_normal_exit $PMEMPOOL$EXESUFFIX create -s 32MB blk 512 $DIR/$POOL POOL_BEFORE=`md5sum -b $DIR/$POOL` PMEMBLK_CONF="${PMEMBLK_CONF}copy_on_write.at_open=1" expect_normal_exit ./ctl_cow$EXESUFFIX $DIR/$POOL blk POOL_AFTER=`md5sum -b $DIR/$POOL` if [ "$POOL_BEFORE" != "$POOL_AFTER" ] then fatal "$POOL_BEFORE != $POOL_AFTER" fi check pass pmdk-1.11.1/src/test/obj_many_size_allocs/0000775000000000000000000000000014123364546017171 5ustar rootrootpmdk-1.11.1/src/test/obj_many_size_allocs/obj_many_size_allocs.vcxproj.filters0000664000000000000000000000256314123364546026450 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {3e13102a-da5c-4b4b-8adb-1d0cc202a313} ps1 {84c8cfa5-2569-4849-8f92-f8fb703837c0} match Source Files Match Files Match Files Test Scripts Test Scripts Test Scripts Match Files pmdk-1.11.1/src/test/obj_many_size_allocs/TEST1.PS10000664000000000000000000000367514123364546020371 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ..\unittest\unittest.ps1 require_test_type long setup # limit number of emitted logs due to excessive log size $Env:PMEMOBJ_LOG_LEVEL=2 create_poolset $DIR\testset1 16M:$DIR\testfile1 16M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\obj_many_size_allocs$Env:EXESUFFIX $DIR\testset1 check pass pmdk-1.11.1/src/test/obj_many_size_allocs/obj_many_size_allocs.vcxproj0000664000000000000000000000764414123364546025006 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {5D362DB7-D2BD-4907-AAD8-4B8627E72282} Win32Proj obj_many_size_allocs 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_many_size_allocs/TEST30000775000000000000000000000375514123364546017773 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type long configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup # limit number of emitted logs due to excessive log size export PMEMOBJ_LOG_LEVEL=2 create_holey_file 16M $DIR/testfile1 expect_normal_exit\ ./obj_many_size_allocs$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_many_size_allocs/TEST00000775000000000000000000000374714123364546017771 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh # covered by TEST3 configure_valgrind memcheck force-disable require_test_type long setup # limit number of emitted logs due to excessive log size export PMEMOBJ_LOG_LEVEL=2 create_holey_file 16M $DIR/testfile1 expect_normal_exit\ ./obj_many_size_allocs$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_many_size_allocs/Makefile0000664000000000000000000000042214123364546020627 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_many_size_allocs/Makefile -- build obj_many_size_allocs test # TARGET = obj_many_size_allocs OBJS = obj_many_size_allocs.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_many_size_allocs/TEST2.PS10000664000000000000000000000404514123364546020362 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ..\unittest\unittest.ps1 require_test_type long setup # limit number of emitted logs due to excessive log size $Env:PMEMOBJ_LOG_LEVEL=2 create_poolset $DIR\testset1 16M:$DIR\testfile1 r 16M:$DIR\testfile2 expect_normal_exit $Env:EXE_DIR\obj_many_size_allocs$Env:EXESUFFIX $DIR\testset1 compare_replicas "-soOaAbd -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_many_size_allocs/out0.log.match0000664000000000000000000000022014123364546021650 0ustar rootrootobj_many_size_allocs$(nW)TEST0: START: obj_many_size_allocs $(nW)obj_many_size_allocs$(nW) $(nW)testfile1 obj_many_size_allocs$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_many_size_allocs/TEST0.PS10000664000000000000000000000072214123364546020356 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/obj_many_size_allocs/TEST0 -- test for allocation of many # objects with different sizes # . ..\unittest\unittest.ps1 require_test_type long setup # limit number of emitted logs due to excessive log size $Env:PMEMOBJ_LOG_LEVEL=2 create_holey_file 16M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\obj_many_size_allocs$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_many_size_allocs/.gitignore0000664000000000000000000000002514123364546021156 0ustar rootrootobj_many_size_allocs pmdk-1.11.1/src/test/obj_many_size_allocs/obj_many_size_allocs.c0000664000000000000000000000542514123364546023530 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * obj_many_size_allocs.c -- allocation of many objects with different sizes * */ #include #include "unittest.h" #include "heap.h" #define LAYOUT_NAME "many_size_allocs" #define TEST_ALLOC_SIZE 2048 #define LAZY_LOAD_SIZE 10 #define LAZY_LOAD_BIG_SIZE 150 struct cargs { size_t size; }; static int test_constructor(PMEMobjpool *pop, void *addr, void *args) { struct cargs *a = args; /* do not use pmem_memset_persit() here */ pmemobj_memset_persist(pop, addr, a->size % 256, a->size); return 0; } static PMEMobjpool * test_allocs(PMEMobjpool *pop, const char *path) { PMEMoid *oid = MALLOC(sizeof(PMEMoid) * TEST_ALLOC_SIZE); if (pmemobj_alloc(pop, &oid[0], 0, 0, NULL, NULL) == 0) UT_FATAL("pmemobj_alloc(0) succeeded"); for (unsigned i = 1; i < TEST_ALLOC_SIZE; ++i) { struct cargs args = { i }; if (pmemobj_alloc(pop, &oid[i], i, 0, test_constructor, &args) != 0) UT_FATAL("!pmemobj_alloc"); UT_ASSERT(!OID_IS_NULL(oid[i])); } pmemobj_close(pop); UT_ASSERT(pmemobj_check(path, LAYOUT_NAME) == 1); UT_ASSERT((pop = pmemobj_open(path, LAYOUT_NAME)) != NULL); for (int i = 1; i < TEST_ALLOC_SIZE; ++i) { pmemobj_free(&oid[i]); UT_ASSERT(OID_IS_NULL(oid[i])); } FREE(oid); return pop; } static PMEMobjpool * test_lazy_load(PMEMobjpool *pop, const char *path) { PMEMoid oid[3]; int ret = pmemobj_alloc(pop, &oid[0], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, &oid[1], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, &oid[2], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); pmemobj_close(pop); UT_ASSERT((pop = pmemobj_open(path, LAYOUT_NAME)) != NULL); pmemobj_free(&oid[1]); ret = pmemobj_alloc(pop, &oid[1], LAZY_LOAD_BIG_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); return pop; } #define ALLOC_BLOCK_SIZE 64 #define MAX_BUCKET_MAP_ENTRIES (RUN_DEFAULT_SIZE / ALLOC_BLOCK_SIZE) static void test_all_classes(PMEMobjpool *pop) { for (unsigned i = 1; i <= MAX_BUCKET_MAP_ENTRIES; ++i) { int err; int nallocs = 0; while ((err = pmemobj_alloc(pop, NULL, i * ALLOC_BLOCK_SIZE, 0, NULL, NULL)) == 0) { nallocs++; } UT_ASSERT(nallocs > 0); PMEMoid iter, niter; POBJ_FOREACH_SAFE(pop, iter, niter) { pmemobj_free(&iter); } } } int main(int argc, char *argv[]) { START(argc, argv, "obj_many_size_allocs"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); pop = test_lazy_load(pop, path); pop = test_allocs(pop, path); test_all_classes(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_many_size_allocs/TEST10000775000000000000000000000061214123364546017756 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type long setup # limit number of emitted logs due to excessive log size export PMEMOBJ_LOG_LEVEL=2 create_poolset $DIR/testset1 16M:$DIR/testfile1 16M:$DIR/testfile2 expect_normal_exit\ ./obj_many_size_allocs$EXESUFFIX $DIR/testset1 check pass pmdk-1.11.1/src/test/obj_many_size_allocs/diff2.log.match0000664000000000000000000000000014123364546021747 0ustar rootrootpmdk-1.11.1/src/test/obj_many_size_allocs/out1.log.match0000664000000000000000000000021714123364546021657 0ustar rootrootobj_many_size_allocs$(nW)TEST1: START: obj_many_size_allocs $(nW)obj_many_size_allocs$(nW) $(nW)testset1 obj_many_size_allocs$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_many_size_allocs/TEST20000775000000000000000000000075614123364546017770 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type long setup # limit number of emitted logs due to excessive log size export PMEMOBJ_LOG_LEVEL=2 create_poolset $DIR/testset1 16M:$DIR/testfile1 r 16M:$DIR/testfile2 expect_normal_exit\ ./obj_many_size_allocs$EXESUFFIX $DIR/testset1 compare_replicas "-soOaAbd -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_many_size_allocs/out2.log.match0000664000000000000000000000021714123364546021660 0ustar rootrootobj_many_size_allocs$(nW)TEST2: START: obj_many_size_allocs $(nW)obj_many_size_allocs$(nW) $(nW)testset1 obj_many_size_allocs$(nW)TEST2: DONE pmdk-1.11.1/src/test/pmem_memset/0000775000000000000000000000000014123364546015314 5ustar rootrootpmdk-1.11.1/src/test/pmem_memset/pmem_memset.c0000664000000000000000000000467414123364546020003 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * pmem_memset.c -- unit test for doing a memset * * usage: pmem_memset file offset length */ #include "unittest.h" #include "util_pmem.h" #include "file.h" #include "memset_common.h" typedef void *pmem_memset_fn(void *pmemdest, int c, size_t len, unsigned flags); static void * pmem_memset_persist_wrapper(void *pmemdest, int c, size_t len, unsigned flags) { (void) flags; return pmem_memset_persist(pmemdest, c, len); } static void * pmem_memset_nodrain_wrapper(void *pmemdest, int c, size_t len, unsigned flags) { (void) flags; return pmem_memset_nodrain(pmemdest, c, len); } static void do_memset_variants(int fd, char *dest, const char *file_name, size_t dest_off, size_t bytes, persist_fn p) { do_memset(fd, dest, file_name, dest_off, bytes, pmem_memset_persist_wrapper, 0, p, NULL, NULL, NULL); do_memset(fd, dest, file_name, dest_off, bytes, pmem_memset_nodrain_wrapper, 0, p, NULL, NULL, NULL); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memset(fd, dest, file_name, dest_off, bytes, pmem_memset, Flags[i], p, NULL, NULL, NULL); if (Flags[i] & PMEMOBJ_F_MEM_NOFLUSH) pmem_persist(dest, bytes); } } static void do_persist_ddax(const void *ptr, size_t size) { util_persist_auto(1, ptr, size); } static void do_persist(const void *ptr, size_t size) { util_persist_auto(0, ptr, size); } int main(int argc, char *argv[]) { int fd; size_t mapped_len; char *dest; if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem_memset %s %s %s %savx %savx512f", argv[2], argv[3], thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); /* open a pmem file and memory map it */ if ((dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL)) == NULL) UT_FATAL("!Could not mmap %s\n", argv[1]); size_t dest_off = strtoul(argv[2], NULL, 0); size_t bytes = strtoul(argv[3], NULL, 0); enum file_type type = util_fd_get_type(fd); if (type < 0) UT_FATAL("cannot check type of file with fd %d", fd); persist_fn p; p = type == TYPE_DEVDAX ? do_persist_ddax : do_persist; do_memset_variants(fd, dest, argv[1], dest_off, bytes, p); UT_ASSERTeq(pmem_unmap(dest, mapped_len), 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem_memset/pmem_memset.vcxproj.filters0000664000000000000000000000214014123364546022705 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c1e5339d-4634-448b-aefc-9b1f077f111e} {7a11237b-94e7-4ee9-beba-b5b9ab50f43e} Source Files Source Files Test scripts Header Files pmdk-1.11.1/src/test/pmem_memset/TEST00000775000000000000000000000112314123364546016076 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_memset/TEST0 -- unit test for pmem_memset # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup function test() { rm -f $DIR/testfile1 truncate -s 4M $DIR/testfile1 expect_normal_exit ./pmem_memset$EXESUFFIX $DIR/testfile1 $@ } function test_all() { test 0 8 test 13 4096 } test_all export PMEM_AVX512F=0 test_all export PMEM_AVX=0 test_all export PMEM_NO_MOVNT=1 test_all export PMEM_NO_GENERIC_MEMCPY=1 test_all pass pmdk-1.11.1/src/test/pmem_memset/Makefile0000664000000000000000000000054614123364546016761 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_memset/Makefile -- build pmem_memset unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/pmem2_memset TARGET = pmem_memset OBJS = pmem_memset.o\ memset_common.o LIBPMEM=y LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -I$(TOP)/src/test/pmem2_memset pmdk-1.11.1/src/test/pmem_memset/TEST0.PS10000664000000000000000000000113314123364546016476 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2020, Intel Corporation # # src/test/pmem_memset/TEST0 -- unit test for pmem_memset # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup function test { remove_files $DIR\testfile1 create_holey_file 4M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\pmem_memset$Env:EXESUFFIX $DIR\testfile1 $args } function test_all { test 0 8 test 13 4096 } test_all $Env:PMEM_AVX512F = 0 test_all $Env:PMEM_AVX = 0 test_all $Env:PMEM_NO_MOVNT = 1 test_all $Env:PMEM_NO_GENERIC_MEMCPY = 1 test_all pass pmdk-1.11.1/src/test/pmem_memset/.gitignore0000664000000000000000000000001414123364546017277 0ustar rootrootpmem_memset pmdk-1.11.1/src/test/pmem_memset/README0000664000000000000000000000143414123364546016176 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_memset/README. This directory contains a unit test for pmem_memset(). SYNOPSIS: pmem_memset file offset length DESCRIPTION: pmem_memset is the unit test for verifying the functionality of memset for persistent storage using non-temporal instructions. OPTIONS: file is $DIR/testfile1 in all cases. offset: Is number of bytes for destination address offset based on a 64 byte boundary. length: Is the length specified in bytes. Cannot be less than 4. In all cases it calls pmem_memset_persist with first a Z character and sets 1/4 of the length specified in the destination location. It repeats this with an F character. The file is read after processing the memcmp and a read of the file to ensure contains the correct values. pmdk-1.11.1/src/test/pmem_memset/pmem_memset.vcxproj0000664000000000000000000000771214123364546021250 0ustar rootroot Debug x64 Release x64 {B36F115C-8139-4C35-A3E7-E6BF9F3DA793} Win32Proj pmem_memset 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\test\pmem2_memset;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\test\pmem2_memset;%(AdditionalIncludeDirectories) {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_oid_thread/0000775000000000000000000000000014123364546015740 5ustar rootrootpmdk-1.11.1/src/test/obj_oid_thread/obj_oid_thread.vcxproj.filters0000664000000000000000000000123314123364546023757 0ustar rootroot {345974e1-6ab8-48ee-bb89-c8351d31e02b} {70ce3522-b530-465b-af08-68b974cee5bb} Test Scripts Source Files pmdk-1.11.1/src/test/obj_oid_thread/TEST00000775000000000000000000000046314123364546016530 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_oid_thread/TEST0 -- unit test for pmemobj_oid # . ../unittest/unittest.sh require_fs_type any require_test_type medium setup expect_normal_exit ./obj_oid_thread$EXESUFFIX $DIR 9 pass pmdk-1.11.1/src/test/obj_oid_thread/Makefile0000664000000000000000000000041714123364546017402 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_oid_thread/Makefile -- build obj_oid_thread unit test # TARGET = obj_oid_thread OBJS = obj_oid_thread.o LIBPMEMOBJ=y include ../Makefile.inc INCS += -I../../libpmemobj/ pmdk-1.11.1/src/test/obj_oid_thread/TEST0.PS10000775000000000000000000000045714123364546017135 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_oid_thread/TEST0 -- unit test for pmemobj_oid # . ..\unittest\unittest.ps1 require_fs_type any require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_oid_thread$Env:EXESUFFIX $DIR 9 pass pmdk-1.11.1/src/test/obj_oid_thread/.gitignore0000664000000000000000000000001714123364546017726 0ustar rootrootobj_oid_thread pmdk-1.11.1/src/test/obj_oid_thread/obj_oid_thread.c0000664000000000000000000000616214123364546021045 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_oid_thread.c -- unit test for the reverse direct operation */ #include "unittest.h" #include "lane.h" #include "obj.h" #include "sys_util.h" #define MAX_PATH_LEN 255 #define LAYOUT_NAME "direct" static os_mutex_t lock; static os_cond_t cond; static int flag = 1; static PMEMoid thread_oid; /* * test_worker -- (internal) test worker thread */ static void * test_worker(void *arg) { util_mutex_lock(&lock); /* before pool is closed */ void *direct = pmemobj_direct(thread_oid); UT_ASSERT(OID_EQUALS(thread_oid, pmemobj_oid(direct))); flag = 0; os_cond_signal(&cond); util_mutex_unlock(&lock); util_mutex_lock(&lock); while (flag == 0) os_cond_wait(&cond, &lock); /* after pool is closed */ UT_ASSERT(OID_IS_NULL(pmemobj_oid(direct))); util_mutex_unlock(&lock); return NULL; } int main(int argc, char *argv[]) { START(argc, argv, "obj_oid_thread"); if (argc != 3) UT_FATAL("usage: %s [directory] [# of pools]", argv[0]); util_mutex_init(&lock); util_cond_init(&cond); unsigned npools = ATOU(argv[2]); const char *dir = argv[1]; int r; PMEMobjpool **pops = MALLOC(npools * sizeof(PMEMoid *)); size_t length = strlen(dir) + MAX_PATH_LEN; char *path = MALLOC(length); for (unsigned i = 0; i < npools; ++i) { int ret = snprintf(path, length, "%s"OS_DIR_SEP_STR"testfile%d", dir, i); if (ret < 0 || ret >= length) UT_FATAL("snprintf: %d", ret); pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (pops[i] == NULL) UT_FATAL("!pmemobj_create"); } /* Address outside the pmemobj pool */ void *allocated_memory = MALLOC(sizeof(int)); UT_ASSERT(OID_IS_NULL(pmemobj_oid(allocated_memory))); PMEMoid *oids = MALLOC(npools * sizeof(PMEMoid)); PMEMoid *tmpoids = MALLOC(npools * sizeof(PMEMoid)); UT_ASSERT(OID_IS_NULL(pmemobj_oid(NULL))); oids[0] = OID_NULL; for (unsigned i = 0; i < npools; ++i) { uint64_t off = pops[i]->heap_offset; oids[i] = (PMEMoid) {pops[i]->uuid_lo, off}; UT_ASSERT(OID_EQUALS(oids[i], pmemobj_oid(pmemobj_direct(oids[i])))); r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL); UT_ASSERTeq(r, 0); UT_ASSERT(OID_EQUALS(tmpoids[i], pmemobj_oid(pmemobj_direct(tmpoids[i])))); } r = pmemobj_alloc(pops[0], &thread_oid, 100, 2, NULL, NULL); UT_ASSERTeq(r, 0); UT_ASSERT(!OID_IS_NULL(pmemobj_oid(pmemobj_direct(thread_oid)))); util_mutex_lock(&lock); os_thread_t t; THREAD_CREATE(&t, NULL, test_worker, NULL); /* wait for the thread to perform the first direct */ while (flag != 0) os_cond_wait(&cond, &lock); for (unsigned i = 0; i < npools; ++i) { pmemobj_free(&tmpoids[i]); UT_ASSERT(OID_IS_NULL(pmemobj_oid( pmemobj_direct(tmpoids[i])))); pmemobj_close(pops[i]); UT_ASSERT(OID_IS_NULL(pmemobj_oid( pmemobj_direct(oids[i])))); } /* signal the waiting thread */ flag = 1; os_cond_signal(&cond); util_mutex_unlock(&lock); THREAD_JOIN(&t, NULL); FREE(path); FREE(tmpoids); FREE(oids); FREE(pops); FREE(allocated_memory); util_mutex_destroy(&lock); util_cond_destroy(&cond); DONE(NULL); } pmdk-1.11.1/src/test/obj_oid_thread/obj_oid_thread.vcxproj0000664000000000000000000000760714123364546022323 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {8C6D73E0-0A6F-4487-A040-0EC78D7D6D9A} Win32Proj obj_oid_thread 10.0.17134.0 obj_oid_thread Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/0000775000000000000000000000000014123364546016637 5ustar rootrootpmdk-1.11.1/src/test/obj_pmalloc_oom_mt/obj_pmalloc_oom_mt.c0000664000000000000000000000220114123364546022631 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_pmalloc_oom_mt.c -- build multithreaded out of memory test * */ #include #include "unittest.h" #define TEST_ALLOC_SIZE (32 * 1024) #define LAYOUT_NAME "oom_mt" static int allocated; static PMEMobjpool *pop; static void * oom_worker(void *arg) { allocated = 0; while (pmemobj_alloc(pop, NULL, TEST_ALLOC_SIZE, 0, NULL, NULL) == 0) allocated++; PMEMoid iter, iter2; POBJ_FOREACH_SAFE(pop, iter, iter2) pmemobj_free(&iter); return NULL; } int main(int argc, char *argv[]) { START(argc, argv, "obj_pmalloc_oom_mt"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); os_thread_t t; THREAD_CREATE(&t, NULL, oom_worker, NULL); THREAD_JOIN(&t, NULL); int first_thread_allocated = allocated; THREAD_CREATE(&t, NULL, oom_worker, NULL); THREAD_JOIN(&t, NULL); UT_ASSERTeq(first_thread_allocated, allocated); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/TEST00000775000000000000000000000040614123364546017424 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium setup export PMEM_IS_PMEM_FORCE=1 expect_normal_exit ./obj_pmalloc_oom_mt$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/Makefile0000664000000000000000000000037514123364546020304 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_oom_mt/Makefile -- build obj_pmalloc_oom_mt test # TARGET = obj_pmalloc_oom_mt OBJS = obj_pmalloc_oom_mt.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/TEST0.PS10000664000000000000000000000051314123364546020022 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_oom_mt/TEST0 -- unit test for pmalloc interface # . ..\unittest\unittest.ps1 require_test_type medium setup $Env:PMEM_IS_PMEM_FORCE=1 expect_normal_exit $Env:EXE_DIR\obj_pmalloc_oom_mt$Env:EXESUFFIX $DIR\testfile pass pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/obj_pmalloc_oom_mt.vcxproj.filters0000664000000000000000000000135014123364546025555 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {f72994aa-3255-41a1-a95c-37d6e2e0fdaa} Source Files Test Scripts pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/.gitignore0000664000000000000000000000002314123364546020622 0ustar rootrootobj_pmalloc_oom_mt pmdk-1.11.1/src/test/obj_pmalloc_oom_mt/obj_pmalloc_oom_mt.vcxproj0000664000000000000000000000704514123364546024115 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {88D239E4-EB7D-4E0A-BE3A-AD78B9F408FC} Win32Proj obj_pmalloc_oom_mt 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/libpmempool_sync_win/0000775000000000000000000000000014123364546017234 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_sync_win/TEST1.PS10000664000000000000000000000373514123364546020431 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_sync_win/TEST1.PS1 -- test for checking replica sync # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:SUFFIX}" $POOLSET = "$DIR\pool0.set" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile1:x ` 20M:$DIR\testfile2:x ` 21M:$DIR\testfile3:x ` R ` 40M:$DIR\testfile4:x ` 20M:$DIR\testfile5:x # CLI script for writing some data hitting all the parts $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 55M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from all the parts $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 srpr 40M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Write some data into the pool, hitting three part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP # Delete the second part in the primary replica rm $DIR\testfile2 -Force -ea si # Synchronize replicas $FLAGS = "0" expect_normal_exit $Env:EXE_DIR\libpmempool_sync_win$Env:EXESUFFIX ` $POOLSET $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly synchronized expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_sync_win/libpmempool_sync_win.c0000664000000000000000000000113214123364546023625 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * libpmempool_sync_win -- a unittest for libpmempool sync. * */ #include #include #include #include #include "unittest.h" int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "libpmempool_sync_win"); if (argc != 3) UT_FATAL("usage: %s poolset_file flags", ut_toUTF8(argv[0])); int ret = pmempool_syncW(argv[1], (unsigned)wcstoul(argv[2], NULL, 0)); if (ret) UT_OUT("result: %d, errno: %d", ret, errno); else UT_OUT("result: 0"); DONEW(NULL); } pmdk-1.11.1/src/test/libpmempool_sync_win/libpmempool_sync_win.vcxproj0000664000000000000000000000744614123364546025114 0ustar rootroot Debug x64 Release x64 {B6DA6617-D98F-4A4D-A7C4-A317212924BF} Win32Proj libpmempool_sync_win 10.0.17134.0 Application true v140 Application false v140 true false true {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_sync_win/TEST2.PS10000664000000000000000000000250414123364546020423 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_sync_win/TEST2.PS1 -- test for checking replica sync # check if flags are supported # pmem/issues#367 # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:SUFFIX}" $POOLSET = "$DIR\poolset" # Create poolset file create_poolset $POOLSET ` 10M:$DIR\part00:x ` r ` 10M:$DIR\part10:x # Create a pool expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Delete a part from the second replica rm $DIR\part10 -Force -ea si # Try to synchronize replicas $FLAGS = "32" # invalid flag expect_normal_exit $Env:EXE_DIR\libpmempool_sync_win$Env:EXESUFFIX ` $POOLSET $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP $FLAGS = "1024" expect_normal_exit $Env:EXE_DIR\libpmempool_sync_win$Env:EXESUFFIX ` $POOLSET $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_sync_win/out0.log.match0000664000000000000000000000043614123364546021724 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 Wrong1234 Wrong5678 Wrong9ABC libpmempool_sync_win$(nW)TEST0: START: libpmempool_sync_win$(nW) $(nW)libpmempool_sync_win$(nW) $(nW)pool0.set 0 result: 0 libpmempool_sync_win$(nW)TEST0: DONE TestOK111 Wrong5678 Wrong9ABC pmdk-1.11.1/src/test/libpmempool_sync_win/TEST0.PS10000664000000000000000000000631114123364546020421 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_sync_win/TEST0.PS1 -- test for checking replica sync # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $LAYOUT = "OBJ_LAYOUT${Env:SUFFIX}" $POOLSET = "$DIR\pool0.set" $M = 1024 * 1024 $M20 = 20 * $M $M40 = 40 * $M $MMAP_ALIGN = "65536" $ADDR_MASK = "0xFFFF0000" # Create poolset file create_poolset $POOLSET ` 20M:$DIR\testfile1:x ` 20M:$DIR\testfile2:x ` 21M:$DIR\testfile3:x ` R ` 40M:$DIR\testfile4:x ` 20M:$DIR\testfile5:x expect_normal_exit $PMEMPOOL create --layout=$LAYOUT obj $POOLSET cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # CLI script for writing some data at 0, 20 and 40 MB $WRITE_SCRIPT = "$DIR\write_data" echo @" pr 55M srcp 0 TestOK111 srcp 20M TestOK222 srcp 40M TestOK333 "@ | out-file -encoding ASCII -literalpath $WRITE_SCRIPT # CLI script for reading 9 characters from 0, 20 and 40 MB offset $READ_SCRIPT = "$DIR\read_data" echo @" srpr 0 9 srpr 20M 9 srpr 40M 9 "@ | out-file -encoding ASCII -literalpath $READ_SCRIPT # Write some data into the pool, hitting three part files expect_normal_exit $PMEMOBJCLI -s $WRITE_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly written expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP # Find root offset $TMP_FILE = "$DIR\obj_info" expect_normal_exit $PMEMPOOL info -f obj -o $DIR\testfile1 | out-file -encoding ascii -literalpath $TMP_FILE $ROOT_ADDR = (Get-Content $TMP_FILE | Select-String -pattern "Root offset").ToString().Split(':')[1] # Calculate offsets from the root object start to hit each part file $PART1_FILE_SIZE = (Get-Item "$DIR\testfile1").length $PART1_SIZE = ($PART1_FILE_SIZE -band $ADDR_MASK) - $ROOT_ADDR $PART2_OFFSET = $M20 - $PART1_SIZE + $MMAP_ALIGN $PART2_FILE_SIZE = (Get-Item "$DIR\testfile2").length $PART2_SIZE = ($PART2_FILE_SIZE -band $ADDR_MASK) - $MMAP_ALIGN $PART3_OFFSET = $M40 - ($PART1_SIZE + $PART2_SIZE) + $MMAP_ALIGN # Corrupt data in primary replica expect_normal_exit $DDMAP -o "$DIR\testfile1" -s $ROOT_ADDR -d "Wrong1234" expect_normal_exit $DDMAP -o "$DIR\testfile2" -s $PART2_OFFSET -d "Wrong5678" expect_normal_exit $DDMAP -o "$DIR\testfile3" -s $PART3_OFFSET -d "Wrong9ABC" # Check if corrupted expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP # Corrupt metadata in primary replica expect_normal_exit $PMEMSPOIL $DIR\testfile1 "pool_hdr.uuid=0000000000000000" ` | out-file -append -encoding ascii -literalpath $LOG_TEMP # Synchronize replicas $FLAGS = "0" expect_normal_exit $Env:EXE_DIR\libpmempool_sync_win$Env:EXESUFFIX ` $POOLSET $FLAGS cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP # Check if correctly copied expect_normal_exit $PMEMOBJCLI -s $READ_SCRIPT $POOLSET | out-file -append -encoding ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_sync_win/README0000664000000000000000000000035314123364546020115 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_sync_win/README. This directory contains unit tests for libpmempool sync. The tests check if poolset gets recovered after deleting a part or damaging metadata of a part. pmdk-1.11.1/src/test/libpmempool_sync_win/libpmempool_sync_win.vcxproj.filters0000664000000000000000000000233114123364546026547 0ustar rootroot {00ea41a3-46b4-4dd3-9b61-f15c100691db} {61f97184-f737-410f-a9c6-265f801213f0} {8db6e2e6-ab20-4ab6-81b4-332d7fb2dc22} Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Source Files pmdk-1.11.1/src/test/libpmempool_sync_win/out1.log.match0000664000000000000000000000040014123364546021714 0ustar rootrootpr($(N)): off = $(nW) uuid = $(nW) TestOK111 TestOK222 TestOK333 libpmempool_sync_win$(nW)TEST1: START: libpmempool_sync_win$(nW) $(nW)libpmempool_sync_win$(nW) $(nW)pool0.set 0 result: 0 libpmempool_sync_win$(nW)TEST1: DONE TestOK111 TestOK222 TestOK333 pmdk-1.11.1/src/test/libpmempool_sync_win/out2.log.match0000664000000000000000000000053214123364546021723 0ustar rootrootlibpmempool_sync_win$(nW)TEST2: START: libpmempool_sync_win$(nW) $(nW)libpmempool_sync_win$(nW) $(nW)poolset 32 result: -1, errno: 22 libpmempool_sync_win$(nW)TEST2: DONE libpmempool_sync_win$(nW)TEST2: START: libpmempool_sync_win$(nW) $(nW)libpmempool_sync_win$(nW) $(nW)poolset 1024 result: -1, errno: 22 libpmempool_sync_win$(nW)TEST2: DONE pmdk-1.11.1/src/test/util_uuid_generate/0000775000000000000000000000000014123364546016661 5ustar rootrootpmdk-1.11.1/src/test/util_uuid_generate/util_uuid_generate.vcxproj0000664000000000000000000000671014123364546024157 0ustar rootroot Debug x64 Release x64 {9A4078F8-B8E4-4EC6-A6FF-4F29DAD9CE48} Win32Proj util_uuid_generate 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_uuid_generate/TEST1.PS10000664000000000000000000000061414123364546020047 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST1 -- unit test for util_uuid_generate. # Valid uuid string specified. . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_uuid_generate$Env:EXESUFFIX ` 563bb872-0d1d-441e-ac28-579c463be0a5 valid check pass pmdk-1.11.1/src/test/util_uuid_generate/TEST00000775000000000000000000000054514123364546017452 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST0 -- unit test for util_uuid_generate. # No uuid string specified. # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem setup expect_normal_exit ./util_uuid_generate$EXESUFFIX check pass pmdk-1.11.1/src/test/util_uuid_generate/Makefile0000664000000000000000000000037014123364546020321 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/util_uuid_generate/Makefile -- create a uuid and verify it # TARGET = util_uuid_generate OBJS = util_uuid_generate.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_uuid_generate/TEST2.PS10000664000000000000000000000056214123364546020052 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST2 -- unit test for util_uuid_generate. # Invalid uuid string provided. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_uuid_generate$Env:EXESUFFIX ` sarah invalid check pass pmdk-1.11.1/src/test/util_uuid_generate/out0.log.match0000664000000000000000000000017114123364546021345 0ustar rootrootutil_uuid_generate$(nW)TEST0: START: util_uuid_generate $(nW)util_uuid_generate$(nW) util_uuid_generate$(nW)TEST0: DONE pmdk-1.11.1/src/test/util_uuid_generate/TEST0.PS10000664000000000000000000000052614123364546020050 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST0 -- unit test for util_uuid_generate. # No uuid string specified. # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_uuid_generate$Env:EXESUFFIX pass pmdk-1.11.1/src/test/util_uuid_generate/util_uuid_generate.vcxproj.filters0000664000000000000000000000240214123364546025620 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c3984bd3-64bd-4066-a821-51fab725916b} {b49cf0e6-5c4f-470f-9c7e-939b1da9bda7} Source Files Test scripts Test scripts Test scripts Match Files Match Files Match Files pmdk-1.11.1/src/test/util_uuid_generate/.gitignore0000664000000000000000000000002314123364546020644 0ustar rootrootutil_uuid_generate pmdk-1.11.1/src/test/util_uuid_generate/util_uuid_generate.c0000664000000000000000000000353514123364546022710 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * util_uuid_generate.c -- unit test for generating a uuid * * usage: util_uuid_generate [string] [valid|invalid] */ #include "unittest.h" #include "uuid.h" #include #include int main(int argc, char *argv[]) { START(argc, argv, "util_uuid_generate"); uuid_t uuid; uuid_t uuid1; int ret; char conv_uu[POOL_HDR_UUID_STR_LEN]; char uu[POOL_HDR_UUID_STR_LEN]; /* * No string passed in. Generate uuid. */ if (argc == 1) { /* generate a UUID string */ ret = ut_get_uuid_str(uu); UT_ASSERTeq(ret, 0); /* * Convert the string to a uuid, convert generated * uuid back to a string and compare strings. */ ret = util_uuid_from_string(uu, (struct uuid *)&uuid); UT_ASSERTeq(ret, 0); ret = util_uuid_to_string(uuid, conv_uu); UT_ASSERTeq(ret, 0); UT_ASSERT(strncmp(uu, conv_uu, POOL_HDR_UUID_STR_LEN) == 0); /* * Generate uuid from util_uuid_generate and translate to * string then back to uuid to verify they match. */ memset(uuid, 0, sizeof(uuid_t)); memset(uu, 0, POOL_HDR_UUID_STR_LEN); memset(conv_uu, 0, POOL_HDR_UUID_STR_LEN); ret = util_uuid_generate(uuid); UT_ASSERTeq(ret, 0); ret = util_uuid_to_string(uuid, uu); UT_ASSERTeq(ret, 0); ret = util_uuid_from_string(uu, (struct uuid *)&uuid1); UT_ASSERTeq(ret, 0); UT_ASSERT(memcmp(&uuid, &uuid1, sizeof(uuid_t)) == 0); } else { /* * Caller passed in string. */ if (strcmp(argv[2], "valid") == 0) { ret = util_uuid_from_string(argv[1], (struct uuid *)&uuid); UT_ASSERTeq(ret, 0); ret = util_uuid_to_string(uuid, conv_uu); UT_ASSERTeq(ret, 0); } else { ret = util_uuid_from_string(argv[1], (struct uuid *)&uuid); UT_ASSERT(ret < 0); UT_OUT("util_uuid_generate: invalid uuid string"); } } DONE(NULL); } pmdk-1.11.1/src/test/util_uuid_generate/TEST10000775000000000000000000000065214123364546017452 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST1 -- unit test for util_uuid_generate. # Valid uuid string specified. # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem setup # valid uuid string expect_normal_exit ./util_uuid_generate$EXESUFFIX \ 563bb872-0d1d-441e-ac28-579c463be0a5 valid check pass pmdk-1.11.1/src/test/util_uuid_generate/out1.log.match0000664000000000000000000000024414123364546021347 0ustar rootrootutil_uuid_generate$(nW)TEST1: START: util_uuid_generate $(nW)util_uuid_generate$(nW) 563bb872-0d1d-441e-ac28-579c463be0a5 valid util_uuid_generate$(nW)TEST1: DONE pmdk-1.11.1/src/test/util_uuid_generate/TEST20000775000000000000000000000056714123364546017460 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_uuid_generate/TEST2 -- unit test for util_uuid_generate. # Invalid uuid string provided. # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem setup expect_normal_exit ./util_uuid_generate$EXESUFFIX sarah invalid check pass pmdk-1.11.1/src/test/util_uuid_generate/out2.log.match0000664000000000000000000000025714123364546021354 0ustar rootrootutil_uuid_generate$(nW)TEST2: START: util_uuid_generate $(nW)util_uuid_generate$(nW) sarah invalid util_uuid_generate: invalid uuid string util_uuid_generate$(nW)TEST2: DONE pmdk-1.11.1/src/test/libpmempool_backup/0000775000000000000000000000000014123364546016650 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_backup/TEST7.PS10000664000000000000000000000146114123364546020045 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST7 -- test backup to pool which already exists # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup $POOLFILE= -join("$DIR\pool.", $POOL_TYPES[$i]); rm $POOLFILE -Force -ea si # create source poolset expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] --size 20M $POOLFILE # create backup pool file truncate -s 20M $POOLFILE$BACKUP backup_and_compare $POOLFILE $POOL_TYPES[$i] # create too small backup pool file truncate -s 10M $POOLFILE$BACKUP backup_and_compare $POOLFILE $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST1.PS10000664000000000000000000000117214123364546020036 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST1 -- test non-existing backup poolset # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 4 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST5.PS10000664000000000000000000000125014123364546020037 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST5 -- test backup to poolset with different sizes of # parts than source poolset # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 6 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST30000775000000000000000000000122414123364546017437 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST3 -- test backup poolset with replica (invalid) # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 2 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/libpmempool_backup.vcxproj.filters0000664000000000000000000000364014123364546025603 0ustar rootroot {710964b0-ff4d-4979-bb64-ca7ece05c7d6} {9eb71f49-772e-405d-9409-87398e9ea0d7} Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/libpmempool_backup/TEST00000775000000000000000000000124014123364546017432 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST0 -- test simple backup scenario # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 1 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} "${POOL_CHECK_PARAMS[$i]}" done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/Makefile0000664000000000000000000000030614123364546020307 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/libpmempool_backup/Makefile -- build libpmempool_backup unittest # include ../libpmempool_api/Makefile.inc pmdk-1.11.1/src/test/libpmempool_backup/TEST3.PS10000664000000000000000000000120514123364546020035 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST3 -- test backup poolset with replica (invalid) # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 2 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST2.PS10000664000000000000000000000116414123364546020040 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST2 -- test empty backup poolset # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 5 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/common.PS10000664000000000000000000000612714123364546020473 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # # libpmempool_backup/common.PS1 -- functions for libpmempool_backup unittest # $POOLSET="$DIR\pool.set" $BACKUP="_backup" $REPLICA="_replica" $POOL_PART="$DIR\pool.part" $OUT="out$Env:UNITTEST_NUM.log" $OUT_TEMP="out$Env:UNITTEST_NUM_temp.log" $DIFF="diff$Env:UNITTEST_NUM.log" rm $DIFF, $OUT_TEMP -Force -ea si touch $DIFF $OUT_TEMP # params for blk, log and obj pools $POOL_TYPES=@( "blk", "log", "obj" ) $POOL_CREATE_PARAMS=@( @("--write-layout", "512"), "", @("--layout", "test_layout")) $POOL_CHECK_PARAMS=@( "-smgB", "-s", @("-soOaAbZH", "-l", "-C")) $POOL_OBJ=2 # create_poolset_variation -- create one from the tested poolset variation # usage: create_poolset_variation [] # function create_poolset_variation() { $sfx="" $variation=$args[0] if($args.Count -gt 1 ) { $sfx=$args[1] } switch($variation) { 1 { # valid poolset file create_poolset $POOLSET$sfx ` 20M:${POOL_PART}1$sfx`:x ` 20M:${POOL_PART}2$sfx`:x ` 20M:${POOL_PART}3$sfx`:x ` 20M:${POOL_PART}4$sfx`:x } 2 { # valid poolset file with replica create_poolset $POOLSET$sfx ` 20M:${POOL_PART}1$sfx`:x ` 20M:${POOL_PART}2$sfx`:x ` 20M:${POOL_PART}3$sfx`:x ` 20M:${POOL_PART}4$sfx`:x ` r 80M:${POOL_PART}${REPLICA}$sfx:x } 3 { # other number of parts create_poolset $POOLSET$sfx ` 20M:${POOL_PART}1$sfx`:x ` 20M:${POOL_PART}2$sfx`:x ` 40M:${POOL_PART}3$sfx`:x } 4 { # no poolset return } 5 { # empty create_poolset $POOLSET$sfx } 6 { # other size of part create_poolset $POOLSET$sfx ` 20M:${POOL_PART}1$sfx`:x ` 20M:${POOL_PART}2$sfx`:x ` 20M:${POOL_PART}3$sfx`:x ` 21M:${POOL_PART}4$sfx`:x } } check_file $POOLSET$sfx } # # backup_and_compare -- perform backup and compare backup result with original # if compare parameters are provided # usage: backup_and_compare [] # function backup_and_compare () { $poolset=$args[0] $type=$args[1] # backup expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -b $poolset$BACKUP -t $type -r 1 $poolset cat -Encoding Ascii $OUT | out-file -append -encoding ascii -literalpath $OUT_TEMP # compare if ($args.Count -gt 2 ) { $check=$args[2] compare_replicas $check $poolset$BACKUP $poolset >> $DIFF } } $ALL_POOL_PARTS="${POOL_PART}1, ${POOL_PART}2, ${POOL_PART}3, ${POOL_PART}4, ` ${POOL_PART}${REPLICA}" $ALL_POOL_BACKUP_PARTS="${POOL_PART}1$BACKUP, ${POOL_PART}2$BACKUP, ` ${POOL_PART}3$BACKUP ${POOL_PART}4$BACKUP, ` ${POOL_PART}${BACKUP}${REPLICA}" # # backup_cleanup -- perform cleanup between test cases # function backup_cleanup() { rm $POOLSET$BACKUP, ${POOL_PART}1, ${POOL_PART}2, ${POOL_PART}3, ` ${POOL_PART}4, ${POOL_PART}${REPLICA} -ea si rm ${POOL_PART}1$BACKUP, ${POOL_PART}2$BACKUP, ${POOL_PART}3$BACKUP, ` ${POOL_PART}4$BACKUP, ${POOL_PART}$BACKUP${REPLICA} -ea si } pmdk-1.11.1/src/test/libpmempool_backup/TEST50000775000000000000000000000126714123364546017450 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST5 -- test backup to poolset with different sizes of # parts than source poolset # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 6 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/out7.log.match0000664000000000000000000000403514123364546021346 0ustar rootrootlibpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.blk_backup -t blk -r 1 $(nW)pool.blk destination of the backup already exists. Do you want to overwrite it? checking shutdown state shutdown state correct checking pool header pool header correct checking pmemblk header pmemblk header correct checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_backup/TEST7: DONE libpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.blk_backup -t blk -r 1 $(nW)pool.blk destination of the backup does not match the size of the source pool file: $(nW)pool.blk_backup status = fatal libpmempool_backup/TEST7: DONE libpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.log_backup -t log -r 1 $(nW)pool.log destination of the backup already exists. Do you want to overwrite it? checking shutdown state shutdown state correct checking pool header pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_backup/TEST7: DONE libpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.log_backup -t log -r 1 $(nW)pool.log destination of the backup does not match the size of the source pool file: $(nW)pool.log_backup status = fatal libpmempool_backup/TEST7: DONE libpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.obj_backup -t obj -r 1 $(nW)pool.obj destination of the backup already exists. Do you want to overwrite it? checking shutdown state shutdown state correct checking pool header pool header correct status = consistent libpmempool_backup/TEST7: DONE libpmempool_backup/TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.obj_backup -t obj -r 1 $(nW)pool.obj destination of the backup does not match the size of the source pool file: $(nW)pool.obj_backup status = fatal libpmempool_backup/TEST7: DONE pmdk-1.11.1/src/test/libpmempool_backup/TEST6.PS10000664000000000000000000000176214123364546020050 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST6 -- test backup to poolset which parts already exist # or almost all parts already exist # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . ./common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 1 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET # create backup poolset parts for ($j=1; $j -lt 5; $j++ ) { truncate -s 20M $POOL_PART$j$BACKUP } backup_and_compare $POOLSET $POOL_TYPES[$i] # one of parts is too small truncate -s 10M ${POOL_PART}3${BACKUP} backup_and_compare $POOLSET $POOL_TYPES[$i] # one of parts does not exist rm ${POOL_PART}3${BACKUP} backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST40000775000000000000000000000127014123364546017441 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST4 -- test backup to poolset with different number of # parts than source poolset # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 3 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST70000775000000000000000000000145414123364546017450 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST7 -- test backup to pool which already exists # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup POOLFILE=$DIR/pool.${POOL_TYPES[$i]} rm -f $POOLFILE # create source poolset expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" --size 20M $POOLFILE # create backup pool file truncate -s 20M $POOLFILE$BACKUP backup_and_compare $POOLFILE ${POOL_TYPES[$i]} # create too small backup pool file truncate -s 10M $POOLFILE$BACKUP backup_and_compare $POOLFILE ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/out0.log.match0000664000000000000000000000454414123364546021344 0ustar rootrootlibpmempool_backup$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set creating backup file: $(nW)pool.part1_backup creating backup file: $(nW)pool.part2_backup creating backup file: $(nW)pool.part3_backup creating backup file: $(nW)pool.part4_backup checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemblk header pmemblk header correct checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_backup$(nW)TEST0: DONE libpmempool_backup$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set creating backup file: $(nW)pool.part1_backup creating backup file: $(nW)pool.part2_backup creating backup file: $(nW)pool.part3_backup creating backup file: $(nW)pool.part4_backup checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_backup$(nW)TEST0: DONE libpmempool_backup$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set creating backup file: $(nW)pool.part1_backup creating backup file: $(nW)pool.part2_backup creating backup file: $(nW)pool.part3_backup creating backup file: $(nW)pool.part4_backup checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct status = consistent libpmempool_backup$(nW)TEST0: DONE pmdk-1.11.1/src/test/libpmempool_backup/libpmempool_backup.vcxproj0000664000000000000000000001115314123364546024132 0ustar rootroot Debug x64 Release x64 {60B463D4-8CD5-4BF6-A25B-01BE13B87590} Win32Proj libpmempool_backup 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC Level3 MaxSpeed true true NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC {a2a0faea-2b7c-4fc3-b904-1db4deacf88d} pmdk-1.11.1/src/test/libpmempool_backup/TEST0.PS10000664000000000000000000000117614123364546020041 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST0 -- test simple backup scenario # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 1 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] $POOL_CHECK_PARAMS[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/README0000664000000000000000000000022714123364546017531 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_backup/README. This directory contains unittest for libpmempool backup functionality. pmdk-1.11.1/src/test/libpmempool_backup/diff0.log.match0000664000000000000000000000000014123364546021424 0ustar rootrootpmdk-1.11.1/src/test/libpmempool_backup/common.sh0000775000000000000000000000520314123364546020477 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/common.sh -- functions for libpmempool_backup unittest # set -e POOLSET=$DIR/pool.set BACKUP=_backup REPLICA=_replica POOL_PART=$DIR/pool.part OUT=out${UNITTEST_NUM}.log OUT_TEMP=out${UNITTEST_NUM}_temp.log DIFF=diff${UNITTEST_NUM}.log rm -f $LOG $DIFF $OUT_TEMP && touch $LOG $DIFF $OUT_TEMP # params for blk, log and obj pools POOL_TYPES=( blk log obj ) POOL_CREATE_PARAMS=( "--write-layout 512" "" "--layout test_layout" ) POOL_CHECK_PARAMS=( "-smgB" "-s" "-soOaAbZH -l -C" ) POOL_OBJ=2 # create_poolset_variation -- create one from the tested poolset variation # usage: create_poolset_variation [] # function create_poolset_variation() { local sfx="" local variation=$1 shift if [ $# -gt 0 ]; then sfx=$1 fi case "$variation" in 1) # valid poolset file create_poolset $POOLSET$sfx \ 20M:${POOL_PART}1$sfx:x \ 20M:${POOL_PART}2$sfx:x \ 20M:${POOL_PART}3$sfx:x \ 20M:${POOL_PART}4$sfx:x ;; 2) # valid poolset file with replica create_poolset $POOLSET$sfx \ 20M:${POOL_PART}1$sfx:x \ 20M:${POOL_PART}2$sfx:x \ 20M:${POOL_PART}3$sfx:x \ 20M:${POOL_PART}4$sfx:x \ r 80M:${POOL_PART}${REPLICA}$sfx:x ;; 3) # other number of parts create_poolset $POOLSET$sfx \ 20M:${POOL_PART}1$sfx:x \ 20M:${POOL_PART}2$sfx:x \ 40M:${POOL_PART}3$sfx:x ;; 4) # no poolset # return without check_file return ;; 5) # empty create_poolset $POOLSET$sfx ;; 6) # other size of part create_poolset $POOLSET$sfx \ 20M:${POOL_PART}1$sfx:x \ 20M:${POOL_PART}2$sfx:x \ 20M:${POOL_PART}3$sfx:x \ 21M:${POOL_PART}4$sfx:x ;; esac check_file $POOLSET$sfx } # # backup_and_compare -- perform backup and compare backup result with original # if compare parameters are provided # usage: backup_and_compare [] # function backup_and_compare () { local poolset=$1 local type=$2 shift 2 # backup expect_normal_exit ../libpmempool_api/libpmempool_test$EXESUFFIX \ -b $poolset$BACKUP -t $type -r 1 $poolset cat $OUT >> $OUT_TEMP # compare if [ $# -gt 0 ]; then compare_replicas "$1" $poolset $poolset$BACKUP >> $DIFF fi } ALL_POOL_PARTS="${POOL_PART}1 ${POOL_PART}2 ${POOL_PART}3 ${POOL_PART}4 \ ${POOL_PART}${REPLICA}" ALL_POOL_BACKUP_PARTS="${POOL_PART}1$BACKUP ${POOL_PART}2$BACKUP \ ${POOL_PART}3$BACKUP ${POOL_PART}4$BACKUP \ ${POOL_PART}${BACKUP}${REPLICA}" # # backup_cleanup -- perform cleanup between test cases # function backup_cleanup() { rm -f $POOLSET$BACKUP $ALL_POOL_PARTS $ALL_POOL_BACKUP_PARTS } pmdk-1.11.1/src/test/libpmempool_backup/config.sh0000664000000000000000000000043014123364546020446 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # libpmempool_backup/config.sh -- test configuration # # Extend timeout for TEST0, as it may take more than a minute # when run on a non-pmem file system. CONF_TIMEOUT[0]='10m' pmdk-1.11.1/src/test/libpmempool_backup/TEST60000775000000000000000000000226614123364546017451 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST6 -- test backup to poolset which parts already exist # or almost all parts already exist # . ../unittest/unittest.sh EXE=../libpmempool_api/libpmempool_test$EXESUFFIX # This test memcpy + persist entire pool, and it runs # forever under pmemcheck. configure_valgrind pmemcheck force-disable $EXE require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 1 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET # create backup poolset parts for j in `seq 1 4` do truncate -s 20M $POOL_PART$j$BACKUP done backup_and_compare $POOLSET ${POOL_TYPES[$i]} # one of parts is too small truncate -s 10M ${POOL_PART}3${BACKUP} backup_and_compare $POOLSET ${POOL_TYPES[$i]} # one of parts does not exist rm ${POOL_PART}3${BACKUP} backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST10000775000000000000000000000121214123364546017432 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST1 -- test non-existing backup poolset # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 4 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/TEST4.PS10000664000000000000000000000125114123364546020037 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST4 -- test backup to poolset with different number of # parts than source poolset # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem setup . .\common.PS1 for ($i=0; $i -lt $POOL_TYPES.Count; $i++ ) { backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 3 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL create $POOL_TYPES[$i] ` $POOL_CREATE_PARAMS[$i] $POOLSET backup_and_compare $POOLSET $POOL_TYPES[$i] } rm $OUT -Force -ea si mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/out6.log.match0000664000000000000000000001207114123364546021344 0ustar rootrootlibpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemblk header pmemblk header correct checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set destination of the backup part does not match size of the source part file: $(nW)pool.part3_backup unable to backup poolset status = fatal libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemblk header pmemblk header correct checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set destination of the backup part does not match size of the source part file: $(nW)pool.part3_backup unable to backup poolset status = fatal libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct status = consistent libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set destination of the backup part does not match size of the source part file: $(nW)pool.part3_backup unable to backup poolset status = fatal libpmempool_backup/TEST6: DONE libpmempool_backup/TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set part files of the destination poolset of the backup already exist. Do you want to overwrite them? checking shutdown state shutdown state correct replica 0 part 0: checking pool header replica 0 part 0: pool header correct replica 0 part 1: checking pool header replica 0 part 1: pool header correct replica 0 part 2: checking pool header replica 0 part 2: pool header correct replica 0 part 3: checking pool header replica 0 part 3: pool header correct status = consistent libpmempool_backup/TEST6: DONE pmdk-1.11.1/src/test/libpmempool_backup/out1.log.match0000664000000000000000000000154314123364546021341 0ustar rootrootlibpmempool_backup$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: No such file or directory unable to backup poolset status = fatal libpmempool_backup$(nW)TEST1: DONE libpmempool_backup$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: No such file or directory unable to backup poolset status = fatal libpmempool_backup$(nW)TEST1: DONE libpmempool_backup$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: No such file or directory unable to backup poolset status = fatal libpmempool_backup$(nW)TEST1: DONE pmdk-1.11.1/src/test/libpmempool_backup/TEST20000775000000000000000000000120314123364546017433 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_backup/TEST2 -- test empty backup poolset # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup . ./common.sh for (( i=0; i<${#POOL_TYPES[@]}; i++ )); do backup_cleanup # prepare poolset files create_poolset_variation 1 create_poolset_variation 5 $BACKUP # create source poolset parts expect_normal_exit $PMEMPOOL$EXESUFFIX create ${POOL_TYPES[$i]} \ "${POOL_CREATE_PARAMS[$i]}" $POOLSET backup_and_compare $POOLSET ${POOL_TYPES[$i]} done mv $OUT_TEMP $OUT check pass pmdk-1.11.1/src/test/libpmempool_backup/out5.log.match0000664000000000000000000000152114123364546021341 0ustar rootrootlibpmempool_backup$(nW)TEST5: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set size of the part 3 of the backup poolset does not match source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST5: DONE libpmempool_backup$(nW)TEST5: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set size of the part 3 of the backup poolset does not match source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST5: DONE libpmempool_backup$(nW)TEST5: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set size of the part 3 of the backup poolset does not match source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST5: DONE pmdk-1.11.1/src/test/libpmempool_backup/out3.log.match0000664000000000000000000000146014123364546021341 0ustar rootrootlibpmempool_backup$(nW)TEST3: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set backup to a poolset with multiple replicas is not supported unable to backup poolset status = fatal libpmempool_backup$(nW)TEST3: DONE libpmempool_backup$(nW)TEST3: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set backup to a poolset with multiple replicas is not supported unable to backup poolset status = fatal libpmempool_backup$(nW)TEST3: DONE libpmempool_backup$(nW)TEST3: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set backup to a poolset with multiple replicas is not supported unable to backup poolset status = fatal libpmempool_backup$(nW)TEST3: DONE pmdk-1.11.1/src/test/libpmempool_backup/out4.log.match0000664000000000000000000000163714123364546021350 0ustar rootrootlibpmempool_backup$(nW)TEST4: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set number of part files in the backup poolset must match number of part files in the source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST4: DONE libpmempool_backup$(nW)TEST4: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set number of part files in the backup poolset must match number of part files in the source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST4: DONE libpmempool_backup$(nW)TEST4: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set number of part files in the backup poolset must match number of part files in the source poolset unable to backup poolset status = fatal libpmempool_backup$(nW)TEST4: DONE pmdk-1.11.1/src/test/libpmempool_backup/out2.log.match0000664000000000000000000000151014123364546021334 0ustar rootrootlibpmempool_backup$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t blk -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: Invalid argument unable to backup poolset status = fatal libpmempool_backup$(nW)TEST2: DONE libpmempool_backup$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t log -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: Invalid argument unable to backup poolset status = fatal libpmempool_backup$(nW)TEST2: DONE libpmempool_backup$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -b $(nW)pool.set_backup -t obj -r 1 $(nW)pool.set invalid poolset backup file: $(nW)pool.set_backup: Invalid argument unable to backup poolset status = fatal libpmempool_backup$(nW)TEST2: DONE pmdk-1.11.1/src/test/ex_libpmemblk/0000775000000000000000000000000014123364546015616 5ustar rootrootpmdk-1.11.1/src/test/ex_libpmemblk/asset_list.txt0000664000000000000000000000002514123364546020526 0ustar rootrootHello World! foo bar pmdk-1.11.1/src/test/ex_libpmemblk/ex_libpmemblk.vcxproj.filters0000664000000000000000000000137714123364546023524 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/ex_libpmemblk/TEST00000775000000000000000000000472414123364546016412 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/ex_libpmemblk/TEST0 -- unit test for libpmemblk examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemblk/assetdb create_holey_file 32M $DIR/testfile1 expect_normal_exit $EX_PATH/asset_load $DIR/testfile1 ./asset_list.txt > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/asset_list $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/asset_checkout $DIR/testfile1 2 Joe >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/asset_list $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/asset_checkin $DIR/testfile1 2 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/asset_list $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/ex_libpmemblk/Makefile0000664000000000000000000000061314123364546017256 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/ex_libpmemblk/Makefile -- build ex_libpmemblk unittest # all: $(EXAMPLES) $(MAKE) -C $(EX_LIBPMEMBLK) include ../Makefile.inc EXAMPLES=$(EX_LIBPMEMBLK)/assetdb/asset_load \ $(EX_LIBPMEMBLK)/assetdb/asset_checkin \ $(EX_LIBPMEMBLK)/assetdb/asset_checkout \ $(EX_LIBPMEMBLK)/assetdb/asset_list pmdk-1.11.1/src/test/ex_libpmemblk/out0.log.match0000664000000000000000000000105314123364546020302 0ustar rootrootAsset ID: 0 State: Free Name: Hello Asset ID: 1 State: Free Name: World! Asset ID: 2 State: Free Name: foo Asset ID: 3 State: Free Name: bar Asset ID: 0 State: Free Name: Hello Asset ID: 1 State: Free Name: World! Asset ID: 2 State: Checked out User: Joe Time: $(*) Name: foo Asset ID: 3 State: Free Name: bar Asset ID: 0 State: Free Name: Hello Asset ID: 1 State: Free Name: World! Asset ID: 2 State: Free Name: foo Asset ID: 3 State: Free Name: bar pmdk-1.11.1/src/test/ex_libpmemblk/TEST0.PS10000664000000000000000000000507014123364546017004 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/ex_libpmemblk/TEST0 -- unit test for libpmemblk examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup create_holey_file 32M $DIR\testfile1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_load $DIR\testfile1 .\asset_list.txt > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_list $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_checkout $DIR\testfile1 2 Joe >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_list $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_checkin $DIR\testfile1 2 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemblk_asset_list $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/ex_libpmemblk/README0000664000000000000000000000032114123364546016472 0ustar rootrootPersistent Memory Development Kit This is src/test/ex_libpmemblk/README. This directory contains unit tests for libpmemblk examples. The unit tests utilizes examples from src/examples/libpmemblk directory. pmdk-1.11.1/src/test/ex_libpmemblk/ex_libpmemblk.vcxproj0000664000000000000000000001040314123364546022043 0ustar rootroot Debug x64 Release x64 {581b3a58-f3f0-4765-91e5-d0c82816a528} {513c4cfa-bd5b-4470-ba93-f6d43778a754} {8008010f-8718-4c5f-86b2-195aebf73422} {c7e42ae1-052f-4024-b8ba-de5dce6bbeec} {1B9B0D6D-E530-44A6-ADAE-09EA2BDC47DE} ex_libpmemblk 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/obj_rpmem_heap_interrupt/0000775000000000000000000000000014123364546020067 5ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_interrupt/TEST00000775000000000000000000000727514123364546020667 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_rpmem_heap_interrupt/TEST0 -- remote test for pool heap # interruption # . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-disable setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER PID_FILE=rpmemd.pid init_rpmem_on_node 1 0:$PID_FILE # binary for this test EXE=obj_heap_interrupt # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 ${NODE_DIR[1]}$TEST_FILE_LOCAL # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 8M:${NODE_DIR[1]}$TEST_FILE_LOCAL:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 9M:${NODE_DIR[0]}$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL # create remote holey pool files create_holey_file_on_node 1 8M ${NODE_DIR[1]}$TEST_FILE_LOCAL create_holey_file_on_node 0 9M ${NODE_DIR[0]}$TEST_FILE_REMOTE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL c 0 # pmempool rm expects flock from the remote parts are released otherwise it will # fail to delete them so it has to wait for rpmemd to exit expect_abnormal_exit wait_on_node 0 $PID_FILE expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$TEST_SET_LOCAL expect_normal_exit run_on_node 1 ../pmempool create --layout heap_interrupt obj \ ${NODE_DIR[1]}$TEST_SET_LOCAL expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL o 0 # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}$TEST_FILE_REMOTE copy_files_from_node 1 $DIR ${NODE_DIR[1]}$TEST_FILE_LOCAL compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/$TEST_FILE_LOCAL $DIR/$TEST_FILE_REMOTE > diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_interrupt/Makefile0000664000000000000000000000046214123364546021531 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/obj_rpmem_heap_interrupt/Makefile -- build obj_rpmem_heap_interrupt # test # SCP_TO_REMOTE_NODES = y SCP_TARGET = obj_heap_interrupt SCP_SRC_DIR = ../obj_heap_interrupt include ../obj_heap_interrupt/Makefile.inc pmdk-1.11.1/src/test/obj_rpmem_heap_interrupt/diff0.log.match0000664000000000000000000000000014123364546022643 0ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_interrupt/config.sh0000664000000000000000000000045714123364546021676 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2017, Intel Corporation # # # src/test/obj_rpmem_heap_interrupt/config.sh -- test configuration # CONF_GLOBAL_FS_TYPE=pmem CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/log_walker/0000775000000000000000000000000014123364546015132 5ustar rootrootpmdk-1.11.1/src/test/log_walker/log_walker.c0000664000000000000000000000411514123364546017425 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * log_walker.c -- unit test to verify pool's write-protection in debug mode * * usage: log_walker file * */ #include #include "unittest.h" /* * do_append -- call pmemlog_append() & print result */ static void do_append(PMEMlogpool *plp) { const char *str[6] = { "1st append string\n", "2nd append string\n", "3rd append string\n", "4th append string\n", "5th append string\n", "6th append string\n" }; for (int i = 0; i < 6; ++i) { int rv = pmemlog_append(plp, str[i], strlen(str[i])); switch (rv) { case 0: UT_OUT("append str[%i] %s", i, str[i]); break; case -1: UT_OUT("!append str[%i] %s", i, str[i]); break; default: UT_OUT("!append: wrong return value"); break; } } } /* * try_to_store -- try to store to the buffer 'buf' * * It is a walker function for pmemlog_walk */ static int try_to_store(const void *buf, size_t len, void *arg) { memset((void *)buf, 0, len); return 0; } /* * do_walk -- call pmemlog_walk() & print result */ static void do_walk(PMEMlogpool *plp) { pmemlog_walk(plp, 0, try_to_store, NULL); UT_OUT("walk all at once"); } static ut_jmp_buf_t Jmp; /* * signal_handler -- called on SIGSEGV */ static void signal_handler(int sig) { UT_OUT("signal: %s", os_strsignal(sig)); ut_siglongjmp(Jmp); } int main(int argc, char *argv[]) { PMEMlogpool *plp; START(argc, argv, "log_walker"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; int fd = OPEN(path, O_RDWR); /* pre-allocate 2MB of persistent memory */ POSIX_FALLOCATE(fd, (os_off_t)0, (size_t)(2 * 1024 * 1024)); CLOSE(fd); if ((plp = pmemlog_create(path, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemlog_create: %s", path); /* append some data */ do_append(plp); /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); if (!ut_sigsetjmp(Jmp)) { do_walk(plp); } pmemlog_close(plp); DONE(NULL); } pmdk-1.11.1/src/test/log_walker/TEST00000775000000000000000000000110114123364546015710 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_walker/TEST0 -- unit test to verify pool's write-protection # in debug mode # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug # exits without cleanup configure_valgrind force-disable setup # this test invokes sigsegvs by design export ASAN_OPTIONS=handle_segv=0 touch $DIR/testfile1 expect_normal_exit ./log_walker$EXESUFFIX $DIR/testfile1 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_walker/log_walker.vcxproj0000664000000000000000000000712214123364546020677 0ustar rootroot Debug x64 Release x64 {4FB4FF90-4E92-4CFB-A01F-C73D6861CA03} Win32Proj log_walker 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/log_walker/Makefile0000664000000000000000000000034214123364546016571 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_walker/Makefile -- build log_walker unit test # TARGET = log_walker OBJS = log_walker.o LIBPMEMLOG=y include ../Makefile.inc pmdk-1.11.1/src/test/log_walker/out0.log.match0000664000000000000000000000052514123364546017621 0ustar rootrootlog_walker$(nW)TEST0: START: log_walker $(nW)log_walker$(nW) $(nW)testfile1 append str[0] 1st append string append str[1] 2nd append string append str[2] 3rd append string append str[3] 4th append string append str[4] 5th append string append str[5] 6th append string signal: Segmentation fault log_walker$(nW)TEST0: DONE pmdk-1.11.1/src/test/log_walker/log_walker.vcxproj.filters0000664000000000000000000000177614123364546022357 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {a943055e-a2b9-4b48-affd-ed0c3c85d224} ps1 {724fe544-99ad-4d30-b241-90219114a03b} match Source Files Match Files Test Scripts pmdk-1.11.1/src/test/log_walker/TEST0.PS10000664000000000000000000000072414123364546016321 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_walker/TEST0 -- unit test to verify pool's write-protection # in debug mode # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup # this test invokes sigsegvs by design touch $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_walker$Env:EXESUFFIX $DIR\testfile1 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_walker/.gitignore0000664000000000000000000000001314123364546017114 0ustar rootrootlog_walker pmdk-1.11.1/src/test/log_walker/README0000664000000000000000000000075714123364546016023 0ustar rootrootPersistent Memory Development Kit This is src/test/log_walker/README. This directory contains a unit test to verify pool's write-protection in debug mode. It works only in debug mode. The program in log_walker.c takes only a file name as an argument. For example: ./log_walker file1 this calls pmemlog_open() on file1 and pmemlog_append() to append six strings to the log. Next pmemlog_walk() is called and the walk handler tries to store to the buffer and SIGSEGV is caught and reported. pmdk-1.11.1/src/test/obj_tx_locks_abort/0000775000000000000000000000000014123364546016653 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_locks_abort/TEST00000775000000000000000000000047414123364546017445 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_locks_abort/TEST0 -- unit test for transaction locks # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_tx_locks_abort$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_locks_abort/Makefile0000664000000000000000000000040214123364546020307 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_locks_abort/Makefile -- build obj_tx_locks_abort unit test # TARGET = obj_tx_locks_abort OBJS = obj_tx_locks_abort.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_locks_abort/out0.log.match0000664000000000000000000000056214123364546021343 0ustar rootrootobj_tx_locks_abort$(nW)TEST0: START: obj_tx_locks_abort $(nW)obj_tx_locks_abort$(nW) $(nW)testfile1 initial state data = 100 data = 101 data = 102 data = 103 nested tx data = 200 data = 200 data = 200 data = 200 aborted nested tx trylock failed trylock failed trylock failed trylock failed data = 200 data = 200 data = 200 data = 200 obj_tx_locks_abort$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_locks_abort/obj_tx_locks_abort.c0000664000000000000000000000566214123364546022677 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * obj_tx_locks_nested.c -- unit test for transaction locks */ #include "unittest.h" #define LAYOUT_NAME "locks" TOID_DECLARE_ROOT(struct root_obj); TOID_DECLARE(struct obj, 1); struct root_obj { PMEMmutex lock; TOID(struct obj) head; }; struct obj { int data; PMEMmutex lock; TOID(struct obj) next; }; /* * do_nested_tx-- (internal) nested transaction */ static void do_nested_tx(PMEMobjpool *pop, TOID(struct obj) o, int value) { TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(o)->lock, TX_PARAM_NONE) { TX_ADD(o); D_RW(o)->data = value; if (!TOID_IS_NULL(D_RO(o)->next)) { /* * Add the object to undo log, while the mutex * it contains is not locked. */ TX_ADD(D_RO(o)->next); do_nested_tx(pop, D_RO(o)->next, value); } } TX_END; } /* * do_aborted_nested_tx -- (internal) aborted nested transaction */ static void do_aborted_nested_tx(PMEMobjpool *pop, TOID(struct obj) oid, int value) { TOID(struct obj) o = oid; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(o)->lock, TX_PARAM_NONE) { TX_ADD(o); D_RW(o)->data = value; if (!TOID_IS_NULL(D_RO(o)->next)) { /* * Add the object to undo log, while the mutex * it contains is not locked. */ TX_ADD(D_RO(o)->next); do_nested_tx(pop, D_RO(o)->next, value); } pmemobj_tx_abort(EINVAL); } TX_FINALLY { o = oid; while (!TOID_IS_NULL(o)) { if (pmemobj_mutex_trylock(pop, &D_RW(o)->lock)) { UT_OUT("trylock failed"); } else { UT_OUT("trylock succeeded"); pmemobj_mutex_unlock(pop, &D_RW(o)->lock); } o = D_RO(o)->next; } } TX_END; } /* * do_check -- (internal) print 'data' value of each object on the list */ static void do_check(TOID(struct obj) o) { while (!TOID_IS_NULL(o)) { UT_OUT("data = %d", D_RO(o)->data); o = D_RO(o)->next; } } int main(int argc, char *argv[]) { PMEMobjpool *pop; START(argc, argv, "obj_tx_locks_abort"); if (argc > 3) UT_FATAL("usage: %s ", argv[0]); pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL * 4, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create"); TOID(struct root_obj) root = POBJ_ROOT(pop, struct root_obj); TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); D_RW(root)->head = TX_ZNEW(struct obj); TOID(struct obj) o; o = D_RW(root)->head; D_RW(o)->data = 100; pmemobj_mutex_zero(pop, &D_RW(o)->lock); for (int i = 0; i < 3; i++) { D_RW(o)->next = TX_ZNEW(struct obj); o = D_RO(o)->next; D_RW(o)->data = 101 + i; pmemobj_mutex_zero(pop, &D_RW(o)->lock); } TOID_ASSIGN(D_RW(o)->next, OID_NULL); } TX_END; UT_OUT("initial state"); do_check(D_RO(root)->head); UT_OUT("nested tx"); do_nested_tx(pop, D_RW(root)->head, 200); do_check(D_RO(root)->head); UT_OUT("aborted nested tx"); do_aborted_nested_tx(pop, D_RW(root)->head, 300); do_check(D_RO(root)->head); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_locks_abort/TEST0.PS10000664000000000000000000000356414123364546020047 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\obj_tx_locks_abort\TEST0 -- unit test for transaction locks # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $ENV:EXE_DIR\obj_tx_locks_abort$ENV:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_tx_locks_abort/.gitignore0000664000000000000000000000002314123364546020636 0ustar rootrootobj_tx_locks_abort pmdk-1.11.1/src/test/obj_tx_locks_abort/README0000664000000000000000000000234514123364546017537 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_tx_locks_abort/README. This directory contains a unit test for handling transaction locks in case of aborted nested transactions. At the beginning of each transaction, the user may provide an arbitrary number of mutexes and/or rwlocks, which will be taken before the transaction starts and released at transaction end. In case of nested transactions, it may happen that the snapshot of the object containing the lock passed to pmemobj_tx_begin() is already added to the undo log. If the transaction is aborted, the object data will be restored first (which also restores the PMEM lock in non-locked state. Once the undo log processing is completed, all the transaction locks are unlocked. So, this may result in calling the unlock() on the lock that is not held by current thread, which may lead to an undefined behavior. The libpmemobj library implements mechanisms to prevent such scenario, and this is what is tested here. The obj_tx_locks_abort application takes as command line arguments the file where the pool will be created and the type of test to be performed: $ obj_tx_locks_abort Some of the tests are performed using valgrind and its following tools: - drd - helgrind pmdk-1.11.1/src/test/obj_tx_locks_abort/TEST10000775000000000000000000000100514123364546017435 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_locks_abort/TEST1 -- unit test for transaction locks # . ../unittest/unittest.sh require_test_type medium unset PMEM_LOG_LEVEL unset PMEM_LOG_FILE unset PMEMOBJ_LOG_LEVEL unset PMEMOBJ_LOG_FILE require_fs_type any require_build_type debug nondebug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_tx_locks_abort$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_locks_abort/obj_tx_locks_abort.vcxproj.filters0000664000000000000000000000200614123364546025604 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {74b7cbd5-3b5a-4400-936c-68387cd34d67} match {91205422-aef7-40bd-bc4d-009c4386aa69} ps1 Source Files Test Scripts Match Files pmdk-1.11.1/src/test/obj_tx_locks_abort/obj_tx_locks_abort.vcxproj0000664000000000000000000000752714123364546024152 0ustar rootroot Debug x64 Release x64 {6F4953DA-FDC3-46CF-BF24-3752CCF2E1CB} Win32Proj obj_tx_locks_abort 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(IncludePath) Disabled CompileAsCpp CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_locks_abort/out1.log.match0000664000000000000000000000056214123364546021344 0ustar rootrootobj_tx_locks_abort$(nW)TEST1: START: obj_tx_locks_abort $(nW)obj_tx_locks_abort$(nW) $(nW)testfile1 initial state data = 100 data = 101 data = 102 data = 103 nested tx data = 200 data = 200 data = 200 data = 200 aborted nested tx trylock failed trylock failed trylock failed trylock failed data = 200 data = 200 data = 200 data = 200 obj_tx_locks_abort$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_tx_locks_abort/TEST20000775000000000000000000000101214123364546017434 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_locks_abort/TEST2 -- unit test for transaction locks # . ../unittest/unittest.sh require_test_type medium unset PMEM_LOG_LEVEL unset PMEM_LOG_FILE unset PMEMOBJ_LOG_LEVEL unset PMEMOBJ_LOG_FILE require_fs_type any require_build_type debug nondebug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_tx_locks_abort$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_locks_abort/out2.log.match0000664000000000000000000000056214123364546021345 0ustar rootrootobj_tx_locks_abort$(nW)TEST2: START: obj_tx_locks_abort $(nW)obj_tx_locks_abort$(nW) $(nW)testfile1 initial state data = 100 data = 101 data = 102 data = 103 nested tx data = 200 data = 200 data = 200 data = 200 aborted nested tx trylock failed trylock failed trylock failed trylock failed data = 200 data = 200 data = 200 data = 200 obj_tx_locks_abort$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_tx_flow/0000775000000000000000000000000014123364546015320 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_flow/obj_tx_flow.vcxproj0000664000000000000000000000765314123364546021264 0ustar rootroot Debug x64 Release x64 {8E374371-30E1-4623-8755-2A2F3742170B} Win32Proj obj_tx_flow 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)libpmemobj;$(IncludePath) $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled CompileAsCpp CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_flow/TEST00000775000000000000000000000073214123364546016107 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_flow/TEST0 -- unit test for transaction flow # . ../unittest/unittest.sh # this test verifies the correctness of the tx management functions only configure_valgrind pmemcheck force-disable require_test_type medium setup expect_normal_exit ./obj_tx_flow$EXESUFFIX f $DIR/testfile1 expect_normal_exit ./obj_tx_flow$EXESUFFIX t $DIR/testfile2 pass pmdk-1.11.1/src/test/obj_tx_flow/Makefile0000664000000000000000000000036314123364546016762 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_flow/Makefile -- build obj_tx_flow unit test # TARGET = obj_tx_flow OBJS = obj_tx_flow.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_flow/TEST0.PS10000664000000000000000000000354014123364546016506 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_flow/TEST0 -- unit test for transaction flow # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $ENV:EXE_DIR\obj_tx_flow$Env:EXESUFFIX t $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_tx_flow/obj_tx_flow.c0000664000000000000000000001642514123364546020010 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_tx_flow.c -- unit test for transaction flow */ #include "unittest.h" #include "obj.h" #define LAYOUT_NAME "direct" #define TEST_VALUE_A 5 #define TEST_VALUE_B 10 #define TEST_VALUE_C 15 #define OPS_NUM 9 TOID_DECLARE(struct test_obj, 1); struct test_obj { int a; int b; int c; }; static void do_tx_macro_commit(PMEMobjpool *pop, TOID(struct test_obj) *obj) { TX_BEGIN(pop) { D_RW(*obj)->a = TEST_VALUE_A; } TX_ONCOMMIT { UT_ASSERT(D_RW(*obj)->a == TEST_VALUE_A); D_RW(*obj)->b = TEST_VALUE_B; } TX_ONABORT { /* not called */ D_RW(*obj)->a = TEST_VALUE_B; } TX_FINALLY { UT_ASSERT(D_RW(*obj)->b == TEST_VALUE_B); D_RW(*obj)->c = TEST_VALUE_C; } TX_END } static void do_tx_macro_abort(PMEMobjpool *pop, TOID(struct test_obj) *obj) { D_RW(*obj)->a = TEST_VALUE_A; D_RW(*obj)->b = TEST_VALUE_B; TX_BEGIN(pop) { TX_ADD(*obj); D_RW(*obj)->a = TEST_VALUE_B; pmemobj_tx_abort(EINVAL); D_RW(*obj)->b = TEST_VALUE_A; } TX_ONCOMMIT { /* not called */ D_RW(*obj)->a = TEST_VALUE_B; } TX_ONABORT { UT_ASSERT(D_RW(*obj)->a == TEST_VALUE_A); UT_ASSERT(D_RW(*obj)->b == TEST_VALUE_B); D_RW(*obj)->b = TEST_VALUE_B; } TX_FINALLY { UT_ASSERT(D_RW(*obj)->b == TEST_VALUE_B); D_RW(*obj)->c = TEST_VALUE_C; } TX_END } static void do_tx_macro_commit_nested(PMEMobjpool *pop, TOID(struct test_obj) *obj) { TX_BEGIN(pop) { TX_BEGIN(pop) { D_RW(*obj)->a = TEST_VALUE_A; } TX_ONCOMMIT { UT_ASSERT(D_RW(*obj)->a == TEST_VALUE_A); D_RW(*obj)->b = TEST_VALUE_B; } TX_END } TX_ONCOMMIT { D_RW(*obj)->c = TEST_VALUE_C; } TX_END } static void do_tx_macro_abort_nested(PMEMobjpool *pop, TOID(struct test_obj) *obj) { volatile int a = 0; volatile int b = 0; volatile int c = 0; D_RW(*obj)->a = TEST_VALUE_A; D_RW(*obj)->b = TEST_VALUE_B; TX_BEGIN(pop) { TX_ADD(*obj); D_RW(*obj)->a = TEST_VALUE_B; a = TEST_VALUE_C; TX_BEGIN(pop) { D_RW(*obj)->b = TEST_VALUE_C; a = TEST_VALUE_A; pmemobj_tx_abort(EINVAL); a = TEST_VALUE_B; } TX_ONCOMMIT { /* not called */ a = TEST_VALUE_C; } TX_ONABORT { UT_ASSERT(a == TEST_VALUE_A); b = TEST_VALUE_B; } TX_FINALLY { UT_ASSERT(b == TEST_VALUE_B); c = TEST_VALUE_C; } TX_END a = TEST_VALUE_B; } TX_ONCOMMIT { /* not called */ UT_ASSERT(a == TEST_VALUE_A); c = TEST_VALUE_C; } TX_ONABORT { UT_ASSERT(a == TEST_VALUE_A); UT_ASSERT(b == TEST_VALUE_B); UT_ASSERT(c == TEST_VALUE_C); b = TEST_VALUE_A; } TX_FINALLY { UT_ASSERT(b == TEST_VALUE_A); D_RW(*obj)->c = TEST_VALUE_C; a = TEST_VALUE_B; } TX_END UT_ASSERT(a == TEST_VALUE_B); } static void do_tx_macro_abort_nested_begin(PMEMobjpool *pop, TOID(struct test_obj) *obj) { errno = 0; TX_BEGIN(pop) { D_RW(*obj)->a = TEST_VALUE_A; D_RW(*obj)->b = TEST_VALUE_B; pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); TX_BEGIN((PMEMobjpool *)(uintptr_t)7) { } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERT(errno == EINVAL); } TX_ONABORT { D_RW(*obj)->c = TEST_VALUE_C; } TX_ONCOMMIT { /* not called */ D_RW(*obj)->a = TEST_VALUE_B; } TX_END } static void do_tx_commit(PMEMobjpool *pop, TOID(struct test_obj) *obj) { pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); D_RW(*obj)->a = TEST_VALUE_A; TX_ADD(*obj); D_RW(*obj)->b = TEST_VALUE_B; pmemobj_tx_commit(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONCOMMIT); D_RW(*obj)->c = TEST_VALUE_C; pmemobj_tx_end(); } static void do_tx_commit_nested(PMEMobjpool *pop, TOID(struct test_obj) *obj) { pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); TX_ADD(*obj); D_RW(*obj)->a = TEST_VALUE_A; pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); TX_ADD(*obj); D_RW(*obj)->b = TEST_VALUE_B; pmemobj_tx_commit(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONCOMMIT); pmemobj_tx_end(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_WORK); pmemobj_tx_commit(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONCOMMIT); D_RW(*obj)->c = TEST_VALUE_C; pmemobj_tx_end(); } static void do_tx_abort(PMEMobjpool *pop, TOID(struct test_obj) *obj) { D_RW(*obj)->a = TEST_VALUE_A; pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); D_RW(*obj)->b = TEST_VALUE_B; TX_ADD(*obj); D_RW(*obj)->a = 0; pmemobj_tx_abort(EINVAL); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT); D_RW(*obj)->c = TEST_VALUE_C; pmemobj_tx_end(); } static void do_tx_abort_nested(PMEMobjpool *pop, TOID(struct test_obj) *obj) { D_RW(*obj)->a = TEST_VALUE_A; D_RW(*obj)->b = TEST_VALUE_B; pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); TX_ADD(*obj); D_RW(*obj)->a = 0; pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); TX_ADD(*obj); D_RW(*obj)->b = 0; pmemobj_tx_abort(EINVAL); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT); pmemobj_tx_end(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT); D_RW(*obj)->c = TEST_VALUE_C; pmemobj_tx_end(); } typedef void (*fn_op)(PMEMobjpool *pop, TOID(struct test_obj) *obj); static fn_op tx_op[OPS_NUM] = {do_tx_macro_commit, do_tx_macro_abort, do_tx_macro_commit_nested, do_tx_macro_abort_nested, do_tx_macro_abort_nested_begin, do_tx_commit, do_tx_commit_nested, do_tx_abort, do_tx_abort_nested}; static void do_tx_process(PMEMobjpool *pop) { pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_WORK); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONCOMMIT); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_FINALLY); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_NONE); pmemobj_tx_end(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_NONE); } static void do_tx_process_nested(PMEMobjpool *pop) { pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_WORK); pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONCOMMIT); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_FINALLY); pmemobj_tx_end(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_WORK); pmemobj_tx_abort(EINVAL); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_FINALLY); pmemobj_tx_process(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_NONE); pmemobj_tx_end(); UT_ASSERT(pmemobj_tx_stage() == TX_STAGE_NONE); } static void do_fault_injection(PMEMobjpool *pop) { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "pmemobj_tx_begin"); int ret = pmemobj_tx_begin(pop, NULL, TX_PARAM_NONE); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_flow"); if (argc != 3) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[2], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); TOID(struct test_obj) obj; POBJ_ZNEW(pop, &obj, struct test_obj); for (int i = 0; i < OPS_NUM; i++) { D_RW(obj)->a = 0; D_RW(obj)->b = 0; D_RW(obj)->c = 0; tx_op[i](pop, &obj); UT_ASSERT(D_RO(obj)->a == TEST_VALUE_A); UT_ASSERT(D_RO(obj)->b == TEST_VALUE_B); UT_ASSERT(D_RO(obj)->c == TEST_VALUE_C); } switch (argv[1][0]) { case 't': do_tx_process(pop); do_tx_process_nested(pop); break; case 'f': do_fault_injection(pop); break; default: UT_FATAL("usage: %s [t|f]", argv[0]); } pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_flow/.gitignore0000664000000000000000000000001414123364546017303 0ustar rootrootobj_tx_flow pmdk-1.11.1/src/test/obj_tx_flow/obj_tx_flow.vcxproj.filters0000664000000000000000000000140414123364546022717 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {0a7439e8-98a6-4032-9c50-9be62fa84b25} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/pmem2_compat/0000775000000000000000000000000014123364546015367 5ustar rootrootpmdk-1.11.1/src/test/pmem2_compat/Makefile0000664000000000000000000000035014123364546017025 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem2_compat/Makefile -- build pmem2_compat test # TARGET = pmem2_compat OBJS = pmem2_compat.o LIBPMEM=y LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_compat/pmem2_compat.vcxproj0000664000000000000000000000625414123364546021376 0ustar rootroot Debug x64 Release x64 {B6C0521B-EECA-47EF-BFA8-147F9C3F6DFE} pmem2_compat 10.0.17134.0 Application true v140 Application false v140 Disabled MaxSpeed {f596c36c-5c96-4f08-b420-8908af500954} pmdk-1.11.1/src/test/pmem2_compat/.gitignore0000664000000000000000000000001514123364546017353 0ustar rootrootpmem2_compat pmdk-1.11.1/src/test/pmem2_compat/pmem2_compat.vcxproj.filters0000664000000000000000000000076214123364546023043 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FE} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files pmdk-1.11.1/src/test/pmem2_compat/pmem2_compat.c0000664000000000000000000000113614123364546020117 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * pmem2_compat.c -- compatibility test for libpmem vs libpmem2 */ #include "unittest.h" int main(int argc, char *argv[]) { UT_COMPILE_ERROR_ON(PMEM_F_MEM_NODRAIN != PMEM2_F_MEM_NODRAIN); UT_COMPILE_ERROR_ON(PMEM_F_MEM_NONTEMPORAL != PMEM2_F_MEM_NONTEMPORAL); UT_COMPILE_ERROR_ON(PMEM_F_MEM_TEMPORAL != PMEM2_F_MEM_TEMPORAL); UT_COMPILE_ERROR_ON(PMEM_F_MEM_WC != PMEM2_F_MEM_WC); UT_COMPILE_ERROR_ON(PMEM_F_MEM_WB != PMEM2_F_MEM_WB); UT_COMPILE_ERROR_ON(PMEM_F_MEM_NOFLUSH != PMEM2_F_MEM_NOFLUSH); return 0; } pmdk-1.11.1/src/test/Makefile.inc0000664000000000000000000005202314123364546015216 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2020, Intel Corporation # # # src/test/Makefile.inc -- common Makefile defs for unit tests # # These defaults apply to most unit tests. The individual Makefile # for each unit test overrides the defaults as necessary. # TOP := $(dir $(lastword $(MAKEFILE_LIST)))../.. include $(TOP)/src/common.inc INCS += $(OS_INCS) LDFLAGS += $(OS_LIBS) LIBS_DIR=$(TOP)/src EXAMPLES_DIR=$(TOP)/src/examples EX_LIBPMEM=$(EXAMPLES_DIR)/libpmem EX_LIBPMEM2=$(EXAMPLES_DIR)/libpmem2 EX_LIBPMEMBLK=$(EXAMPLES_DIR)/libpmemblk EX_LIBPMEMLOG=$(EXAMPLES_DIR)/libpmemlog EX_LIBPMEMOBJ=$(EXAMPLES_DIR)/libpmemobj EX_PMREORDER=$(EXAMPLES_DIR)/pmreorder UT = ../unittest/libut.a LIBS += $(UT) $(LIBUUID) ifeq ($(USE_LIBUNWIND),y) LIBS += $(LIBDL) $(LIBUNWIND_LIBS) endif LIBS += -L$(LIBS_DIR)/debug LIBS += -pthread $(LIBUTIL) ifeq ($(LIBRT_NEEDED), y) LIBS += -lrt endif ifeq ($(LIBPMEMPOOL), y) LIBPMEM=y DYNAMIC_LIBS += -lpmempool STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmempool.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmempool.a CFLAGS += -DUSE_LIBDL endif ifeq ($(LIBPMEMBLK), y) LIBPMEM=y DYNAMIC_LIBS += -lpmemblk STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmemblk.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmemblk.a endif ifeq ($(LIBPMEMLOG), y) LIBPMEM=y DYNAMIC_LIBS += -lpmemlog STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmemlog.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmemlog.a endif ifeq ($(LIBPMEMOBJ), y) LIBPMEM=y DYNAMIC_LIBS += -lpmemobj STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmemobj.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmemobj.a endif ifeq ($(LIBPMEMOBJ), internal-debug) LIBPMEM=y LIBPMEMCOMMON=internal-debug OBJS += $(TOP)/src/debug/libpmemobj/alloc_class.o\ $(TOP)/src/debug/libpmemobj/bucket.o\ $(TOP)/src/debug/libpmemobj/container_ravl.o\ $(TOP)/src/debug/libpmemobj/container_seglists.o\ $(TOP)/src/debug/libpmemobj/critnib.o\ $(TOP)/src/debug/libpmemobj/ctl_debug.o\ $(TOP)/src/debug/libpmemobj/heap.o\ $(TOP)/src/debug/libpmemobj/lane.o\ $(TOP)/src/debug/libpmemobj/libpmemobj.o\ $(TOP)/src/debug/libpmemobj/list.o\ $(TOP)/src/debug/libpmemobj/memblock.o\ $(TOP)/src/debug/libpmemobj/memops.o\ $(TOP)/src/debug/libpmemobj/obj.o\ $(TOP)/src/debug/libpmemobj/palloc.o\ $(TOP)/src/debug/libpmemobj/pmalloc.o\ $(TOP)/src/debug/libpmemobj/recycler.o\ $(TOP)/src/debug/libpmemobj/ulog.o\ $(TOP)/src/debug/libpmemobj/sync.o\ $(TOP)/src/debug/libpmemobj/tx.o\ $(TOP)/src/debug/libpmemobj/stats.o INCS += -I$(TOP)/src/libpmemobj endif ifeq ($(LIBPMEMOBJ), internal-nondebug) LIBPMEM=y LIBPMEMCOMMON=internal-nondebug OBJS += $(TOP)/src/nondebug/libpmemobj/alloc_class.o\ $(TOP)/src/nondebug/libpmemobj/bucket.o\ $(TOP)/src/nondebug/libpmemobj/container_ravl.o\ $(TOP)/src/nondebug/libpmemobj/container_seglists.o\ $(TOP)/src/nondebug/libpmemobj/critnib.o\ $(TOP)/src/nondebug/libpmemobj/ctl_debug.o\ $(TOP)/src/nondebug/libpmemobj/heap.o\ $(TOP)/src/nondebug/libpmemobj/lane.o\ $(TOP)/src/nondebug/libpmemobj/libpmemobj.o\ $(TOP)/src/nondebug/libpmemobj/list.o\ $(TOP)/src/nondebug/libpmemobj/memblock.o\ $(TOP)/src/nondebug/libpmemobj/memops.o\ $(TOP)/src/nondebug/libpmemobj/obj.o\ $(TOP)/src/nondebug/libpmemobj/palloc.o\ $(TOP)/src/nondebug/libpmemobj/pmalloc.o\ $(TOP)/src/nondebug/libpmemobj/recycler.o\ $(TOP)/src/nondebug/libpmemobj/ulog.o\ $(TOP)/src/nondebug/libpmemobj/sync.o\ $(TOP)/src/nondebug/libpmemobj/tx.o\ $(TOP)/src/nondebug/libpmemobj/stats.o INCS += -I$(TOP)/src/libpmemobj endif ifeq ($(LIBPMEMSET), y) LIBPMEM2=y DYNAMIC_LIBS += -lpmemset STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmemset.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmemset.a endif ifeq ($(LIBPMEMSET), internal-debug) LIBPMEM2=y LIBPMEMCORE=internal-debug OBJS +=\ $(TOP)/src/debug/libpmemset/config.o\ $(TOP)/src/debug/libpmemset/errormsg.o\ $(TOP)/src/debug/libpmemset/file.o\ $(TOP)/src/debug/libpmemset/file_posix.o\ $(TOP)/src/debug/libpmemset/libpmemset.o\ $(TOP)/src/debug/libpmemset/part.o\ $(TOP)/src/debug/libpmemset/pmemset.o\ $(TOP)/src/debug/libpmemset/pmemset_utils.o\ $(TOP)/src/debug/libpmemset/source.o INCS += -I$(TOP)/src/libpmemset endif ifeq ($(LIBPMEMSET), internal-nondebug) LIBPMEM2=y LIBPMEMCORE=internal-nondebug OBJS +=\ $(TOP)/src/nondebug/libpmemset/config.o\ $(TOP)/src/nondebug/libpmemset/errormsg.o\ $(TOP)/src/nondebug/libpmemset/file.o\ $(TOP)/src/nondebug/libpmemset/file_posix.o\ $(TOP)/src/nondebug/libpmemset/libpmemset.o\ $(TOP)/src/nondebug/libpmemset/part.o\ $(TOP)/src/nondebug/libpmemset/pmemset.o\ $(TOP)/src/nondebug/libpmemset/pmemset_utils.o\ $(TOP)/src/nondebug/libpmemset/source.o INCS += -I$(TOP)/src/libpmemset endif ifeq ($(LIBPMEM), internal-nondebug) OBJS +=\ $(TOP)/src/nondebug/libpmem/libpmem.o\ $(TOP)/src/nondebug/libpmem/memops_generic.o\ $(TOP)/src/nondebug/libpmem/pmem.o\ $(TOP)/src/nondebug/libpmem/pmem_posix.o include $(TOP)/src/libpmem2/$(ARCH)/sources.inc OBJS_MEM = $(LIBPMEM2_ARCH_SOURCE:.c=.o) OBJS += $(addprefix $(TOP)/src/nondebug/libpmem/, ${OBJS_MEM}) INCS += -I$(TOP)/src/libpmem INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) endif ifeq ($(LIBPMEM), internal-debug) OBJS +=\ $(TOP)/src/debug/libpmem/libpmem.o\ $(TOP)/src/debug/libpmem/memops_generic.o\ $(TOP)/src/debug/libpmem/pmem.o\ $(TOP)/src/debug/libpmem/pmem_posix.o include $(TOP)/src/libpmem2/$(ARCH)/sources.inc OBJS_MEM = $(LIBPMEM2_ARCH_SOURCE:.c=.o) OBJS += $(addprefix $(TOP)/src/debug/libpmem/, ${OBJS_MEM}) INCS += -I$(TOP)/src/libpmem INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) endif ifeq ($(LIBPMEM2), internal-debug) LIBPMEMCORE=internal-debug OBJS +=\ $(TOP)/src/debug/libpmem2/badblocks.o\ $(TOP)/src/debug/libpmem2/badblocks_$(OS_DIMM).o\ $(TOP)/src/debug/libpmem2/config.o\ $(TOP)/src/debug/libpmem2/errormsg.o\ $(TOP)/src/debug/libpmem2/libpmem2.o\ $(TOP)/src/debug/libpmem2/map.o\ $(TOP)/src/debug/libpmem2/map_posix.o\ $(TOP)/src/debug/libpmem2/memops_generic.o\ $(TOP)/src/debug/libpmem2/persist.o\ $(TOP)/src/debug/libpmem2/persist_posix.o\ $(TOP)/src/debug/libpmem2/pmem2_utils.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_$(OS_DIMM).o\ $(TOP)/src/debug/libpmem2/source.o\ $(TOP)/src/debug/libpmem2/source_posix.o\ $(TOP)/src/debug/libpmem2/usc_$(OS_DIMM).o\ $(TOP)/src/debug/libpmem2/vm_reservation.o\ $(TOP)/src/debug/libpmem2/vm_reservation_posix.o\ ifeq ($(OS_KERNEL_NAME),Linux) OBJS +=\ $(TOP)/src/debug/libpmem2/auto_flush_linux.o\ $(TOP)/src/debug/libpmem2/deep_flush_linux.o\ $(TOP)/src/debug/libpmem2/extent_linux.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_linux.o else OBJS +=\ $(TOP)/src/debug/libpmem2/auto_flush_none.o\ $(TOP)/src/debug/libpmem2/extent_none.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_other.o\ $(TOP)/src/debug/libpmem2/deep_flush_other.o endif ifeq ($(OS_DIMM),ndctl) OBJS +=\ $(TOP)/src/debug/libpmem2/region_namespace_ndctl.o\ $(TOP)/src/debug/libpmem2/numa_ndctl.o else OBJS +=\ $(TOP)/src/debug/libpmem2/region_namespace_none.o\ $(TOP)/src/debug/libpmem2/numa_none.o endif include $(TOP)/src/libpmem2/$(ARCH)/sources.inc OBJS_MEM = $(LIBPMEM2_ARCH_SOURCE:.c=.o) OBJS += $(addprefix $(TOP)/src/nondebug/libpmem2/, ${OBJS_MEM}) INCS += -I$(TOP)/src/common INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) endif ifeq ($(LIBPMEM2), internal-nondebug) LIBPMEMCORE=internal-nondebug OBJS +=\ $(TOP)/src/nondebug/libpmem2/libpmem2.o\ $(TOP)/src/nondebug/libpmem2/badblocks.o\ $(TOP)/src/nondebug/libpmem2/badblocks_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/config.o\ $(TOP)/src/nondebug/libpmem2/source.o\ $(TOP)/src/nondebug/libpmem2/source_posix.o\ $(TOP)/src/nondebug/libpmem2/errormsg.o\ $(TOP)/src/nondebug/libpmem2/map.o\ $(TOP)/src/nondebug/libpmem2/map_posix.o\ $(TOP)/src/nondebug/libpmem2/memops_generic.o\ $(TOP)/src/nondebug/libpmem2/persist.o\ $(TOP)/src/nondebug/libpmem2/persist_posix.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/usc_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/vm_reservation.o\ $(TOP)/src/nondebug/libpmem2/vm_reservation_posix.o\ ifeq ($(OS_KERNEL_NAME),Linux) OBJS +=\ $(TOP)/src/nondebug/libpmem2/auto_flush_linux.o\ $(TOP)/src/nondebug/libpmem2/deep_flush_linuc.o\ $(TOP)/src/nondebug/libpmem2/extent_linux.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_linux.o else OBJS +=\ $(TOP)/src/nondebug/libpmem2/auto_flush_none.o\ $(TOP)/src/nondebug/libpmem2/extent_none.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_other.o $(TOP)/src/nondebug/libpmem2/deep_flush_other.o endif ifeq ($(OS_DIMM),ndctl) OBJS +=\ $(TOP)/src/nondebug/libpmem2/region_namespace_ndctl.o\ $(TOP)/src/nondebug/libpmem2/numa_ndctl.o else OBJS +=\ $(TOP)/src/nondebug/libpmem2/region_namespace_none.o\ $(TOP)/src/nondebug/libpmem2/numa_none.o endif include $(TOP)/src/libpmem2/$(ARCH)/sources.inc OBJS_MEM = $(LIBPMEM2_ARCH_SOURCE:.c=.o) OBJS += $(addprefix $(TOP)/src/debug/libpmem2/, ${OBJS_MEM}) INCS += -I$(TOP)/src/common INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) endif ifeq ($(LIBPMEM2),y) DYNAMIC_LIBS += -lpmem2 STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmem2.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmem2.a endif ifeq ($(LIBPMEMCOMMON), y) LIBPMEM=y LIBPMEMCORE=y OBJS += $(LIBS_DIR)/debug/libpmemcommon.a INCS += -I$(TOP)/src/common endif ifeq ($(LIBPMEMCOMMON), internal-nondebug) LIBPMEMCORE=internal-nondebug OBJS +=\ $(TOP)/src/nondebug/common/bad_blocks.o\ $(TOP)/src/nondebug/common/set_badblocks.o\ $(TOP)/src/nondebug/common/ctl.o\ $(TOP)/src/nondebug/common/ctl_prefault.o\ $(TOP)/src/nondebug/common/ctl_sds.o\ $(TOP)/src/nondebug/common/ctl_fallocate.o\ $(TOP)/src/nondebug/common/ctl_cow.o\ $(TOP)/src/nondebug/common/file.o\ $(TOP)/src/nondebug/common/file_posix.o\ $(TOP)/src/nondebug/common/mmap.o\ $(TOP)/src/nondebug/common/mmap_posix.o\ $(TOP)/src/nondebug/common/os_deep_linux.o\ $(TOP)/src/nondebug/common/pool_hdr.o\ $(TOP)/src/nondebug/common/set.o\ $(TOP)/src/nondebug/common/shutdown_state.o\ $(TOP)/src/nondebug/common/util.o\ $(TOP)/src/nondebug/common/util_posix.o\ $(TOP)/src/nondebug/common/uuid.o\ $(call osdep, $(TOP)/src/nondebug/common/uuid,.o)\ $(TOP)/src/nondebug/libpmem2/pmem2_utils.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/config.o\ $(TOP)/src/nondebug/libpmem2/persist_posix.o\ $(TOP)/src/nondebug/libpmem2/badblocks.o\ $(TOP)/src/nondebug/libpmem2/badblocks_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/usc_$(OS_DIMM).o\ $(TOP)/src/nondebug/libpmem2/source.o\ $(TOP)/src/nondebug/libpmem2/source_posix.o ifeq ($(OS_KERNEL_NAME),Linux) OBJS +=\ $(TOP)/src/nondebug/libpmem2/auto_flush_linux.o\ $(TOP)/src/nondebug/libpmem2/deep_flush_linux.o\ $(TOP)/src/nondebug/libpmem2/extent_linux.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_linux.o else OBJS +=\ $(TOP)/src/nondebug/libpmem2/auto_flush_none.o\ $(TOP)/src/nondebug/libpmem2/extent_none.o\ $(TOP)/src/nondebug/libpmem2/pmem2_utils_other.o\ $(TOP)/src/nondebug/libpmem2/deep_flush_other.o endif ifeq ($(OS_DIMM),ndctl) OBJS +=\ $(TOP)/src/nondebug/libpmem2/region_namespace_ndctl.o\ $(TOP)/src/nondebug/libpmem2/numa_ndctl.o else OBJS +=\ $(TOP)/src/nondebug/libpmem2/region_namespace_none.o\ $(TOP)/src/nondebug/libpmem2/numa_none.o endif INCS += -I$(TOP)/src/common endif ifeq ($(LIBPMEMCOMMON), internal-debug) LIBPMEMCORE=internal-debug OBJS +=\ $(TOP)/src/debug/common/bad_blocks.o\ $(TOP)/src/debug/common/set_badblocks.o\ $(TOP)/src/debug/common/ctl.o\ $(TOP)/src/debug/common/ctl_prefault.o\ $(TOP)/src/debug/common/ctl_sds.o\ $(TOP)/src/debug/common/ctl_fallocate.o\ $(TOP)/src/debug/common/ctl_cow.o\ $(TOP)/src/debug/common/file.o\ $(TOP)/src/debug/common/file_posix.o\ $(TOP)/src/debug/common/mmap.o\ $(TOP)/src/debug/common/mmap_posix.o\ $(TOP)/src/debug/common/os_deep_linux.o\ $(TOP)/src/debug/common/pool_hdr.o\ $(TOP)/src/debug/common/set.o\ $(TOP)/src/debug/common/shutdown_state.o\ $(TOP)/src/debug/common/uuid.o\ $(call osdep, $(TOP)/src/debug/common/uuid,.o)\ $(TOP)/src/debug/libpmem2/pmem2_utils.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_$(OS_DIMM).o\ $(TOP)/src/debug/libpmem2/config.o\ $(TOP)/src/debug/libpmem2/persist_posix.o\ $(TOP)/src/debug/libpmem2/badblocks.o\ $(TOP)/src/debug/libpmem2/badblocks_$(OS_DIMM).o\ $(TOP)/src/debug/libpmem2/source.o\ $(TOP)/src/debug/libpmem2/source_posix.o\ $(TOP)/src/debug/libpmem2/usc_$(OS_DIMM).o ifeq ($(OS_KERNEL_NAME),Linux) OBJS +=\ $(TOP)/src/debug/libpmem2/auto_flush_linux.o\ $(TOP)/src/debug/libpmem2/deep_flush_linux.o\ $(TOP)/src/debug/libpmem2/extent_linux.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_linux.o else OBJS +=\ $(TOP)/src/debug/libpmem2/auto_flush_none.o\ $(TOP)/src/debug/libpmem2/extent_none.o\ $(TOP)/src/debug/libpmem2/pmem2_utils_other.o\ $(TOP)/src/debug/libpmem2/deep_flush_other.o endif ifeq ($(OS_DIMM),ndctl) OBJS +=\ $(TOP)/src/debug/libpmem2/region_namespace_ndctl.o\ $(TOP)/src/debug/libpmem2/numa_ndctl.o else OBJS +=\ $(TOP)/src/debug/libpmem2/region_namespace_none.o\ $(TOP)/src/debug/libpmem2/numa_none.o endif INCS += -I$(TOP)/src/common endif ifeq ($(LIBPMEMCORE), y) LIBPMEM=y OBJS += $(LIBS_DIR)/debug/libpmemcore.a INCS += -I$(TOP)/src/core endif ifeq ($(LIBPMEMCORE), internal-nondebug) OBJS +=\ $(TOP)/src/nondebug/core/alloc.o\ $(TOP)/src/nondebug/core/fs_posix.o\ $(TOP)/src/nondebug/core/os_posix.o\ $(TOP)/src/nondebug/core/os_thread_posix.o\ $(TOP)/src/nondebug/core/out.o\ $(TOP)/src/nondebug/core/ravl.o\ $(TOP)/src/nondebug/core/ravl_interval.o\ $(TOP)/src/nondebug/core/util.o\ $(TOP)/src/nondebug/core/util_posix.o INCS += -I$(TOP)/src/core endif ifeq ($(LIBPMEMCORE), internal-debug) OBJS +=\ $(TOP)/src/debug/core/alloc.o\ $(TOP)/src/debug/core/fs_posix.o\ $(TOP)/src/debug/core/os_posix.o\ $(TOP)/src/debug/core/os_thread_posix.o\ $(TOP)/src/debug/core/out.o\ $(TOP)/src/debug/core/ravl.o\ $(TOP)/src/debug/core/ravl_interval.o\ $(TOP)/src/debug/core/util.o\ $(TOP)/src/debug/core/util_posix.o INCS += -I$(TOP)/src/core endif ifeq ($(LIBPMEM),y) DYNAMIC_LIBS += -lpmem STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmem.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmem.a endif ifeq ($(LIBRPMEM),y) DYNAMIC_LIBS += -lrpmem STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/librpmem.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/librpmem.a endif ifneq ($(LIBPMEMCOMMON)$(LIBPMEM)$(LIBPMEM2)$(LIBPMEMPOOL)$(LIBPMEMBLK)$(LIBPMEMLOG)$(LIBPMEMOBJ)$(LIBRPMEM),) LIBS += -pthread endif ifneq ($(LIBPMEMCOMMON)$(LIBPMEMPOOL)$(LIBPMEMOBJ),) LIBS += $(LIBDL) endif ifneq ($(LIBPMEM)$(LIBPMEM2)$(LIBPMEMCOMMON)$(LIBPMEMPOOL)$(LIBPMEMBLK)$(LIBPMEMLOG)$(LIBPMEMOBJ),) CFLAGS += $(LIBNDCTL_CFLAGS) LIBS += $(LIBNDCTL_LIBS) endif # # This is a helper function to be combined with usage of macros available # in the unittest framework. It scans the code for functions that should be # wrapped and adds required linker flags. # PAREN=( extract_funcs = $(shell \ awk -F '[$(PAREN),]' \ '/(FUNC_MOCK_RET_ALWAYS|FUNC_MOCK_RET_ALWAYS_VOID|FUNC_MOCK)\$(PAREN)[^,]/ \ { \ print "-Wl,--wrap=" $$2 \ }' $(1) ) INCS += -I../unittest -I$(TOP)/src/include -I$(TOP)/src/common -I$(TOP)/src/core COMMON_FLAGS = -ggdb COMMON_FLAGS += -Wall COMMON_FLAGS += -Werror COMMON_FLAGS += -Wpointer-arith ifeq ($(IS_ICC), n) COMMON_FLAGS += -Wunused-macros endif COMMON_FLAGS += -fno-common CXXFLAGS = -std=c++11 CXXFLAGS += $(GLIBC_CXXFLAGS) CXXFLAGS += -ggdb CXXFLAGS += $(COMMON_FLAGS) CXXFLAGS += $(EXTRA_CXXFLAGS) CFLAGS = -std=gnu99 CFLAGS += -Wmissing-prototypes CFLAGS += $(COMMON_FLAGS) CFLAGS += -Wsign-conversion ifeq ($(WUNREACHABLE_CODE_RETURN_AVAILABLE), y) CFLAGS += -Wunreachable-code-return endif ifeq ($(WMISSING_VARIABLE_DECLARATIONS_AVAILABLE), y) CFLAGS += -Wmissing-variable-declarations endif ifeq ($(WFLOAT_EQUAL_AVAILABLE), y) CFLAGS += -Wfloat-equal endif ifeq ($(WCAST_FUNCTION_TYPE_AVAILABLE), y) CFLAGS += -Wcast-function-type endif ifeq ($(LINK_NDCTL),y) CFLAGS += $(LIBNDCTL_CFLAGS) LIBS += $(LIBNDCTL_LIBS) endif CFLAGS += $(EXTRA_CFLAGS) LDFLAGS = -Wl,--warn-common -Wl,--fatal-warnings $(EXTRA_LDFLAGS) ifeq ($(OS_DIMM),ndctl) CFLAGS += $(OS_DIMM_CFLAG) CFLAGS += -DSDS_ENABLED endif ifeq ($(COVERAGE),1) CFLAGS += $(GCOV_CFLAGS) CXXFLAGS += $(GCOV_CFLAGS) LDFLAGS += $(GCOV_LDFLAGS) LIBS += $(GCOV_LIBS) endif ifeq ($(VALGRIND),0) CFLAGS += -DVALGRIND_ENABLED=0 CXXFLAGS += -DVALGRIND_ENABLED=0 endif ifeq ($(FAULT_INJECTION),1) CFLAGS += -DFAULT_INJECTION=1 CXXFLAGS += -DFAULT_INJECTION=1 endif ifneq ($(SANITIZE),) CFLAGS += -fsanitize=$(SANITIZE) CXXFLAGS += -fsanitize=$(SANITIZE) LDFLAGS += -fsanitize=$(SANITIZE) endif LINKER=$(CC) ifeq ($(COMPILE_LANG), cpp) LINKER=$(CXX) endif SUFFIX_STATIC_DEBUG=static-debug SUFFIX_STATIC_NONDEBUG=static-nondebug ifneq ($(TARGET),) SCP_TARGET=$(TARGET) SCP_SRC_DIR=. # # By default debug and non-debug static versions are built. # It can be changed by setting BUILD_STATIC_DEBUG, BUILD_STATIC_NONDEBUG # or BUILD_STATIC (for both of them) to 'n'. # ifneq ($(BUILD_STATIC),n) ifneq ($(BUILD_STATIC_DEBUG),n) TARGET_STATIC_DEBUG=$(TARGET).$(SUFFIX_STATIC_DEBUG) SCP_TARGET_STATIC_DEBUG=$(SCP_SRC_DIR)/$(SCP_TARGET).$(SUFFIX_STATIC_DEBUG) endif ifneq ($(BUILD_STATIC_NONDEBUG),n) ifneq ($(DEBUG),1) TARGET_STATIC_NONDEBUG=$(TARGET).$(SUFFIX_STATIC_NONDEBUG) SCP_TARGET_STATIC_NONDEBUG=$(SCP_SRC_DIR)/$(SCP_TARGET).$(SUFFIX_STATIC_NONDEBUG) endif endif endif endif SCP=../sync-remotes/copy-to-remote-nodes.sh TESTCONFIG=../testconfig.sh SYNC_FILE=.synced MAKEFILE_DEPS=Makefile ../Makefile.inc $(TOP)/src/common.inc ifneq ($(HEADERS),) ifneq ($(filter 1 2, $(CSTYLEON)),) TMP_HEADERS := $(addsuffix tmp, $(HEADERS)) endif endif all: $(TARGET) $(TARGET_STATIC_DEBUG) $(TARGET_STATIC_NONDEBUG) $(UT): $(MAKE) -C ../unittest $(TARGET_STATIC_DEBUG): $(TMP_HEADERS) $(OBJS) $(UT) $(STATIC_DEBUG_LIBS) $(EXTRA_DEPS) $(MAKEFILE_DEPS) $(LINKER) -o $@ $(LDFLAGS) $(OBJS) $(STATIC_DEBUG_LIBS) $(LIBS) $(TARGET_STATIC_NONDEBUG): $(TMP_HEADERS) $(OBJS) $(UT) $(STATIC_NONDEBUG_LIBS) $(EXTRA_DEPS) $(MAKEFILE_DEPS) $(LINKER) -o $@ $(LDFLAGS) $(OBJS) $(STATIC_NONDEBUG_LIBS) $(LIBS) $(TARGET): $(TMP_HEADERS) $(OBJS) $(UT) $(EXTRA_DEPS) $(MAKEFILE_DEPS) $(LINKER) -o $@ $(LDFLAGS) $(OBJS) $(DYNAMIC_LIBS) $(LIBS) objdir=. %.o: %.c $(MAKEFILE_DEPS) $(call check-cstyle, $<) @mkdir -p .deps $(CC) -MD -c $(CFLAGS) $(INCS) $(call coverage-path, $<) -o $@ $(call check-os, $@, $<) $(create-deps) %.o: %.cpp $(MAKEFILE_DEPS) $(call check-cstyle, $<) @mkdir -p .deps $(CXX) -MD -c $(CXXFLAGS) $(INCS) $(call coverage-path, $<) -o $@ $(call check-os, $@, $<) $(create-deps) %.htmp: %.h $(call check-cstyle, $<, $@) clean: $(RM) *.o */*.o core *.core a.out *.log testfile* $(SYNC_FILE) $(TMP_HEADERS) clobber: clean $(RM) $(TARGET) $(TARGET).$(SUFFIX_STATIC_DEBUG) $(TARGET).$(SUFFIX_STATIC_NONDEBUG) $(RM) -r .deps $(RM) -r __pycache__ $(TESTCONFIG): $(SYNC_FILE): $(TARGET) $(TESTCONFIG) ifeq ($(SCP_TO_REMOTE_NODES), y) ifeq ($(SCP_TARGET),) $(SCP) test else ifeq ($(SCP_SRC_DIR),) $(error SCP_SRC_DIR is not set) endif $(SCP) common $(SCP) test $(SCP_SRC_DIR)/$(SCP_TARGET) $(SCP_TARGET_STATIC_DEBUG) $(SCP_TARGET_STATIC_NONDEBUG) endif @touch $(SYNC_FILE) endif sync-test: all $(SYNC_FILE) $(TESTCONFIG) TST=$(shell basename `pwd`) TSTCHECKS=$(shell ls -1 TEST* 2> /dev/null | grep '^TEST[0-9]\+$$' | sort -V) TSTCHECKSPY=$(shell test -f TESTS.py && cd .. && ./RUNTESTS.py --list-testcases $(TST) | while read name; do echo py/$$name; done) $(TSTCHECKSPY): @cd .. && ./RUNTESTS.py $(subst nondebug,release,$(RUNTEST_OPTIONS)) -u $(shell echo $@ | sed 's/^py\/[^0-9]*\([0-9]*\)$$/\1/') -- ${TST} $(TSTCHECKS): sync-test @cd .. && ./RUNTESTS ${TST} $(RUNTEST_OPTIONS) -s $@ check: sync-test @cd .. && ./RUNTESTS ${TST} $(RUNTEST_OPTIONS) pcheck: export NOTTY=1 pcheck: $(TSTCHECKS) pycheck: $(TSTCHECKSPY) test: all TOOLS=../tools $(TOOLS)/anonymous_mmap/anonymous_mmap: $(MAKE) -C $(TOOLS)/anonymous_mmap all ifeq ($(USE_ANONYMOUS_MMAP), y) all: $(TOOLS)/anonymous_mmap/anonymous_mmap endif $(TOOLS)/pmemspoil/pmemspoil: $(MAKE) -C $(TOOLS)/pmemspoil all ifeq ($(USE_PMEMSPOIL), y) all: $(TOOLS)/pmemspoil/pmemspoil endif $(TOOLS)/bttcreate/bttcreate: $(MAKE) -C $(TOOLS)/bttcreate all ifeq ($(USE_BTTCREATE), y) all: $(TOOLS)/bttcreate/bttcreate endif $(TOOLS)/pmemwrite/pmemwrite: $(MAKE) -C $(TOOLS)/pmemwrite all ifeq ($(USE_PMEMWRITE), y) all: $(TOOLS)/pmemwrite/pmemwrite endif $(TOOLS)/pmemalloc/pmemalloc: $(MAKE) -C $(TOOLS)/pmemalloc all ifeq ($(USE_PMEMALLOC), y) all: $(TOOLS)/pmemalloc/pmemalloc endif $(TOOLS)/pmemobjcli/pmemobjcli: $(MAKE) -C $(TOOLS)/pmemobjcli all ifeq ($(USE_PMEMOBJCLI), y) all: $(TOOLS)/pmemobjcli/pmemobjcli endif $(TOOLS)/ddmap/ddmap: $(MAKE) -C $(TOOLS)/ddmap all ifeq ($(USE_DDMAP), y) all: $(TOOLS)/ddmap/ddmap endif $(TOOLS)/obj_verify/obj_verify: $(MAKE) -C $(TOOLS)/obj_verify all ifeq ($(USE_OBJ_VERIFY), y) all: $(TOOLS)/obj_verify/obj_verify endif $(TOOLS)/pmemdetect/pmemdetect.$(SUFFIX_STATIC_NONDEBUG): $(MAKE) -C $(TOOLS)/pmemdetect all all: $(TOOLS)/pmemdetect/pmemdetect.$(SUFFIX_STATIC_NONDEBUG) sparse: $(if $(TARGET), $(sparse-c)) .PHONY: all check clean clobber pcheck test sync-test $(TSTCHECKS) -include .deps/*.P pmdk-1.11.1/src/test/memcheck-ndctl.supp0000664000000000000000000000106714123364546016577 0ustar rootroot{ ndctl suppression Memcheck:Leak match-leak-kinds: definite fun:realloc ... fun:ndctl_pfn_get_first fun:ndctl_namespace_get_pfn ... } { ndctl suppression Memcheck:Leak match-leak-kinds: definite fun:realloc ... fun:ndctl_dax_get_first ... } { memory leak in ndctl 63 Memcheck:Leak match-leak-kinds: reachable fun:malloc ... fun:ndctl_namespace_get_first_badblock ... } { cond jump in libkmod Memcheck:Cond ... fun:kmod_module_new_from_lookup ... fun:ndctl_region_get_first ... } pmdk-1.11.1/src/test/obj_persist_count/0000775000000000000000000000000014123364546016537 5ustar rootrootpmdk-1.11.1/src/test/obj_persist_count/obj_persist_count.c0000664000000000000000000002532214123364546022442 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_persist_count.c -- counting number of persists */ #define _GNU_SOURCE #include "obj.h" #include "pmalloc.h" #include "unittest.h" struct ops_counter { unsigned n_cl_stores; unsigned n_drain; unsigned n_pmem_persist; unsigned n_pmem_msync; unsigned n_pmem_flush; unsigned n_pmem_drain; unsigned n_flush_from_pmem_memcpy; unsigned n_flush_from_pmem_memset; unsigned n_drain_from_pmem_memcpy; unsigned n_drain_from_pmem_memset; unsigned n_pot_cache_misses; }; static struct ops_counter ops_counter; static struct ops_counter tx_counter; #define FLUSH_ALIGN ((uintptr_t)64) #define MOVNT_THRESHOLD 256 static unsigned cl_flushed(const void *addr, size_t len, uintptr_t alignment) { uintptr_t start = (uintptr_t)addr & ~(alignment - 1); uintptr_t end = ((uintptr_t)addr + len + alignment - 1) & ~(alignment - 1); return (unsigned)(end - start) / FLUSH_ALIGN; } #define PMEM_F_MEM_MOVNT (PMEM_F_MEM_WC | PMEM_F_MEM_NONTEMPORAL) #define PMEM_F_MEM_MOV (PMEM_F_MEM_WB | PMEM_F_MEM_TEMPORAL) static unsigned bulk_cl_changed(const void *addr, size_t len, unsigned flags) { uintptr_t start = (uintptr_t)addr & ~(FLUSH_ALIGN - 1); uintptr_t end = ((uintptr_t)addr + len + FLUSH_ALIGN - 1) & ~(FLUSH_ALIGN - 1); unsigned cl_changed = (unsigned)(end - start) / FLUSH_ALIGN; int wc; /* write combining */ if (flags & PMEM_F_MEM_NOFLUSH) wc = 0; /* NOFLUSH always uses temporal instructions */ else if (flags & PMEM_F_MEM_MOVNT) wc = 1; else if (flags & PMEM_F_MEM_MOV) wc = 0; else if (len < MOVNT_THRESHOLD) wc = 0; else wc = 1; /* count number of potential cache misses */ if (!wc) { /* * When we don't use write combining, it means all * cache lines may be missing. */ ops_counter.n_pot_cache_misses += cl_changed; } else { /* * When we use write combining there won't be any cache misses, * with an exception of unaligned beginning or end. */ if (start != (uintptr_t)addr) ops_counter.n_pot_cache_misses++; if (end != ((uintptr_t)addr + len) && start + FLUSH_ALIGN != end) ops_counter.n_pot_cache_misses++; } return cl_changed; } static void flush_cl(const void *addr, size_t len) { unsigned flushed = cl_flushed(addr, len, FLUSH_ALIGN); ops_counter.n_cl_stores += flushed; ops_counter.n_pot_cache_misses += flushed; } static void flush_msync(const void *addr, size_t len) { unsigned flushed = cl_flushed(addr, len, Pagesize); ops_counter.n_cl_stores += flushed; ops_counter.n_pot_cache_misses += flushed; } FUNC_MOCK(pmem_persist, void, const void *addr, size_t len) FUNC_MOCK_RUN_DEFAULT { ops_counter.n_pmem_persist++; flush_cl(addr, len); ops_counter.n_drain++; _FUNC_REAL(pmem_persist)(addr, len); } FUNC_MOCK_END FUNC_MOCK(pmem_msync, int, const void *addr, size_t len) FUNC_MOCK_RUN_DEFAULT { ops_counter.n_pmem_msync++; flush_msync(addr, len); ops_counter.n_drain++; return _FUNC_REAL(pmem_msync)(addr, len); } FUNC_MOCK_END FUNC_MOCK(pmem_flush, void, const void *addr, size_t len) FUNC_MOCK_RUN_DEFAULT { ops_counter.n_pmem_flush++; flush_cl(addr, len); _FUNC_REAL(pmem_flush)(addr, len); } FUNC_MOCK_END FUNC_MOCK(pmem_drain, void, void) FUNC_MOCK_RUN_DEFAULT { ops_counter.n_pmem_drain++; ops_counter.n_drain++; _FUNC_REAL(pmem_drain)(); } FUNC_MOCK_END static void memcpy_nodrain_count(void *dest, const void *src, size_t len, unsigned flags) { unsigned cl_stores = bulk_cl_changed(dest, len, flags); if (!(flags & PMEM_F_MEM_NOFLUSH)) ops_counter.n_flush_from_pmem_memcpy += cl_stores; ops_counter.n_cl_stores += cl_stores; } static void memcpy_persist_count(void *dest, const void *src, size_t len, unsigned flags) { memcpy_nodrain_count(dest, src, len, flags); ops_counter.n_drain_from_pmem_memcpy++; ops_counter.n_drain++; } FUNC_MOCK(pmem_memcpy_persist, void *, void *dest, const void *src, size_t len) FUNC_MOCK_RUN_DEFAULT { memcpy_persist_count(dest, src, len, 0); return _FUNC_REAL(pmem_memcpy_persist)(dest, src, len); } FUNC_MOCK_END FUNC_MOCK(pmem_memcpy_nodrain, void *, void *dest, const void *src, size_t len) FUNC_MOCK_RUN_DEFAULT { memcpy_nodrain_count(dest, src, len, 0); return _FUNC_REAL(pmem_memcpy_nodrain)(dest, src, len); } FUNC_MOCK_END static unsigned sanitize_flags(unsigned flags) { if (flags & PMEM_F_MEM_NOFLUSH) { /* NOFLUSH implies NODRAIN */ flags |= PMEM_F_MEM_NODRAIN; } return flags; } FUNC_MOCK(pmem_memcpy, void *, void *dest, const void *src, size_t len, unsigned flags) FUNC_MOCK_RUN_DEFAULT { flags = sanitize_flags(flags); if (flags & PMEM_F_MEM_NODRAIN) memcpy_nodrain_count(dest, src, len, flags); else memcpy_persist_count(dest, src, len, flags); return _FUNC_REAL(pmem_memcpy)(dest, src, len, flags); } FUNC_MOCK_END FUNC_MOCK(pmem_memmove_persist, void *, void *dest, const void *src, size_t len) FUNC_MOCK_RUN_DEFAULT { memcpy_persist_count(dest, src, len, 0); return _FUNC_REAL(pmem_memmove_persist)(dest, src, len); } FUNC_MOCK_END FUNC_MOCK(pmem_memmove_nodrain, void *, void *dest, const void *src, size_t len) FUNC_MOCK_RUN_DEFAULT { memcpy_nodrain_count(dest, src, len, 0); return _FUNC_REAL(pmem_memmove_nodrain)(dest, src, len); } FUNC_MOCK_END FUNC_MOCK(pmem_memmove, void *, void *dest, const void *src, size_t len, unsigned flags) FUNC_MOCK_RUN_DEFAULT { flags = sanitize_flags(flags); if (flags & PMEM_F_MEM_NODRAIN) memcpy_nodrain_count(dest, src, len, flags); else memcpy_persist_count(dest, src, len, flags); return _FUNC_REAL(pmem_memmove)(dest, src, len, flags); } FUNC_MOCK_END static void memset_nodrain_count(void *dest, size_t len, unsigned flags) { unsigned cl_set = bulk_cl_changed(dest, len, flags); if (!(flags & PMEM_F_MEM_NOFLUSH)) ops_counter.n_flush_from_pmem_memset += cl_set; ops_counter.n_cl_stores += cl_set; } static void memset_persist_count(void *dest, size_t len, unsigned flags) { memset_nodrain_count(dest, len, flags); ops_counter.n_drain_from_pmem_memset++; ops_counter.n_drain++; } FUNC_MOCK(pmem_memset_persist, void *, void *dest, int c, size_t len) FUNC_MOCK_RUN_DEFAULT { memset_persist_count(dest, len, 0); return _FUNC_REAL(pmem_memset_persist)(dest, c, len); } FUNC_MOCK_END FUNC_MOCK(pmem_memset_nodrain, void *, void *dest, int c, size_t len) FUNC_MOCK_RUN_DEFAULT { memset_nodrain_count(dest, len, 0); return _FUNC_REAL(pmem_memset_nodrain)(dest, c, len); } FUNC_MOCK_END FUNC_MOCK(pmem_memset, void *, void *dest, int c, size_t len, unsigned flags) FUNC_MOCK_RUN_DEFAULT { flags = sanitize_flags(flags); if (flags & PMEM_F_MEM_NODRAIN) memset_nodrain_count(dest, len, flags); else memset_persist_count(dest, len, flags); return _FUNC_REAL(pmem_memset)(dest, c, len, flags); } FUNC_MOCK_END /* * reset_counters -- zero all counters */ static void reset_counters(void) { memset(&ops_counter, 0, sizeof(ops_counter)); } /* * print_reset_counters -- print and then zero all counters */ static void print_reset_counters(const char *task, unsigned tx) { #define CNT(name) (ops_counter.name - tx * tx_counter.name) UT_OUT( "%-14s %-7d %-10d %-12d %-10d %-10d %-10d %-15d %-17d %-15d %-17d %-23d", task, CNT(n_cl_stores), CNT(n_drain), CNT(n_pmem_persist), CNT(n_pmem_msync), CNT(n_pmem_flush), CNT(n_pmem_drain), CNT(n_flush_from_pmem_memcpy), CNT(n_drain_from_pmem_memcpy), CNT(n_flush_from_pmem_memset), CNT(n_drain_from_pmem_memset), CNT(n_pot_cache_misses)); #undef CNT reset_counters(); } #define LARGE_SNAPSHOT ((1 << 10) * 10) struct foo_large { uint8_t snapshot[LARGE_SNAPSHOT]; }; struct foo { int val; uint64_t dest; PMEMoid bar; PMEMoid bar2; }; int main(int argc, char *argv[]) { START(argc, argv, "obj_persist_count"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop; if ((pop = pmemobj_create(path, "persist_count", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); UT_OUT( "%-14s %-7s %-10s %-12s %-10s %-10s %-10s %-15s %-17s %-15s %-17s %-23s", "task", "cl(all)", "drain(all)", "pmem_persist", "pmem_msync", "pmem_flush", "pmem_drain", "pmem_memcpy_cls", "pmem_memcpy_drain", "pmem_memset_cls", "pmem_memset_drain", "potential_cache_misses"); print_reset_counters("pool_create", 0); /* allocate one structure to create a run */ pmemobj_alloc(pop, NULL, sizeof(struct foo), 0, NULL, NULL); reset_counters(); PMEMoid root = pmemobj_root(pop, sizeof(struct foo)); UT_ASSERT(!OID_IS_NULL(root)); print_reset_counters("root_alloc", 0); PMEMoid oid; int ret = pmemobj_alloc(pop, &oid, sizeof(struct foo), 0, NULL, NULL); UT_ASSERTeq(ret, 0); print_reset_counters("atomic_alloc", 0); pmemobj_free(&oid); print_reset_counters("atomic_free", 0); struct foo *f = pmemobj_direct(root); TX_BEGIN(pop) { } TX_END memcpy(&tx_counter, &ops_counter, sizeof(ops_counter)); print_reset_counters("tx_begin_end", 0); TX_BEGIN(pop) { f->bar = pmemobj_tx_alloc(sizeof(struct foo), 0); UT_ASSERT(!OID_IS_NULL(f->bar)); } TX_END print_reset_counters("tx_alloc", 1); TX_BEGIN(pop) { f->bar2 = pmemobj_tx_alloc(sizeof(struct foo), 0); UT_ASSERT(!OID_IS_NULL(f->bar2)); } TX_END print_reset_counters("tx_alloc_next", 1); TX_BEGIN(pop) { pmemobj_tx_free(f->bar); } TX_END print_reset_counters("tx_free", 1); TX_BEGIN(pop) { pmemobj_tx_free(f->bar2); } TX_END print_reset_counters("tx_free_next", 1); TX_BEGIN(pop) { pmemobj_tx_xadd_range_direct(&f->val, sizeof(f->val), POBJ_XADD_NO_FLUSH); } TX_END print_reset_counters("tx_add", 1); TX_BEGIN(pop) { pmemobj_tx_xadd_range_direct(&f->val, sizeof(f->val), POBJ_XADD_NO_FLUSH); } TX_END print_reset_counters("tx_add_next", 1); PMEMoid large_foo; pmemobj_zalloc(pop, &large_foo, sizeof(struct foo_large), 0); UT_ASSERT(!OID_IS_NULL(large_foo)); reset_counters(); struct foo_large *flarge = pmemobj_direct(large_foo); TX_BEGIN(pop) { pmemobj_tx_xadd_range_direct(&flarge->snapshot, sizeof(flarge->snapshot), POBJ_XADD_NO_FLUSH); } TX_END print_reset_counters("tx_add_large", 1); TX_BEGIN(pop) { pmemobj_tx_xadd_range_direct(&flarge->snapshot, sizeof(flarge->snapshot), POBJ_XADD_NO_FLUSH); } TX_END print_reset_counters("tx_add_lnext", 1); pmalloc(pop, &f->dest, sizeof(f->val), 0, 0); print_reset_counters("pmalloc", 0); pfree(pop, &f->dest); print_reset_counters("pfree", 0); uint64_t stack_var; pmalloc(pop, &stack_var, sizeof(f->val), 0, 0); print_reset_counters("pmalloc_stack", 0); pfree(pop, &stack_var); print_reset_counters("pfree_stack", 0); pmemobj_close(pop); DONE(NULL); } #ifdef _MSC_VER /* * Since libpmemobj is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) #endif pmdk-1.11.1/src/test/obj_persist_count/TEST1.PS10000664000000000000000000000050714123364546017726 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_persist_count/TEST1 -- unit test for persist count # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit $Env:EXE_DIR\obj_persist_count$Env:EXESUFFIX $DIR\testfile check pass pmdk-1.11.1/src/test/obj_persist_count/TEST30000775000000000000000000000115314123364546017327 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, IBM Corporation # # src/test/obj_persist_count/TEST3 -- unit test for persist count # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem require_build_type debug nondebug require_ppc64 # Pmemcheck would complain about making a store without adding to transaction # in this test. As the test counts the exact number of pmem_persist calls for # sheer transactions, pmemcheck is disabled. configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_persist_count$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_persist_count/mocks_windows.h0000664000000000000000000000215514123364546021601 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of pmem functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmemobj * files, when compiled for the purpose of obj_persist_count test. * It would replace default implementation with mocked functions defined * in obj_persist_count.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define pmem_persist __wrap_pmem_persist #define pmem_flush __wrap_pmem_flush #define pmem_drain __wrap_pmem_drain #define pmem_msync __wrap_pmem_msync #define pmem_memcpy_persist __wrap_pmem_memcpy_persist #define pmem_memcpy_nodrain __wrap_pmem_memcpy_nodrain #define pmem_memcpy __wrap_pmem_memcpy #define pmem_memmove_persist __wrap_pmem_memmove_persist #define pmem_memmove_nodrain __wrap_pmem_memmove_nodrain #define pmem_memmove __wrap_pmem_memmove #define pmem_memset_persist __wrap_pmem_memset_persist #define pmem_memset_nodrain __wrap_pmem_memset_nodrain #define pmem_memset __wrap_pmem_memset #endif pmdk-1.11.1/src/test/obj_persist_count/TEST00000775000000000000000000000116214123364546017324 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_persist_count/TEST0 -- unit test for persist count # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem require_build_type debug nondebug exclude_ppc64 # Pmemcheck would complain about making a store without adding to transaction # in this test. As the test counts the exact number of pmem_msync calls for # sheer transactions, pmemcheck is disabled. configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_persist_count$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_persist_count/Makefile0000664000000000000000000000056114123364546020201 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_persist_count/Makefile -- build obj_persist_count unit test # TARGET = obj_persist_count OBJS = obj_persist_count.o LIBPMEMOBJ=internal-debug BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_persist_count.c) pmdk-1.11.1/src/test/obj_persist_count/obj_persist_count.vcxproj0000664000000000000000000001466014123364546023716 0ustar rootroot Debug x64 Release x64 {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {8D75FA1A-EC74-4F88-8AC1-CE3F98E4D828} Win32Proj obj_pmalloc_basic 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) pmdk-1.11.1/src/test/obj_persist_count/out0.log.match0000664000000000000000000000652314123364546021232 0ustar rootrootobj_persist_count$(nW)TEST0: START: obj_persist_count $(nW)obj_persist_count$(nW) $(nW)testfile task cl(all) drain(all) pmem_persist pmem_msync pmem_flush pmem_drain pmem_memcpy_cls pmem_memcpy_drain pmem_memset_cls pmem_memset_drain potential_cache_misses $(OPT)pool_create 49995 14 0 14 0 0 0 0 0 0 49995 $(OPX)pool_create 50315 19 0 19 0 0 0 0 0 0 50315 root_alloc 454 7 0 7 0 0 0 0 0 0 454 atomic_alloc 129 2 0 2 0 0 0 0 0 0 129 atomic_free 64 1 0 1 0 0 0 0 0 0 64 tx_begin_end 0 0 0 0 0 0 0 0 0 0 0 tx_alloc 193 3 0 3 0 0 0 0 0 0 193 tx_alloc_next 193 3 0 3 0 0 0 0 0 0 193 tx_free 64 1 0 1 0 0 0 0 0 0 64 tx_free_next 64 1 0 1 0 0 0 0 0 0 64 tx_add 194 3 0 3 0 0 0 0 0 0 194 tx_add_next 194 3 0 3 0 0 0 0 0 0 194 tx_add_large 1640 21 0 21 0 0 0 0 0 0 1640 tx_add_lnext 803 8 0 8 0 0 0 0 0 0 803 pmalloc 324 5 0 5 0 0 0 0 0 0 324 pfree 259 4 0 4 0 0 0 0 0 0 259 pmalloc_stack 129 2 0 2 0 0 0 0 0 0 129 pfree_stack 64 1 0 1 0 0 0 0 0 0 64 obj_persist_count$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_persist_count/TEST0.PS10000664000000000000000000000051314123364546017722 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_persist_count/TEST0 -- unit test for persist count # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem setup expect_normal_exit $Env:EXE_DIR\obj_persist_count$Env:EXESUFFIX $DIR\testfile check pass pmdk-1.11.1/src/test/obj_persist_count/.gitignore0000664000000000000000000000002214123364546020521 0ustar rootrootobj_persist_count pmdk-1.11.1/src/test/obj_persist_count/README0000664000000000000000000000070314123364546017417 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_persist_count/README. This directory contains a unit test that verifies the number of internal calls to pmem_flush, pmem_drain and pmem_persist (PMEM FS), or to pmem_msync (non-PMEM FS) for basic pmemobj operations. Any change to the number of PMEM flushes/drains may indicate potential regression introduced as a side effect of other changes in libpmemobj. Usage: $ obj_persist_count pmdk-1.11.1/src/test/obj_persist_count/TEST10000775000000000000000000000116014123364546017323 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_persist_count/TEST1 -- unit test for persist count # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem require_build_type debug nondebug exclude_ppc64 # Pmemcheck would complain about making a store without adding to transaction # in this test. As the test counts the exact number of pmem_persist calls for # sheer transactions, pmemcheck is disabled. configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_persist_count$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_persist_count/obj_persist_count.vcxproj.filters0000664000000000000000000001273614123364546025367 0ustar rootroot {189d0bf0-2f10-40d2-9a97-1c627dede493} {c775678f-276b-4eef-a23a-1e2e5e70e6f2} {1c3585e0-7b64-4460-86ee-dd837e30fecd} {d5932343-5e43-4cca-82a3-cde9c0443952} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Match Files Match Files Test Scripts Test Scripts Header Files pmdk-1.11.1/src/test/obj_persist_count/out1.log.match0000664000000000000000000000652314123364546021233 0ustar rootrootobj_persist_count$(nW)TEST1: START: obj_persist_count $(nW)obj_persist_count$(nW) $(nW)testfile task cl(all) drain(all) pmem_persist pmem_msync pmem_flush pmem_drain pmem_memcpy_cls pmem_memcpy_drain pmem_memset_cls pmem_memset_drain potential_cache_misses $(OPT)pool_create 49282 14 11 0 0 0 0 0 11 3 49275 $(OPX)pool_create 49602 24 11 5 0 5 0 0 11 3 49595 root_alloc 9 5 0 0 3 2 4 2 2 1 5 atomic_alloc 2 2 1 0 0 1 1 0 0 0 1 atomic_free 1 2 1 0 0 1 0 0 0 0 1 tx_begin_end 0 2 0 0 0 2 0 0 0 0 0 tx_alloc 4 1 1 0 1 0 1 0 0 0 3 tx_alloc_next 4 1 1 0 1 0 1 0 0 0 3 tx_free 1 1 1 0 0 0 0 0 0 0 1 tx_free_next 1 1 1 0 0 0 0 0 0 0 1 tx_add 3 3 1 0 0 1 1 0 1 1 1 tx_add_next 3 3 1 0 0 1 1 0 1 1 1 tx_add_large 178 14 6 0 4 4 165 2 3 2 10 tx_add_lnext 164 5 1 0 0 2 161 0 2 2 1 pmalloc 6 4 0 0 2 2 4 2 0 0 2 pfree 5 4 0 0 2 2 3 2 0 0 2 pmalloc_stack 2 2 1 0 0 1 1 0 0 0 1 pfree_stack 1 2 1 0 0 1 0 0 0 0 1 obj_persist_count$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_persist_count/TEST20000775000000000000000000000115514123364546017330 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, IBM Corporation # # src/test/obj_persist_count/TEST2 -- unit test for persist count # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem require_build_type debug nondebug require_ppc64 # Pmemcheck would complain about making a store without adding to transaction # in this test. As the test counts the exact number of pmem_msync calls for # sheer transactions, pmemcheck is disabled. configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_persist_count$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_persist_count/out3.log.match0000664000000000000000000000652314123364546021235 0ustar rootrootobj_persist_count$(nW)TEST3: START: obj_persist_count $(nW)obj_persist_count$(nW) $(nW)testfile task cl(all) drain(all) pmem_persist pmem_msync pmem_flush pmem_drain pmem_memcpy_cls pmem_memcpy_drain pmem_memset_cls pmem_memset_drain potential_cache_misses $(OPT)pool_create 55362 24 11 5 0 5 0 0 11 3 55355 $(OPX)pool_create 50242 14 11 0 0 0 0 0 11 3 50235 root_alloc 13 5 0 0 3 2 8 2 2 1 5 atomic_alloc 3 2 1 0 0 1 2 0 0 0 1 atomic_free 1 2 1 0 0 1 0 0 0 0 1 tx_begin_end 0 2 0 0 0 2 0 0 0 0 0 tx_alloc 5 1 1 0 1 0 2 0 0 0 3 tx_alloc_next 5 1 1 0 1 0 2 0 0 0 3 tx_free 1 1 1 0 0 0 0 0 0 0 1 tx_free_next 1 1 1 0 0 0 0 0 0 0 1 tx_add 5 3 1 0 0 1 2 0 2 1 1 tx_add_next 5 3 1 0 0 1 2 0 2 1 1 tx_add_large 189 14 6 0 4 4 170 2 6 2 13 tx_add_lnext 167 5 1 0 0 2 162 0 4 2 1 pmalloc 10 4 0 0 2 2 8 2 0 0 2 pfree 8 4 0 0 2 2 6 2 0 0 2 pmalloc_stack 3 2 1 0 0 1 2 0 0 0 1 pfree_stack 1 2 1 0 0 1 0 0 0 0 1 obj_persist_count$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_persist_count/out2.log.match0000664000000000000000000000652314123364546021234 0ustar rootrootobj_persist_count$(nW)TEST2: START: obj_persist_count $(nW)obj_persist_count$(nW) $(nW)testfile task cl(all) drain(all) pmem_persist pmem_msync pmem_flush pmem_drain pmem_memcpy_cls pmem_memcpy_drain pmem_memset_cls pmem_memset_drain potential_cache_misses $(OPT)pool_create 62475 14 0 14 0 0 0 0 0 0 62475 $(OPX)pool_create 67595 19 0 19 0 0 0 0 0 0 67595 root_alloc 7178 7 0 7 0 0 0 0 0 0 7178 atomic_alloc 2050 2 0 2 0 0 0 0 0 0 2050 atomic_free 1024 1 0 1 0 0 0 0 0 0 1024 tx_begin_end 0 0 0 0 0 0 0 0 0 0 0 tx_alloc 3074 3 0 3 0 0 0 0 0 0 3074 tx_alloc_next 3074 3 0 3 0 0 0 0 0 0 3074 tx_free 1024 1 0 1 0 0 0 0 0 0 1024 tx_free_next 1024 1 0 1 0 0 0 0 0 0 1024 tx_add 3076 3 0 3 0 0 0 0 0 0 3076 tx_add_next 3076 3 0 3 0 0 0 0 0 0 3076 tx_add_large 21680 21 0 21 0 0 0 0 0 0 21680 tx_add_lnext 8358 8 0 8 0 0 0 0 0 0 8358 pmalloc 5128 5 0 5 0 0 0 0 0 0 5128 pfree 4102 4 0 4 0 0 0 0 0 0 4102 pmalloc_stack 2050 2 0 2 0 0 0 0 0 0 2050 pfree_stack 1024 1 0 1 0 0 0 0 0 0 1024 obj_persist_count$(nW)TEST2: DONE pmdk-1.11.1/src/test/util_ravl/0000775000000000000000000000000014123364546015005 5ustar rootrootpmdk-1.11.1/src/test/util_ravl/TEST00000775000000000000000000000045514123364546015576 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # src/test/util_ravl/TEST0 -- unit test for util_ravl interface # . ../unittest/unittest.sh require_fs_type none require_test_type medium setup expect_normal_exit ./util_ravl$EXESUFFIX pass pmdk-1.11.1/src/test/util_ravl/Makefile0000664000000000000000000000055014123364546016445 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # src/test/util_ravl/Makefile -- build ravl tree unit test # TARGET = util_ravl OBJS = util_ravl.o alloc.o ravl.o out.o util_posix.o util.o INCS += -I$(TOP)/src/common include ../Makefile.inc vpath %.c $(TOP)/src/core vpath %.c $(TOP)/src/common CFLAGS += -DSRCVERSION="" pmdk-1.11.1/src/test/util_ravl/TEST0.PS10000664000000000000000000000045114123364546016171 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # # src/test/util_ravl/TEST0 -- unit test for util_ravl interface # . ..\unittest\unittest.ps1 require_fs_type none require_test_type medium setup expect_normal_exit $Env:EXE_DIR\util_ravl$Env:EXESUFFIX pass pmdk-1.11.1/src/test/util_ravl/util_ravl.vcxproj0000664000000000000000000000714114123364546020426 0ustar rootroot Debug x64 Release x64 {72C9DB46-C665-48AD-B805-BA885B40CA3E} Win32Proj util_ravl 10.0.17134.0 Application true v140 Application false v140 true $(SolutionDir)libpmemobj\;$(IncludePath) $(SolutionDir)libpmemobj\;$(IncludePath) Disabled MaxSpeed {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_ravl/.gitignore0000664000000000000000000000001214123364546016766 0ustar rootrootutil_ravl pmdk-1.11.1/src/test/util_ravl/util_ravl.vcxproj.filters0000664000000000000000000000154214123364546022074 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Source Files Test Files pmdk-1.11.1/src/test/util_ravl/util_ravl.c0000664000000000000000000001222714123364546017156 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2020, Intel Corporation */ /* * util_ravl.c -- unit test for ravl tree */ #include #include #include "ravl.h" #include "util.h" #include "unittest.h" #include "fault_injection.h" static int cmpkey(const void *lhs, const void *rhs) { intptr_t l = (intptr_t)lhs; intptr_t r = (intptr_t)rhs; return (int)(l - r); } static void test_misc(void) { struct ravl *r = ravl_new(cmpkey); struct ravl_node *n = NULL; ravl_insert(r, (void *)3); ravl_insert(r, (void *)6); ravl_insert(r, (void *)1); ravl_insert(r, (void *)7); ravl_insert(r, (void *)9); ravl_insert(r, (void *)5); ravl_insert(r, (void *)8); ravl_insert(r, (void *)2); ravl_insert(r, (void *)4); ravl_insert(r, (void *)10); n = ravl_find(r, (void *)11, RAVL_PREDICATE_EQUAL); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)10, RAVL_PREDICATE_GREATER); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)11, RAVL_PREDICATE_GREATER); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)11, RAVL_PREDICATE_GREATER | RAVL_PREDICATE_EQUAL); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)1, RAVL_PREDICATE_LESS); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)0, RAVL_PREDICATE_LESS_EQUAL); UT_ASSERTeq(n, NULL); n = ravl_find(r, (void *)9, RAVL_PREDICATE_GREATER); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)10); n = ravl_find(r, (void *)9, RAVL_PREDICATE_LESS); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)8); n = ravl_find(r, (void *)9, RAVL_PREDICATE_GREATER | RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)9); n = ravl_find(r, (void *)9, RAVL_PREDICATE_LESS | RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)9); n = ravl_find(r, (void *)100, RAVL_PREDICATE_LESS); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)10); n = ravl_find(r, (void *)0, RAVL_PREDICATE_GREATER); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)1); n = ravl_find(r, (void *)3, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)10, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)6, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)9, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)7, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)1, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)5, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)8, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)2, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); n = ravl_find(r, (void *)4, RAVL_PREDICATE_EQUAL); UT_ASSERTne(n, NULL); ravl_remove(r, n); ravl_delete(r); } static void test_predicate(void) { struct ravl *r = ravl_new(cmpkey); struct ravl_node *n = NULL; ravl_insert(r, (void *)10); ravl_insert(r, (void *)5); ravl_insert(r, (void *)7); n = ravl_find(r, (void *)6, RAVL_PREDICATE_GREATER); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)7); n = ravl_find(r, (void *)6, RAVL_PREDICATE_LESS); UT_ASSERTne(n, NULL); UT_ASSERTeq(ravl_data(n), (void *)5); ravl_delete(r); } static void test_stress(void) { struct ravl *r = ravl_new(cmpkey); for (int i = 0; i < 1000000; ++i) { ravl_insert(r, (void *)(uintptr_t)rand()); } ravl_delete(r); } struct foo { int a; int b; int c; }; static int cmpfoo(const void *lhs, const void *rhs) { const struct foo *l = lhs; const struct foo *r = rhs; return ((l->a + l->b + l->c) - (r->a + r->b + r->c)); } static void test_emplace(void) { struct ravl *r = ravl_new_sized(cmpfoo, sizeof(struct foo)); struct foo a = {1, 2, 3}; struct foo b = {2, 3, 4}; struct foo z = {0, 0, 0}; ravl_emplace_copy(r, &a); ravl_emplace_copy(r, &b); struct ravl_node *n = ravl_find(r, &z, RAVL_PREDICATE_GREATER); struct foo *fn = ravl_data(n); UT_ASSERTeq(fn->a, a.a); UT_ASSERTeq(fn->b, a.b); UT_ASSERTeq(fn->c, a.c); ravl_remove(r, n); n = ravl_find(r, &z, RAVL_PREDICATE_GREATER); fn = ravl_data(n); UT_ASSERTeq(fn->a, b.a); UT_ASSERTeq(fn->b, b.b); UT_ASSERTeq(fn->c, b.c); ravl_remove(r, n); ravl_delete(r); } static void test_fault_injection_ravl_sized() { if (!core_fault_injection_enabled()) return; core_inject_fault_at(PMEM_MALLOC, 1, "ravl_new_sized"); struct ravl *r = ravl_new_sized(NULL, 0); UT_ASSERTeq(r, NULL); UT_ASSERTeq(errno, ENOMEM); } static void test_fault_injection_ravl_node() { if (!core_fault_injection_enabled()) return; struct foo a = {1, 2, 3}; struct ravl *r = ravl_new_sized(cmpfoo, sizeof(struct foo)); UT_ASSERTne(r, NULL); core_inject_fault_at(PMEM_MALLOC, 1, "ravl_new_node"); int ret = ravl_emplace_copy(r, &a); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); } int main(int argc, char *argv[]) { START(argc, argv, "util_ravl"); test_predicate(); test_misc(); test_stress(); test_emplace(); test_fault_injection_ravl_sized(); test_fault_injection_ravl_node(); DONE(NULL); } pmdk-1.11.1/src/test/pmem_movnt/0000775000000000000000000000000014123364546015165 5ustar rootrootpmdk-1.11.1/src/test/pmem_movnt/pmem_movnt.vcxproj.filters0000664000000000000000000000171514123364546022436 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2064aaf4-2eca-4fa2-99dc-b24c1acfe798} Source Files Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/pmem_movnt/TEST00000775000000000000000000000135214123364546015753 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_movnt/TEST0 -- unit test for pmem_memcpy, pmem_memmove # and pmem_memset # . ../unittest/unittest.sh require_test_type medium require_build_type debug setup export PMEM_IS_PMEM_FORCE=1 export PMEM_LOG_LEVEL=15 function test() { expect_normal_exit ./pmem_movnt$EXESUFFIX } function test_all() { unset PMEM_MOVNT_THRESHOLD test export PMEM_MOVNT_THRESHOLD=1024 test export PMEM_MOVNT_THRESHOLD=5 test export PMEM_MOVNT_THRESHOLD=-15 test } test_all export PMEM_AVX512F=0 test_all export PMEM_AVX=0 test_all export PMEM_NO_MOVNT=1 export PMEM_NO_GENERIC_MEMCPY=1 test pass pmdk-1.11.1/src/test/pmem_movnt/Makefile0000664000000000000000000000033714123364546016630 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/pmem_movnt/Makefile -- build pmem_movnt unit test # TARGET = pmem_movnt OBJS = pmem_movnt.o LIBPMEM=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem_movnt/TEST0.PS10000664000000000000000000000437714123364546016364 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/pmem_movnt/TEST0 -- unit test for pmem_memcpy, pmem_memmove # and pmem_memset . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug setup $Env:PMEM_IS_PMEM_FORCE=1 $Env:PMEM_LOG_LEVEL=15 function test { expect_normal_exit $Env:EXE_DIR\pmem_movnt$Env:EXESUFFIX } function test_all { $Env:PMEM_MOVNT_THRESHOLD=$null $Env:PMEM_MOVNT_THRESHOLD=1024 $Env:PMEM_MOVNT_THRESHOLD=5 $Env:PMEM_MOVNT_THRESHOLD=-15 } test_all $Env:PMEM_AVX512F = 0 test_all $Env:PMEM_AVX = 0 test_all $Env:PMEM_NO_MOVNT = 1 $Env:PMEM_NO_GENERIC_MEMCPY = 1 test pass pmdk-1.11.1/src/test/pmem_movnt/.gitignore0000664000000000000000000000001314123364546017147 0ustar rootrootpmem_movnt pmdk-1.11.1/src/test/pmem_movnt/README0000664000000000000000000000053714123364546016052 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_movnt/README. This directory contains a unit test for MOVNT threshold check. The program in pmem_movnt.c verifies if the correct variant of pmem_memcpy, pmem_memmove and pmem_memset functions is used depending on function arguments and the PMEM_MOVNT_THRESHOLD environment variable settings. pmdk-1.11.1/src/test/pmem_movnt/pmem_movnt.c0000664000000000000000000000237114123364546017515 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * pmem_movnt.c -- unit test for MOVNT threshold * * usage: pmem_movnt * */ #include "unittest.h" int main(int argc, char *argv[]) { char *dst; char *src; const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem_movnt %s %savx %savx512f", thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); src = MEMALIGN(64, 8192); dst = MEMALIGN(64, 8192); memset(src, 0x88, 8192); memset(dst, 0, 8192); for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); pmem_memcpy_nodrain(dst, src, size); UT_ASSERTeq(memcmp(src, dst, size), 0); UT_ASSERTeq(dst[size], 0); } for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); pmem_memmove_nodrain(dst, src, size); UT_ASSERTeq(memcmp(src, dst, size), 0); UT_ASSERTeq(dst[size], 0); } for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); pmem_memset_nodrain(dst, 0x77, size); UT_ASSERTeq(dst[0], 0x77); UT_ASSERTeq(dst[size - 1], 0x77); UT_ASSERTeq(dst[size], 0); } ALIGNED_FREE(dst); ALIGNED_FREE(src); DONE(NULL); } pmdk-1.11.1/src/test/pmem_movnt/pmem_movnt.vcxproj0000664000000000000000000000721614123364546020771 0ustar rootroot Debug x64 Release x64 {96D00A19-5CEF-4CC5-BDE8-E33C68BCE90F} Win32Proj pmem_movnt 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_config/0000775000000000000000000000000014123364546015351 5ustar rootrootpmdk-1.11.1/src/test/pmem2_config/Makefile0000664000000000000000000000064014123364546017011 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem2_config/Makefile -- build pmem2_config unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_config OBJS += pmem2_config.o\ ut_pmem2_config.o\ ut_pmem2_source.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_config/pmem2_config.vcxproj0000664000000000000000000001126314123364546021336 0ustar rootroot Debug x64 Release x64 {DE068BE1-A8E9-48A2-B216-92A7CE5EA4CE} pmem2_config 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_config/TESTS.py0000775000000000000000000000413714123364546016635 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class Pmem2Config(t.Test): test_type = t.Short def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') ctx.exec('pmem2_config', self.test_case, filepath) @g.no_testdir() class Pmem2ConfigNoDir(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem2_config', self.test_case) class TEST0(Pmem2ConfigNoDir): """allocation and dealocation of pmem2_config""" test_case = "test_cfg_create_and_delete_valid" class TEST1(Pmem2ConfigNoDir): """allocation of pmem2_config in case of missing memory in system""" test_case = "test_alloc_cfg_enomem" class TEST2(Pmem2ConfigNoDir): """deleting null pmem2_config""" test_case = "test_delete_null_config" class TEST3(Pmem2ConfigNoDir): """set valid granularity in the config""" test_case = "test_config_set_granularity_valid" class TEST4(Pmem2ConfigNoDir): """set invalid granularity in the config""" test_case = "test_config_set_granularity_invalid" class TEST5(Pmem2ConfigNoDir): """setting offset which is too large""" test_case = "test_set_offset_too_large" class TEST6(Pmem2ConfigNoDir): """setting a valid offset""" test_case = "test_set_offset_success" class TEST7(Pmem2ConfigNoDir): """setting a valid length""" test_case = "test_set_length_success" class TEST8(Pmem2ConfigNoDir): """setting maximum possible offset""" test_case = "test_set_offset_max" class TEST9(Pmem2ConfigNoDir): """setting a valid sharing""" test_case = "test_set_sharing_valid" class TEST10(Pmem2ConfigNoDir): """setting a invalid sharing""" test_case = "test_set_sharing_invalid" class TEST11(Pmem2ConfigNoDir): """ setting a valid protection flags """ test_case = "test_set_valid_prot_flag" class TEST12(Pmem2ConfigNoDir): """ setting a invalid protection flags """ test_case = "test_set_invalid_prot_flag" pmdk-1.11.1/src/test/pmem2_config/pmem2_config.vcxproj.filters0000664000000000000000000000370514123364546023007 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files pmdk-1.11.1/src/test/pmem2_config/.gitignore0000664000000000000000000000001514123364546017335 0ustar rootrootpmem2_config pmdk-1.11.1/src/test/pmem2_config/pmem2_config.c0000664000000000000000000001562014123364546020066 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * pmem_config.c -- pmem2_config unittests */ #include "fault_injection.h" #include "unittest.h" #include "ut_pmem2.h" #include "config.h" #include "out.h" #include "source.h" /* * test_cfg_create_and_delete_valid - test pmem2_config allocation */ static int test_cfg_create_and_delete_valid(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config *cfg; int ret = pmem2_config_new(&cfg); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); ret = pmem2_config_delete(&cfg); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(cfg, NULL); return 0; } /* * test_alloc_cfg_enomem - test pmem2_config allocation with error injection */ static int test_alloc_cfg_enomem(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config *cfg; if (!core_fault_injection_enabled()) { return 0; } core_inject_fault_at(PMEM_MALLOC, 1, "pmem2_malloc"); int ret = pmem2_config_new(&cfg); UT_PMEM2_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(cfg, NULL); return 0; } /* * test_delete_null_config - test pmem2_delete on NULL config */ static int test_delete_null_config(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config *cfg = NULL; /* should not crash */ int ret = pmem2_config_delete(&cfg); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(cfg, NULL); return 0; } /* * test_config_set_granularity_valid - check valid granularity values */ static int test_config_set_granularity_valid(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; pmem2_config_init(&cfg); /* check default granularity */ enum pmem2_granularity g = (enum pmem2_granularity)PMEM2_GRANULARITY_INVALID; UT_ASSERTeq(cfg.requested_max_granularity, g); /* change default granularity */ int ret = -1; g = PMEM2_GRANULARITY_BYTE; ret = pmem2_config_set_required_store_granularity(&cfg, g); UT_ASSERTeq(cfg.requested_max_granularity, g); UT_PMEM2_EXPECT_RETURN(ret, 0); /* set granularity once more */ ret = -1; g = PMEM2_GRANULARITY_PAGE; ret = pmem2_config_set_required_store_granularity(&cfg, g); UT_ASSERTeq(cfg.requested_max_granularity, g); UT_PMEM2_EXPECT_RETURN(ret, 0); return 0; } /* * test_config_set_granularity_invalid - check invalid granularity values */ static int test_config_set_granularity_invalid(const struct test_case *tc, int argc, char *argv[]) { /* pass invalid granularity */ int ret = 0; enum pmem2_granularity g_inval = 999; struct pmem2_config cfg; pmem2_config_init(&cfg); ret = pmem2_config_set_required_store_granularity(&cfg, g_inval); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_GRANULARITY_NOT_SUPPORTED); return 0; } /* * test_set_offset_too_large - setting offset which is too large */ static int test_set_offset_too_large(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; /* let's try to set the offset which is too large */ size_t offset = (size_t)INT64_MAX + 1; int ret = pmem2_config_set_offset(&cfg, offset); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_OFFSET_OUT_OF_RANGE); return 0; } /* * test_set_offset_success - setting a valid offset */ static int test_set_offset_success(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; /* let's try to successfully set the offset */ size_t offset = Ut_mmap_align; int ret = pmem2_config_set_offset(&cfg, offset); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(cfg.offset, offset); return 0; } /* * test_set_length_success - setting a valid length */ static int test_set_length_success(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; /* let's try to successfully set the length, can be any length */ size_t length = Ut_mmap_align; int ret = pmem2_config_set_length(&cfg, length); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(cfg.length, length); return 0; } /* * test_set_offset_max - setting maximum possible offset */ static int test_set_offset_max(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; /* let's try to successfully set maximum possible offset */ size_t offset = (INT64_MAX / Ut_mmap_align) * Ut_mmap_align; int ret = pmem2_config_set_offset(&cfg, offset); UT_PMEM2_EXPECT_RETURN(ret, 0); return 0; } /* * test_set_sharing_valid - setting valid sharing */ static int test_set_sharing_valid(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; pmem2_config_init(&cfg); /* check sharing default value */ UT_ASSERTeq(cfg.sharing, PMEM2_SHARED); int ret = pmem2_config_set_sharing(&cfg, PMEM2_PRIVATE); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(cfg.sharing, PMEM2_PRIVATE); return 0; } /* * test_set_sharing_invalid - setting invalid sharing */ static int test_set_sharing_invalid(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; unsigned invalid_sharing = 777; int ret = pmem2_config_set_sharing(&cfg, invalid_sharing); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_SHARING_VALUE); return 0; } /* * test_set_valid_prot_flag -- set valid protection flag */ static int test_set_valid_prot_flag(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; pmem2_config_init(&cfg); int ret = pmem2_config_set_protection(&cfg, PMEM2_PROT_READ); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_protection(&cfg, PMEM2_PROT_WRITE); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_protection(&cfg, PMEM2_PROT_EXEC); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_protection(&cfg, PMEM2_PROT_NONE); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_protection(&cfg, PMEM2_PROT_WRITE | PMEM2_PROT_READ | PMEM2_PROT_EXEC); UT_PMEM2_EXPECT_RETURN(ret, 0); return 0; } /* * test_set_invalid_prot_flag -- set invalid protection flag */ static int test_set_invalid_prot_flag(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_config cfg; pmem2_config_init(&cfg); int ret = pmem2_config_set_protection(&cfg, PROT_WRITE); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_PROT_FLAG); UT_ASSERTeq(cfg.protection_flag, PMEM2_PROT_READ | PMEM2_PROT_WRITE); return 0; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_cfg_create_and_delete_valid), TEST_CASE(test_alloc_cfg_enomem), TEST_CASE(test_delete_null_config), TEST_CASE(test_config_set_granularity_valid), TEST_CASE(test_config_set_granularity_invalid), TEST_CASE(test_set_offset_too_large), TEST_CASE(test_set_offset_success), TEST_CASE(test_set_length_success), TEST_CASE(test_set_offset_max), TEST_CASE(test_set_sharing_valid), TEST_CASE(test_set_sharing_invalid), TEST_CASE(test_set_valid_prot_flag), TEST_CASE(test_set_invalid_prot_flag), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmem2_config"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/memcheck-libibverbs.supp0000664000000000000000000000034314123364546017612 0ustar rootroot{ Memcheck:Param write(buf) ... fun:ibv_cmd_modify_qp fun:modify_rc_qp fun:c4iw_modify_qp fun:ibv_modify_qp@@IBVERBS_1.1 ... } pmdk-1.11.1/src/test/obj_locks/0000775000000000000000000000000014123364546014751 5ustar rootrootpmdk-1.11.1/src/test/obj_locks/obj_locks.vcxproj0000664000000000000000000000725114123364546020340 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {2DE6B085-3C19-49B1-894A-AD9376000E09} Win32Proj obj_locks 10.0.17134.0 Application true v140 Application false v140 CompileAsCpp CompileAsCpp pmdk-1.11.1/src/test/obj_locks/obj_locks.vcxproj.filters0000664000000000000000000000140214123364546021777 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {d8a9a63b-f6d7-40af-964f-ae2c6b7f3b7f} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/obj_locks/TEST00000775000000000000000000000046214123364546015540 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_locks/TEST0 -- unit test for pmemobj_mutex and pmemobj_rwlock # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_locks$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_locks/Makefile0000664000000000000000000000033614123364546016413 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_locks/Makefile -- build obj_locks unit test # TARGET = obj_locks OBJS = obj_locks.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_locks/drd1.log.match0000664000000000000000000000037514123364546017406 0ustar rootroot==$(N)== drd, a thread error detector ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: ./obj_locks$(nW) $(nW) ==$(N)== Parent PID: $(N) ==$(N)==$(W) ==$(N)==$(W) ==$(N)== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: $(N) from $(N)) pmdk-1.11.1/src/test/obj_locks/TEST0.PS10000664000000000000000000000045614123364546016142 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_locks/TEST0 -- unit test for pmemobj_mutex and pmemobj_rwlock # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_locks$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_locks/helgrind2.log.match0000664000000000000000000000062314123364546020426 0ustar rootroot==$(N)== Helgrind, a thread error detector ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: ./obj_locks$(nW) $(nW) ==$(N)== Parent PID: $(N) ==$(N)==$(W) ==$(N)==$(W) ==$(N)== Use --history-level=approx or =none to gain increased speed, at ==$(N)== the cost of reduced accuracy of conflicting-access information ==$(N)== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: $(N) from $(N)) pmdk-1.11.1/src/test/obj_locks/.gitignore0000664000000000000000000000001214123364546016732 0ustar rootrootobj_locks pmdk-1.11.1/src/test/obj_locks/obj_locks.c0000664000000000000000000001132514123364546017064 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * obj_locks.c -- unit test for PMEMmutex, PMEMrwlock and PMEMcond */ #include #include #include "unittest.h" #include "libpmemobj.h" #define LAYOUT_NAME "obj_locks" #define NUM_THREADS 16 #define MAX_FUNC 5 TOID_DECLARE(struct locks, 0); struct locks { PMEMobjpool *pop; PMEMmutex mtx; PMEMrwlock rwlk; PMEMcond cond; int data; }; struct thread_args { os_thread_t t; TOID(struct locks) lock; int t_id; }; typedef void *(*fn_lock)(void *arg); static struct thread_args threads[NUM_THREADS]; /* * do_mutex_lock -- lock and unlock the mutex */ static void * do_mutex_lock(void *arg) { struct thread_args *t = (struct thread_args *)arg; struct locks *lock = D_RW(t->lock); pmemobj_mutex_lock(lock->pop, &lock->mtx); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_mutex_unlock(lock->pop, &lock->mtx); return NULL; } /* * do_rwlock_wrlock -- lock and unlock the write rwlock */ static void * do_rwlock_wrlock(void *arg) { struct thread_args *t = (struct thread_args *)arg; struct locks *lock = D_RW(t->lock); pmemobj_rwlock_wrlock(lock->pop, &lock->rwlk); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_rwlock_unlock(lock->pop, &lock->rwlk); return NULL; } /* * do_rwlock_rdlock -- lock and unlock the read rwlock */ static void * do_rwlock_rdlock(void *arg) { struct thread_args *t = (struct thread_args *)arg; struct locks *lock = D_RW(t->lock); pmemobj_rwlock_rdlock(lock->pop, &lock->rwlk); pmemobj_rwlock_unlock(lock->pop, &lock->rwlk); return NULL; } /* * do_cond_signal -- lock block on a condition variables, * and unlock them by signal */ static void * do_cond_signal(void *arg) { struct thread_args *t = (struct thread_args *)arg; struct locks *lock = D_RW(t->lock); if (t->t_id == 0) { pmemobj_mutex_lock(lock->pop, &lock->mtx); while (lock->data < (NUM_THREADS - 1)) pmemobj_cond_wait(lock->pop, &lock->cond, &lock->mtx); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_mutex_unlock(lock->pop, &lock->mtx); } else { pmemobj_mutex_lock(lock->pop, &lock->mtx); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_cond_signal(lock->pop, &lock->cond); pmemobj_mutex_unlock(lock->pop, &lock->mtx); } return NULL; } /* * do_cond_broadcast -- lock block on a condition variables and unlock * by broadcasting */ static void * do_cond_broadcast(void *arg) { struct thread_args *t = (struct thread_args *)arg; struct locks *lock = D_RW(t->lock); if (t->t_id < (NUM_THREADS / 2)) { pmemobj_mutex_lock(lock->pop, &lock->mtx); while (lock->data < (NUM_THREADS / 2)) pmemobj_cond_wait(lock->pop, &lock->cond, &lock->mtx); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_mutex_unlock(lock->pop, &lock->mtx); } else { pmemobj_mutex_lock(lock->pop, &lock->mtx); lock->data++; pmemobj_persist(lock->pop, &lock->data, sizeof(lock->data)); pmemobj_cond_broadcast(lock->pop, &lock->cond); pmemobj_mutex_unlock(lock->pop, &lock->mtx); } return NULL; } static fn_lock do_lock[MAX_FUNC] = {do_mutex_lock, do_rwlock_wrlock, do_rwlock_rdlock, do_cond_signal, do_cond_broadcast}; /* * do_lock_init -- initialize all types of locks */ static void do_lock_init(struct locks *lock) { pmemobj_mutex_zero(lock->pop, &lock->mtx); pmemobj_rwlock_zero(lock->pop, &lock->rwlk); pmemobj_cond_zero(lock->pop, &lock->cond); } /* * do_lock_mt -- perform multithread lock operations */ static void do_lock_mt(TOID(struct locks) lock, unsigned f_num) { D_RW(lock)->data = 0; for (int i = 0; i < NUM_THREADS; ++i) { threads[i].lock = lock; threads[i].t_id = i; THREAD_CREATE(&threads[i].t, NULL, do_lock[f_num], &threads[i]); } for (int i = 0; i < NUM_THREADS; ++i) THREAD_JOIN(&threads[i].t, NULL); /* * If all threads passed function properly and used every lock, there * should be every element in data array incremented exactly one time * by every thread. */ UT_ASSERT((D_RO(lock)->data == NUM_THREADS) || (D_RO(lock)->data == 0)); } int main(int argc, char *argv[]) { START(argc, argv, "obj_locks"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); TOID(struct locks) lock; POBJ_ALLOC(pop, &lock, struct locks, sizeof(struct locks), NULL, NULL); D_RW(lock)->pop = pop; do_lock_init(D_RW(lock)); for (unsigned i = 0; i < MAX_FUNC; i++) do_lock_mt(lock, i); POBJ_FREE(&lock); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_locks/TEST10000775000000000000000000000061514123364546015541 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_locks/TEST1 -- unit test for pmemobj_mutex and pmemobj_rwlock # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_locks$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_locks/out1.log.match0000664000000000000000000000013114123364546017432 0ustar rootrootobj_locks/TEST1: START: obj_locks ./obj_locks$(nW) $(nW)testfile1 obj_locks/TEST1: DONE pmdk-1.11.1/src/test/obj_locks/TEST20000775000000000000000000000062214123364546015540 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_locks/TEST2 -- unit test for pmemobj_mutex and pmemobj_rwlock # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_locks$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_locks/out2.log.match0000664000000000000000000000013114123364546017433 0ustar rootrootobj_locks/TEST2: START: obj_locks ./obj_locks$(nW) $(nW)testfile1 obj_locks/TEST2: DONE pmdk-1.11.1/src/test/util_poolset_foreach/0000775000000000000000000000000014123364546017215 5ustar rootrootpmdk-1.11.1/src/test/util_poolset_foreach/util_poolset_foreach.vcxproj0000664000000000000000000000672514123364546025055 0ustar rootroot Debug x64 Release x64 {E648732D-78FA-427A-928C-9A59222D37B7} Win32Proj util_poolset_foreach 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_poolset_foreach/util_poolset_foreach.c0000664000000000000000000000241514123364546023574 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * util_poolset_foreach.c -- unit test for util_poolset_foreach_part() * * usage: util_poolset_foreach file... */ #include "unittest.h" #include "set.h" #include "pmemcommon.h" #include #define LOG_PREFIX "ut" #define LOG_LEVEL_VAR "TEST_LOG_LEVEL" #define LOG_FILE_VAR "TEST_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 static int cb(struct part_file *pf, void *arg) { if (pf->is_remote) { /* remote replica */ const char *node_addr = pf->remote->node_addr; const char *pool_desc = pf->remote->pool_desc; char *set_name = (char *)arg; UT_OUT("%s: %s %s", set_name, node_addr, pool_desc); } else { const char *name = pf->part->path; char *set_name = (char *)arg; UT_OUT("%s: %s", set_name, name); } return 0; } int main(int argc, char *argv[]) { START(argc, argv, "util_poolset_foreach"); common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); if (argc < 2) UT_FATAL("usage: %s file...", argv[0]); for (int i = 1; i < argc; i++) { char *fname = argv[i]; int ret = util_poolset_foreach_part(fname, cb, fname); UT_OUT("util_poolset_foreach_part(%s): %d", fname, ret); } common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/util_poolset_foreach/TEST00000775000000000000000000000146014123364546020003 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_poolset_foreach/TEST0 -- unit test for util_poolset_foreach # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup create_poolset $DIR/pool.set1 32K:$DIR/testfile:x create_poolset $DIR/pool.set2 32K:$DIR/testfile1:x 32M:$DIR/testfile2:x create_poolset $DIR/pool.set3\ 32M:$DIR/testfile11:x 32M:$DIR/testfile12:x\ R 64M:$DIR/testfile21:x 32M:$DIR/testfile22:x create_poolset $DIR/pool.set4\ 32M:$DIR/testfile11:x 32M:$DIR/testfile12:x\ R 64M:$DIR/testfile21:x 32M:$DIR/testfile22:x\ R 64M:$DIR/testfile31:x 64M:$DIR/testfile32:x expect_normal_exit ./util_poolset_foreach$EXESUFFIX\ $DIR/pool.set1\ $DIR/pool.set2\ $DIR/pool.set3\ $DIR/pool.set4 check pass pmdk-1.11.1/src/test/util_poolset_foreach/Makefile0000664000000000000000000000041214123364546020652 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_poolset_foreach/Makefile -- build util_poolset_foreach test # # TARGET = util_poolset_foreach OBJS = util_poolset_foreach.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_poolset_foreach/out0.log.match0000664000000000000000000000135314123364546021704 0ustar rootrootutil_poolset_foreach$(nW)TEST0: START: util_poolset_foreach $(nW)util_poolset_foreach$(nW) $(*)pool.set1 $(*)pool.set2 $(*)pool.set3 $(*)pool.set4 $(*)pool.set1: $(*)testfile util_poolset_foreach_part($(*)pool.set1): 0 $(*)pool.set2: $(*)testfile1 $(*)pool.set2: $(*)testfile2 util_poolset_foreach_part($(*)pool.set2): 0 $(*)pool.set3: $(*)testfile11 $(*)pool.set3: $(*)testfile12 $(*)pool.set3: $(*)testfile21 $(*)pool.set3: $(*)testfile22 util_poolset_foreach_part($(*)pool.set3): 0 $(*)pool.set4: $(*)testfile11 $(*)pool.set4: $(*)testfile12 $(*)pool.set4: $(*)testfile21 $(*)pool.set4: $(*)testfile22 $(*)pool.set4: $(*)testfile31 $(*)pool.set4: $(*)testfile32 util_poolset_foreach_part($(*)pool.set4): 0 util_poolset_foreach$(nW)TEST0: DONE pmdk-1.11.1/src/test/util_poolset_foreach/TEST0.PS10000664000000000000000000000146714123364546020411 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src\test\util_poolset_foreach\TEST0 -- unit test for util_poolset_foreach # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\pool.set1 128K:$DIR\testfile:x create_poolset $DIR\pool.set2 128K:$DIR\testfile1:x 32M:$DIR\testfile2:x create_poolset $DIR\pool.set3 ` 32M:$DIR\testfile11:x 32M:$DIR\testfile12:x ` R 64M:$DIR\testfile21:x 32M:$DIR\testfile22:x create_poolset $DIR\pool.set4 ` 32M:$DIR\testfile11:x 32M:$DIR\testfile12:x ` R 64M:$DIR\testfile21:x 32M:$DIR\testfile22:x ` R 64M:$DIR\testfile31:x 64M:$DIR\testfile32:x expect_normal_exit $Env:EXE_DIR\util_poolset_foreach$Env:EXESUFFIX ` $DIR\pool.set1 ` $DIR\pool.set2 ` $DIR\pool.set3 ` $DIR\pool.set4 check pass pmdk-1.11.1/src/test/util_poolset_foreach/.gitignore0000664000000000000000000000002514123364546021202 0ustar rootrootutil_poolset_foreach pmdk-1.11.1/src/test/util_poolset_foreach/README0000664000000000000000000000063214123364546020076 0ustar rootrootPersistent Memory Development Kit This is src/test/util_poolset_foreach/README. This directory contains a unit test for util_poolset_foreach_part(). The program in util_poolset_foreach.c takes a file name(s) as arguments: For example: ./util_poolset_foreach pool.set1 pool.set2 This will call util_poolset_foreach_part() on all files, print result value and will print all part files from given poolset. pmdk-1.11.1/src/test/util_poolset_foreach/TEST10000775000000000000000000000167014123364546020007 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_poolset_foreach/TEST1 -- unit test for util_poolset_foreach # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup create_poolset $DIR/pool.set1 32K:$DIR/testfile:x\ M remote_node1:remote_pool.set1 create_poolset $DIR/pool.set2 32K:$DIR/testfile1:x 32M:$DIR/testfile2:x\ M remote_node2:remote_pool.set2 create_poolset $DIR/pool.set3\ 32M:$DIR/testfile11:x 32M:$DIR/testfile12:x\ R 64M:$DIR/testfile21:x 32M:$DIR/testfile22:x\ M remote_node3:remote_pool.set3 create_poolset $DIR/pool.set4\ 32M:$DIR/testfile11:x 32M:$DIR/testfile12:x\ R 64M:$DIR/testfile21:x 32M:$DIR/testfile22:x\ R 64M:$DIR/testfile31:x 64M:$DIR/testfile32:x\ M remote_node4:remote_pool.set4 expect_normal_exit ./util_poolset_foreach$EXESUFFIX\ $DIR/pool.set1\ $DIR/pool.set2\ $DIR/pool.set3\ $DIR/pool.set4 check pass pmdk-1.11.1/src/test/util_poolset_foreach/out1.log.match0000664000000000000000000000163714123364546021712 0ustar rootrootutil_poolset_foreach$(nW)TEST1: START: util_poolset_foreach $(nW)util_poolset_foreach$(nW) $(*)pool.set1 $(*)pool.set2 $(*)pool.set3 $(*)pool.set4 $(*)pool.set1: $(*)testfile $(*)pool.set1: remote_node1 remote_pool.set1 util_poolset_foreach_part($(*)pool.set1): 0 $(*)pool.set2: $(*)testfile1 $(*)pool.set2: $(*)testfile2 $(*)pool.set2: remote_node2 remote_pool.set2 util_poolset_foreach_part($(*)pool.set2): 0 $(*)pool.set3: $(*)testfile11 $(*)pool.set3: $(*)testfile12 $(*)pool.set3: $(*)testfile21 $(*)pool.set3: $(*)testfile22 $(*)pool.set3: remote_node3 remote_pool.set3 util_poolset_foreach_part($(*)pool.set3): 0 $(*)pool.set4: $(*)testfile11 $(*)pool.set4: $(*)testfile12 $(*)pool.set4: $(*)testfile21 $(*)pool.set4: $(*)testfile22 $(*)pool.set4: $(*)testfile31 $(*)pool.set4: $(*)testfile32 $(*)pool.set4: remote_node4 remote_pool.set4 util_poolset_foreach_part($(*)pool.set4): 0 util_poolset_foreach$(nW)TEST1: DONE pmdk-1.11.1/src/test/util_poolset_foreach/util_poolset_foreach.vcxproj.filters0000664000000000000000000000170014123364546026510 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {ddc9f661-883f-425f-a835-1ac9d5a8949a} {cb560619-3b24-4fa0-b698-a785c5666af7} Source Files Test scripts Match Files pmdk-1.11.1/src/test/obj_alloc/0000775000000000000000000000000014123364546014730 5ustar rootrootpmdk-1.11.1/src/test/obj_alloc/TEST00000775000000000000000000000154114123364546015516 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_alloc/TEST0 -- unit test for obj_alloc # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup create_poolset $DIR/testset1 16M:$DIR/testfile1:x r 16M:$DIR/testfile2:x # expect_normal_exit ./obj_alloc$EXESUFFIX \ $DIR/testset1 O 0 1 1 0 0 \ $DIR/testset1 1 S 0 0 0 0 \ $DIR/testset1 1 0 0 0 0 0 \ $DIR/testset1 1 0 0 1 0 0 \ $DIR/testset1 O B 0 0 0 0 \ $DIR/testset1 O B 0 1 0 0 \ $DIR/testset1 O 0 0 1 0 0 \ $DIR/testset1 O 1 0 1 0 0 \ $DIR/testset1 O S 0 1 0 0 \ $DIR/testset1 0 0 0 0 -1 22 \ $DIR/testset1 0 0 0 1 -1 22 \ $DIR/testset1 B 0 0 0 -1 12 \ $DIR/testset1 B 0 0 1 -1 12 check pass pmdk-1.11.1/src/test/obj_alloc/Makefile0000664000000000000000000000034614123364546016373 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_alloc/Makefile -- build obj_alloc unit test # TARGET = obj_alloc OBJS = obj_alloc.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_alloc/TEST0.PS10000664000000000000000000000153514123364546016120 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_alloc/TEST0 -- unit test for obj_alloc # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\testset1 16M:$DIR\testfile1:x r 16M:$DIR\testfile2:x # expect_normal_exit $Env:EXE_DIR\obj_alloc$Env:EXESUFFIX ` $DIR\testset1 O 0 1 1 0 0 ` $DIR\testset1 1 S 0 0 0 0 ` $DIR\testset1 1 0 0 0 0 0 ` $DIR\testset1 1 0 0 1 0 0 ` $DIR\testset1 O B 0 0 0 0 ` $DIR\testset1 O B 0 1 0 0 ` $DIR\testset1 O 0 0 1 0 0 ` $DIR\testset1 O 1 0 1 0 0 ` $DIR\testset1 O S 0 1 0 0 ` $DIR\testset1 0 0 0 0 -1 22 ` $DIR\testset1 0 0 0 1 -1 22 ` $DIR\testset1 B 0 0 0 -1 12 ` $DIR\testset1 B 0 0 1 -1 12 check pass pmdk-1.11.1/src/test/obj_alloc/obj_alloc.vcxproj.filters0000664000000000000000000000143614123364546021744 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c01d120f-0cb1-4d38-8eab-0fb965a987e4} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/obj_alloc/obj_alloc.c0000664000000000000000000000466314123364546017031 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * obj_alloc.c -- unit test for pmemobj_alloc and pmemobj_zalloc */ #include "unittest.h" #include "heap.h" #include POBJ_LAYOUT_BEGIN(alloc); POBJ_LAYOUT_ROOT(alloc, struct root); POBJ_LAYOUT_TOID(alloc, struct object); POBJ_LAYOUT_END(alloc); struct object { size_t value; char data[]; }; struct root { TOID(struct object) obj; char data[CHUNKSIZE - sizeof(TOID(struct object))]; }; static uint64_t check_int(const char *size_str) { uint64_t ret; switch (*size_str) { case 'S': ret = SIZE_MAX; break; case 'B': ret = SIZE_MAX - 1; break; case 'O': ret = sizeof(struct object); break; default: ret = ATOULL(size_str); } return ret; } int main(int argc, char *argv[]) { START(argc, argv, "obj_alloc"); const char *path; size_t size; uint64_t type_num; int is_oid_null; uint64_t flags; int expected_return_code; int expected_errno; int ret; if (argc < 8) UT_FATAL("usage: %s path size type_num is_oid_null flags " "expected_return_code expected_errno ...", argv[0]); PMEMobjpool *pop = NULL; PMEMoid *oidp; path = argv[1]; pop = pmemobj_create(path, POBJ_LAYOUT_NAME(basic), 0, S_IWUSR | S_IRUSR); if (pop == NULL) { UT_FATAL("!pmemobj_create: %s", path); } for (int i = 1; i + 6 < argc; i += 7) { size = (size_t)check_int(argv[i + 1]); type_num = check_int(argv[i + 2]); is_oid_null = ATOI(argv[i + 3]); flags = ATOULL(argv[i + 4]); expected_return_code = ATOI(argv[i + 5]); expected_errno = ATOI(argv[i + 6]); UT_OUT("%s %zu %lu %d %lu %d %d", path, size, type_num, is_oid_null, flags, expected_return_code, expected_errno); TOID(struct root) root = POBJ_ROOT(pop, struct root); oidp = &D_RW(root)->obj.oid; if (is_oid_null) { TOID_ASSIGN(root, OID_NULL); oidp = &root.oid; } ret = pmemobj_xalloc( pop, oidp, size, type_num, flags, NULL, NULL); UT_ASSERTeq(ret, expected_return_code); if (expected_errno != 0) { UT_ASSERTeq(errno, expected_errno); } if (ret == 0) { UT_OUT("alloc: %zu, size: %zu", size, pmemobj_alloc_usable_size(D_RW(root)->obj.oid)); if (is_oid_null == 0) { UT_ASSERT(!TOID_IS_NULL(D_RW(root)->obj)); UT_ASSERT(pmemobj_alloc_usable_size( D_RW(root)->obj.oid) >= size); } } pmemobj_free(&D_RW(root)->obj.oid); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); UT_OUT("free"); } pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_alloc/.gitignore0000664000000000000000000000001214123364546016711 0ustar rootrootobj_alloc pmdk-1.11.1/src/test/obj_alloc/README0000664000000000000000000000075114123364546015613 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_alloc/README. This directory contains a unit test for pmemobj_alloc and pmemobj_zalloc. The program in obj_alloc.c takes a path, size, type_num, is_oid_null, flags, expected_return_code and expected_errno. The accepted flags in 'size' and 'type_num' string are: 'S' - SIZE_MAX 'B' - SIZE_MAX-1 'O' - sizeof(struct object) 'flags' - determines usage of POBJ_FLAG_ZERO flag Example: $ obj_alloc /mnt/pmem/testfile O 0 0 1 0 0 ... pmdk-1.11.1/src/test/obj_alloc/obj_alloc.vcxproj0000664000000000000000000001033514123364546020273 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {42B97D47-F800-4100-BFA2-B3AC357E8B6B} Win32Proj obj_alloc 10.0.17134.0 Application true v140 Application false v140 true NotUsing Disabled CompileAsCpp $(ProjectDir)\..\..\libpmemobj;%(AdditionalIncludeDirectories) NotUsing MaxSpeed stdafx.h CompileAsCpp $(ProjectDir)\..\..\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmempool_info_remote/0000775000000000000000000000000014123364546017222 5ustar rootrootpmdk-1.11.1/src/test/pmempool_info_remote/TEST00000775000000000000000000000231314123364546020006 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # # pmempool_info_remote/TEST0 -- test for info command with remote replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" LOG=out${UNITTEST_NUM}.log # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 16M:${NODE_DIR[1]}/$TEST_FILE_LOCAL:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 17M:${NODE_DIR[0]}/$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 ${NODE_DIR[1]}$TEST_FILE_LOCAL expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$TEST_SET_LOCAL expect_normal_exit run_on_node 1 ../pmempool info ${NODE_DIR[1]}$TEST_SET_LOCAL > ./$LOG check_local pass pmdk-1.11.1/src/test/pmempool_info_remote/Makefile0000664000000000000000000000034414123364546020663 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/pmempool_info_remote/Makefile -- build unittest for pmempool # info with remote replicas # SCP_TO_REMOTE_NODES=y include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_info_remote/out0.log.match0000664000000000000000000000224314123364546021710 0ustar rootroot$(OPT)$(*) Poolset structure: Number of replicas : 2 Replica 0 (master) - local, 1 part(s): part 0: path : $(nW)/testfile_local type : regular file size : 16777216 Replica 1 - remote: node : $(nW) pool set : $(nW)testset_remote POOL Header: Signature : PMEMOBJ Major : $(*) Mandatory features : $(*) Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(*) UUID : $(*) Previous part UUID : $(*) Next part UUID : $(*) Previous replica UUID : $(*) Next replica UUID : $(*) Creation Time : $(*) Alignment Descriptor : $(*)[OK] Class : 64 Data : $(*) Machine : $(*) Last shutdown : clean Checksum : $(nW) [OK] PMEM OBJ Header: Layout : (null) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Checksum : $(nW) [OK] Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_info_remote/config.sh0000664000000000000000000000045114123364546021023 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # pmempool_info_remote/config.sh -- test configuration # set -e CONF_GLOBAL_FS_TYPE=any CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=sockets CONF_GLOBAL_RPMEM_PMETHOD=GPSPM pmdk-1.11.1/src/test/obj_sync/0000775000000000000000000000000014123364546014612 5ustar rootrootpmdk-1.11.1/src/test/obj_sync/obj_sync.vcxproj0000664000000000000000000001174414123364546020044 0ustar rootroot Debug x64 Release x64 {6516D6CF-8000-4341-9487-312BC83EE370} Win32Proj obj_sync 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) MaxSpeed $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) WRAP_REAL;%(PreprocessorDefinitions) WRAP_REAL;%(PreprocessorDefinitions) {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_sync/err7.log.match0000664000000000000000000000014314123364546017265 0ustar rootroot{$(*)obj_sync.c:$(N) timed_check_worker} obj_sync/TEST7: pmemobj_mutex_timedlock: Invalid argument pmdk-1.11.1/src/test/obj_sync/TEST7.PS10000664000000000000000000000362114123364546016007 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_sync/TEST7 -- unit test for PMEM-resident locks # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit $Env:EXE_DIR\obj_sync$Env:EXESUFFIX t 50 5 check pass pmdk-1.11.1/src/test/obj_sync/TEST5.PS10000664000000000000000000000362114123364546016005 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_sync/TEST5 -- unit test for PMEM-resident locks # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit $Env:EXE_DIR\obj_sync$Env:EXESUFFIX c 10 5 check pass pmdk-1.11.1/src/test/obj_sync/err6.log.match0000664000000000000000000000012014123364546017257 0ustar rootroot{$(nW)obj_sync.c:$(N) cond_$(nW)_worker} obj_sync$(nW)TEST6: pmemobj_cond_$(nW) pmdk-1.11.1/src/test/obj_sync/err4.log.match0000664000000000000000000000012414123364546017261 0ustar rootroot{$(nW)obj_sync.c:$(N) rwlock_$(nW)_worker} obj_sync$(nW)TEST4: pmemobj_rwlock_$(nW) pmdk-1.11.1/src/test/obj_sync/err3.log.match0000664000000000000000000000012414123364546017260 0ustar rootroot{$(nW)obj_sync.c:$(N) rwlock_$(nW)_worker} obj_sync$(nW)TEST3: pmemobj_rwlock_$(nW) pmdk-1.11.1/src/test/obj_sync/TEST30000775000000000000000000000062314123364546015403 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST3 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX r 10 5 check pass pmdk-1.11.1/src/test/obj_sync/TEST90000775000000000000000000000062214123364546015410 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sync/TEST9 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX t 10 5 pass pmdk-1.11.1/src/test/obj_sync/mocks_windows.h0000664000000000000000000000433414123364546017655 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * Copyright (c) 2016, Microsoft Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * mocks_windows.h -- redefinitions of pthread functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmemobj * files, when compiled for the purpose of obj_sync test. * It would replace default implementation with mocked functions defined * in obj_sync.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define os_mutex_init __wrap_os_mutex_init #define os_rwlock_init __wrap_os_rwlock_init #define os_cond_init __wrap_os_cond_init #endif pmdk-1.11.1/src/test/obj_sync/obj_sync.vcxproj.filters0000664000000000000000000000445014123364546021507 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {63b52744-5704-42f4-84ef-4c888e892158} PS1 {dbb30ab2-6c7b-4d25-b385-2e4412e65a08} Source Files Source Files Source Files Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Header Files pmdk-1.11.1/src/test/obj_sync/TEST00000775000000000000000000000053214123364546015377 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST0 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit ./obj_sync$EXESUFFIX m 50 5 check pass pmdk-1.11.1/src/test/obj_sync/Makefile0000664000000000000000000000056614123364546016261 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/Makefile -- build obj_sync unit test # TOP = ../../.. vpath %.c $(TOP)/src/libpmemobj TARGET = obj_sync OBJS = obj_sync.o sync.o mocks_posix.o LIBPMEMCOMMON=y include ../Makefile.inc LDFLAGS += $(call extract_funcs, mocks_posix.c) INCS += -I$(TOP)/src/libpmemobj/ pmdk-1.11.1/src/test/obj_sync/TEST3.PS10000664000000000000000000000362114123364546016003 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_sync/TEST3 -- unit test for PMEM-resident locks # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit $Env:EXE_DIR\obj_sync$Env:EXESUFFIX r 10 5 check pass pmdk-1.11.1/src/test/obj_sync/err1.log.match0000664000000000000000000000012114123364546017253 0ustar rootroot{$(nW)obj_sync.c:$(N) mutex_$(nW)_worker} obj_sync$(nW)TEST1: pmemobj_mutex_lock pmdk-1.11.1/src/test/obj_sync/TEST50000775000000000000000000000062314123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST5 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX c 10 5 check pass pmdk-1.11.1/src/test/obj_sync/out7.log.match0000664000000000000000000000014114123364546017302 0ustar rootrootobj_sync$(nW)TEST7: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST7: DONE pmdk-1.11.1/src/test/obj_sync/TEST40000775000000000000000000000063014123364546015402 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST4 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX r 10 5 check pass pmdk-1.11.1/src/test/obj_sync/TEST70000775000000000000000000000053214123364546015406 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_sync/TEST7 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit ./obj_sync$EXESUFFIX t 50 5 check pass pmdk-1.11.1/src/test/obj_sync/out0.log.match0000664000000000000000000000014114123364546017273 0ustar rootrootobj_sync$(nW)TEST0: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_sync/TEST0.PS10000664000000000000000000000362114123364546016000 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_sync/TEST0 -- unit test for PMEM-resident locks # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug nondebug setup expect_normal_exit $Env:EXE_DIR\obj_sync$Env:EXESUFFIX m 50 5 check pass pmdk-1.11.1/src/test/obj_sync/obj_sync.c0000664000000000000000000002111014123364546016557 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_sync.c -- unit test for PMEM-resident locks */ #include "obj.h" #include "sync.h" #include "unittest.h" #include "sys_util.h" #include "util.h" #include "os.h" #define MAX_THREAD_NUM 200 #define DATA_SIZE 128 #define LOCKED_MUTEX 1 #define NANO_PER_ONE 1000000000LL #define TIMEOUT (NANO_PER_ONE / 1000LL) #define WORKER_RUNS 10 #define MAX_OPENS 5 #define FATAL_USAGE() UT_FATAL("usage: obj_sync [mrc] \n") /* posix thread worker typedef */ typedef void *(*worker)(void *); /* the mock pmemobj pool */ static PMEMobjpool Mock_pop; /* the tested object containing persistent synchronization primitives */ static struct mock_obj { PMEMmutex mutex; PMEMmutex mutex_locked; PMEMcond cond; PMEMrwlock rwlock; int check_data; uint8_t data[DATA_SIZE]; } *Test_obj; PMEMobjpool * pmemobj_pool_by_ptr(const void *arg) { return &Mock_pop; } /* * mock_open_pool -- (internal) simulate pool opening */ static void mock_open_pool(PMEMobjpool *pop) { util_fetch_and_add64(&pop->run_id, 2); } /* * mutex_write_worker -- (internal) write data with mutex */ static void * mutex_write_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex)) { UT_ERR("pmemobj_mutex_lock"); return NULL; } memset(Test_obj->data, (int)(uintptr_t)arg, DATA_SIZE); if (pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex)) UT_ERR("pmemobj_mutex_unlock"); } return NULL; } /* * mutex_check_worker -- (internal) check consistency with mutex */ static void * mutex_check_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex)) { UT_ERR("pmemobj_mutex_lock"); return NULL; } uint8_t val = Test_obj->data[0]; for (int i = 1; i < DATA_SIZE; i++) UT_ASSERTeq(Test_obj->data[i], val); memset(Test_obj->data, 0, DATA_SIZE); if (pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex)) UT_ERR("pmemobj_mutex_unlock"); } return NULL; } /* * cond_write_worker -- (internal) write data with cond variable */ static void * cond_write_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex)) return NULL; memset(Test_obj->data, (int)(uintptr_t)arg, DATA_SIZE); Test_obj->check_data = 1; if (pmemobj_cond_signal(&Mock_pop, &Test_obj->cond)) UT_ERR("pmemobj_cond_signal"); pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex); } return NULL; } /* * cond_check_worker -- (internal) check consistency with cond variable */ static void * cond_check_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex)) return NULL; while (Test_obj->check_data != 1) { if (pmemobj_cond_wait(&Mock_pop, &Test_obj->cond, &Test_obj->mutex)) UT_ERR("pmemobj_cond_wait"); } uint8_t val = Test_obj->data[0]; for (int i = 1; i < DATA_SIZE; i++) UT_ASSERTeq(Test_obj->data[i], val); memset(Test_obj->data, 0, DATA_SIZE); pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex); } return NULL; } /* * rwlock_write_worker -- (internal) write data with rwlock */ static void * rwlock_write_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_rwlock_wrlock(&Mock_pop, &Test_obj->rwlock)) { UT_ERR("pmemobj_rwlock_wrlock"); return NULL; } memset(Test_obj->data, (int)(uintptr_t)arg, DATA_SIZE); if (pmemobj_rwlock_unlock(&Mock_pop, &Test_obj->rwlock)) UT_ERR("pmemobj_rwlock_unlock"); } return NULL; } /* * rwlock_check_worker -- (internal) check consistency with rwlock */ static void * rwlock_check_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { if (pmemobj_rwlock_rdlock(&Mock_pop, &Test_obj->rwlock)) { UT_ERR("pmemobj_rwlock_rdlock"); return NULL; } uint8_t val = Test_obj->data[0]; for (int i = 1; i < DATA_SIZE; i++) UT_ASSERTeq(Test_obj->data[i], val); if (pmemobj_rwlock_unlock(&Mock_pop, &Test_obj->rwlock)) UT_ERR("pmemobj_rwlock_unlock"); } return NULL; } /* * timed_write_worker -- (internal) intentionally doing nothing */ static void * timed_write_worker(void *arg) { return NULL; } /* * timed_check_worker -- (internal) check consistency with mutex */ static void * timed_check_worker(void *arg) { for (unsigned run = 0; run < WORKER_RUNS; run++) { int mutex_id = (int)(uintptr_t)arg % 2; PMEMmutex *mtx = mutex_id == LOCKED_MUTEX ? &Test_obj->mutex_locked : &Test_obj->mutex; struct timespec t1, t2, abs_time; os_clock_gettime(CLOCK_REALTIME, &t1); abs_time = t1; abs_time.tv_nsec += TIMEOUT; if (abs_time.tv_nsec >= NANO_PER_ONE) { abs_time.tv_sec++; abs_time.tv_nsec -= NANO_PER_ONE; } int ret = pmemobj_mutex_timedlock(&Mock_pop, mtx, &abs_time); os_clock_gettime(CLOCK_REALTIME, &t2); if (mutex_id == LOCKED_MUTEX) { UT_ASSERTeq(ret, ETIMEDOUT); uint64_t diff = (uint64_t)((t2.tv_sec - t1.tv_sec) * NANO_PER_ONE + t2.tv_nsec - t1.tv_nsec); UT_ASSERT(diff >= TIMEOUT); return NULL; } if (ret == 0) { UT_ASSERTne(mutex_id, LOCKED_MUTEX); pmemobj_mutex_unlock(&Mock_pop, mtx); } else if (ret == ETIMEDOUT) { uint64_t diff = (uint64_t)((t2.tv_sec - t1.tv_sec) * NANO_PER_ONE + t2.tv_nsec - t1.tv_nsec); UT_ASSERT(diff >= TIMEOUT); } else { errno = ret; UT_ERR("!pmemobj_mutex_timedlock"); } } return NULL; } /* * cleanup -- (internal) clean up after each run */ static void cleanup(char test_type) { switch (test_type) { case 'm': util_mutex_destroy(&((PMEMmutex_internal *) &(Test_obj->mutex))->PMEMmutex_lock); break; case 'r': util_rwlock_destroy(&((PMEMrwlock_internal *) &(Test_obj->rwlock))->PMEMrwlock_lock); break; case 'c': util_mutex_destroy(&((PMEMmutex_internal *) &(Test_obj->mutex))->PMEMmutex_lock); util_cond_destroy(&((PMEMcond_internal *) &(Test_obj->cond))->PMEMcond_cond); break; case 't': util_mutex_destroy(&((PMEMmutex_internal *) &(Test_obj->mutex))->PMEMmutex_lock); util_mutex_destroy(&((PMEMmutex_internal *) &(Test_obj->mutex_locked))->PMEMmutex_lock); break; default: FATAL_USAGE(); } } static int obj_sync_persist(void *ctx, const void *ptr, size_t sz, unsigned flags) { /* no-op */ return 0; } int main(int argc, char *argv[]) { START(argc, argv, "obj_sync"); util_init(); if (argc < 4) FATAL_USAGE(); worker writer; worker checker; char test_type = argv[1][0]; switch (test_type) { case 'm': writer = mutex_write_worker; checker = mutex_check_worker; break; case 'r': writer = rwlock_write_worker; checker = rwlock_check_worker; break; case 'c': writer = cond_write_worker; checker = cond_check_worker; break; case 't': writer = timed_write_worker; checker = timed_check_worker; break; default: FATAL_USAGE(); } unsigned long num_threads = strtoul(argv[2], NULL, 10); if (num_threads > MAX_THREAD_NUM) UT_FATAL("Do not use more than %d threads.\n", MAX_THREAD_NUM); unsigned long opens = strtoul(argv[3], NULL, 10); if (opens > MAX_OPENS) UT_FATAL("Do not use more than %d runs.\n", MAX_OPENS); os_thread_t *write_threads = (os_thread_t *)MALLOC(num_threads * sizeof(os_thread_t)); os_thread_t *check_threads = (os_thread_t *)MALLOC(num_threads * sizeof(os_thread_t)); /* first pool open */ mock_open_pool(&Mock_pop); Mock_pop.p_ops.persist = obj_sync_persist; Mock_pop.p_ops.base = &Mock_pop; Test_obj = (struct mock_obj *)MALLOC(sizeof(struct mock_obj)); /* zero-initialize the test object */ pmemobj_mutex_zero(&Mock_pop, &Test_obj->mutex); pmemobj_mutex_zero(&Mock_pop, &Test_obj->mutex_locked); pmemobj_cond_zero(&Mock_pop, &Test_obj->cond); pmemobj_rwlock_zero(&Mock_pop, &Test_obj->rwlock); Test_obj->check_data = 0; memset(&Test_obj->data, 0, DATA_SIZE); for (unsigned long run = 0; run < opens; run++) { if (test_type == 't') { pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex_locked); } for (unsigned i = 0; i < num_threads; i++) { THREAD_CREATE(&write_threads[i], NULL, writer, (void *)(uintptr_t)i); THREAD_CREATE(&check_threads[i], NULL, checker, (void *)(uintptr_t)i); } for (unsigned i = 0; i < num_threads; i++) { THREAD_JOIN(&write_threads[i], NULL); THREAD_JOIN(&check_threads[i], NULL); } if (test_type == 't') { pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex_locked); } /* up the run_id counter and cleanup */ mock_open_pool(&Mock_pop); cleanup(test_type); } FREE(check_threads); FREE(write_threads); FREE(Test_obj); DONE(NULL); } pmdk-1.11.1/src/test/obj_sync/.gitignore0000664000000000000000000000001114123364546016572 0ustar rootrootobj_sync pmdk-1.11.1/src/test/obj_sync/README0000664000000000000000000000115114123364546015470 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_sync/README. This directory contains a unit test for persistent synchronization mechanisms. The types of synchronization primitives tested are: mutexes, rwlocks and condition variables. The obj_sync application takes as command line arguments the primitive type to be tested, the number of threads to be run and the number of times the test will be restarted: $ obj_sync [mrc] Where: m - test mutexes r - test rwlocks c - test condition variables The tests are performed using valgrind and its following tools: - drd - helgrind pmdk-1.11.1/src/test/obj_sync/err0.log.match0000664000000000000000000000012114123364546017252 0ustar rootroot{$(nW)obj_sync.c:$(N) mutex_$(nW)_worker} obj_sync$(nW)TEST0: pmemobj_mutex_lock pmdk-1.11.1/src/test/obj_sync/TEST60000775000000000000000000000063014123364546015404 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST6 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX c 10 5 check pass pmdk-1.11.1/src/test/obj_sync/TEST10000775000000000000000000000062314123364546015401 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST1 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX m 10 5 check pass pmdk-1.11.1/src/test/obj_sync/out6.log.match0000664000000000000000000000014114123364546017301 0ustar rootrootobj_sync$(nW)TEST6: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST6: DONE pmdk-1.11.1/src/test/obj_sync/TEST80000775000000000000000000000061514123364546015411 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_sync/TEST8 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind drd force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX t 10 5 pass pmdk-1.11.1/src/test/obj_sync/mocks_windows.c0000664000000000000000000000125714123364546017651 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * mock-windows.c -- redefinitions of locks function */ #include "os.h" #include "unittest.h" FUNC_MOCK(os_mutex_init, int, os_mutex_t *__restrict mutex) FUNC_MOCK_RUN_RET_DEFAULT_REAL(os_mutex_init, mutex) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END FUNC_MOCK(os_rwlock_init, int, os_rwlock_t *__restrict rwlock) FUNC_MOCK_RUN_RET_DEFAULT_REAL(os_rwlock_init, rwlock) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END FUNC_MOCK(os_cond_init, int, os_cond_t *__restrict cond) FUNC_MOCK_RUN_RET_DEFAULT_REAL(os_cond_init, cond) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END pmdk-1.11.1/src/test/obj_sync/err2.log.match0000664000000000000000000000012114123364546017254 0ustar rootroot{$(nW)obj_sync.c:$(N) mutex_$(nW)_worker} obj_sync$(nW)TEST2: pmemobj_mutex_lock pmdk-1.11.1/src/test/obj_sync/out1.log.match0000664000000000000000000000014114123364546017274 0ustar rootrootobj_sync$(nW)TEST1: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_sync/TEST20000775000000000000000000000063114123364546015401 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_sync/TEST2 -- unit test for PMEM-resident locks # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type debug nondebug require_valgrind 3.10 configure_valgrind helgrind force-enable setup expect_normal_exit ./obj_sync$EXESUFFIX m 10 5 check pass pmdk-1.11.1/src/test/obj_sync/out5.log.match0000664000000000000000000000014114123364546017300 0ustar rootrootobj_sync$(nW)TEST5: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST5: DONE pmdk-1.11.1/src/test/obj_sync/err5.log.match0000664000000000000000000000012014123364546017256 0ustar rootroot{$(nW)obj_sync.c:$(N) cond_$(nW)_worker} obj_sync$(nW)TEST5: pmemobj_cond_$(nW) pmdk-1.11.1/src/test/obj_sync/out3.log.match0000664000000000000000000000014114123364546017276 0ustar rootrootobj_sync$(nW)TEST3: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_sync/mocks_posix.c0000664000000000000000000000166614123364546017325 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * mocks_posix.c -- redefinitions of lock functions (Posix implementation) */ #include #include "util.h" #include "os.h" #include "unittest.h" FUNC_MOCK(pthread_mutex_init, int, pthread_mutex_t *__restrict mutex, const pthread_mutexattr_t *__restrict attr) FUNC_MOCK_RUN_RET_DEFAULT_REAL(pthread_mutex_init, mutex, attr) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END FUNC_MOCK(pthread_rwlock_init, int, pthread_rwlock_t *__restrict rwlock, const pthread_rwlockattr_t *__restrict attr) FUNC_MOCK_RUN_RET_DEFAULT_REAL(pthread_rwlock_init, rwlock, attr) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END FUNC_MOCK(pthread_cond_init, int, pthread_cond_t *__restrict cond, const pthread_condattr_t *__restrict attr) FUNC_MOCK_RUN_RET_DEFAULT_REAL(pthread_cond_init, cond, attr) FUNC_MOCK_RUN(1) { return -1; } FUNC_MOCK_END pmdk-1.11.1/src/test/obj_sync/out4.log.match0000664000000000000000000000014114123364546017277 0ustar rootrootobj_sync$(nW)TEST4: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST4: DONE pmdk-1.11.1/src/test/obj_sync/out2.log.match0000664000000000000000000000014114123364546017275 0ustar rootrootobj_sync$(nW)TEST2: START: obj_sync $(nW)obj_sync$(nW) $(nW) $(N) $(N) obj_sync$(nW)TEST2: DONE pmdk-1.11.1/src/test/pmem2_source/0000775000000000000000000000000014123364546015404 5ustar rootrootpmdk-1.11.1/src/test/pmem2_source/Makefile0000664000000000000000000000061414123364546017045 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem2_source/Makefile -- build pmem2_source unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_source OBJS += pmem2_source.o\ ut_pmem2_config.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_source/TESTS.py0000775000000000000000000000541514123364546016670 0ustar rootroot#!../env.py # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class PMEM2_SOURCE(t.Test): test_type = t.Short def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') ctx.exec('pmem2_source', self.test_case, filepath) @g.no_testdir() class PMEM2_SOURCE_NO_DIR(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem2_source', self.test_case) class TEST0(PMEM2_SOURCE): """setting a read + write file descriptor in pmem2_source""" test_case = "test_set_rw_fd" class TEST1(PMEM2_SOURCE): """setting a read only file descriptor in pmem2_source""" test_case = "test_set_ro_fd" class TEST2(PMEM2_SOURCE): """setting invalid (closed) file descriptor in pmem2_source""" test_case = "test_set_invalid_fd" class TEST3(PMEM2_SOURCE): """setting a write only file descriptor in pmem2_source""" test_case = "test_set_wronly_fd" class TEST4(PMEM2_SOURCE): """allocation of pmem2_source in case of missing memory in system""" test_case = "test_alloc_src_enomem" class TEST5(PMEM2_SOURCE_NO_DIR): """deleting null pmem2_source""" test_case = "test_delete_null_config" @t.windows_only class TEST6(PMEM2_SOURCE): """set handle in the source""" test_case = "test_set_handle" @t.windows_only class TEST7(PMEM2_SOURCE_NO_DIR): """set INVALID_HANLE_VALUE in the source""" test_case = "test_set_null_handle" @t.windows_only class TEST8(PMEM2_SOURCE): """set invalid handle in the source""" test_case = "test_set_invalid_handle" @t.windows_only class TEST9(PMEM2_SOURCE): """set handle to a directory in the source""" test_case = "test_set_directory_handle" def run(self, ctx): ctx.exec('pmem2_source', self.test_case, ctx.testdir) @t.windows_only class TEST10(PMEM2_SOURCE_NO_DIR): """set handle to a mutex in the source""" test_case = "test_set_mutex_handle" @t.windows_exclude class TEST11(PMEM2_SOURCE): """set directory's fd in the source""" test_case = "test_set_directory_fd" def run(self, ctx): ctx.exec('pmem2_source', self.test_case, ctx.testdir) @t.windows_only class TEST12(PMEM2_SOURCE): """get handle from the source""" test_case = "test_get_handle" @t.windows_exclude class TEST13(PMEM2_SOURCE): """get file descriptor from the source""" test_case = "test_get_fd" @t.windows_only class TEST14(PMEM2_SOURCE_NO_DIR): """get handle from the invalid source type""" test_case = "test_get_handle_inval_type" @t.windows_exclude class TEST15(PMEM2_SOURCE_NO_DIR): """get file descriptor from the invalid source type""" test_case = "test_get_fd_inval_type" pmdk-1.11.1/src/test/pmem2_source/.gitignore0000664000000000000000000000001514123364546017370 0ustar rootrootpmem2_source pmdk-1.11.1/src/test/pmem2_source/pmem2_source.vcxproj.filters0000664000000000000000000000161314123364546023071 0ustar rootroot pmdk-1.11.1/src/test/pmem2_source/pmem2_source.vcxproj0000664000000000000000000001127114123364546021423 0ustar rootroot Debug x64 Release x64 {34F31D9D-3D33-4C09-85A3-4749A8AB8EBB} pmem2_config 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_source/pmem2_source.c0000664000000000000000000002310114123364546020145 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * pmem2_source.c -- pmem2_source unittests */ #include "fault_injection.h" #include "libpmem2.h" #include "unittest.h" #include "ut_pmem2_utils.h" #include "ut_pmem2_config.h" #include "source.h" #include "out.h" /* * verify_fd -- verify value fd or handle in source */ static void verify_fd(struct pmem2_source *src, int fd) { #ifdef WIN32 UT_ASSERTeq(src->type, PMEM2_SOURCE_HANDLE); UT_ASSERTeq(src->value.handle, fd != INVALID_FD ? (HANDLE)_get_osfhandle(fd) : INVALID_HANDLE_VALUE); #else UT_ASSERTeq(src->type, PMEM2_SOURCE_FD); UT_ASSERTeq(src->value.fd, fd); #endif } /* * test_set_rw_fd - test setting O_RDWR fd */ static int test_set_rw_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_rw_fd "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, fd); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); verify_fd(src, fd); ret = pmem2_source_delete(&src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); CLOSE(fd); return 1; } /* * test_set_ro_fd - test setting O_RDONLY fd */ static int test_set_ro_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_ro_fd "); char *file = argv[0]; int fd = OPEN(file, O_RDONLY); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, fd); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); verify_fd(src, fd); ret = pmem2_source_delete(&src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); CLOSE(fd); return 1; } /* * test_set_invalid_fd - test setting invalid fd */ static int test_set_invalid_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_invalid_fd "); char *file = argv[0]; /* open and close the file to get invalid fd */ int fd = OPEN(file, O_WRONLY); CLOSE(fd); ut_suppress_crt_assert(); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, fd); ut_unsuppress_crt_assert(); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); UT_ASSERTeq(src, NULL); return 1; } /* * test_set_wronly_fd - test setting wronly fd */ static int test_set_wronly_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_wronly_fd "); char *file = argv[0]; int fd = OPEN(file, O_WRONLY); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, fd); #ifdef _WIN32 /* windows doesn't validate open flags */ UT_PMEM2_EXPECT_RETURN(ret, 0); verify_fd(src, fd); ret = pmem2_source_delete(&src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); #else UT_ASSERTeq(src, NULL); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); #endif CLOSE(fd); return 1; } /* * test_alloc_src_enomem - test pmem2_source allocation with error injection */ static int test_alloc_src_enomem(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_alloc_src_enomem "); char *file = argv[0]; struct pmem2_source *src; if (!core_fault_injection_enabled()) { return 1; } int fd = OPEN(file, O_RDWR); core_inject_fault_at(PMEM_MALLOC, 1, "pmem2_malloc"); int ret = pmem2_source_from_fd(&src, fd); UT_PMEM2_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(src, NULL); CLOSE(fd); return 1; } /* * test_delete_null_config - test pmem2_source_delete on NULL config */ static int test_delete_null_config(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_source *src = NULL; /* should not crash */ int ret = pmem2_source_delete(&src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 0; } #ifdef WIN32 /* * test_set_handle - test setting valid handle */ static int test_set_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_handle "); char *file = argv[0]; HANDLE h = CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); UT_ASSERTne(h, INVALID_HANDLE_VALUE); struct pmem2_source *src; int ret = pmem2_source_from_handle(&src, h); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src->value.handle, h); CloseHandle(h); pmem2_source_delete(&src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_set_null_handle - test resetting handle */ static int test_set_null_handle(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_source *src; int ret = pmem2_source_from_handle(&src, INVALID_HANDLE_VALUE); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); UT_ASSERTeq(src, NULL); return 0; } /* * test_set_invalid_handle - test setting invalid handle */ static int test_set_invalid_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_invalid_handle "); char *file = argv[0]; struct pmem2_source *src; HANDLE h = CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); UT_ASSERTne(h, INVALID_HANDLE_VALUE); CloseHandle(h); int ret = pmem2_source_from_handle(&src, h); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); return 1; } /* * test_set_directory_handle - test setting a directory handle */ static int test_set_directory_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_directory_handle "); char *file = argv[0]; struct pmem2_source *src; HANDLE h = CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL); UT_ASSERTne(h, INVALID_HANDLE_VALUE); int ret = pmem2_source_from_handle(&src, h); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_TYPE); UT_ASSERTeq(src, NULL); CloseHandle(h); return 1; } /* * test_set_directory_handle - test setting a mutex handle */ static int test_set_mutex_handle(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_source *src; HANDLE h = CreateMutex(NULL, FALSE, NULL); UT_ASSERTne(h, INVALID_HANDLE_VALUE); int ret = pmem2_source_from_handle(&src, h); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); UT_ASSERTeq(src, NULL); CloseHandle(h); return 0; } /* * test_get_handle - test getting handle value */ static int test_get_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_get_handle "); char *file = argv[0]; HANDLE h = CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); UT_ASSERTne(h, INVALID_HANDLE_VALUE); struct pmem2_source *src; int ret = pmem2_source_from_handle(&src, h); UT_PMEM2_EXPECT_RETURN(ret, 0); HANDLE handle_from_pmem2; ret = pmem2_source_get_handle(src, &handle_from_pmem2); UT_ASSERTeq(handle_from_pmem2, h); UT_PMEM2_EXPECT_RETURN(ret, 0); CloseHandle(h); pmem2_source_delete(&src); return 1; } /* * test_get_handle_inval_type - test getting handle value from invalid type */ static int test_get_handle_inval_type(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_source *src; int ret = pmem2_source_from_anon(&src, 0); UT_PMEM2_EXPECT_RETURN(ret, 0); HANDLE handle_from_pmem2; ret = pmem2_source_get_handle(src, &handle_from_pmem2); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_FILE_HANDLE_NOT_SET); pmem2_source_delete(&src); return 0; } #else /* * test_set_directory_handle - test setting directory's fd */ static int test_set_directory_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_directory_fd "); char *file = argv[0]; struct pmem2_source *src; int fd = OPEN(file, O_RDONLY); int ret = pmem2_source_from_fd(&src, fd); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_TYPE); CLOSE(fd); return 1; } /* * test_get_fd - test getting file descriptor value */ static int test_get_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_get_fd "); char *file = argv[0]; int fd = OPEN(file, O_RDONLY); UT_ASSERTne(fd, -1); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, fd); UT_PMEM2_EXPECT_RETURN(ret, 0); int fd_from_pmem2; ret = pmem2_source_get_fd(src, &fd_from_pmem2); UT_ASSERTeq(fd_from_pmem2, fd); UT_PMEM2_EXPECT_RETURN(ret, 0); CLOSE(fd); pmem2_source_delete(&src); return 1; } /* * test_get_fd_inval_type - test getting fd value from invalid type */ static int test_get_fd_inval_type(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_source *src; int ret = pmem2_source_from_anon(&src, 0); UT_PMEM2_EXPECT_RETURN(ret, 0); int fd_from_pmem2; ret = pmem2_source_get_fd(src, &fd_from_pmem2); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_FILE_DESCRIPTOR_NOT_SET); pmem2_source_delete(&src); return 0; } #endif /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_set_rw_fd), TEST_CASE(test_set_ro_fd), TEST_CASE(test_set_invalid_fd), TEST_CASE(test_set_wronly_fd), TEST_CASE(test_alloc_src_enomem), TEST_CASE(test_delete_null_config), #ifdef _WIN32 TEST_CASE(test_set_handle), TEST_CASE(test_set_null_handle), TEST_CASE(test_set_invalid_handle), TEST_CASE(test_set_directory_handle), TEST_CASE(test_set_mutex_handle), TEST_CASE(test_get_handle), TEST_CASE(test_get_handle_inval_type), #else TEST_CASE(test_set_directory_fd), TEST_CASE(test_get_fd), TEST_CASE(test_get_fd_inval_type), #endif }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmem2_source"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_movnt/0000775000000000000000000000000014123364546015247 5ustar rootrootpmdk-1.11.1/src/test/pmem2_movnt/pmem2_movnt.c0000664000000000000000000000364214123364546017663 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_movnt.c -- test for MOVNT threshold * * usage: pmem2_movnt */ #include "unittest.h" #include "ut_pmem2.h" int main(int argc, char *argv[]) { int fd; char *dst; char *src; struct pmem2_config *cfg; struct pmem2_source *psrc; struct pmem2_map *map; if (argc != 2) UT_FATAL("usage: %s file", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_movnt %s %savx %savx512f", thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&psrc, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, psrc); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); src = MEMALIGN(64, 8192); dst = MEMALIGN(64, 8192); memset(src, 0x88, 8192); memset(dst, 0, 8192); pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); memcpy_fn(dst, src, size, PMEM2_F_MEM_NODRAIN); UT_ASSERTeq(memcmp(src, dst, size), 0); UT_ASSERTeq(dst[size], 0); } for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); memmove_fn(dst, src, size, PMEM2_F_MEM_NODRAIN); UT_ASSERTeq(memcmp(src, dst, size), 0); UT_ASSERTeq(dst[size], 0); } for (size_t size = 1; size <= 4096; size *= 2) { memset(dst, 0, 4096); memset_fn(dst, 0x77, size, PMEM2_F_MEM_NODRAIN); UT_ASSERTeq(dst[0], 0x77); UT_ASSERTeq(dst[size - 1], 0x77); UT_ASSERTeq(dst[size], 0); } ALIGNED_FREE(dst); ALIGNED_FREE(src); ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_movnt/Makefile0000664000000000000000000000054614123364546016714 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_movnt/Makefile -- build pmem2_movnt test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_movnt OBJS = pmem2_movnt.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_movnt/pmem2_movnt.vcxproj.filters0000664000000000000000000000204614123364546022600 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2064aaf4-2eca-4fa2-99dc-b24c1acfe798} Source Files Source Files Source Files Source Files Test Scripts pmdk-1.11.1/src/test/pmem2_movnt/TESTS.py0000775000000000000000000000255314123364546016533 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t class Pmem2MovntCommon(t.Test): test_type = t.Short filesize = 4 * t.MiB filepath = None def create_file(self, ctx): self.filepath = ctx.create_holey_file(self.filesize, 'testfile',) class Pmem2Movnt(Pmem2MovntCommon): threshold = None threshold_values = ['1024', '5', '-15'] envs0 = () def run(self, ctx): super().create_file(ctx) for env in self.envs0: ctx.env[env] = '0' ctx.exec('pmem2_movnt', self.filepath) for tv in self.threshold_values: ctx.env['PMEM_MOVNT_THRESHOLD'] = tv ctx.exec('pmem2_movnt', self.filepath) class TEST0(Pmem2Movnt): pass @t.require_architectures('x86_64') class TEST1(Pmem2Movnt): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') class TEST2(Pmem2Movnt): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) class TEST3(Pmem2MovntCommon): def run(self, ctx): super().create_file(ctx) ctx.env['PMEM_NO_MOVNT'] = '1' ctx.exec('pmem2_movnt', self.filepath) class TEST4(Pmem2MovntCommon): def run(self, ctx): super().create_file(ctx) ctx.env['PMEM_NO_MOVNT'] = '1' ctx.env['PMEM_NO_GENERIC_MEMCPY'] = '1' ctx.exec('pmem2_movnt', self.filepath) pmdk-1.11.1/src/test/pmem2_movnt/.gitignore0000664000000000000000000000001414123364546017232 0ustar rootrootpmem2_movnt pmdk-1.11.1/src/test/pmem2_movnt/pmem2_movnt.vcxproj0000664000000000000000000000772114123364546021136 0ustar rootroot Debug x64 Release x64 {10B732EF-1783-4B61-B431-36BA5A2A3C9C} Win32Proj pmem2_movnt 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) {492baa3d-0d5d-478e-9765-500463ae69aa} {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/rpmemd_dbg/0000775000000000000000000000000014123364546015104 5ustar rootrootpmdk-1.11.1/src/test/rpmemd_dbg/logfile0.log.match0000664000000000000000000000326314123364546020407 0ustar rootroot[rpmemd_log_test.c:$(N)] ERR message on err level [rpmemd_log_test.c:$(N)] ERR message on warn level [rpmemd_log_test.c:$(N)] WARN message on warn level [rpmemd_log_test.c:$(N)] ERR message on notice level [rpmemd_log_test.c:$(N)] WARN message on notice level [rpmemd_log_test.c:$(N)] NOTICE message on notice level [rpmemd_log_test.c:$(N)] ERR message on info level [rpmemd_log_test.c:$(N)] WARN message on info level [rpmemd_log_test.c:$(N)] NOTICE message on info level [rpmemd_log_test.c:$(N)] INFO message on info level [rpmemd_log_test.c:$(N)] ERR message on debug level [rpmemd_log_test.c:$(N)] WARN message on debug level [rpmemd_log_test.c:$(N)] NOTICE message on debug level [rpmemd_log_test.c:$(N)] INFO message on debug level [rpmemd_log_test.c:$(N)] DBG message on debug level [rpmemd_log_test.c:$(N)] [prefix] ERR message on err level [rpmemd_log_test.c:$(N)] [prefix] ERR message on warn level [rpmemd_log_test.c:$(N)] [prefix] WARN message on warn level [rpmemd_log_test.c:$(N)] [prefix] ERR message on notice level [rpmemd_log_test.c:$(N)] [prefix] WARN message on notice level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on notice level [rpmemd_log_test.c:$(N)] [prefix] ERR message on info level [rpmemd_log_test.c:$(N)] [prefix] WARN message on info level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on info level [rpmemd_log_test.c:$(N)] [prefix] INFO message on info level [rpmemd_log_test.c:$(N)] [prefix] ERR message on debug level [rpmemd_log_test.c:$(N)] [prefix] WARN message on debug level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on debug level [rpmemd_log_test.c:$(N)] [prefix] INFO message on debug level [rpmemd_log_test.c:$(N)] [prefix] DBG message on debug level pmdk-1.11.1/src/test/rpmemd_dbg/stderr2.log.match0000664000000000000000000000005414123364546020266 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_dbg/syslog2.log.match0000664000000000000000000000005414123364546020303 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_dbg/stderr0.log.match0000664000000000000000000000326314123364546020271 0ustar rootroot[rpmemd_log_test.c:$(N)] ERR message on err level [rpmemd_log_test.c:$(N)] ERR message on warn level [rpmemd_log_test.c:$(N)] WARN message on warn level [rpmemd_log_test.c:$(N)] ERR message on notice level [rpmemd_log_test.c:$(N)] WARN message on notice level [rpmemd_log_test.c:$(N)] NOTICE message on notice level [rpmemd_log_test.c:$(N)] ERR message on info level [rpmemd_log_test.c:$(N)] WARN message on info level [rpmemd_log_test.c:$(N)] NOTICE message on info level [rpmemd_log_test.c:$(N)] INFO message on info level [rpmemd_log_test.c:$(N)] ERR message on debug level [rpmemd_log_test.c:$(N)] WARN message on debug level [rpmemd_log_test.c:$(N)] NOTICE message on debug level [rpmemd_log_test.c:$(N)] INFO message on debug level [rpmemd_log_test.c:$(N)] DBG message on debug level [rpmemd_log_test.c:$(N)] [prefix] ERR message on err level [rpmemd_log_test.c:$(N)] [prefix] ERR message on warn level [rpmemd_log_test.c:$(N)] [prefix] WARN message on warn level [rpmemd_log_test.c:$(N)] [prefix] ERR message on notice level [rpmemd_log_test.c:$(N)] [prefix] WARN message on notice level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on notice level [rpmemd_log_test.c:$(N)] [prefix] ERR message on info level [rpmemd_log_test.c:$(N)] [prefix] WARN message on info level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on info level [rpmemd_log_test.c:$(N)] [prefix] INFO message on info level [rpmemd_log_test.c:$(N)] [prefix] ERR message on debug level [rpmemd_log_test.c:$(N)] [prefix] WARN message on debug level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on debug level [rpmemd_log_test.c:$(N)] [prefix] INFO message on debug level [rpmemd_log_test.c:$(N)] [prefix] DBG message on debug level pmdk-1.11.1/src/test/rpmemd_dbg/TEST00000775000000000000000000000110714123364546015670 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_dbg/TEST0 -- unit test for rpmemd_log module # # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_normal_exit ./rpmemd_dbg\ log stderr stderr$UNITTEST_NUM.log expect_normal_exit ./rpmemd_dbg\ log file logfile$UNITTEST_NUM.log expect_normal_exit ./rpmemd_dbg\ log syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_dbg/Makefile0000664000000000000000000000072414123364546016547 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/rpmemd_dbg/Makefile -- build rpmemd_dbg test # TOP = ../../.. vpath %.c $(TOP)/src/tools/rpmemd vpath %.c ../rpmemd_log/ TARGET = rpmemd_dbg OBJS = rpmemd_log_test.o rpmemd_log.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -I../../tools/rpmemd -DDEBUG LDFLAGS += $(call extract_funcs, ../rpmemd_log/rpmemd_log_test.c) pmdk-1.11.1/src/test/rpmemd_dbg/syslog1.log.match0000664000000000000000000000003714123364546020303 0ustar rootroot[rpmemd_log_test.c:$(N)] fatal pmdk-1.11.1/src/test/rpmemd_dbg/logfile2.log.match0000664000000000000000000000005414123364546020404 0ustar rootroot[rpmemd_log_test.c:$(N)] assertion fault: 0 pmdk-1.11.1/src/test/rpmemd_dbg/.gitignore0000664000000000000000000000001314123364546017066 0ustar rootrootrpmemd_dbg pmdk-1.11.1/src/test/rpmemd_dbg/logfile1.log.match0000664000000000000000000000003714123364546020404 0ustar rootroot[rpmemd_log_test.c:$(N)] fatal pmdk-1.11.1/src/test/rpmemd_dbg/TEST10000775000000000000000000000112114123364546015665 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_dbg/TEST1 -- unit test for rpmemd_log module # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ fatal stderr stderr$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ fatal file logfile$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ fatal syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_dbg/TEST20000775000000000000000000000112414123364546015671 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmemd_dbg/TEST2 -- unit test for rpmemd_log module # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup rm -f stderr$UNITTEST_NUM.log\ logfile$UNITTEST_NUM.log\ syslog$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ assert stderr stderr$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ assert file logfile$UNITTEST_NUM.log expect_abnormal_exit ./rpmemd_dbg\ assert syslog syslog$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/rpmemd_dbg/stderr1.log.match0000664000000000000000000000003714123364546020266 0ustar rootroot[rpmemd_log_test.c:$(N)] fatal pmdk-1.11.1/src/test/rpmemd_dbg/syslog0.log.match0000664000000000000000000000543514123364546020311 0ustar rootroot[rpmemd_log_test.c:$(N)] ERR message on err level [rpmemd_log_test.c:$(N)] WARN message on err level [rpmemd_log_test.c:$(N)] NOTICE message on err level [rpmemd_log_test.c:$(N)] INFO message on err level [rpmemd_log_test.c:$(N)] DBG message on err level [rpmemd_log_test.c:$(N)] ERR message on warn level [rpmemd_log_test.c:$(N)] WARN message on warn level [rpmemd_log_test.c:$(N)] NOTICE message on warn level [rpmemd_log_test.c:$(N)] INFO message on warn level [rpmemd_log_test.c:$(N)] DBG message on warn level [rpmemd_log_test.c:$(N)] ERR message on notice level [rpmemd_log_test.c:$(N)] WARN message on notice level [rpmemd_log_test.c:$(N)] NOTICE message on notice level [rpmemd_log_test.c:$(N)] INFO message on notice level [rpmemd_log_test.c:$(N)] DBG message on notice level [rpmemd_log_test.c:$(N)] ERR message on info level [rpmemd_log_test.c:$(N)] WARN message on info level [rpmemd_log_test.c:$(N)] NOTICE message on info level [rpmemd_log_test.c:$(N)] INFO message on info level [rpmemd_log_test.c:$(N)] DBG message on info level [rpmemd_log_test.c:$(N)] ERR message on debug level [rpmemd_log_test.c:$(N)] WARN message on debug level [rpmemd_log_test.c:$(N)] NOTICE message on debug level [rpmemd_log_test.c:$(N)] INFO message on debug level [rpmemd_log_test.c:$(N)] DBG message on debug level [rpmemd_log_test.c:$(N)] [prefix] ERR message on err level [rpmemd_log_test.c:$(N)] [prefix] WARN message on err level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on err level [rpmemd_log_test.c:$(N)] [prefix] INFO message on err level [rpmemd_log_test.c:$(N)] [prefix] DBG message on err level [rpmemd_log_test.c:$(N)] [prefix] ERR message on warn level [rpmemd_log_test.c:$(N)] [prefix] WARN message on warn level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on warn level [rpmemd_log_test.c:$(N)] [prefix] INFO message on warn level [rpmemd_log_test.c:$(N)] [prefix] DBG message on warn level [rpmemd_log_test.c:$(N)] [prefix] ERR message on notice level [rpmemd_log_test.c:$(N)] [prefix] WARN message on notice level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on notice level [rpmemd_log_test.c:$(N)] [prefix] INFO message on notice level [rpmemd_log_test.c:$(N)] [prefix] DBG message on notice level [rpmemd_log_test.c:$(N)] [prefix] ERR message on info level [rpmemd_log_test.c:$(N)] [prefix] WARN message on info level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on info level [rpmemd_log_test.c:$(N)] [prefix] INFO message on info level [rpmemd_log_test.c:$(N)] [prefix] DBG message on info level [rpmemd_log_test.c:$(N)] [prefix] ERR message on debug level [rpmemd_log_test.c:$(N)] [prefix] WARN message on debug level [rpmemd_log_test.c:$(N)] [prefix] NOTICE message on debug level [rpmemd_log_test.c:$(N)] [prefix] INFO message on debug level [rpmemd_log_test.c:$(N)] [prefix] DBG message on debug level pmdk-1.11.1/src/test/pmempool_help/0000775000000000000000000000000014123364546015644 5ustar rootrootpmdk-1.11.1/src/test/pmempool_help/TEST1.PS10000664000000000000000000000123014123364546017025 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_help/TEST1 -- test for pmempool help # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si foreach($cmd in "info","dump","create","check") { rm help_${cmd}.log -Force -ea si rm ${cmd}_help.log -Force -ea si expect_normal_exit $PMEMPOOL help $cmd >> help_${cmd}.log expect_normal_exit $PMEMPOOL ${cmd} --help >> ${cmd}_help.log compare-object (get-content help_${cmd}.log) (get-content ${cmd}_help.log) >> $LOG } expect_normal_exit $PMEMPOOL help help >> $LOG check pass pmdk-1.11.1/src/test/pmempool_help/TEST00000775000000000000000000000072714123364546016437 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_help/TEST0 -- test for pmempool help # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX --version >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX --help >> $LOG check pass pmdk-1.11.1/src/test/pmempool_help/pmempool_help.vcxproj.filters0000664000000000000000000000146014123364546023571 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/pmempool_help/Makefile0000664000000000000000000000026014123364546017302 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/pmempool_help/Makefile -- build pmempool help unittest # include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_help/out0.log.match0000664000000000000000000000060614123364546020333 0ustar rootrootusage: pmempool [--version] [--help] [] pmempool $(*) usage: pmempool [--version] [--help] [] pmempool $(*) $(*) -V, --version $(*) -h, --help $(*) $(*) info - $(*) create - $(*) dump - $(*) check - $(*) rm - remove pool or poolset convert - $(*) sync - $(*) transform - $(*) feature - $(*) help - $(*) $(*) pmempool(1) $(*) pmdk-1.11.1/src/test/pmempool_help/TEST0.PS10000664000000000000000000000063714123364546017036 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_help/TEST0 -- test for pmempool help # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL >> $LOG expect_normal_exit $PMEMPOOL --version >> $LOG expect_normal_exit $PMEMPOOL --help >> $LOG check pass pmdk-1.11.1/src/test/pmempool_help/pmempool_help.vcxproj0000664000000000000000000000734714123364546022134 0ustar rootroot Debug x64 Release x64 {7dc3b3dd-73ed-4602-9af3-8d7053620dea} {D4035736-1AD6-4100-9FA9-A8A0C1DAE0C7} pmempool_help 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/pmempool_help/.gitignore0000664000000000000000000000000614123364546017630 0ustar rootroot*.out pmdk-1.11.1/src/test/pmempool_help/README0000664000000000000000000000021414123364546016521 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_help/README. This directory contains a unit test for 'pmempool help' command. pmdk-1.11.1/src/test/pmempool_help/TEST10000775000000000000000000000120014123364546016423 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_help/TEST1 -- test for pmempool help # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG for cmd in info dump create check do rm -f help_${cmd}.log ${cmd}_help.log expect_normal_exit $PMEMPOOL$EXESUFFIX help $cmd >> help_${cmd}.log expect_normal_exit $PMEMPOOL$EXESUFFIX ${cmd} --help >> ${cmd}_help.log diff help_${cmd}.log ${cmd}_help.log >> $LOG done expect_normal_exit $PMEMPOOL$EXESUFFIX help help >> $LOG check pass pmdk-1.11.1/src/test/pmempool_help/out1.log.match0000664000000000000000000000003714123364546020332 0ustar rootrootUsage: pmempool help pmdk-1.11.1/src/test/rpmem_obc/0000775000000000000000000000000014123364546014747 5ustar rootrootpmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_close.c0000664000000000000000000001116514123364546021306 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmem_obc_test_close.c -- test cases for rpmem_obj_close function */ #include "rpmem_obc_test_common.h" static const struct rpmem_msg_close_resp CLOSE_RESP = { .hdr = { .type = RPMEM_MSG_TYPE_CLOSE_RESP, .size = sizeof(struct rpmem_msg_close_resp), .status = 0, }, }; /* * check_close_msg -- check close message */ static void check_close_msg(struct rpmem_msg_close *msg) { size_t msg_size = sizeof(struct rpmem_msg_close); UT_ASSERTeq(msg->hdr.type, RPMEM_MSG_TYPE_CLOSE); UT_ASSERTeq(msg->hdr.size, msg_size); } /* * server_close_handle -- handle a close request message */ static void server_close_handle(struct server *s, const struct rpmem_msg_close_resp *resp) { struct rpmem_msg_close msg; srv_recv(s, &msg, sizeof(msg)); rpmem_ntoh_msg_close(&msg); check_close_msg(&msg); srv_send(s, resp, sizeof(*resp)); } /* * client_close_errno -- perform close request operation and expect * specified errno */ static void client_close_errno(char *target, int ex_errno) { int ret; struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_close(rpc, 0); if (ex_errno) { UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); } else { UT_ASSERTeq(ret, 0); } rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } /* * Number of cases for EPROTO test. Must be kept in sync with the * server_close_eproto function. */ #define CLOSE_EPROTO_COUNT 5 /* * server_close_eproto -- send invalid create request responses to a client */ int server_close_eproto(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, CLOSE_EPROTO_COUNT - 1); int i = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_close_resp resp = CLOSE_RESP; switch (i) { case 0: resp.hdr.type = MAX_RPMEM_MSG_TYPE; break; case 1: resp.hdr.type = RPMEM_MSG_TYPE_OPEN_RESP; break; case 2: resp.hdr.size -= 1; break; case 3: resp.hdr.size += 1; break; case 4: resp.hdr.status = MAX_RPMEM_ERR; break; default: UT_ASSERT(0); break; } rpmem_hton_msg_close_resp(&resp); server_close_handle(s, &resp); srv_fini(s); return 1; } /* * client_close_error -- check if valid errno is set if error status returned */ static void client_close_error(char *target) { int ret; for (enum rpmem_err e = 1; e < MAX_RPMEM_ERR; e++) { set_rpmem_cmd("server_close_error %d", e); int ex_errno = rpmem_util_proto_errno(e); struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_close(rpc, 0); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } } /* * client_close -- test case for close request operation - client side */ int client_close(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; for (int i = 0; i < ECONNRESET_LOOP; i++) { set_rpmem_cmd("server_close_econnreset %d", i % 2); client_close_errno(target, ECONNRESET); } for (int i = 0; i < CLOSE_EPROTO_COUNT; i++) { set_rpmem_cmd("server_close_eproto %d", i); client_close_errno(target, EPROTO); } client_close_error(target); set_rpmem_cmd("server_close"); client_close_errno(target, 0); return 1; } /* * server_close_error -- return error status in close response message */ int server_close_error(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, MAX_RPMEM_ERR); enum rpmem_err e = (enum rpmem_err)atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_close_resp resp = CLOSE_RESP; resp.hdr.status = e; rpmem_hton_msg_close_resp(&resp); server_close_handle(s, &resp); srv_fini(s); return 1; } /* * server_close_econnreset -- test case for closing connection - server size */ int server_close_econnreset(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0|1", tc->name); int do_send = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_close_resp resp = CLOSE_RESP; rpmem_hton_msg_close_resp(&resp); if (do_send) srv_send(s, &resp, sizeof(resp) / 2); srv_fini(s); return 1; } /* * server_close -- test case for close request operation - server side */ int server_close(const struct test_case *tc, int argc, char *argv[]) { struct server *s = srv_init(); struct rpmem_msg_close_resp resp = CLOSE_RESP; rpmem_hton_msg_close_resp(&resp); server_close_handle(s, &resp); srv_fini(s); return 0; } pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_set_attr.c0000664000000000000000000001306414123364546022026 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017, Intel Corporation */ /* * rpmem_obc_test_set_attr.c -- test cases for rpmem_set_attr function */ #include "rpmem_obc_test_common.h" static const struct rpmem_msg_set_attr_resp SET_ATTR_RESP = { .hdr = { .type = RPMEM_MSG_TYPE_SET_ATTR_RESP, .size = sizeof(struct rpmem_msg_set_attr_resp), .status = 0, } }; /* * check_set_attr_msg -- check set attributes message */ static void check_set_attr_msg(struct rpmem_msg_set_attr *msg) { size_t msg_size = sizeof(struct rpmem_msg_set_attr); struct rpmem_pool_attr pool_attr = POOL_ATTR_ALT; UT_ASSERTeq(msg->hdr.type, RPMEM_MSG_TYPE_SET_ATTR); UT_ASSERTeq(msg->hdr.size, msg_size); UT_ASSERTeq(memcmp(&msg->pool_attr, &pool_attr, sizeof(pool_attr)), 0); } /* * server_open_handle -- handle an set attributes request message */ static void server_set_attr_handle(struct server *s, const struct rpmem_msg_set_attr_resp *resp) { size_t msg_size = sizeof(struct rpmem_msg_set_attr); struct rpmem_msg_set_attr *msg = MALLOC(msg_size); srv_recv(s, msg, msg_size); rpmem_ntoh_msg_set_attr(msg); check_set_attr_msg(msg); srv_send(s, resp, sizeof(*resp)); FREE(msg); } /* * Number of cases for EPROTO test. Must be kept in sync with the * server_set_attr_eproto function. */ #define SET_ATTR_EPROTO_COUNT 5 /* * server_set_attr_eproto -- send invalid set attributes request responses to * a client */ int server_set_attr_eproto(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, SET_ATTR_EPROTO_COUNT - 1); int i = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_set_attr_resp resp = SET_ATTR_RESP; switch (i) { case 0: resp.hdr.type = MAX_RPMEM_MSG_TYPE; break; case 1: resp.hdr.type = RPMEM_MSG_TYPE_CREATE_RESP; break; case 2: resp.hdr.size -= 1; break; case 3: resp.hdr.size += 1; break; case 4: resp.hdr.status = MAX_RPMEM_ERR; break; default: UT_ASSERT(0); break; } rpmem_hton_msg_set_attr_resp(&resp); server_set_attr_handle(s, &resp); srv_fini(s); return 1; } /* * server_set_attr_error -- return error status in set attributes response * message */ int server_set_attr_error(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, MAX_RPMEM_ERR); enum rpmem_err e = (enum rpmem_err)atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_set_attr_resp resp = SET_ATTR_RESP; resp.hdr.status = e; rpmem_hton_msg_set_attr_resp(&resp); server_set_attr_handle(s, &resp); srv_fini(s); return 1; } /* * server_set_attr_econnreset -- test case for closing connection - server side */ int server_set_attr_econnreset(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0|1", tc->name); int do_send = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_set_attr_resp resp = SET_ATTR_RESP; rpmem_hton_msg_set_attr_resp(&resp); if (do_send) srv_send(s, &resp, sizeof(resp) / 2); srv_fini(s); return 1; } /* * server_set_attr -- test case for rpmem_obc_set_attr - server side * side */ int server_set_attr(const struct test_case *tc, int argc, char *argv[]) { struct server *s = srv_init(); struct rpmem_msg_set_attr_resp resp = SET_ATTR_RESP; rpmem_hton_msg_set_attr_resp(&resp); server_set_attr_handle(s, &resp); srv_fini(s); return 0; } /* * client_set_attr_init -- initialize communication - client side */ static struct rpmem_obc * client_set_attr_init(char *target) { struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); return rpc; } /* * client_set_attr_fini -- finalize communication - client side */ static void client_set_attr_fini(struct rpmem_obc *rpc) { rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } /* * client_set_attr_errno -- perform set attributes request operation and expect * specified errno. */ static void client_set_attr_errno(char *target, int ex_errno) { struct rpmem_obc *rpc = client_set_attr_init(target); const struct rpmem_pool_attr pool_attr_alt = POOL_ATTR_ALT; int ret = rpmem_obc_set_attr(rpc, &pool_attr_alt); if (ex_errno) { UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); } else { UT_ASSERTeq(ret, 0); } client_set_attr_fini(rpc); } /* * client_set_attr_error -- check if valid errno is set if error status * returned */ static void client_set_attr_error(char *target) { int ret; for (enum rpmem_err e = 1; e < MAX_RPMEM_ERR; e++) { set_rpmem_cmd("server_set_attr_error %d", e); int ex_errno = rpmem_util_proto_errno(e); struct rpmem_obc *rpc = client_set_attr_init(target); const struct rpmem_pool_attr pool_attr_alt = POOL_ATTR_ALT; ret = rpmem_obc_set_attr(rpc, &pool_attr_alt); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); client_set_attr_fini(rpc); } } /* * client_set_attr -- test case for set attributes request operation - client * side */ int client_set_attr(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; for (int i = 0; i < ECONNRESET_LOOP; i++) { set_rpmem_cmd("server_set_attr_econnreset %d", i % 2); client_set_attr_errno(target, ECONNRESET); } for (int i = 0; i < SET_ATTR_EPROTO_COUNT; i++) { set_rpmem_cmd("server_set_attr_eproto %d", i); client_set_attr_errno(target, EPROTO); } client_set_attr_error(target); set_rpmem_cmd("server_set_attr"); client_set_attr_errno(target, 0); return 1; } pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_common.h0000664000000000000000000000561214123364546021476 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_obc_test_common.h -- common declarations for rpmem_obc test */ #include "unittest.h" #include "out.h" #include "librpmem.h" #include "rpmem.h" #include "rpmem_proto.h" #include "rpmem_common.h" #include "rpmem_util.h" #include "rpmem_obc.h" #define POOL_SIZE 1024 #define NLANES 32 #define NLANES_RESP 16 #define PROVIDER RPMEM_PROV_LIBFABRIC_SOCKETS #define POOL_DESC "pool_desc" #define RKEY 0xabababababababab #define RADDR 0x0101010101010101 #define PORT 1234 #define BUFF_SIZE 8192 #define POOL_ATTR_INIT {\ .signature = "",\ .major = 1,\ .compat_features = 2,\ .incompat_features = 3,\ .ro_compat_features = 4,\ .poolset_uuid = "POOLSET_UUID0123",\ .uuid = "UUID0123456789AB",\ .next_uuid = "NEXT_UUID0123456",\ .prev_uuid = "PREV_UUID0123456",\ .user_flags = "USER_FLAGS012345",\ } #define POOL_ATTR_ALT {\ .signature = "",\ .major = 5,\ .compat_features = 6,\ .incompat_features = 7,\ .ro_compat_features = 8,\ .poolset_uuid = "UUID_POOLSET_ALT",\ .uuid = "ALT_UUIDCDEFFEDC",\ .next_uuid = "456UUID_NEXT_ALT",\ .prev_uuid = "UUID012_ALT_PREV",\ .user_flags = "012345USER_FLAGS",\ } static const struct rpmem_pool_attr POOL_ATTR = POOL_ATTR_INIT; struct server { int fd_in; int fd_out; }; void set_rpmem_cmd(const char *fmt, ...); struct server *srv_init(void); void srv_fini(struct server *s); void srv_recv(struct server *s, void *buff, size_t len); void srv_send(struct server *s, const void *buff, size_t len); void srv_wait_disconnect(struct server *s); void client_connect_wait(struct rpmem_obc *rpc, char *target); /* * Since the server may disconnect the connection at any moment * from the client's perspective, execute the test in a loop so * the moment when the connection is closed will be possibly different. */ #define ECONNRESET_LOOP 10 void server_econnreset(struct server *s, const void *msg, size_t len); TEST_CASE_DECLARE(client_enotconn); TEST_CASE_DECLARE(client_connect); TEST_CASE_DECLARE(client_monitor); TEST_CASE_DECLARE(server_monitor); TEST_CASE_DECLARE(server_wait); TEST_CASE_DECLARE(client_create); TEST_CASE_DECLARE(server_create); TEST_CASE_DECLARE(server_create_econnreset); TEST_CASE_DECLARE(server_create_eproto); TEST_CASE_DECLARE(server_create_error); TEST_CASE_DECLARE(client_open); TEST_CASE_DECLARE(server_open); TEST_CASE_DECLARE(server_open_econnreset); TEST_CASE_DECLARE(server_open_eproto); TEST_CASE_DECLARE(server_open_error); TEST_CASE_DECLARE(client_close); TEST_CASE_DECLARE(server_close); TEST_CASE_DECLARE(server_close_econnreset); TEST_CASE_DECLARE(server_close_eproto); TEST_CASE_DECLARE(server_close_error); TEST_CASE_DECLARE(client_set_attr); TEST_CASE_DECLARE(server_set_attr); TEST_CASE_DECLARE(server_set_attr_econnreset); TEST_CASE_DECLARE(server_set_attr_eproto); TEST_CASE_DECLARE(server_set_attr_error); pmdk-1.11.1/src/test/rpmem_obc/TEST30000775000000000000000000000061614123364546015542 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST3 -- unit test for rpmem_obc_create function # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_obc$EXESUFFIX\ client_create ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_misc.c0000664000000000000000000000760714123364546021142 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmem_obc_test_misc.c -- miscellaneous test cases for rpmem_obc module */ #include #include "rpmem_obc_test_common.h" static const struct rpmem_msg_close_resp CLOSE_RESP = { .hdr = { .type = RPMEM_MSG_TYPE_CLOSE_RESP, .size = sizeof(struct rpmem_msg_close_resp), .status = 0, }, }; /* * client_enotconn -- check if ENOTCONN error is returned after * calling rpmem_obc API without connecting to the server. */ int client_enotconn(const struct test_case *tc, int argc, char *argv[]) { struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); struct rpmem_req_attr req = { .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .pool_desc = POOL_DESC, }; struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); struct rpmem_resp_attr res; int ret; ret = rpmem_obc_monitor(rpc, 1); UT_ASSERTeq(ret, 0); ret = rpmem_obc_create(rpc, &req, &res, &pool_attr); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOTCONN); ret = rpmem_obc_open(rpc, &req, &res, &pool_attr); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOTCONN); ret = rpmem_obc_close(rpc, 0); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOTCONN); ret = rpmem_obc_disconnect(rpc); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOTCONN); rpmem_obc_fini(rpc); return 0; } /* * client_connect -- try to connect to the server at specified address and port */ int client_connect(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]...", tc->name); for (int i = 0; i < argc; i++) { struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); struct rpmem_target_info *info; info = rpmem_target_parse(argv[i]); UT_ASSERTne(info, NULL); int ret = rpmem_obc_connect(rpc, info); if (ret) { UT_OUT("not connected: %s: %s", argv[i], out_get_errormsg()); } else { UT_OUT(" connected: %s", argv[i]); rpmem_obc_disconnect(rpc); } rpmem_target_free(info); rpmem_obc_fini(rpc); } return argc; } /* * server_monitor -- test case for rpmem_obc_create function - server side */ int server_monitor(const struct test_case *tc, int argc, char *argv[]) { struct server *s = srv_init(); struct rpmem_msg_close close; struct rpmem_msg_close_resp resp = CLOSE_RESP; rpmem_hton_msg_close_resp(&resp); srv_recv(s, &close, sizeof(close)); srv_send(s, &resp, sizeof(resp)); srv_fini(s); return 0; } /* * server_monitor -- test case for rpmem_obc_monitor function - server side */ int client_monitor(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; set_rpmem_cmd("server_monitor"); { /* * Connect to target node, check connection state before * and after disconnecting. */ struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); int ret = rpmem_obc_connect(rpc, info); UT_ASSERTeq(ret, 0); ret = rpmem_obc_monitor(rpc, 1); UT_ASSERTeq(ret, 1); ret = rpmem_obc_disconnect(rpc); UT_ASSERTeq(ret, 0); ret = rpmem_obc_monitor(rpc, 1); UT_ASSERTne(ret, 1); rpmem_target_free(info); rpmem_obc_fini(rpc); } { /* * Connect to target node and expect that server will * disconnect. */ struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); int ret = rpmem_obc_connect(rpc, info); UT_ASSERTeq(ret, 0); ret = rpmem_obc_monitor(rpc, 1); UT_ASSERTeq(ret, 1); ret = rpmem_obc_close(rpc, 0); UT_ASSERTeq(ret, 0); ret = rpmem_obc_monitor(rpc, 0); UT_ASSERTne(ret, 1); rpmem_obc_disconnect(rpc); rpmem_target_free(info); rpmem_obc_fini(rpc); } return 1; } pmdk-1.11.1/src/test/rpmem_obc/TEST00000775000000000000000000000061614123364546015537 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST0 -- unit test for rpmem_obc_* # functions which require established connection # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup expect_normal_exit ./rpmem_obc$EXESUFFIX client_enotconn check pass pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_common.c0000664000000000000000000000507714123364546021476 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * rpmem_obc_test_common.c -- common definitions for rpmem_obc tests */ #include #include #include "rpmem_obc_test_common.h" #include "os.h" #define CMD_BUFF_SIZE 4096 static const char *rpmem_cmd; /* * set_rpmem_cmd -- set RPMEM_CMD variable */ void set_rpmem_cmd(const char *fmt, ...) { static char cmd_buff[CMD_BUFF_SIZE]; if (!rpmem_cmd) { char *cmd = os_getenv(RPMEM_CMD_ENV); UT_ASSERTne(cmd, NULL); rpmem_cmd = STRDUP(cmd); } ssize_t ret; size_t cnt = 0; va_list ap; va_start(ap, fmt); ret = SNPRINTF(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, "%s ", rpmem_cmd); UT_ASSERT(ret > 0); cnt += (size_t)ret; ret = vsnprintf(&cmd_buff[cnt], CMD_BUFF_SIZE - cnt, fmt, ap); UT_ASSERT(ret > 0); cnt += (size_t)ret; va_end(ap); ret = os_setenv(RPMEM_CMD_ENV, cmd_buff, 1); UT_ASSERTeq(ret, 0); /* * Rpmem has internal RPMEM_CMD variable copy and it is assumed * RPMEMD_CMD will not change its value during execution. To refresh the * internal copy it must be destroyed and a instance must be initialized * manually. */ rpmem_util_cmds_fini(); rpmem_util_cmds_init(); } struct server * srv_init(void) { struct server *s = MALLOC(sizeof(*s)); s->fd_in = STDIN_FILENO; s->fd_out = STDOUT_FILENO; uint32_t status = 0; srv_send(s, &status, sizeof(status)); return s; } /* * srv_stop -- close the server */ void srv_fini(struct server *s) { FREE(s); } /* * srv_recv -- read a message from the client */ void srv_recv(struct server *s, void *buff, size_t len) { size_t rd = 0; uint8_t *cbuf = buff; while (rd < len) { ssize_t ret = read(s->fd_in, &cbuf[rd], len - rd); UT_ASSERT(ret > 0); rd += (size_t)ret; } } /* * srv_send -- send a message to the client */ void srv_send(struct server *s, const void *buff, size_t len) { size_t wr = 0; const uint8_t *cbuf = buff; while (wr < len) { ssize_t ret = write(s->fd_out, &cbuf[wr], len - wr); UT_ASSERT(ret > 0); wr += (size_t)ret; } } /* * client_connect_wait -- wait until client connects to the server */ void client_connect_wait(struct rpmem_obc *rpc, char *target) { struct rpmem_target_info *info; info = rpmem_target_parse(target); UT_ASSERTne(info, NULL); while (rpmem_obc_connect(rpc, info)) ; rpmem_target_free(info); } /* * server_econnreset -- disconnect from client during performing an * operation */ void server_econnreset(struct server *s, const void *msg, size_t len) { for (int i = 0; i < ECONNRESET_LOOP; i++) { srv_send(s, msg, len); } } pmdk-1.11.1/src/test/rpmem_obc/Makefile0000664000000000000000000000131314123364546016405 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/Makefile -- build rpmem_obc test # SCP_TO_REMOTE_NODES = y vpath %.c ../../librpmem/ vpath %.c ../../rpmem_common/ TARGET = rpmem_obc OBJS = rpmem_obc_test.o\ rpmem_obc_test_common.o\ rpmem_obc_test_misc.o\ rpmem_obc_test_create.o\ rpmem_obc_test_open.o\ rpmem_obc_test_set_attr.o\ rpmem_obc_test_close.o\ rpmem_obc.o rpmem_util.o rpmem_common.o\ rpmem_ssh.o rpmem_cmd.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n LIBPMEMCOMMON=y include ../Makefile.inc CFLAGS += -DRPMEMC_LOG_RPMEM -DDEBUG INCS += -I../../librpmem/ INCS += -I../../rpmem_common/ pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_open.c0000664000000000000000000001640314123364546021142 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmem_obc_test_open.c -- test cases for rpmem_obj_open function */ #include "rpmem_obc_test_common.h" static const struct rpmem_msg_open_resp OPEN_RESP = { .hdr = { .type = RPMEM_MSG_TYPE_OPEN_RESP, .size = sizeof(struct rpmem_msg_open_resp), .status = 0, }, .ibc = { .port = PORT, .rkey = RKEY, .raddr = RADDR, .persist_method = RPMEM_PM_GPSPM, .nlanes = NLANES_RESP, }, .pool_attr = POOL_ATTR_INIT, }; /* * check_open_msg -- check open message */ static void check_open_msg(struct rpmem_msg_open *msg) { size_t pool_desc_size = strlen(POOL_DESC) + 1; size_t msg_size = sizeof(struct rpmem_msg_open) + pool_desc_size; UT_ASSERTeq(msg->hdr.type, RPMEM_MSG_TYPE_OPEN); UT_ASSERTeq(msg->hdr.size, msg_size); UT_ASSERTeq(msg->c.major, RPMEM_PROTO_MAJOR); UT_ASSERTeq(msg->c.minor, RPMEM_PROTO_MINOR); UT_ASSERTeq(msg->c.pool_size, POOL_SIZE); UT_ASSERTeq(msg->c.provider, PROVIDER); UT_ASSERTeq(msg->c.nlanes, NLANES); UT_ASSERTeq(msg->c.buff_size, BUFF_SIZE); UT_ASSERTeq(msg->pool_desc.size, pool_desc_size); UT_ASSERTeq(strcmp((char *)msg->pool_desc.desc, POOL_DESC), 0); } /* * server_open_handle -- handle an open request message */ static void server_open_handle(struct server *s, const struct rpmem_msg_open_resp *resp) { size_t msg_size = sizeof(struct rpmem_msg_open) + strlen(POOL_DESC) + 1; struct rpmem_msg_open *msg = MALLOC(msg_size); srv_recv(s, msg, msg_size); rpmem_ntoh_msg_open(msg); check_open_msg(msg); srv_send(s, resp, sizeof(*resp)); FREE(msg); } /* * Number of cases for EPROTO test. Must be kept in sync with the * server_open_eproto function. */ #define OPEN_EPROTO_COUNT 8 /* * server_open_eproto -- send invalid open request responses to a client */ int server_open_eproto(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, OPEN_EPROTO_COUNT - 1); int i = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_open_resp resp = OPEN_RESP; switch (i) { case 0: resp.hdr.type = MAX_RPMEM_MSG_TYPE; break; case 1: resp.hdr.type = RPMEM_MSG_TYPE_CREATE_RESP; break; case 2: resp.hdr.size -= 1; break; case 3: resp.hdr.size += 1; break; case 4: resp.hdr.status = MAX_RPMEM_ERR; break; case 5: resp.ibc.port = 0; break; case 6: resp.ibc.port = UINT16_MAX + 1; break; case 7: resp.ibc.persist_method = MAX_RPMEM_PM; break; default: UT_ASSERT(0); break; } rpmem_hton_msg_open_resp(&resp); server_open_handle(s, &resp); srv_fini(s); return 1; } /* * server_open_error -- return error status in open response message */ int server_open_error(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, MAX_RPMEM_ERR); enum rpmem_err e = (enum rpmem_err)atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_open_resp resp = OPEN_RESP; resp.hdr.status = e; rpmem_hton_msg_open_resp(&resp); server_open_handle(s, &resp); srv_fini(s); return 1; } /* * server_open -- test case for rpmem_obc_create function - server side */ int server_open_econnreset(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0|1", tc->name); int do_send = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_open_resp resp = OPEN_RESP; rpmem_hton_msg_open_resp(&resp); if (do_send) srv_send(s, &resp, sizeof(resp) / 2); srv_fini(s); return 1; } /* * server_open -- test case for open request message - server side */ int server_open(const struct test_case *tc, int argc, char *argv[]) { struct server *s = srv_init(); struct rpmem_msg_open_resp resp = OPEN_RESP; rpmem_hton_msg_open_resp(&resp); server_open_handle(s, &resp); srv_fini(s); return 0; } /* * client_open_errno -- perform open request operation and expect * specified errno, repeat the operation specified number of times. * If ex_errno is zero expect certain values in res struct. */ static void client_open_errno(char *target, int ex_errno) { struct rpmem_req_attr req = { .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .pool_desc = POOL_DESC, .buff_size = BUFF_SIZE, }; struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); struct rpmem_resp_attr res; int ret; struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_open(rpc, &req, &res, &pool_attr); if (ex_errno) { UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); } else { UT_ASSERTeq(ret, 0); UT_ASSERTeq(res.port, OPEN_RESP.ibc.port); UT_ASSERTeq(res.rkey, OPEN_RESP.ibc.rkey); UT_ASSERTeq(res.raddr, OPEN_RESP.ibc.raddr); UT_ASSERTeq(res.persist_method, OPEN_RESP.ibc.persist_method); UT_ASSERTeq(res.nlanes, OPEN_RESP.ibc.nlanes); UT_ASSERTeq(memcmp(pool_attr.signature, OPEN_RESP.pool_attr.signature, RPMEM_POOL_HDR_SIG_LEN), 0); UT_ASSERTeq(pool_attr.major, OPEN_RESP.pool_attr.major); UT_ASSERTeq(pool_attr.compat_features, OPEN_RESP.pool_attr.compat_features); UT_ASSERTeq(pool_attr.incompat_features, OPEN_RESP.pool_attr.incompat_features); UT_ASSERTeq(pool_attr.ro_compat_features, OPEN_RESP.pool_attr.ro_compat_features); UT_ASSERTeq(memcmp(pool_attr.poolset_uuid, OPEN_RESP.pool_attr.poolset_uuid, RPMEM_POOL_HDR_UUID_LEN), 0); UT_ASSERTeq(memcmp(pool_attr.uuid, OPEN_RESP.pool_attr.uuid, RPMEM_POOL_HDR_UUID_LEN), 0); UT_ASSERTeq(memcmp(pool_attr.next_uuid, OPEN_RESP.pool_attr.next_uuid, RPMEM_POOL_HDR_UUID_LEN), 0); UT_ASSERTeq(memcmp(pool_attr.prev_uuid, OPEN_RESP.pool_attr.prev_uuid, RPMEM_POOL_HDR_UUID_LEN), 0); UT_ASSERTeq(memcmp(pool_attr.user_flags, OPEN_RESP.pool_attr.user_flags, RPMEM_POOL_USER_FLAGS_LEN), 0); } rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } /* * client_open_error -- check if valid errno is set if error status returned */ static void client_open_error(char *target) { struct rpmem_req_attr req = { .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .pool_desc = POOL_DESC, .buff_size = BUFF_SIZE, }; struct rpmem_pool_attr pool_attr; memset(&pool_attr, 0, sizeof(pool_attr)); struct rpmem_resp_attr res; int ret; for (enum rpmem_err e = 1; e < MAX_RPMEM_ERR; e++) { set_rpmem_cmd("server_open_error %d", e); int ex_errno = rpmem_util_proto_errno(e); struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_open(rpc, &req, &res, &pool_attr); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } } /* * client_open -- test case for open request message - client side */ int client_open(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; for (int i = 0; i < ECONNRESET_LOOP; i++) { set_rpmem_cmd("server_open_econnreset %d", i % 2); client_open_errno(target, ECONNRESET); } for (int i = 0; i < OPEN_EPROTO_COUNT; i++) { set_rpmem_cmd("server_open_eproto %d", i); client_open_errno(target, EPROTO); } client_open_error(target); set_rpmem_cmd("server_open"); client_open_errno(target, 0); return 1; } pmdk-1.11.1/src/test/rpmem_obc/TEST50000775000000000000000000000061214123364546015540 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST5 -- unit test for rpmem_obc_open function # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_obc$EXESUFFIX\ client_open ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmem_obc/TEST40000775000000000000000000000061414123364546015541 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST4 -- unit test for rpmem_obc_close function # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_obc$EXESUFFIX\ client_close ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmem_obc/out0.log.match0000664000000000000000000000013214123364546017430 0ustar rootrootrpmem_obc/TEST0: START: rpmem_obc ./rpmem_obc$(nW) client_enotconn rpmem_obc/TEST0: DONE pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test_create.c0000664000000000000000000001476214123364546021452 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmem_obc_test_create.c -- test cases for rpmem_obc_create function */ #include "rpmem_obc_test_common.h" static const struct rpmem_msg_create_resp CREATE_RESP = { .hdr = { .type = RPMEM_MSG_TYPE_CREATE_RESP, .size = sizeof(struct rpmem_msg_create_resp), .status = 0, }, .ibc = { .port = PORT, .rkey = RKEY, .raddr = RADDR, .persist_method = RPMEM_PM_GPSPM, .nlanes = NLANES_RESP, }, }; /* * check_create_msg -- check create message */ static void check_create_msg(struct rpmem_msg_create *msg) { size_t pool_desc_size = strlen(POOL_DESC) + 1; size_t msg_size = sizeof(struct rpmem_msg_create) + pool_desc_size; struct rpmem_pool_attr pool_attr = POOL_ATTR_INIT; UT_ASSERTeq(msg->hdr.type, RPMEM_MSG_TYPE_CREATE); UT_ASSERTeq(msg->hdr.size, msg_size); UT_ASSERTeq(msg->c.major, RPMEM_PROTO_MAJOR); UT_ASSERTeq(msg->c.minor, RPMEM_PROTO_MINOR); UT_ASSERTeq(msg->c.pool_size, POOL_SIZE); UT_ASSERTeq(msg->c.provider, PROVIDER); UT_ASSERTeq(msg->c.nlanes, NLANES); UT_ASSERTeq(msg->c.buff_size, BUFF_SIZE); UT_ASSERTeq(msg->pool_desc.size, pool_desc_size); UT_ASSERTeq(strcmp((char *)msg->pool_desc.desc, POOL_DESC), 0); UT_ASSERTeq(memcmp(&msg->pool_attr, &pool_attr, sizeof(pool_attr)), 0); } /* * server_create_handle -- handle a create request message */ static void server_create_handle(struct server *s, const struct rpmem_msg_create_resp *resp) { size_t msg_size = sizeof(struct rpmem_msg_create) + strlen(POOL_DESC) + 1; struct rpmem_msg_create *msg = MALLOC(msg_size); srv_recv(s, msg, msg_size); rpmem_ntoh_msg_create(msg); check_create_msg(msg); srv_send(s, resp, sizeof(*resp)); FREE(msg); } /* * Number of cases for EPROTO test. Must be kept in sync with the * server_create_eproto function. */ #define CREATE_EPROTO_COUNT 8 /* * server_create_eproto -- send invalid create request responses to a client */ int server_create_eproto(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, CREATE_EPROTO_COUNT - 1); int i = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_create_resp resp = CREATE_RESP; switch (i) { case 0: resp.hdr.type = MAX_RPMEM_MSG_TYPE; break; case 1: resp.hdr.type = RPMEM_MSG_TYPE_OPEN_RESP; break; case 2: resp.hdr.size -= 1; break; case 3: resp.hdr.size += 1; break; case 4: resp.hdr.status = MAX_RPMEM_ERR; break; case 5: resp.ibc.port = 0; break; case 6: resp.ibc.port = UINT16_MAX + 1; break; case 7: resp.ibc.persist_method = MAX_RPMEM_PM; break; default: UT_ASSERT(0); break; } rpmem_hton_msg_create_resp(&resp); server_create_handle(s, &resp); srv_fini(s); return 1; } /* * server_create_error -- return an error status in create response message */ int server_create_error(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0-%d", tc->name, MAX_RPMEM_ERR); enum rpmem_err e = (enum rpmem_err)atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_create_resp resp = CREATE_RESP; resp.hdr.status = e; rpmem_hton_msg_create_resp(&resp); server_create_handle(s, &resp); srv_fini(s); return 1; } /* * server_create_econnreset -- test case for closing connection - server side */ int server_create_econnreset(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s 0|1", tc->name); int do_send = atoi(argv[0]); struct server *s = srv_init(); struct rpmem_msg_create_resp resp = CREATE_RESP; rpmem_hton_msg_create_resp(&resp); if (do_send) srv_send(s, &resp, sizeof(resp) / 2); srv_fini(s); return 1; } /* * server_create -- test case for rpmem_obc_create function - server side */ int server_create(const struct test_case *tc, int argc, char *argv[]) { if (argc < 0) UT_FATAL("usage: %s", tc->name); struct server *s = srv_init(); struct rpmem_msg_create_resp resp = CREATE_RESP; rpmem_hton_msg_create_resp(&resp); server_create_handle(s, &resp); srv_fini(s); return 0; } /* * client_create_errno -- perform create request operation and expect * specified errno. If ex_errno is zero expect certain values in res struct. */ static void client_create_errno(char *target, int ex_errno) { struct rpmem_req_attr req = { .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .pool_desc = POOL_DESC, .buff_size = BUFF_SIZE, }; struct rpmem_pool_attr pool_attr = POOL_ATTR_INIT; struct rpmem_resp_attr res; int ret; struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_create(rpc, &req, &res, &pool_attr); if (ex_errno) { UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); } else { UT_ASSERTeq(ret, 0); UT_ASSERTeq(res.port, CREATE_RESP.ibc.port); UT_ASSERTeq(res.rkey, CREATE_RESP.ibc.rkey); UT_ASSERTeq(res.raddr, CREATE_RESP.ibc.raddr); UT_ASSERTeq(res.persist_method, CREATE_RESP.ibc.persist_method); UT_ASSERTeq(res.nlanes, CREATE_RESP.ibc.nlanes); } rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } /* * client_create_error -- check if valid errno is set if error status returned */ static void client_create_error(char *target) { struct rpmem_req_attr req = { .pool_size = POOL_SIZE, .nlanes = NLANES, .provider = PROVIDER, .pool_desc = POOL_DESC, .buff_size = BUFF_SIZE, }; struct rpmem_pool_attr pool_attr = POOL_ATTR_INIT; struct rpmem_resp_attr res; int ret; for (enum rpmem_err e = 1; e < MAX_RPMEM_ERR; e++) { set_rpmem_cmd("server_create_error %d", e); int ex_errno = rpmem_util_proto_errno(e); struct rpmem_obc *rpc = rpmem_obc_init(); UT_ASSERTne(rpc, NULL); client_connect_wait(rpc, target); ret = rpmem_obc_create(rpc, &req, &res, &pool_attr); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ex_errno); rpmem_obc_disconnect(rpc); rpmem_obc_fini(rpc); } } /* * client_create -- test case for create request operation - client side */ int client_create(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: %s [:]", tc->name); char *target = argv[0]; for (int i = 0; i < ECONNRESET_LOOP; i++) { set_rpmem_cmd("server_create_econnreset %d", i % 2); client_create_errno(target, ECONNRESET); } for (int i = 0; i < CREATE_EPROTO_COUNT; i++) { set_rpmem_cmd("server_create_eproto %d", i); client_create_errno(target, EPROTO); } client_create_error(target); set_rpmem_cmd("server_create"); client_create_errno(target, 0); return 1; } pmdk-1.11.1/src/test/rpmem_obc/.gitignore0000664000000000000000000000001214123364546016730 0ustar rootrootrpmem_obc pmdk-1.11.1/src/test/rpmem_obc/TEST60000775000000000000000000000062214123364546015542 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST6 -- unit test for rpmem_obc_set_attr function # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_obc$EXESUFFIX\ client_set_attr ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmem_obc/TEST10000775000000000000000000000140114123364546015531 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST1 -- unit test for rpmem_obc_connect # # This test checks negative connection attempts. # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug export RPMEM_CMD="echo -n ERROR!==" setup expect_normal_exit ./rpmem_obc$EXESUFFIX\ client_connect\ 127.0.0.1\ 0.0.0.0\ localhost\ 127.0.0.1:123\ 0.0.0.0:123\ localhost:123\ 127.0.0.1:\ 127.0.0.1::123\ 127.0.0.1:-1\ 127.0.0.1:0\ 127.0.0.1:1\ 127.0.0.1:123\ 127.0.0.1:65535\ 127.0.0.1:65536\ 127.0.0.1:12345678\ 127.0.0.1:port\ 127.0.0.1:port123\ 127.0.0.1:123port\ 127.0.0.0.1\ 999.0.0.1\ 999.0.0.1:123 check pass pmdk-1.11.1/src/test/rpmem_obc/out1.log.match0000664000000000000000000000245014123364546017436 0ustar rootrootrpmem_obc/TEST1: START: rpmem_obc ./rpmem_obc$(nW) client_connect 127.0.0.1 0.0.0.0 localhost 127.0.0.1:123 0.0.0.0:123 localhost:123 127.0.0.1: 127.0.0.1::123 127.0.0.1:-1 127.0.0.1:0 127.0.0.1:1 127.0.0.1:123 127.0.0.1:65535 127.0.0.1:65536 127.0.0.1:12345678 127.0.0.1:port 127.0.0.1:port123 127.0.0.1:123port 127.0.0.0.1 999.0.0.1 999.0.0.1:123 not connected: 127.0.0.1: $(*) not connected: 0.0.0.0: $(*) not connected: localhost: $(*) not connected: 127.0.0.1:123: $(*) not connected: 0.0.0.0:123: $(*) not connected: localhost:123: $(*) not connected: 127.0.0.1:: invalid port number -- '' not connected: 127.0.0.1::123: $(*) not connected: 127.0.0.1:-1: port number must be positive -- '-1' not connected: 127.0.0.1:0: port number must be positive -- '0' not connected: 127.0.0.1:1: $(*) not connected: 127.0.0.1:123: $(*) not connected: 127.0.0.1:65535: $(*) not connected: 127.0.0.1:65536: port number too large -- '65536' not connected: 127.0.0.1:12345678: port number too large -- '12345678' not connected: 127.0.0.1:port: invalid port number -- 'port' not connected: 127.0.0.1:port123: invalid port number -- 'port123' not connected: 127.0.0.1:123port: invalid port number -- '123port' not connected: 127.0.0.0.1: $(*) not connected: 999.0.0.1: $(*) not connected: 999.0.0.1:123: $(*) rpmem_obc/TEST1: DONE pmdk-1.11.1/src/test/rpmem_obc/rpmem_obc_test.c0000664000000000000000000000255414123364546020123 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2017, Intel Corporation */ /* * rpmem_obc_test.c -- unit test for rpmem_obc module */ #include "rpmem_obc_test_common.h" #include "pmemcommon.h" /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(client_enotconn), TEST_CASE(client_connect), TEST_CASE(client_create), TEST_CASE(server_create), TEST_CASE(server_create_econnreset), TEST_CASE(server_create_eproto), TEST_CASE(server_create_error), TEST_CASE(client_open), TEST_CASE(server_open), TEST_CASE(server_open_econnreset), TEST_CASE(server_open_eproto), TEST_CASE(server_open_error), TEST_CASE(client_close), TEST_CASE(server_close), TEST_CASE(server_close_econnreset), TEST_CASE(server_close_eproto), TEST_CASE(server_close_error), TEST_CASE(client_monitor), TEST_CASE(server_monitor), TEST_CASE(client_set_attr), TEST_CASE(server_set_attr), TEST_CASE(server_set_attr_econnreset), TEST_CASE(server_set_attr_eproto), TEST_CASE(server_set_attr_error), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "rpmem_obc"); common_init("rpmem_obc", "RPMEM_LOG_LEVEL", "RPMEM_LOG_FILE", 0, 0); rpmem_util_cmds_init(); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); rpmem_util_cmds_fini(); common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/rpmem_obc/TEST20000775000000000000000000000062014123364546015534 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST2 -- unit test for rpmem_obc_monitor function # . ../unittest/unittest.sh require_test_type medium require_fs_type none require_build_type nondebug debug setup . setup.sh expect_normal_exit run_on_node 1 ./rpmem_obc$EXESUFFIX\ client_monitor ${NODE_ADDR[0]} pass pmdk-1.11.1/src/test/rpmem_obc/setup.sh0000664000000000000000000000065414123364546016450 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/setup.sh -- common setup for rpmem_obc tests # set -e require_nodes 2 require_node_log_files 1 $RPMEM_LOG_FILE RPMEM_CMD="\"cd ${NODE_TEST_DIR[0]} && UNITTEST_FORCE_QUIET=1 \ LD_LIBRARY_PATH=${NODE_LD_LIBRARY_PATH[0]}:$REMOTE_LD_LIBRARY_PATH \ ./rpmem_obc$EXESUFFIX\"" export_vars_node 1 RPMEM_CMD pmdk-1.11.1/src/test/Makefile0000664000000000000000000002522114123364546014446 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2021, Intel Corporation # # # src/test/Makefile -- build all unit tests # # Makefile -- build all unit tests # include ../common.inc TEST_DEPS = \ unittest\ tools BLK_TESTS = \ blk_include\ blk_nblock\ blk_non_zero\ blk_pool\ blk_pool_lock\ blk_recovery\ blk_rw\ blk_rw_mt LOG_TESTS = \ log_basic\ log_include\ log_pool\ log_pool_lock\ log_recovery\ log_walker OBJ_DEPS = \ obj_list # long tests first OBJ_TESTS = \ obj_basic_integration\ obj_many_size_allocs\ obj_realloc\ obj_sync\ \ obj_action\ obj_alloc\ obj_badblock\ obj_bucket\ obj_check\ obj_constructor\ obj_critnib\ obj_critnib_mt\ obj_ctl_alignment\ obj_ctl_alloc_class\ obj_ctl_alloc_class_config\ obj_ctl_arenas\ obj_ctl_config\ obj_ctl_debug\ obj_ctl_heap_size\ obj_ctl_stats\ obj_debug\ obj_defrag\ obj_defrag_advanced\ obj_direct\ obj_direct_volatile\ obj_extend\ obj_first_next\ obj_fragmentation\ obj_fragmentation2\ obj_heap\ obj_heap_interrupt\ obj_heap_state\ obj_include\ obj_lane\ obj_layout\ obj_list_insert\ obj_list_move\ obj_list_recovery\ obj_list_remove\ obj_list_valgrind\ obj_list_macro\ obj_locks\ obj_mem\ obj_memblock\ obj_memcheck\ obj_memcheck_register\ obj_memops\ obj_oid_thread\ obj_out_of_memory\ obj_persist_count\ obj_pmalloc_basic\ obj_pmalloc_mt\ obj_pmalloc_oom_mt\ obj_pmalloc_rand_mt\ obj_pmemcheck\ obj_pool\ obj_pool_lock\ obj_pool_lookup\ obj_pool_open_mt\ obj_recovery\ obj_recreate\ obj_root\ obj_reorder_basic\ obj_strdup\ obj_sds\ obj_toid\ obj_tx_alloc\ obj_tx_add_range\ obj_tx_add_range_direct\ obj_tx_callbacks\ obj_tx_flow\ obj_tx_free\ obj_tx_invalid\ obj_tx_lock\ obj_tx_locks\ obj_tx_locks_abort\ obj_tx_mt\ obj_tx_realloc\ obj_tx_strdup\ obj_tx_user_data\ obj_ulog_size\ obj_zones OBJ_REMOTE_DEPS = \ obj_basic_integration\ obj_heap_interrupt\ obj_heap_state OBJ_REMOTE_TESTS = \ obj_rpmem_basic_integration\ obj_rpmem_heap_interrupt\ obj_rpmem_heap_state\ obj_check_remote OTHER_TESTS = \ arch_flags\ bttdevice\ checksum\ compat_incompat_features\ ctl_prefault\ ctl_cow\ getopt\ magic\ mmap\ mmap_fixed\ out_err\ out_err_mt\ pmemobjcli\ pmemspoil\ scope\ set_funcs\ traces\ traces_custom_function\ traces_pmem\ unicode_api\ unicode_match_script\ util_badblock\ util_ctl\ util_extent\ util_file_create\ util_file_open\ util_is_absolute\ util_is_poolset\ util_is_zeroed\ util_map_proc\ util_parse_size\ util_pool_hdr\ util_poolset\ util_poolset_foreach\ util_poolset_parse\ util_poolset_size\ util_ravl\ util_sds\ util_uuid_generate\ util_vec\ util_vecq ifeq ($(ARCH), x86_64) OTHER_TESTS += \ util_cpuid endif PMEM_TESTS = \ pmem_include\ pmem_is_pmem\ pmem_is_pmem_posix\ pmem_map_file\ pmem_map_file_trunc\ pmem_has_auto_flush\ pmem_deep_persist\ pmem_memcpy\ pmem_memmove\ pmem_memset\ pmem_movnt\ pmem_movnt_align\ pmem_valgr_simple\ pmem_unmap PMEM2_TESTS = \ pmem2_api\ pmem2_compat\ pmem2_config\ pmem2_source\ pmem2_source_alignment\ pmem2_source_size\ pmem2_granularity\ pmem2_include\ pmem2_integration\ pmem2_granularity_detection\ pmem2_map\ pmem2_map_from_existing\ pmem2_map_prot\ pmem2_persist\ pmem2_persist_valgrind\ pmem2_perror\ pmem2_memcpy\ pmem2_memmove\ pmem2_memset\ pmem2_movnt\ pmem2_movnt_align\ pmem2_mem_ext\ pmem2_deep_flush\ pmem2_vm_reservation ifeq ($(OS_DIMM),ndctl) PMEM2_TESTS += \ pmem2_badblock_mocks\ pmem2_source_numa else $(info NOTE: Skipping tests because libndctl is disabled (see NDCTL_ENABLE)\ Skipped tests: pmem2_badblock_mocks pmem2_source_numa) endif PMEMPOOL_TESTS = \ pmempool_check\ pmempool_create\ pmempool_dump\ pmempool_feature\ pmempool_help\ pmempool_info\ pmempool_rm\ pmempool_sync\ pmempool_transform RPMEM_TESTS = \ rpmem_addr\ rpmem_addr_ext\ rpmem_basic\ rpmem_fip\ rpmem_obc\ rpmem_obc_int\ rpmem_proto\ rpmemd_config\ rpmemd_db\ rpmemd_dbg\ rpmemd_log\ rpmemd_obc\ rpmemd_util EXAMPLES_TESTS = \ ex_libpmem\ ex_libpmem2\ ex_libpmemblk\ ex_libpmemlog\ ex_libpmemobj\ ex_linkedlist RPMEM_EXAMPLES_TESTS = \ ex_librpmem_manpage\ ex_librpmem_basic\ ex_librpmem_hello\ ex_librpmem_fibonacci LIBPMEMPOOL_DEPS = \ libpmempool_api LIBPMEMPOOL_TESTS = \ libpmempool_include\ libpmempool_backup\ libpmempool_bttdev\ libpmempool_check_version\ libpmempool_feature\ libpmempool_map_flog\ libpmempool_rm LIBPMEMPOOL_MOD_DEPS = \ libpmempool_sync LIBPMEMPOOL_MOD_TESTS = \ libpmempool_transform DAXIO_TESTS = \ daxio PMREORDER_TESTS = \ pmreorder_flushes\ pmreorder_simple\ pmreorder_stack PMEMSET_TESTS = \ pmemset_config\ pmemset_deep_flush\ pmemset_event\ pmemset_file\ pmemset_include\ pmemset_memcpy\ pmemset_memmove\ pmemset_memset\ pmemset_new\ pmemset_part\ pmemset_perror\ pmemset_persist\ pmemset_source LOCAL_TESTS = \ $(OBJ_TESTS)\ $(BLK_TESTS)\ $(LOG_TESTS)\ $(OTHER_TESTS)\ $(PMEM_TESTS)\ $(PMEM2_TESTS)\ $(PMEMSET_TESTS)\ $(PMEMPOOL_TESTS)\ $(LIBPMEMPOOL_TESTS)\ $(LIBPMEMPOOL_MOD_TESTS)\ $(DAXIO_TESTS)\ $(PMREORDER_TESTS) REMOTE_TESTS = \ $(OBJ_REMOTE_TESTS)\ $(RPMEM_TESTS)\ libpmempool_rm_remote\ remote_basic\ remote_obj_basic\ pmempool_info_remote\ pmempool_feature_remote\ pmempool_rm_remote\ pmempool_sync_remote\ pmempool_transform_remote ifneq ($(BUILD_EXAMPLES),n) LOCAL_TESTS += $(EXAMPLES_TESTS) REMOTE_TESTS += $(RPMEM_EXAMPLES_TESTS) endif TESTS = \ $(LOCAL_TESTS)\ $(REMOTE_TESTS) TESTS_BUILD = \ $(TEST_DEPS)\ $(OBJ_DEPS)\ $(LIBPMEMPOOL_DEPS)\ $(LIBPMEMPOOL_MOD_DEPS)\ $(TESTS) ifneq ($(BLACKLIST_FILE),) ifeq ("$(wildcard $(BLACKLIST_FILE))","") $(error Missing blacklist file: $(BLACKLIST_FILE)) endif BLACKLIST_TESTS := $(shell cat $(BLACKLIST_FILE)) TESTS := $(filter-out $(BLACKLIST_TESTS),$(TESTS)) LOCAL_TESTS := $(filter-out $(BLACKLIST_TESTS),$(LOCAL_TESTS)) REMOTE_TESTS := $(filter-out $(BLACKLIST_TESTS),$(REMOTE_TESTS)) TESTS_BUILD := $(filter-out $(BLACKLIST_TESTS),$(TESTS_BUILD)) endif all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber test : TARGET = test cstyle : TARGET = cstyle format : TARGET = format check : TARGET = check pcheck : TARGET = pcheck sparse : TARGET = sparse pycheck : TARGET = pycheck DIR_SYNC=$(TOP)/src/test/.sync-dir SYNC_EXT=synced TESTCONFIG=$(TOP)/src/test/testconfig.sh FILE_MAX_DAX_DEVICES=$(TOP)/src/test/tools/anonymous_mmap/max_dax_devices all test format sparse: $(TESTS_BUILD) envconfig.sh envconfig.py cstyle: $(TESTS_BUILD) $(CHECK_SHEBANG) $(foreach dir,$(TESTS_BUILD),$(dir)/TEST? $(dir)/TEST??) clean clobber: $(TESTS_BUILD) $(RM) -r $(DIR_SYNC) $(RM) *.$(SYNC_EXT) $(RM) $(FILE_MAX_DAX_DEVICES) $(RM) envconfig.sh envconfig.py $(TESTS) $(OBJ_DEPS) $(LIBPMEMPOOL_DEPS) $(LIBPMEMPOOL_MOD_DEPS): $(TEST_DEPS) $(OBJ_TESTS): $(OBJ_DEPS) $(OBJ_REMOTE_TESTS): $(OBJ_REMOTE_DEPS) $(LIBPMEMPOOL_TESTS): $(LIBPMEMPOOL_DEPS) $(LIBPMEMPOOL_MOD_TESTS): $(LIBPMEMPOOL_MOD_DEPS) $(TESTS_BUILD): $(MAKE) -C $@ $(TARGET) envconfig.sh: @printf "# autogenerated file\nGLOBAL_LIB_PATH=%s\nGLOBAL_PATH=%s\nGLOBAL_PKG_CONFIG_PATH=%s\n" "$(LIBFABRIC_LD_LIBRARY_PATHS):$(LIBNDCTL_LD_LIBRARY_PATHS)" "$(LIBFABRIC_PATH)" "$(PKG_CONFIG_PATH)" > envconfig.sh PMEM2_AVX512F_ENABLED := $(shell strings $(TOP)/src/debug/libpmem2/libpmem2_all.o 2>&1 | \ grep -q "avx512f supported, but disabled at build time" && echo "0" || echo "1") envconfig.py: @printf "# autogenerated file\nconfig = {\n 'GLOBAL_LIB_PATH': '%s',\n 'PMEM2_AVX512F_ENABLED': '%s',\n 'GLOBAL_PATH': '%s',\n 'GLOBAL_PKG_CONFIG_PATH': '%s'\n}\n" \ "$(LIBFABRIC_LD_LIBRARY_PATHS):$(LIBNDCTL_LD_LIBRARY_PATHS)" "$(PMEM2_AVX512F_ENABLED)" "$(LIBFABRIC_PATH)" "$(PKG_CONFIG_PATH)" > envconfig.py require-rpmem: ifneq ($(BUILD_RPMEM),y) $(error ERROR: cannot run remote tests because $(BUILD_RPMEM_INFO)) endif memcheck-summary: grep ERROR */memcheck*.log memcheck-summary-errors: grep ERROR */memcheck*.log | grep -v " 0 errors" || true memcheck-summary-leaks: grep "in use at exit" */memcheck*.log | grep -v " 0 bytes in 0 blocks" || true check: @[ -z "$(BLACKLIST_TESTS)" ] || echo "Blacklisted tests: $(BLACKLIST_TESTS)" @./RUNTESTS $(RUNTEST_OPTIONS) $(LOCAL_TESTS) $(MAKE) check-remote-quiet-conditional @echo "No failures." pycheck: TARGET = pycheck pycheck: $(TESTS) @echo "No failures." check-remote-quiet-conditional: ifeq ($(BUILD_RPMEM),y) $(MAKE) check-remote-quiet else $(info NOTE: Skipping remote tests because $(BUILD_RPMEM_INFO)) endif check-remote-quiet: sync-remotes @MAKEFLAGS="$(MAKEFLAGS)" ./RUNTESTS $(RUNTEST_OPTIONS) $(REMOTE_TESTS) sync-remotes: require-rpmem test check-remote: check-remote-quiet @echo "No failures." # XXX remote tests do not work in parallel mode pcheck: pcheck-local-quiet check-remote-quiet-conditional @echo "No failures." pcheck-blk: TARGET = pcheck pcheck-blk: $(BLK_TESTS) @echo "No failures." pcheck-log: TARGET = pcheck pcheck-log: $(LOG_TESTS) @echo "No failures." pcheck-obj: TARGET = pcheck pcheck-obj: $(OBJ_TESTS) @echo "No failures." pcheck-other: TARGET = pcheck pcheck-other: $(OTHER_TESTS) @echo "No failures." pcheck-pmem: TARGET = pcheck pcheck-pmem: $(PMEM_TESTS) @echo "No failures." pcheck-pmem2: TARGET = pcheck pcheck-pmem2: $(PMEM2_TESTS) @echo "No failures." pcheck-pmemset: TARGET = pcheck pcheck-pmemset: $(PMEMSET_TESTS) @echo "No failures." pcheck-rpmem: TARGET = pcheck pcheck-rpmem: $(RPMEM_TESTS) @echo "No failures." pcheck-pmempool: TARGET = pcheck pcheck-pmempool: $(PMEMPOOL_TESTS) @echo "No failures." pcheck-libpmempool: TARGET = pcheck pcheck-libpmempool: $(LIBPMEMPOOL_TESTS) @echo "No failures." pcheck-local-quiet: TARGET = pcheck pcheck-local-quiet: $(LOCAL_TESTS) pcheck-local: pcheck-local-quiet @echo "No failures." pcheck-remote: TARGET = pcheck pcheck-remote: $(REMOTE_TESTS) @echo "No failures." $(TESTCONFIG): SUPP_SYNC_FILES=$(shell echo *.supp | sed s/supp/$(SYNC_EXT)/g) %.$(SYNC_EXT): %.supp $(TESTCONFIG) cp $(shell echo $^ | cut -d" " -f1) $(DIR_SYNC) @touch $@ # sync remote nodes sync-remotes: ifeq ($(FORCE_SYNC_REMOTES),y) @touch $(TESTCONFIG) endif ifneq ($(SKIP_SYNC_REMOTES),y) @rm -rf $(DIR_SYNC) && mkdir -p $(DIR_SYNC) $(MAKE) $(SUPP_SYNC_FILES) $(MAKE) -C tools $@ $(MAKE) -C ../tools $@ $(MAKE) -C sync-remotes $@ @for test in $(REMOTE_TESTS); do \ echo "$(MAKE) -C $$test sync-test" ; \ $(MAKE) -C $$test sync-test || exit 1 ; \ done @rm -rf $(DIR_SYNC) endif .PHONY: all check clean clobber cstyle pcheck pcheck-blk pcheck-log pcheck-obj\ pcheck-other pcheck-pmem pcheck-pmempool\ test unittest tools check-remote format pcheck-libpmempool pycheck\ pcheck-rpmem pcheck-local pcheck-remote sync-remotes $(TESTS_BUILD)\ require-rpmem check-remote-quiet check-remote-quiet-conditional pmdk-1.11.1/src/test/log_pool_lock/0000775000000000000000000000000014123364546015626 5ustar rootrootpmdk-1.11.1/src/test/log_pool_lock/log_pool_lock.c0000664000000000000000000000547514123364546020627 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * log_pool_lock.c -- unit test which checks whether it's possible to * simultaneously open the same log pool */ #include "unittest.h" static void test_reopen(const char *path) { PMEMlogpool *log1 = pmemlog_create(path, PMEMLOG_MIN_POOL, S_IWUSR | S_IRUSR); if (!log1) UT_FATAL("!create"); PMEMlogpool *log2 = pmemlog_open(path); if (log2) UT_FATAL("pmemlog_open should not succeed"); if (errno != EWOULDBLOCK) UT_FATAL("!pmemlog_open failed but for unexpected reason"); pmemlog_close(log1); log2 = pmemlog_open(path); if (!log2) UT_FATAL("pmemlog_open should succeed after close"); pmemlog_close(log2); UNLINK(path); } #ifndef _WIN32 static void test_open_in_different_process(int argc, char **argv, unsigned sleep) { pid_t pid = fork(); PMEMlogpool *log; char *path = argv[1]; if (pid < 0) UT_FATAL("fork failed"); if (pid == 0) { /* child */ if (sleep) usleep(sleep); while (os_access(path, R_OK)) usleep(100 * 1000); log = pmemlog_open(path); if (log) UT_FATAL("pmemlog_open after fork should not succeed"); if (errno != EWOULDBLOCK) UT_FATAL("!pmemlog_open after fork failed but for " "unexpected reason"); exit(0); } log = pmemlog_create(path, PMEMLOG_MIN_POOL, S_IWUSR | S_IRUSR); if (!log) UT_FATAL("!create"); int status; if (waitpid(pid, &status, 0) < 0) UT_FATAL("!waitpid failed"); if (!WIFEXITED(status)) UT_FATAL("child process failed"); pmemlog_close(log); UNLINK(path); } #else static void test_open_in_different_process(int argc, char **argv, unsigned sleep) { PMEMlogpool *log; if (sleep > 0) return; char *path = argv[1]; /* before starting the 2nd process, create a pool */ log = pmemlog_create(path, PMEMLOG_MIN_POOL, S_IWUSR | S_IRUSR); if (!log) UT_FATAL("!create"); /* * "X" is pass as an additional param to the new process * created by ut_spawnv to distinguish second process on Windows */ uintptr_t result = ut_spawnv(argc, argv, "X", NULL); if (result == -1) UT_FATAL("Create new process failed error: %d", GetLastError()); pmemlog_close(log); } #endif int main(int argc, char *argv[]) { START(argc, argv, "log_pool_lock"); if (argc < 2) UT_FATAL("usage: %s path", argv[0]); if (argc == 2) { test_reopen(argv[1]); test_open_in_different_process(argc, argv, 0); for (unsigned i = 1; i < 100000; i *= 2) test_open_in_different_process(argc, argv, i); } else if (argc == 3) { PMEMlogpool *log; /* 2nd arg used by windows for 2 process test */ log = pmemlog_open(argv[1]); if (log) UT_FATAL("pmemlog_open after create process should " "not succeed"); if (errno != EWOULDBLOCK) UT_FATAL("!pmemlog_open after create process failed " "but for unexpected reason"); } DONE(NULL); } pmdk-1.11.1/src/test/log_pool_lock/TEST00000775000000000000000000000047214123364546016416 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool_lock/TEST0 -- unit test for pmemlog_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup expect_normal_exit ./log_pool_lock$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/log_pool_lock/Makefile0000664000000000000000000000035614123364546017272 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool_lock/Makefile -- build log_pool_lock unit test # TARGET = log_pool_lock OBJS = log_pool_lock.o LIBPMEMLOG=y include ../Makefile.inc pmdk-1.11.1/src/test/log_pool_lock/TEST0.PS10000664000000000000000000000057214123364546017016 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_pool_lock/TEST0 -- unit test for pmemlog_open # . ..\unittest\unittest.ps1 require_test_type medium require_no_superuser # doesn't make sense to run in local directory require_fs_type any setup expect_normal_exit $Env:EXE_DIR\log_pool_lock$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/log_pool_lock/.gitignore0000664000000000000000000000001614123364546017613 0ustar rootrootlog_pool_lock pmdk-1.11.1/src/test/log_pool_lock/log_pool_lock.vcxproj.filters0000664000000000000000000000140614123364546023535 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {6a5dddce-bc61-4d43-80c6-1f87a9224cb4} ps1 Test Scripts Source Files pmdk-1.11.1/src/test/log_pool_lock/log_pool_lock.vcxproj0000664000000000000000000000706214123364546022072 0ustar rootroot Debug x64 Release x64 {E68DEB59-C709-4945-AF80-EEBCADDED944} Win32Proj log_pool_lock 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_persist_valgrind/0000775000000000000000000000000014123364546017463 5ustar rootrootpmdk-1.11.1/src/test/pmem2_persist_valgrind/Makefile0000664000000000000000000000067214123364546021130 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_persist_valgrind/Makefile -- build pmem2_persist_valgrind test # TOP = ../../.. vpath %.c $(TOP)/src/core vpath %.c $(TOP)/src/test/unittest TARGET = pmem2_persist_valgrind OBJS = alloc.o\ out.o\ pmem2_persist_valgrind.o\ util.o\ util_posix.o\ ut_pmem2_utils.o LIBPMEM2=y include ../Makefile.inc CFLAGS += -DSRCVERSION='"$(SRCVERSION)"' pmdk-1.11.1/src/test/pmem2_persist_valgrind/TESTS.py0000775000000000000000000000335514123364546020750 0ustar rootroot#!../env.py # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation import testframework as t from testframework import granularity as g import futils import os # All test cases in pmem2_persist_valgrind use Valgrind, which is not available # on Windows systems. @t.windows_exclude @t.require_valgrind_enabled('pmemcheck') # XXX In the match file, there are two possible numbers of errors. It varies # from compiler to compiler. There should be only one number when pmemcheck # will be fixed. Please also remove the below requirement after pmemcheck fix. # https://github.com/pmem/valgrind/pull/76 @g.require_granularity(g.CL_OR_LESS) class PMEM2_PERSIST(t.Test): test_type = t.Medium available_granularity = None def run(self, ctx): filepath = ctx.create_holey_file(2 * t.MiB, 'testfile') ctx.exec('pmem2_persist_valgrind', self.test_case, filepath) class TEST0(PMEM2_PERSIST): """persist continuous data in a range of pmem""" test_case = "test_persist_continuous_range" class TEST1(PMEM2_PERSIST): """persist discontinuous data in a range of pmem""" test_case = "test_persist_discontinuous_range" class TEST2(PMEM2_PERSIST): """persist part of discontinuous data in a range of pmem""" test_case = "test_persist_discontinuous_range_partially" def run(self, ctx): filepath = ctx.create_holey_file(16 * t.KiB, 'testfile') ctx.exec('pmem2_persist_valgrind', self.test_case, filepath) pmemecheck_log = os.path.join( os.getcwd(), 'pmem2_persist_valgrind', 'pmemcheck2.log') futils.tail(pmemecheck_log, 2) class TEST3(PMEM2_PERSIST): """persist data in a range of the memory mapped by mmap()""" test_case = "test_persist_nonpmem_data" pmdk-1.11.1/src/test/pmem2_persist_valgrind/pmem2_persist_valgrind.c0000664000000000000000000001173514123364546024315 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_persist_valgrind.c -- pmem2_persist_valgrind tests */ #include "out.h" #include "unittest.h" #include "ut_pmem2_utils.h" #define DATA "XXXXXXXX" #define STRIDE_SIZE 4096 /* * test_ctx -- essential parameters used by test */ struct test_ctx { int fd; struct pmem2_map *map; }; /* * test_init -- prepare resources required for testing */ static int test_init(const struct test_case *tc, int argc, char *argv[], struct test_ctx *ctx) { if (argc < 1) UT_FATAL("usage: %s ", tc->name); char *file = argv[0]; ctx->fd = OPEN(file, O_RDWR); struct pmem2_source *src; int ret = pmem2_source_from_fd(&src, ctx->fd); UT_PMEM2_EXPECT_RETURN(ret, 0); struct pmem2_config *cfg; /* fill pmem2_config in minimal scope */ ret = pmem2_config_new(&cfg); UT_PMEM2_EXPECT_RETURN(ret, 0); ret = pmem2_config_set_required_store_granularity( cfg, PMEM2_GRANULARITY_PAGE); UT_PMEM2_EXPECT_RETURN(ret, 0); /* execute pmem2_map new and validate the result */ ret = pmem2_map_new(&ctx->map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTne(ctx->map, NULL); size_t size; UT_ASSERTeq(pmem2_source_size(src, &size), 0); UT_ASSERTeq(pmem2_map_get_size(ctx->map), size); pmem2_config_delete(&cfg); /* the function returns the number of consumed arguments */ return 1; } /* * test_fini -- cleanup the test resources */ static void test_fini(struct test_ctx *ctx) { pmem2_map_delete(&ctx->map); CLOSE(ctx->fd); } /* * data_write -- write the data in mapped memory */ static void data_write(void *addr, size_t size, size_t stride) { for (size_t offset = 0; offset + sizeof(DATA) <= size; offset += stride) { memcpy((void *)((uintptr_t)addr + offset), DATA, sizeof(DATA)); } } /* * data_persist -- persist data in a range of mapped memory with defined stride */ static void data_persist(struct pmem2_map *map, size_t len, size_t stride) { size_t map_size = pmem2_map_get_size(map); char *addr = pmem2_map_get_address(map); pmem2_persist_fn p_func = pmem2_get_persist_fn(map); for (size_t offset = 0; offset + len <= map_size; offset += stride) { p_func(addr + offset, len); } } /* * test_persist_continuous_range -- persist continuous data in a range of * the persistent memory */ static int test_persist_continuous_range(const struct test_case *tc, int argc, char *argv[]) { struct test_ctx ctx = {0}; int ret = test_init(tc, argc, argv, &ctx); char *addr = pmem2_map_get_address(ctx.map); size_t map_size = pmem2_map_get_size(ctx.map); data_write(addr, map_size, sizeof(DATA) /* stride */); data_persist(ctx.map, map_size, map_size /* stride */); test_fini(&ctx); return ret; } /* * test_persist_discontinuous_range -- persist discontinuous data in a range of * the persistent memory */ static int test_persist_discontinuous_range(const struct test_case *tc, int argc, char *argv[]) { struct test_ctx ctx = {0}; int ret = test_init(tc, argc, argv, &ctx); char *addr = pmem2_map_get_address(ctx.map); size_t map_size = pmem2_map_get_size(ctx.map); data_write(addr, map_size, STRIDE_SIZE); data_persist(ctx.map, sizeof(DATA), STRIDE_SIZE); test_fini(&ctx); return ret; } /* * test_persist_discontinuous_range_partially -- persist part of discontinuous * data in a range of persistent memory */ static int test_persist_discontinuous_range_partially(const struct test_case *tc, int argc, char *argv[]) { struct test_ctx ctx = {0}; int ret = test_init(tc, argc, argv, &ctx); char *addr = pmem2_map_get_address(ctx.map); size_t map_size = pmem2_map_get_size(ctx.map); data_write(addr, map_size, STRIDE_SIZE); /* persist only a half of the writes */ data_persist(ctx.map, sizeof(DATA), 2 * STRIDE_SIZE); test_fini(&ctx); return ret; } /* * test_persist_nonpmem_data -- persist data in a range of the memory mapped * by mmap() */ static int test_persist_nonpmem_data(const struct test_case *tc, int argc, char *argv[]) { struct test_ctx ctx = {0}; /* pmem2_map is needed to get persist function */ int ret = test_init(tc, argc, argv, &ctx); size_t size = pmem2_map_get_size(ctx.map); int flags = MAP_SHARED; int proto = PROT_READ | PROT_WRITE; char *addr; addr = mmap(NULL, size, proto, flags, ctx.fd, 0); data_write(addr, size, sizeof(DATA) /* stride */); pmem2_persist_fn p_func = pmem2_get_persist_fn(ctx.map); p_func(addr, size); munmap(addr, size); test_fini(&ctx); return ret; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_persist_continuous_range), TEST_CASE(test_persist_discontinuous_range), TEST_CASE(test_persist_discontinuous_range_partially), TEST_CASE(test_persist_nonpmem_data), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_persist_valgrind"); out_init("pmem2_persist_valgrind", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_persist_valgrind/.gitignore0000664000000000000000000000003514123364546021451 0ustar rootrootpmem2_persist_valgrind *.old pmdk-1.11.1/src/test/pmem2_persist_valgrind/pmemcheck2.log.match0000664000000000000000000000012414123364546023274 0ustar rootroot==$(*)== Total memory not made persistent: 18 ==$(*)== ERROR SUMMARY: ${2|4} errors pmdk-1.11.1/src/test/pmempool_transform_remote/0000775000000000000000000000000014123364546020302 5ustar rootrootpmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out10.log.match0000664000000000000000000000360214123364546024276 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : 2097152 part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out16.log.match0000664000000000000000000000375714123364546024317 0ustar rootrootPoolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : 2097152 part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out11.log.match0000664000000000000000000000344514123364546024304 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : regular file size : $(nW) part 1: path : $(nW) type : regular file size : $(nW) Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/pmemobjcli.read.script0000664000000000000000000000005014123364546024556 0ustar rootrootstr_root_print 0 9 str_root_print 10M 9 pmdk-1.11.1/src/test/pmempool_transform_remote/TEST180000775000000000000000000000531514123364546021164 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST18 -- test for pmempool transform with SINGLEHDR # option # # (like TEST17 but with different alignment) # removing a remote replica # local replica: files # remote replica: device daxes, 2MB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root 1030M str_root_copy 0 TestOK111 str_root_copy 1000M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print 1000M 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 ${NODE_DIR[1]}part00 $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST160000775000000000000000000000562214123364546021163 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST16 -- test for pmempool transform with SINGLEHDR # option # # (like TEST15 but with different alignment) # removing a remote replica # local replica: device daxes, 2MB alignment # remote replica: device daxes, 2MB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_2MB $SIZE_2MB require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out19.log.match0000664000000000000000000000374614123364546024320 0ustar rootrootPoolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out7.log.match0000664000000000000000000000360214123364546024224 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : 2097152 part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out14.log.match0000664000000000000000000000121714123364546024301 0ustar rootrootPart file: path : $(nW)partr0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out12.log.match0000664000000000000000000000344514123364546024305 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : regular file size : $(nW) part 1: path : $(nW) type : regular file size : $(nW) Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW)part00 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/TEST170000775000000000000000000000524014123364546021160 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST17 -- test for pmempool transform with SINGLEHDR # option # # removing a remote replica # local replica: files # remote replica: device daxes, 4KB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 0 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root 1030M str_root_copy 0 TestOK111 str_root_copy 1000M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print 1000M 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 ${NODE_DIR[1]}part00 $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST30000775000000000000000000000464014123364546021076 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST3 -- test for checking pmempool transform; # adding a second remote replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any . common.sh # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE1 create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE1 \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE2 # Create remote poolset files create_poolset $DIR/$POOLSET_REMOTE1 \ 20M:${NODE_DIR[0]}remote.1.part0:x create_poolset $DIR/$POOLSET_REMOTE2 \ 20M:${NODE_DIR[0]}remote.2.part0:x copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE1 copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE2 check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE1 $POOLSET_REMOTE2 # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST90000775000000000000000000000570314123364546021105 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST9 -- test for pmempool transform with SINGLEHDR # option # # (like TEST6 but with different alignment) # adding a remote replica # local replica: device daxes, mixed alignment # remote replica: device daxes, mixed alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_2MB require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_4KB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST120000775000000000000000000000537414123364546021163 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST12 -- test for pmempool transform with SINGLEHDR # option # # (like TEST11 but with different alignment) # adding a remote replica # local replica: files # remote replica: device daxes, 2MB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root 1030M str_root_copy 0 TestOK111 str_root_copy 1000M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print 1000M 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 ${NODE_DIR[1]}part00 $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST130000775000000000000000000000563214123364546021161 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST13 -- test for pmempool transform with SINGLEHDR # option # # adding a remote replica # local replica: device daxes, 4KB alignment # remote replica: files # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 1 NODE_1_DAX_SIZE[0]=$(get_node_devdax_size 1 0) NODE_1_DAX_SIZE[1]=$(get_node_devdax_size 1 1) # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ ${NODE_1_DAX_SIZE[0]}:${NODE_DIR[0]}partr0:x \ ${NODE_1_DAX_SIZE[1]}:${NODE_DIR[0]}partr1:x \ OFFSET=${NODE_1_DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 ${NODE_DIR[0]}partr0 $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST00000775000000000000000000000425214123364546021072 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST0 -- test for checking pmempool transform; # removing remote replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any . common.sh # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x # Create remote poolset file create_poolset $DIR/$POOLSET_REMOTE \ 20M:${NODE_DIR[0]}remote.part00:x copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out14.log.match0000664000000000000000000000360214123364546024302 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : 2097152 part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/Makefile0000664000000000000000000000036214123364546021743 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/pmempool_transform_remote/Makefile -- build unit test for pmempool # transform with remote replication # SCP_TO_REMOTE_NODES=y include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_transform_remote/TEST50000775000000000000000000000437614123364546021106 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST5 -- test for checking pmempool transform; # adding a remote replica on DAX device # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device 0 1 . common.sh node_dax_device_zero 0 # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE # Create remote poolset files create_poolset $DIR/$POOLSET_REMOTE \ AUTO:$(get_node_devdax_path 0 0) copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST40000775000000000000000000000437714123364546021106 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST4 -- test for checking pmempool transform; # removing remote replica on DAX device # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device 0 1 . common.sh node_dax_device_zero 0 # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x # Create remote poolset files create_poolset $DIR/$POOLSET_REMOTE \ AUTO:$(get_node_devdax_path 0 0):x copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST70000775000000000000000000000567714123364546021115 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST7 -- test for pmempool transform with SINGLEHDR # option # # (like TEST6 but with different alignment) # adding a remote replica # local replica: device daxes, 2MB alignment # remote replica: device daxes, 4KB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_2MB $SIZE_2MB require_node_dax_device_alignments 0 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out8.log.match0000664000000000000000000000125214123364546024223 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out17.log.match0000664000000000000000000000361414123364546024310 0ustar rootrootPoolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : regular file size : $(nW) part 1: path : $(nW) type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out13.log.match0000664000000000000000000000121714123364546024300 0ustar rootrootPart file: path : $(nW)partr0 type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out18.log.match0000664000000000000000000000361414123364546024311 0ustar rootrootPoolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : regular file size : $(nW) part 1: path : $(nW) type : regular file size : $(nW) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : regular file size : $(nW) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform_remote/TEST190000775000000000000000000000556214123364546021171 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST19 -- test for pmempool transform with SINGLEHDR # option # # removing a remote replica # local replica: device daxes, 4KB alignment # remote replica: files # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 1 NODE_1_DAX_SIZE[0]=$(get_node_devdax_size 1 0) NODE_1_DAX_SIZE[1]=$(get_node_devdax_size 1 1) # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ ${NODE_1_DAX_SIZE[0]}:${NODE_DIR[0]}partr0:x \ ${NODE_1_DAX_SIZE[1]}:${NODE_DIR[0]}partr1:x \ OFFSET=${NODE_1_DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/README0000664000000000000000000000035014123364546021160 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_transform_remote/README. This directory contains unit tests for pmempool transform with remote replication. The tests check if adding and deleting remote replicas works. pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out6.log.match0000664000000000000000000000124714123364546024225 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out9.log.match0000664000000000000000000000125214123364546024224 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/common.sh0000664000000000000000000000437214123364546022134 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/common.sh -- commons for pmempool transform tests # with remote replication # set -e require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 require_node_log_files 1 pmemobj$UNITTEST_NUM.log require_node_log_files 1 pmempool$UNITTEST_NUM.log LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP rm_files_from_node 0 ${NODE_TEST_DIR[0]}/$LOG rm_files_from_node 1 ${NODE_TEST_DIR[1]}/$LOG LAYOUT=OBJ_LAYOUT POOLSET_LOCAL_IN=poolset.in POOLSET_LOCAL_OUT=poolset.out POOLSET_REMOTE=poolset.remote POOLSET_REMOTE1=poolset.remote1 POOLSET_REMOTE2=poolset.remote2 # CLI scripts for writing and reading some data hitting all the parts WRITE_SCRIPT="pmemobjcli.write.script" READ_SCRIPT="pmemobjcli.read.script" copy_files_to_node 1 ${NODE_DIR[1]} $WRITE_SCRIPT $READ_SCRIPT DUMP_INFO_LOG="../pmempool info" DUMP_INFO_LOG_REMOTE="$DUMP_INFO_LOG -f obj" DUMP_INFO_SED="sed -e '/^Checksum/d' -e '/^Creation/d' -e '/^Previous replica UUID/d' -e '/^Next replica UUID/d'" DUMP_INFO_SED_REMOTE="$DUMP_INFO_SED -e '/^Previous part UUID/d' -e '/^Next part UUID/d'" function dump_info_log() { local node=$1 local poolset=$2 local name=$3 local ignore=$4 local sed_cmd="$DUMP_INFO_SED" if [ -n "$ignore" ]; then sed_cmd="$sed_cmd -e '/^$ignore/d'" fi expect_normal_exit run_on_node $node "\"$DUMP_INFO_LOG $poolset | $sed_cmd >> $name\"" } function dump_info_log_remote() { local node=$1 local poolset=$2 local name=$3 local ignore=$4 local sed_cmd="$DUMP_INFO_SED_REMOTE" if [ -n "$ignore" ]; then sed_cmd="$sed_cmd -e '/^$ignore/d'" fi expect_normal_exit run_on_node $node "\"$DUMP_INFO_LOG_REMOTE $poolset | $sed_cmd >> $name\"" } function diff_log() { local node=$1 local f1=$2 local f2=$3 expect_normal_exit run_on_node $node "\"[ -s $f1 ] && [ -s $f2 ] && diff $f1 $f2\"" } exec_pmemobjcli_script() { local node=$1 local script=$2 local poolset=$3 local out=$4 expect_normal_exit run_on_node $node "\"../pmemobjcli -s $script $poolset > $out \"" } pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out8.log.match0000664000000000000000000000357114123364546024232 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/TEST150000775000000000000000000000554514123364546021166 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST15 -- test for pmempool transform with SINGLEHDR # option # # removing a remote replica # local replica: device daxes, 4KB alignment # remote replica: device daxes, 4KB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_4KB require_node_dax_device_alignments 0 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/config.sh0000664000000000000000000000045214123364546022104 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # pmempool_transform_remote/config.sh -- configuration of unit tests # CONF_GLOBAL_FS_TYPE=any CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/pmempool_transform_remote/TEST140000775000000000000000000000570714123364546021165 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST14 -- test for pmempool transform with SINGLEHDR # option # # (like TEST13 but with different alignment) # adding a remote replica # local replica: device daxes, 2MB alignment # remote replica: files # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 1 NODE_1_DAX_SIZE[0]=$(get_node_devdax_size 1 0) NODE_1_DAX_SIZE[1]=$(get_node_devdax_size 1 1) # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ ${NODE_1_DAX_SIZE[0]}:${NODE_DIR[0]}partr0:x \ ${NODE_1_DAX_SIZE[1]}:${NODE_DIR[0]}partr1:x \ OFFSET=${NODE_1_DAX_SIZE[0]} ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 ${NODE_DIR[0]}partr0 $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST60000775000000000000000000000562314123364546021103 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST6 -- test for pmempool transform with SINGLEHDR # option # # adding a remote replica # local replica: device daxes, 4KB alignment # remote replica: device daxes, 4KB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_4KB require_node_dax_device_alignments 0 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST10000775000000000000000000000425214123364546021073 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST1 -- test for checking pmempool transform; # adding a remote replica # . ../unittest/unittest.sh require_test_type medium require_fs_type any . common.sh # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE # Create remote poolset file create_poolset $DIR/$POOLSET_REMOTE \ 20M:${NODE_DIR[0]}remote.part00:x copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out15.log.match0000664000000000000000000000374614123364546024314 0ustar rootrootPoolset structure: Number of replicas : 1 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out12.log.match0000664000000000000000000000125214123364546024276 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out10.log.match0000664000000000000000000000125214123364546024274 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : 2097152 POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/TEST80000775000000000000000000000567714123364546021116 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST8 -- test for pmempool transform with SINGLEHDR # option # # (like TEST6 but with different alignment) # adding a remote replica # local replica: device daxes, 4KB alignment # remote replica: device daxes, 2MB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_4KB $SIZE_4KB require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out13.log.match0000664000000000000000000000357114123364546024306 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out11.log.match0000664000000000000000000000124714123364546024301 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/pmemobjcli.write.script0000664000000000000000000000010714123364546025000 0ustar rootrootpmemobj_root 11M str_root_copy 0 TestOK111 str_root_copy 10M TestOK222 pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out9.log.match0000664000000000000000000000357414123364546024236 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : 2097152 Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/TEST100000775000000000000000000000570014123364546021152 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST10 -- test for pmempool transform with SINGLEHDR # option # # (like TEST6 but with different alignment) # adding a remote replica # local replica: device daxes, 2MB alignment # remote replica: device daxes, 2MB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 1 $SIZE_2MB $SIZE_2MB require_node_dax_device_alignments 0 $SIZE_2MB $SIZE_2MB . common.sh node_dax_device_zero 1 node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 1 0) \ AUTO:$(get_node_devdax_path 1 1) \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) OFFSET=$(get_node_devdax_size 1 0) ROOT_SIZE=$[OFFSET + 1024] # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root $ROOT_SIZE str_root_copy 0 TestOK111 str_root_copy $OFFSET TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print $OFFSET 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 $(get_node_devdax_path 1 0) $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/pmempool_transform_remote/TEST20000775000000000000000000000465114123364546021077 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST2 -- test for checking pmempool transform; # removing the first of two remote replicas # . ../unittest/unittest.sh require_test_type medium require_fs_type any . common.sh # Create local poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE1 \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE2 create_poolset $DIR/$POOLSET_LOCAL_OUT \ 10M:${NODE_DIR[1]}part00:x \ 10M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE2 # Create remote poolset files create_poolset $DIR/$POOLSET_REMOTE1 \ 20M:${NODE_DIR[0]}remote.part10:x create_poolset $DIR/$POOLSET_REMOTE2 \ 20M:${NODE_DIR[0]}remote.part20:x copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE1 copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE2 check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE1 $POOLSET_REMOTE2 # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 before.00.log dump_info_log 1 ${NODE_DIR[1]}part01 before.01.log # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if correctly copied exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Log the first replica structure dump_info_log 1 ${NODE_DIR[1]}part00 after.00.log dump_info_log 1 ${NODE_DIR[1]}part01 after.01.log # Compare the logs diff_log 1 before.00.log after.00.log diff_log 1 before.01.log after.01.log diff_log 1 before.data.log after.data.log pass pmdk-1.11.1/src/test/pmempool_transform_remote/node_0_out7.log.match0000664000000000000000000000124714123364546024226 0ustar rootrootPart file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/node_1_out6.log.match0000664000000000000000000000357114123364546024230 0ustar rootrootPoolset structure: Number of replicas : 2 Replica 0 (master) - local, 2 part(s): part 0: path : $(nW) type : device dax size : $(nW) alignment : $(N) part 1: path : $(nW) type : device dax size : $(nW) alignment : $(N) Replica 1 - remote: node : $(nW) pool set : poolset.remote Poolset options: SINGLEHDR POOL Header: Signature : PMEMOBJ Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean PMEM OBJ Header: Layout : $(nW) Lanes offset : $(nW) Number of lanes : $(nW) Heap offset : $(nW) Heap size : $(nW) Root offset : $(nW) Part file: path : $(nW) type : device dax size : $(nW) alignment : $(N) POOL Header: Signature : PMEMOBJ [part file] Major : $(nW) Mandatory features : 0x$(X) [SINGLEHDR$(*)] Not mandatory features : $(*) Forced RO : $(*) Pool set UUID : $(nW) UUID : $(nW) Previous part UUID : $(nW) Next part UUID : $(nW) Alignment Descriptor : $(nW)[OK] Class : $(nW) Data : 2's complement, little endian Machine : $(*) Last shutdown : clean pmdk-1.11.1/src/test/pmempool_transform_remote/TEST110000775000000000000000000000531714123364546021157 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_transform_remote/TEST11 -- test for pmempool transform with SINGLEHDR # option # # adding a remote replica # local replica: files # remote replica: device daxes, 4KB alignment # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_nodes 2 require_node_dax_device_alignments 0 $SIZE_4KB $SIZE_4KB . common.sh node_dax_device_zero 0 # Create poolset files create_poolset $DIR/$POOLSET_LOCAL_IN \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x create_poolset $DIR/$POOLSET_LOCAL_OUT \ O SINGLEHDR \ 1000M:${NODE_DIR[1]}part00:x \ 1000M:${NODE_DIR[1]}part01:x \ m \ ${NODE_ADDR[0]}:$POOLSET_REMOTE create_poolset $DIR/$POOLSET_REMOTE \ O SINGLEHDR \ AUTO:$(get_node_devdax_path 0 0) \ AUTO:$(get_node_devdax_path 0 1) # CLI script for writing some data hitting all the parts WRITE_SCRIPT=write_data cat << EOF > $DIR/$WRITE_SCRIPT pmemobj_root 1030M str_root_copy 0 TestOK111 str_root_copy 1000M TestOK222 EOF # CLI script for reading 9 characters from all the parts READ_SCRIPT=read_data cat << EOF > $DIR/$READ_SCRIPT str_root_print 0 9 str_root_print 1000M 9 EOF copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_IN copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$POOLSET_LOCAL_OUT copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$WRITE_SCRIPT copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$READ_SCRIPT check_files_on_node 1 $POOLSET_LOCAL_IN $POOLSET_LOCAL_OUT $WRITE_SCRIPT $READ_SCRIPT check_files_on_node 0 $POOLSET_REMOTE # Create a pool expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_IN expect_normal_exit run_on_node 1 ../pmempool rm -sf ${NODE_DIR[1]}$POOLSET_LOCAL_OUT expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}$POOLSET_LOCAL_IN # Write some data into the pool, hitting two part files exec_pmemobjcli_script 1 ${NODE_DIR[1]}$WRITE_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN /dev/null exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_IN before.data.log # Transform poolset expect_normal_exit run_on_node 1 ../pmempool transform \ ${NODE_DIR[1]}$POOLSET_LOCAL_IN ${NODE_DIR[1]}$POOLSET_LOCAL_OUT # Check if data is still correctly written exec_pmemobjcli_script 1 ${NODE_DIR[1]}$READ_SCRIPT ${NODE_DIR[1]}$POOLSET_LOCAL_OUT after.data.log # Check metadata by pmempool info dump_info_log 1 ${NODE_DIR[1]}$POOLSET_LOCAL_OUT $LOG dump_info_log 1 ${NODE_DIR[1]}part00 $LOG dump_info_log 0 $(get_node_devdax_path 0 0) $LOG # Compare the logs diff_log 1 before.data.log after.data.log check pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/0000775000000000000000000000000014123364546017153 5ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out3.log.match0000664000000000000000000000227214123364546023073 0ustar rootrootobj_rpmem_heap_state/TEST3: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4318608 1 4318736 2 4318864 3 4318992 4 4319120 5 4319248 6 4319376 7 4319504 8 4319632 9 4319760 10 4319888 11 4320016 12 4320144 13 4320272 14 4320400 15 4320528 16 4320656 17 4320784 18 4320912 19 4321040 20 4321168 21 4321296 22 4321424 23 4321552 24 4321680 25 4321808 26 4321936 27 4322064 28 4322192 29 4322320 30 4322448 31 4322576 32 4322704 33 4322832 34 4322960 35 4323088 36 4323216 37 4323344 38 4323472 39 4323600 40 4323728 41 4323856 42 4323984 43 4324112 44 4324240 45 4324368 46 4324496 47 4324624 48 4324752 49 4324880 50 4325008 51 4325136 52 4325264 53 4325392 54 4325520 55 4325648 56 4325776 57 4325904 58 4326032 59 4326160 60 4326288 61 4064656 62 4064784 63 4064912 64 4065040 65 4065168 66 4065296 67 4065424 68 4065552 69 4065680 70 4065808 71 4065936 72 4066064 73 4066192 74 4066320 75 4066448 76 4066576 77 4066704 78 4066832 79 4066960 80 4067088 81 4067216 82 4067344 83 4067472 84 4067600 85 4067728 86 4067856 87 4067984 88 4068112 89 4068240 90 4068368 91 4068496 92 4068624 93 4068752 94 4068880 95 4069008 96 4069136 97 4069264 98 4069392 99 4069520 obj_rpmem_heap_state/TEST3: DONE pmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST30000775000000000000000000000626214123364546017751 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, IBM Corporation # # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium require_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 ${NODE_DIR[1]}$TEST_FILE_LOCAL # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 8M:${NODE_DIR[1]}/$TEST_FILE_LOCAL:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 9M:${NODE_DIR[0]}$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL # create remote holey pool files create_holey_file_on_node 1 8M ${NODE_DIR[1]}$TEST_FILE_LOCAL create_holey_file_on_node 0 9M ${NODE_DIR[0]}$TEST_FILE_REMOTE PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}$TEST_FILE_REMOTE copy_files_from_node 1 $DIR ${NODE_DIR[1]}$TEST_FILE_LOCAL compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/$TEST_FILE_LOCAL $DIR/$TEST_FILE_REMOTE > diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST00000775000000000000000000000621614123364546017745 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 ${NODE_DIR[1]}$TEST_FILE_LOCAL # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 8M:${NODE_DIR[1]}/$TEST_FILE_LOCAL:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 9M:${NODE_DIR[0]}$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL # create remote holey pool files create_holey_file_on_node 1 8M ${NODE_DIR[1]}$TEST_FILE_LOCAL create_holey_file_on_node 0 9M ${NODE_DIR[0]}$TEST_FILE_REMOTE PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}$TEST_FILE_REMOTE copy_files_from_node 1 $DIR ${NODE_DIR[1]}$TEST_FILE_LOCAL compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/$TEST_FILE_LOCAL $DIR/$TEST_FILE_REMOTE > diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out4.log.match0000664000000000000000000000227214123364546023074 0ustar rootrootobj_rpmem_heap_state/TEST4: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4318608 1 4318736 2 4318864 3 4318992 4 4319120 5 4319248 6 4319376 7 4319504 8 4319632 9 4319760 10 4319888 11 4320016 12 4320144 13 4320272 14 4320400 15 4320528 16 4320656 17 4320784 18 4320912 19 4321040 20 4321168 21 4321296 22 4321424 23 4321552 24 4321680 25 4321808 26 4321936 27 4322064 28 4322192 29 4322320 30 4322448 31 4322576 32 4322704 33 4322832 34 4322960 35 4323088 36 4323216 37 4323344 38 4323472 39 4323600 40 4323728 41 4323856 42 4323984 43 4324112 44 4324240 45 4324368 46 4324496 47 4324624 48 4324752 49 4324880 50 4325008 51 4325136 52 4325264 53 4325392 54 4325520 55 4325648 56 4325776 57 4325904 58 4326032 59 4326160 60 4326288 61 4064656 62 4064784 63 4064912 64 4065040 65 4065168 66 4065296 67 4065424 68 4065552 69 4065680 70 4065808 71 4065936 72 4066064 73 4066192 74 4066320 75 4066448 76 4066576 77 4066704 78 4066832 79 4066960 80 4067088 81 4067216 82 4067344 83 4067472 84 4067600 85 4067728 86 4067856 87 4067984 88 4068112 89 4068240 90 4068368 91 4068496 92 4068624 93 4068752 94 4068880 95 4069008 96 4069136 97 4069264 98 4069392 99 4069520 obj_rpmem_heap_state/TEST4: DONE pmdk-1.11.1/src/test/obj_rpmem_heap_state/Makefile0000664000000000000000000000043114123364546020611 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/obj_rpmem_heap_state/Makefile -- build obj_rpmem_heap_state test # SCP_TO_REMOTE_NODES = y SCP_TARGET = obj_heap_state SCP_SRC_DIR = ../obj_heap_state include ../obj_heap_state/Makefile.inc pmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST50000775000000000000000000000332014123364546017743 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, IBM Corporation # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 "${NODE_DIR[1]}$TEST_FILE_LOCAL ${NODE_DIR[1]}${TEST_FILE_LOCAL}_replica" # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 8M:${NODE_DIR[1]}/$TEST_FILE_LOCAL:x \ r 9M:${NODE_DIR[1]}/${TEST_FILE_LOCAL}_replica \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 9M:${NODE_DIR[0]}/$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}$TEST_FILE_REMOTE copy_files_from_node 1 $DIR ${NODE_DIR[1]}$TEST_FILE_LOCAL ${NODE_DIR[1]}${TEST_FILE_LOCAL}_replica compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/$TEST_FILE_LOCAL $DIR/$TEST_FILE_REMOTE > diff$UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_replica $DIR/$TEST_FILE_REMOTE >> diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST40000775000000000000000000000375514123364546017756 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, IBM Corporation # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL \ 16M:${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1:x \ 16M:${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE \ 16M:${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1:x \ 16M:${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL rm_files_from_node 0 "${NODE_DIR[0]}${TEST_FILE_REMOTE} ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1 ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2" rm_files_from_node 1 "${NODE_DIR[1]}${TEST_FILE_LOCAL} ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1 ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2" PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1 \ ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2 copy_files_from_node 1 $DIR ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1 \ ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2 compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_part1 $DIR/${TEST_FILE_REMOTE}_part1 \ > diff$UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_part2 $DIR/${TEST_FILE_REMOTE}_part2 \ >> diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out5.log.match0000664000000000000000000000227214123364546023075 0ustar rootrootobj_rpmem_heap_state/TEST5: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4318608 1 4318736 2 4318864 3 4318992 4 4319120 5 4319248 6 4319376 7 4319504 8 4319632 9 4319760 10 4319888 11 4320016 12 4320144 13 4320272 14 4320400 15 4320528 16 4320656 17 4320784 18 4320912 19 4321040 20 4321168 21 4321296 22 4321424 23 4321552 24 4321680 25 4321808 26 4321936 27 4322064 28 4322192 29 4322320 30 4322448 31 4322576 32 4322704 33 4322832 34 4322960 35 4323088 36 4323216 37 4323344 38 4323472 39 4323600 40 4323728 41 4323856 42 4323984 43 4324112 44 4324240 45 4324368 46 4324496 47 4324624 48 4324752 49 4324880 50 4325008 51 4325136 52 4325264 53 4325392 54 4325520 55 4325648 56 4325776 57 4325904 58 4326032 59 4326160 60 4326288 61 4064656 62 4064784 63 4064912 64 4065040 65 4065168 66 4065296 67 4065424 68 4065552 69 4065680 70 4065808 71 4065936 72 4066064 73 4066192 74 4066320 75 4066448 76 4066576 77 4066704 78 4066832 79 4066960 80 4067088 81 4067216 82 4067344 83 4067472 84 4067600 85 4067728 86 4067856 87 4067984 88 4068112 89 4068240 90 4068368 91 4068496 92 4068624 93 4068752 94 4068880 95 4069008 96 4069136 97 4069264 98 4069392 99 4069520 obj_rpmem_heap_state/TEST5: DONE pmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out0.log.match0000664000000000000000000000227214123364546023070 0ustar rootrootobj_rpmem_heap_state/TEST0: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4195664 1 4195792 2 4195920 3 4196048 4 4196176 5 4196304 6 4196432 7 4196560 8 4196688 9 4196816 10 4196944 11 4197072 12 4197200 13 4197328 14 4197456 15 4197584 16 4197712 17 4197840 18 4197968 19 4198096 20 4198224 21 4198352 22 4198480 23 4198608 24 4198736 25 4198864 26 4198992 27 4199120 28 4199248 29 4199376 30 4199504 31 4199632 32 4199760 33 4199888 34 4200016 35 4200144 36 4200272 37 4200400 38 4200528 39 4200656 40 4200784 41 4200912 42 4201040 43 4201168 44 4201296 45 4201424 46 4201552 47 4201680 48 4201808 49 4201936 50 4202064 51 4202192 52 4202320 53 4202448 54 4202576 55 4202704 56 4202832 57 4202960 58 4203088 59 4203216 60 4203344 61 3941712 62 3941840 63 3941968 64 3942096 65 3942224 66 3942352 67 3942480 68 3942608 69 3942736 70 3942864 71 3942992 72 3943120 73 3943248 74 3943376 75 3943504 76 3943632 77 3943760 78 3943888 79 3944016 80 3944144 81 3944272 82 3944400 83 3944528 84 3944656 85 3944784 86 3944912 87 3945040 88 3945168 89 3945296 90 3945424 91 3945552 92 3945680 93 3945808 94 3945936 95 3946064 96 3946192 97 3946320 98 3946448 99 3946576 obj_rpmem_heap_state/TEST0: DONE pmdk-1.11.1/src/test/obj_rpmem_heap_state/diff0.log.match0000664000000000000000000000000014123364546021727 0ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_state/config.sh0000664000000000000000000000044214123364546020754 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2017, Intel Corporation # # # obj_rpmem_heap_state/config.sh -- test configuration # CONF_GLOBAL_FS_TYPE=pmem CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST10000775000000000000000000000371314123364546017745 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL \ 16M:${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1:x \ 16M:${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2:x \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE \ 16M:${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1:x \ 16M:${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL rm_files_from_node 0 "${NODE_DIR[0]}${TEST_FILE_REMOTE} ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1 ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2" rm_files_from_node 1 "${NODE_DIR[1]}${TEST_FILE_LOCAL} ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1 ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2" PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part1 \ ${NODE_DIR[0]}${TEST_FILE_REMOTE}_part2 copy_files_from_node 1 $DIR ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part1 \ ${NODE_DIR[1]}${TEST_FILE_LOCAL}_part2 compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_part1 $DIR/${TEST_FILE_REMOTE}_part1 \ > diff$UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_part2 $DIR/${TEST_FILE_REMOTE}_part2 \ >> diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/diff1.log.match0000664000000000000000000000000014123364546021730 0ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out2.log.match0000664000000000000000000000227214123364546023072 0ustar rootrootobj_rpmem_heap_state/TEST2: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4195664 1 4195792 2 4195920 3 4196048 4 4196176 5 4196304 6 4196432 7 4196560 8 4196688 9 4196816 10 4196944 11 4197072 12 4197200 13 4197328 14 4197456 15 4197584 16 4197712 17 4197840 18 4197968 19 4198096 20 4198224 21 4198352 22 4198480 23 4198608 24 4198736 25 4198864 26 4198992 27 4199120 28 4199248 29 4199376 30 4199504 31 4199632 32 4199760 33 4199888 34 4200016 35 4200144 36 4200272 37 4200400 38 4200528 39 4200656 40 4200784 41 4200912 42 4201040 43 4201168 44 4201296 45 4201424 46 4201552 47 4201680 48 4201808 49 4201936 50 4202064 51 4202192 52 4202320 53 4202448 54 4202576 55 4202704 56 4202832 57 4202960 58 4203088 59 4203216 60 4203344 61 3941712 62 3941840 63 3941968 64 3942096 65 3942224 66 3942352 67 3942480 68 3942608 69 3942736 70 3942864 71 3942992 72 3943120 73 3943248 74 3943376 75 3943504 76 3943632 77 3943760 78 3943888 79 3944016 80 3944144 81 3944272 82 3944400 83 3944528 84 3944656 85 3944784 86 3944912 87 3945040 88 3945168 89 3945296 90 3945424 91 3945552 92 3945680 93 3945808 94 3945936 95 3946064 96 3946192 97 3946320 98 3946448 99 3946576 obj_rpmem_heap_state/TEST2: DONE pmdk-1.11.1/src/test/obj_rpmem_heap_state/diff2.log.match0000664000000000000000000000000014123364546021731 0ustar rootrootpmdk-1.11.1/src/test/obj_rpmem_heap_state/TEST20000775000000000000000000000325614123364546017750 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium exclude_ppc64 setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER init_rpmem_on_node 1 0 # binary for this test EXE=obj_heap_state # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" TEST_FILE_LOCAL="testfile_local" TEST_FILE_REMOTE="testfile_remote" rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE rm_files_from_node 1 "${NODE_DIR[1]}$TEST_FILE_LOCAL ${NODE_DIR[1]}${TEST_FILE_LOCAL}_replica" # XXX: Make sum of all parts and replicas sizes equal # create and upload poolset files create_poolset $DIR/$TEST_SET_LOCAL 8M:${NODE_DIR[1]}/$TEST_FILE_LOCAL:x \ r 9M:${NODE_DIR[1]}/${TEST_FILE_LOCAL}_replica \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 9M:${NODE_DIR[0]}/$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL PMEM_IS_PMEM_FORCE=1 export_vars_node 1 PMEM_IS_PMEM_FORCE # execute test expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}$TEST_SET_LOCAL check # download pools and compare them copy_files_from_node 0 $DIR ${NODE_DIR[0]}$TEST_FILE_REMOTE copy_files_from_node 1 $DIR ${NODE_DIR[1]}$TEST_FILE_LOCAL ${NODE_DIR[1]}${TEST_FILE_LOCAL}_replica compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/$TEST_FILE_LOCAL $DIR/$TEST_FILE_REMOTE > diff$UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/${TEST_FILE_LOCAL}_replica $DIR/$TEST_FILE_REMOTE >> diff$UNITTEST_NUM.log check_local pass pmdk-1.11.1/src/test/obj_rpmem_heap_state/node_1_out1.log.match0000664000000000000000000000227214123364546023071 0ustar rootrootobj_rpmem_heap_state/TEST1: START: obj_heap_state ./obj_heap_state $(nW)testset_local 0 4195664 1 4195792 2 4195920 3 4196048 4 4196176 5 4196304 6 4196432 7 4196560 8 4196688 9 4196816 10 4196944 11 4197072 12 4197200 13 4197328 14 4197456 15 4197584 16 4197712 17 4197840 18 4197968 19 4198096 20 4198224 21 4198352 22 4198480 23 4198608 24 4198736 25 4198864 26 4198992 27 4199120 28 4199248 29 4199376 30 4199504 31 4199632 32 4199760 33 4199888 34 4200016 35 4200144 36 4200272 37 4200400 38 4200528 39 4200656 40 4200784 41 4200912 42 4201040 43 4201168 44 4201296 45 4201424 46 4201552 47 4201680 48 4201808 49 4201936 50 4202064 51 4202192 52 4202320 53 4202448 54 4202576 55 4202704 56 4202832 57 4202960 58 4203088 59 4203216 60 4203344 61 3941712 62 3941840 63 3941968 64 3942096 65 3942224 66 3942352 67 3942480 68 3942608 69 3942736 70 3942864 71 3942992 72 3943120 73 3943248 74 3943376 75 3943504 76 3943632 77 3943760 78 3943888 79 3944016 80 3944144 81 3944272 82 3944400 83 3944528 84 3944656 85 3944784 86 3944912 87 3945040 88 3945168 89 3945296 90 3945424 91 3945552 92 3945680 93 3945808 94 3945936 95 3946064 96 3946192 97 3946320 98 3946448 99 3946576 obj_rpmem_heap_state/TEST1: DONE pmdk-1.11.1/src/test/testconfig.sh.example0000664000000000000000000001744214123364546017147 0ustar rootroot# # src/test/testconfig.sh -- configuration for local and remote unit tests # # # 1) *** LOCAL CONFIGURATION *** # # The first part of the file tells the script unittest/unittest.sh # which file system locations are to be used for local testing. # # # Appended to PMEM_FS_DIR and NON_PMEM_FS_DIR to test PMDK with # file path longer than 255 characters. # # LONGDIR="LoremipsumdolorsitametconsecteturadipiscingelitVivamuslacinianibhattortordictumsollicitudinNullamvariusvestibulumligulaetegestaselitsemperidMaurisultriciesligulaeuipsumtinciduntluctusMorbimaximusvariusdolorid" # DIRSUFFIX="$LONGDIR/$LONGDIR/$LONGDIR/$LONGDIR/$LONGDIR" # # For tests that require true persistent memory, set the path to a directory # on a PMEM-aware file system here. Uncomment this line if there's an # actual persistent memory available on this system. # Note that PMEM_FS_DIR is intended mostly to test codepaths where # pmem_persist() is used for flushing data to persistence. For now, there is # no file system on Linux that fully supports pmem_persist(), so even in case # of DAX-enabled file systems (like ext4), PMDK would behave as for non-PMEM # file system and would still use pmem_msync(). # You may change this behavior by setting PMEM_FS_DIR_FORCE_PMEM (see below). # To fully test the PMEM codepaths it is strongly recommended to configure # DEVICE_DAX_PATH as well. # #PMEM_FS_DIR=/mnt/pmem # # For tests that require true a non-persistent memory aware file system (i.e. # to verify something works on traditional page-cache based memory-mapped # files) set the path to a directory on a normal file system here. # #NON_PMEM_FS_DIR=/tmp # # If you don't have real PMEM or PMEM emulation set up and/or the filesystem # does not support MAP_SYNC flag, but still want to test PMEM codepaths # uncomment this line. It will set PMEM_IS_PMEM_FORCE to 1 for tests that # require pmem. # # Setting this flag to 1, if the PMEM_FS_DIR filesystem supports MAP_SYNC will # cause an error. This flag cannot be used with filesystems which support # MAP_SYNC because it would prevent from testing the target PMEM codepaths. # If you want to ignore this error set the value to 2. # #PMEM_FS_DIR_FORCE_PMEM=1 # # For tests that require raw dax devices without a file system, set a path to # those devices in an array format. For most tests one device is enough, but # some might require more. # # For big sizes of DAX devices, some tests ran against Valgrind might fail due # to length of anonymous mmap and Valgrind limitations. Maximum possible length # is being calculated each time testconfig.sh changes. Tests which require more # than detected maximum possible length are skipped. # # It is required to have R/W access to these devices and at least RO access # to all of the following resource files (containing physical addresses) # of NVDIMM devices (only root can read them by default): # # /sys/bus/nd/devices/ndbus*/region*/resource # /sys/bus/nd/devices/ndbus*/region*/dax*/resource # /sys/bus/nd/devices/ndbus*/region*/pfn*/resource # /sys/bus/nd/devices/ndbus*/region*/namespace*/resource # # Note: some tests require write access to '/sys/bus/nd/devices/region*/deep_flush'. # #DEVICE_DAX_PATH=(/dev/dax0.0 /dev/dax1.0) # # Overwrite default test type: # check (default), short, medium, long, all # where: check = short + medium; all = short + medium + long # #TEST_TYPE=check # # Overwrite available build types: # debug, nondebug, static-debug, static-nondebug, all (default) # #TEST_BUILD=all # # Overwrite available filesystem types: # pmem, non-pmem, any, none, all (default) # #TEST_FS=all # # Overwrite default timeout # (floating point number with an optional suffix: 's' for seconds (the default), # 'm' for minutes, 'h' for hours or 'd' for days) # #TEST_TIMEOUT=3m # # To display execution time of each test # TM=1 # # Normally the first failed test terminates the test run. If KEEP_GOING # is set, continues executing all tests. If any tests fail, once all tests # have completed reports number of failures, lists failed tests and exits # with error status. # #KEEP_GOING=y # # This option works only if KEEP_GOING=y, then if CLEAN_FAILED is set # all data created by test is removed on test failure. # #CLEAN_FAILED=y # # Changes logging level. Possible values: # 0 - silent (only error messages) # 1 - normal (above + SETUP + START + DONE + PASS + important SKIP messages) # 2 - verbose (above + all SKIP messages + stdout from test binaries) # #UNITTEST_LOG_LEVEL=1 # # Test against installed libraries, NOT the one built in tree. # Note that these variable won't affect tests that link statically. You should # disabled them using TEST_BUILD variable. # #PMDK_LIB_PATH_NONDEBUG=/usr/lib/x86_64-linux-gnu/ #PMDK_LIB_PATH_DEBUG=/usr/lib/x86_64-linux-gnu/pmdk_dbg # # Tests using the 'sudo' command can be potentially very harmful, # so they have to be enabled deliberately. # #ENABLE_SUDO_TESTS=y # # Enable and select the type of tests for code handling bad blocks. # Options: nfit_test, real_pmem, none (do not run, default). # # Running tests on emulated memory ('nfit test' option) requires 'nfit_test' # kernel module to be present in the system. # See https://github.com/pmem/ndctl#unit-tests # # If the 'real_pmem' option is enabled, tests are run on real hardware # provided through PMEM_FS_DIR or DEVICE_DAX_PATH config fields. # # The tests use 'sudo' command many times and, in case of tests on # emulated memory, insert the 'nfit_test' kernel module, so they can be # considered as POTENTIALLY DANGEROUS and have to be explicitly enabled. # Enable them ONLY IF you are sure you know what you are doing. # # As of kernel 4.20, the nfit-test module causes kernel oops whenever a devdax # namespace is created and then accessed for the first time. This causes several # of badblock-related unit tests to fail. # # BADBLOCK_TEST_TYPE=none # # 2) *** REMOTE CONFIGURATION *** # # The second part of the file tells the script unittest/unittest.sh # which remote nodes and their file system locations are to be used # for remote testing. # # # Addresses of nodes should be defined as an array: # # NODE[index]=[@] # # The remote account must be set up for automated ssh authentication. # The remote user's login shell must be bash. # #NODE[0]=127.0.0.1 #NODE[1]=user1@host1 #NODE[2]=user2@host2 # # Addresses of interfaces which the remote nodes # shall communicate on should be defined as an array: # # NODE_ADDR[index]=[@] # #NODE_ADDR[0]=192.168.0.1 #NODE_ADDR[1]=192.168.0.2 #NODE_ADDR[2]=192.168.0.3 # # Working directories on remote nodes (they will be created) # #NODE_WORKING_DIR[0]=/remote/dir0 #NODE_WORKING_DIR[1]=/remote/dir1 #NODE_WORKING_DIR[2]=/remote/dir2 # # NODE_LD_LIBRARY_PATH variable for each remote node # #NODE_LD_LIBRARY_PATH[0]=/usr/local/lib #NODE_LD_LIBRARY_PATH[1]=/usr/local/lib #NODE_LD_LIBRARY_PATH[2]=/usr/local/lib # # # NODE_DEVICE_DAX_PATH variable for each remote node which # can be used to specify path to multiple device daxes on remote node. # # All remote tests assume the master replica is present on a node of index 1. # So the size of device dax on the node of index 1 should not be bigger than # a size of device dax devices on other nodes. # #NODE_DEVICE_DAX_PATH[0]="/dev/dax0.0 /dev/dax1.0" #NODE_DEVICE_DAX_PATH[1]="/dev/dax0.0 /dev/dax1.0" #NODE_DEVICE_DAX_PATH[2]="/dev/dax0.0" #NODE_DEVICE_DAX_PATH[3]="/dev/dax0.0" # # NODE_ENV variable for setting environment variables on specified nodes # #NODE_ENV[0]="VAR=1" #NODE_ENV[1]="VAR=\$VAR:1" #NODE_ENV[2]="" # # RPMEM_VALGRIND_ENABLED variable enables valgrind rpmem tests # Valgrind rpmem tests require libibverbs and librdmacm compiled with valgrind # support. # #RPMEM_VALGRIND_ENABLED=y # # Overwrite available providers: # verbs, sockets, all (default) # #TEST_PROVIDERS=all # # Overwrite available persistency methods: # GPSPM, APM, all (default) # #TEST_PMETHODS=all pmdk-1.11.1/src/test/sync-remotes/0000775000000000000000000000000014123364546015434 5ustar rootrootpmdk-1.11.1/src/test/sync-remotes/Makefile0000664000000000000000000000042514123364546017075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/sync-remote/Makefile -- copy common files to remote nodes # DIR_SYNC=../.sync-dir # sync remote nodes sync-remotes: @./copy-to-remote-nodes.sh common $(DIR_SYNC) .PHONY: sync-remotes pmdk-1.11.1/src/test/sync-remotes/copy-to-remote-nodes.sh0000775000000000000000000000142414123364546021765 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # copy-to-remote-nodes.sh -- helper script used to sync remote nodes # set -e if [ ! -f ../testconfig.sh ]; then echo "SKIP: testconfig.sh does not exist" exit 0 fi # defined only to be able to source unittest.sh UNITTEST_NAME=sync-remotes UNITTEST_NUM=0 # Override default FS (any). # This is not a real test, so it should not depend on whether # PMEM_FS_DIR/NON_PMEM_FS_DIR are set. FS=none . ../unittest/unittest.sh COPY_TYPE=$1 shift case "$COPY_TYPE" in common) copy_common_to_remote_nodes $* > /dev/null exit 0 ;; test) copy_test_to_remote_nodes $* > /dev/null exit 0 ;; esac echo "Error: unknown copy type: $COPY_TYPE" exit 1 pmdk-1.11.1/src/test/pmreorder_flushes/0000775000000000000000000000000014123364546016534 5ustar rootrootpmdk-1.11.1/src/test/pmreorder_flushes/TEST00000775000000000000000000000167414123364546017331 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmreorder_flushes/TEST0 -- test for the reordering script # Tests positive case using no reorder engine. Checks if once flushed # variable can be overwrite in the next barrier and then persisted properly. # . ../unittest/unittest.sh require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup export PMREORDER_EMIT_LOG=1 # create holey file truncate -s 4M $DIR/testfile LOG_FILE=./pmreorder_flushes${UNITTEST_NUM}.log touch $LOG_FILE BIN="./pmreorder_flushes$EXESUFFIX" PMEMCHECK_CMD="$BIN g $DIR/testfile $LOG_FILE" PMREORDER_CMD="$BIN c $DIR/testfile $LOG_FILE" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success NoReorderDoCheck "DO_NOT_CHECK_E=NoReorderNoCheck" "$PMREORDER_CMD" check pass pmdk-1.11.1/src/test/pmreorder_flushes/Makefile0000664000000000000000000000044414123364546020176 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmreorder_flushes/Makefile -- build pmreorder_flushes test # TARGET = pmreorder_flushes OBJS = pmreorder_flushes.o LIBPMEM=y # included for VALGRIND_EMIT_LOG LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/pmreorder_flushes/.gitignore0000664000000000000000000000002214123364546020516 0ustar rootrootpmreorder_flushes pmdk-1.11.1/src/test/pmreorder_flushes/pmreorder_flushes.c0000664000000000000000000000620714123364546022435 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * pmreorder_flushes.c -- test for store reordering with flushes * in different barriers * * usage: pmreorder_flushes g|c file * * g - write data in a specific manner - some flushes * of the stores are made in different barriers, * c - check data consistency - stores should be applied only * after flush - no matter in which barrier the flush will happen * */ #include "unittest.h" #include "util.h" #include "valgrind_internal.h" #define STORE_SIZE 64 static FILE *fp; struct stores_fields { char A[STORE_SIZE]; char B[STORE_SIZE]; char C[STORE_SIZE]; char D[STORE_SIZE]; char E[STORE_SIZE]; }; /* * write_consistent -- (internal) write data in a specific order */ static void write_consistent(struct stores_fields *sf) { /* * STORE (A) * STORE (B) * STORE (C) * * FLUSH (A, B) (no flush C) * FENCE */ pmem_memset(&sf->A, -1, sizeof(sf->A), PMEM_F_MEM_NODRAIN); pmem_memset(&sf->B, 2, sizeof(sf->B), PMEM_F_MEM_NODRAIN); pmem_memset(&sf->C, 3, sizeof(sf->C), PMEM_F_MEM_NOFLUSH); pmem_drain(); /* * STORE (A) * STORE (D) * * FLUSH (D) (no flush A, still no flush C) * FENCE */ pmem_memset(sf->A, 1, sizeof(sf->A), PMEM_F_MEM_NOFLUSH); pmem_memset(sf->D, 4, sizeof(sf->D), PMEM_F_MEM_NODRAIN); pmem_drain(); /* * There are two transitive stores now: A (which does not change * it's value) and C (which is modified). * * STORE (D) * STORE (C) * * FLUSH (D) (still no flush A and C) * FENCE */ pmem_memset(sf->D, 5, sizeof(sf->D), PMEM_F_MEM_NODRAIN); pmem_memset(sf->C, 8, sizeof(sf->C), PMEM_F_MEM_NOFLUSH); pmem_drain(); /* * E is modified just to add additional step to the log. * Values of A and C should still be -1, 2. * * STORE (E) * FLUSH (E) * FENCE */ pmem_memset(sf->E, 6, sizeof(sf->E), PMEM_F_MEM_NODRAIN); pmem_drain(); /* * FLUSH (A, C) * FENCE */ pmem_flush(sf->A, sizeof(sf->A)); pmem_flush(sf->C, sizeof(sf->C)); pmem_drain(); } /* * check_consistency -- (internal) check if stores are made in proper manner */ static int check_consistency(struct stores_fields *sf) { fprintf(fp, "A=%d B=%d C=%d D=%d E=%d\n", sf->A[0], sf->B[0], sf->C[0], sf->D[0], sf->E[0]); return 0; } int main(int argc, char *argv[]) { START(argc, argv, "pmreorder_flushes"); util_init(); if ((argc < 4) || (strchr("gc", argv[1][0]) == NULL) || argv[1][1] != '\0') UT_FATAL("usage: %s g|c file log_file", argv[0]); int fd = OPEN(argv[2], O_RDWR); size_t size; /* mmap and register in valgrind pmemcheck */ void *map = pmem_map_file(argv[2], 0, 0, 0, &size, NULL); UT_ASSERTne(map, NULL); struct stores_fields *sf = map; char opt = argv[1][0]; /* clear the struct to get a consistent start state for writing */ if (strchr("g", opt)) pmem_memset_persist(sf, 0, sizeof(*sf)); switch (opt) { case 'g': write_consistent(sf); break; case 'c': fp = os_fopen(argv[3], "a"); if (fp == NULL) UT_FATAL("!fopen"); int ret; ret = check_consistency(sf); fclose(fp); return ret; default: UT_FATAL("Unrecognized option %c", opt); } CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmreorder_flushes/pmreorder_flushes0.log.match0000664000000000000000000000017414123364546024144 0ustar rootrootA=0 B=0 C=0 D=0 E=0 A=-1 B=2 C=0 D=0 E=0 A=-1 B=2 C=0 D=4 E=0 A=-1 B=2 C=0 D=5 E=0 A=-1 B=2 C=0 D=5 E=6 A=1 B=2 C=8 D=5 E=6 pmdk-1.11.1/src/test/libpmempool_include/0000775000000000000000000000000014123364546017026 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_include/libpmempool_include.vcxproj0000664000000000000000000000615014123364546024467 0ustar rootroot Debug x64 Release x64 {4E334022-7A71-4197-9E15-878F7EFC877E} libpmempool_include 10.0.17134.0 Application true v140 Application false v140 {cf9a0883-6334-44c7-ac29-349468c78e27} pmdk-1.11.1/src/test/libpmempool_include/Makefile0000664000000000000000000000040314123364546020463 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/libpmempool_include/Makefile -- compilation test for libpmemblk # TARGET = libpmempool_include OBJS = libpmempool_include.o LIBPMEMPOOL=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_include/libpmempool_include.vcxproj.filters0000664000000000000000000000077114123364546026141 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files pmdk-1.11.1/src/test/libpmempool_include/.gitignore0000664000000000000000000000002414123364546021012 0ustar rootrootlibpmempool_include pmdk-1.11.1/src/test/libpmempool_include/libpmempool_include.c0000664000000000000000000000043514123364546023216 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * libpmempool_include.c -- include test for libpmempool * * this is only a compilation test - do not run this program */ #include int main(int argc, char *argv[]) { return 0; } pmdk-1.11.1/src/test/pmem_movnt_align/0000775000000000000000000000000014123364546016337 5ustar rootrootpmdk-1.11.1/src/test/pmem_movnt_align/pmem_movnt_align.vcxproj.filters0000664000000000000000000000223414123364546024757 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {84215fd4-bb77-4e9b-b9b6-38ad838e1cfe} PS1 {c938d730-8c66-4d94-ae37-6a5ce463e749} Source Files Source Files Test Scripts Header Files pmdk-1.11.1/src/test/pmem_movnt_align/TEST00000775000000000000000000000153314123364546017126 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_movnt_align/TEST0 -- unit test for pmem_memcpy_persist # . ../unittest/unittest.sh require_test_type medium require_x86_64 require_fs_type pmem non-pmem require_build_type debug static-debug setup export PMEM_LOG_LEVEL=15 function test() { expect_normal_exit ./pmem_movnt_align$EXESUFFIX C 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX F 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX B 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX S 1 } function test_all() { unset PMEM_MOVNT_THRESHOLD test export PMEM_MOVNT_THRESHOLD=0 test export PMEM_MOVNT_THRESHOLD=99999 test } test_all export PMEM_AVX512F=0 test_all export PMEM_AVX=0 test_all export PMEM_NO_MOVNT=1 export PMEM_NO_GENERIC_MEMCPY=1 test pass pmdk-1.11.1/src/test/pmem_movnt_align/Makefile0000664000000000000000000000057014123364546020001 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_movnt_align/Makefile -- build pmem_movnt_align unittest # TOP = ../../.. vpath %.c $(TOP)/src/test/pmem2_movnt_align TARGET = pmem_movnt_align OBJS = pmem_movnt_align.o\ movnt_align_common.o LIBPMEM=y include ../Makefile.inc CFLAGS += -I$(TOP)/src/test/pmem2_movnt_align pmdk-1.11.1/src/test/pmem_movnt_align/TEST0.PS10000664000000000000000000000465414123364546017534 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/pmem_movnt_align/TEST0 -- unit test for pmem_memcpy_persist # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem non-pmem require_build_type debug static-debug setup $Env:PMEM_LOG_LEVEL=15 function test { expect_normal_exit $Env:EXE_DIR\pmem_movnt_align$Env:EXESUFFIX C 1 expect_normal_exit $Env:EXE_DIR\pmem_movnt_align$Env:EXESUFFIX F 1 expect_normal_exit $Env:EXE_DIR\pmem_movnt_align$Env:EXESUFFIX B 1 expect_normal_exit $Env:EXE_DIR\pmem_movnt_align$Env:EXESUFFIX S 1 } function test_all { $Env:PMEM_MOVNT_THRESHOLD=$null test $Env:PMEM_MOVNT_THRESHOLD=0 test $Env:PMEM_MOVNT_THRESHOLD=99999 test } test_all $Env:PMEM_AVX512F = 0 test_all $Env:PMEM_AVX = 0 test_all $Env:PMEM_NO_MOVNT = 1 $Env:PMEM_NO_GENERIC_MEMCPY = 1 test pass pmdk-1.11.1/src/test/pmem_movnt_align/.gitignore0000664000000000000000000000002114123364546020320 0ustar rootrootpmem_movnt_align pmdk-1.11.1/src/test/pmem_movnt_align/README0000664000000000000000000000063314123364546017221 0ustar rootrootPersistent Memory Development Kit This is src/test/pmem_movnt_align/README. This directory contains a unit test for the following functions: - pmem_memcpy_persist() - pmem_memmove_persist() - pmem_memset_persist() Usage: $ pmem_movnt_align [C|F|B|S] * C - pmem_memcpy_persist() * B - pmem_memmove_persist() in backward direction * F - pmem_memmove_persist() in forward direction * S - pmem_memset_persist() pmdk-1.11.1/src/test/pmem_movnt_align/TEST10000775000000000000000000000171014123364546017124 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # src/test/pmem_movnt_align/TEST1 -- unit test for pmem_memcpy_persist # with valgrind pmemcheck tool # . ../unittest/unittest.sh require_test_type medium require_x86_64 require_fs_type pmem non-pmem require_build_type debug nondebug configure_valgrind pmemcheck force-enable export VALGRIND_OPTS="--mult-stores=yes" setup export PMEM_LOG_LEVEL=15 function test() { expect_normal_exit ./pmem_movnt_align$EXESUFFIX C 0 expect_normal_exit ./pmem_movnt_align$EXESUFFIX F 0 expect_normal_exit ./pmem_movnt_align$EXESUFFIX B 0 expect_normal_exit ./pmem_movnt_align$EXESUFFIX S 0 } function test_all() { unset PMEM_MOVNT_THRESHOLD test export PMEM_MOVNT_THRESHOLD=0 test export PMEM_MOVNT_THRESHOLD=99999 test } test_all export PMEM_AVX512F=0 test_all export PMEM_AVX=0 test_all export PMEM_NO_MOVNT=1 export PMEM_NO_GENERIC_MEMCPY=1 test pass pmdk-1.11.1/src/test/pmem_movnt_align/pmem_movnt_align.vcxproj0000664000000000000000000000752614123364546023321 0ustar rootroot Debug x64 Release x64 {025E7D51-41F2-4CBA-956E-C37A4443DB1B} Win32Proj pmem_movnt_align 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\test\pmem2_movnt_align;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\test\pmem2_movnt_align;%(AdditionalIncludeDirectories) {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem_movnt_align/pmem_movnt_align.c0000664000000000000000000001412514123364546022041 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * pmem_movnt_align.c -- unit test for functions with non-temporal stores * * usage: pmem_movnt_align [C|F|B|S] * * C - pmem_memcpy_persist() * B - pmem_memmove_persist() in backward direction * F - pmem_memmove_persist() in forward direction * S - pmem_memset_persist() */ #include #include #include #include "libpmem.h" #include "unittest.h" #include "movnt_align_common.h" #define N_BYTES (Ut_pagesize * 2) static int Heavy; static void * pmem_memcpy_persist_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memcpy_persist(pmemdest, src, len); } static void * pmem_memcpy_nodrain_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memcpy_nodrain(pmemdest, src, len); } static void * pmem_memmove_persist_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memmove_persist(pmemdest, src, len); } static void * pmem_memmove_nodrain_wrapper(void *pmemdest, const void *src, size_t len, unsigned flags) { (void) flags; return pmem_memmove_nodrain(pmemdest, src, len); } static void * pmem_memset_persist_wrapper(void *pmemdest, int c, size_t len, unsigned flags) { (void) flags; return pmem_memset_persist(pmemdest, c, len); } static void * pmem_memset_nodrain_wrapper(void *pmemdest, int c, size_t len, unsigned flags) { (void) flags; return pmem_memset_nodrain(pmemdest, c, len); } static void check_memmove_variants(size_t doff, size_t soff, size_t len) { check_memmove(doff, soff, len, pmem_memmove_persist_wrapper, 0); if (!Heavy) return; check_memmove(doff, soff, len, pmem_memmove_nodrain_wrapper, 0); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memmove(doff, soff, len, pmem_memmove, Flags[i]); } static void check_memcpy_variants(size_t doff, size_t soff, size_t len) { check_memcpy(doff, soff, len, pmem_memcpy_persist_wrapper, 0); if (!Heavy) return; check_memcpy(doff, soff, len, pmem_memcpy_nodrain_wrapper, 0); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memcpy(doff, soff, len, pmem_memcpy, Flags[i]); } static void check_memset_variants(size_t off, size_t len) { check_memset(off, len, pmem_memset_persist_wrapper, 0); if (!Heavy) return; check_memset(off, len, pmem_memset_nodrain_wrapper, 0); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memset(off, len, pmem_memset, Flags[i]); } int main(int argc, char *argv[]) { if (argc != 3) UT_FATAL("usage: %s type heavy=[0|1]", argv[0]); char type = argv[1][0]; Heavy = argv[2][0] == '1'; const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem_movnt_align %c %s %savx %savx512f", type, thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); size_t page_size = Ut_pagesize; size_t s; switch (type) { case 'C': /* memcpy */ /* mmap with guard pages */ Src = MMAP_ANON_ALIGNED(N_BYTES, 0); Dst = MMAP_ANON_ALIGNED(N_BYTES, 0); if (Src == NULL || Dst == NULL) UT_FATAL("!mmap"); Scratch = MALLOC(N_BYTES); /* check memcpy with 0 size */ check_memcpy_variants(0, 0, 0); /* check memcpy with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(0, 0, N_BYTES - s); /* check memcpy with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(s, 0, N_BYTES - s); /* check memcpy with unaligned begin and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Src, N_BYTES); MUNMAP_ANON_ALIGNED(Dst, N_BYTES); FREE(Scratch); break; case 'B': /* memmove backward */ /* mmap with guard pages */ Src = MMAP_ANON_ALIGNED(2 * N_BYTES - page_size, 0); Dst = Src + N_BYTES - page_size; if (Src == NULL) UT_FATAL("!mmap"); /* check memmove in backward direction with 0 size */ check_memmove_variants(0, 0, 0); /* check memmove in backward direction with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(0, 0, N_BYTES - s); /* check memmove in backward direction with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, 0, N_BYTES - s); /* * check memmove in backward direction with unaligned begin * and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Src, 2 * N_BYTES - page_size); break; case 'F': /* memmove forward */ /* mmap with guard pages */ Dst = MMAP_ANON_ALIGNED(2 * N_BYTES - page_size, 0); Src = Dst + N_BYTES - page_size; if (Src == NULL) UT_FATAL("!mmap"); /* check memmove in forward direction with 0 size */ check_memmove_variants(0, 0, 0); /* check memmove in forward direction with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(0, 0, N_BYTES - s); /* check memmove in forward direction with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, 0, N_BYTES - s); /* * check memmove in forward direction with unaligned begin * and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Dst, 2 * N_BYTES - page_size); break; case 'S': /* memset */ /* mmap with guard pages */ Dst = MMAP_ANON_ALIGNED(N_BYTES, 0); if (Dst == NULL) UT_FATAL("!mmap"); Scratch = MALLOC(N_BYTES); /* check memset with 0 size */ check_memset_variants(0, 0); /* check memset with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(0, N_BYTES - s); /* check memset with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(s, N_BYTES - s); /* check memset with unaligned begin and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Dst, N_BYTES); FREE(Scratch); break; default: UT_FATAL("!wrong type of test"); break; } DONE(NULL); } pmdk-1.11.1/src/test/pmem_movnt_align/TEST20000775000000000000000000000117614123364546017133 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/pmem_movnt_align/TEST0 -- unit test for pmem_memcpy_persist # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem require_build_type debug static-debug setup export PMEM_LOG_LEVEL=4 function test() { expect_normal_exit ./pmem_movnt_align$EXESUFFIX C 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX F 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX B 1 expect_normal_exit ./pmem_movnt_align$EXESUFFIX S 1 } test export PMEM_NO_MOVNT=1 export PMEM_NO_GENERIC_MEMCPY=1 test pass pmdk-1.11.1/src/test/libpmempool_bttdev/0000775000000000000000000000000014123364546016673 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_bttdev/TEST7.PS10000664000000000000000000000154414123364546020072 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST7 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG expect_normal_exit $PMEMSPOIL -v $POOL "bttdevice.arena(0).btt_info.sig=BADSIGNATURE" ` "bttdevice.arena(0).btt_info.external_lbasize=10" ` "bttdevice.arena(0).btt_info.major=0x0" >> $LOG expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST1.PS10000664000000000000000000000144214123364546020061 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST1 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL ?? $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST5.PS10000664000000000000000000000227714123364546020074 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # libpmempool_bttdev/TEST5 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium # dax on windows doesn't support sparse files require_fs_type non-pmem # # For a large pool, util_map consumes so much memory. # require_free_physical_memory 3G # # Automatic page file size management eliminate the risk # of exceeding the available resources. # require_automatic_managed_pagefile setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" truncate -s 1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.sig=ERROR" ` "bttdevice.arena(1).btt_info.sig=ERROR" ` "bttdevice.arena(1).btt_info_backup.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST9.PS10000664000000000000000000000237714123364546020101 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST9 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG $btt_info_dic_err = @{ "sig"="ERROR" "uuid"="01-02" "flags"="7" "major"="7" "minor"="7" "nfree"="7" "infosize"="7" "nextoff"="7" "dataoff"="7" "infooff"="7" "unused"="7" } foreach ($field in ("flags", "unused", "major", "sig", "nextoff", "infosize", "infooff", "dataoff", "nfree", "uuid", "minor")) { $x = $btt_info_dic_err[$field] $spcmd=("${spcmd}bttdevice.arena(0).btt_info.$field=${x} ") rm $POOL -Force -ea si expect_normal_exit $BTTCREATE $POOL expect_normal_exit $PMEMSPOIL -v $POOL $spcmd.Split(" ") >> $LOG_TEMP expect_normal_exit $EXE -r 1 -t btt $POOL cat -Encoding Ascii $LOG | out-file -append -literalpath $LOG_TEMP } check_file $POOL mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_bttdev/libpmempool_bttdev.vcxproj0000664000000000000000000001171114123364546024200 0ustar rootroot Debug x64 Release x64 {E85E017F-04C0-4716-BF21-949C82C68912} Win32Proj libpmempool_bttdev 10.0.17134.0 Application true v140 Application false v140 true Level3 Disabled NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC Level3 MaxSpeed true true NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC true {27fa11c6-431d-41d1-a417-fab7c4f93dca} pmdk-1.11.1/src/test/libpmempool_bttdev/out10.log.match0000664000000000000000000000032314123364546021437 0ustar rootrootlibpmempool_bttdev/TEST10: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers can not find any valid BTT Info status = not consistent libpmempool_bttdev/TEST10: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST30000775000000000000000000000143414123364546017465 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST3 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind cannot trace more than 32G which is required for this test configure_valgrind memcheck force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test truncate -s1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.sig=ERROR"\ "bttdevice.arena(1).btt_info_backup.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST10.PS10000664000000000000000000000147314123364546020145 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST10 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.checksum=777" ` "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.checksum=777" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST90000775000000000000000000000205614123364546017474 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST9 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG declare -A btt_info_dic_err=(["sig"]="ERROR" ["uuid"]="01-02" ["flags"]="7" ["major"]="7" ["minor"]="7" ["nfree"]="7" ["infosize"]="7" ["nextoff"]="7" ["dataoff"]="7" ["infooff"]="7" ["unused"]="7") for field in flags unused major sig nextoff infosize infooff dataoff nfree uuid minor do spcmd=$spcmd"bttdevice.arena(0).btt_info.$field=${btt_info_dic_err["$field"]} " rm -f $POOL expect_normal_exit $BTTCREATE $POOL $PMEMSPOIL -v $POOL $spcmd >> $LOG_TEMP expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL cat $LOG >> $LOG_TEMP check_file $POOL done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST00000775000000000000000000000075214123364546017464 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST0 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/Makefile0000664000000000000000000000030614123364546020332 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/libpmempool_bttdev/Makefile -- build libpmempool_bttdev unittest # include ../libpmempool_api/Makefile.inc pmdk-1.11.1/src/test/libpmempool_bttdev/TEST3.PS10000664000000000000000000000222414123364546020062 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # libpmempool_bttdev/TEST3 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type non-pmem # dax on windows doesn't support sparse files # # For a large pool, util_map consumes so much memory. # require_free_physical_memory 3G # # Automatic page file size management eliminate the risk # of exceeding the available resources. # require_automatic_managed_pagefile setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" truncate -s 1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.sig=ERROR" ` "bttdevice.arena(1).btt_info_backup.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST2.PS10000664000000000000000000000167614123364546020073 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST2 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info_backup.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST50000775000000000000000000000150614123364546017467 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST5 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind cannot trace more than 32G which is required for this test configure_valgrind memcheck force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test truncate -s1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.sig=ERROR"\ "bttdevice.arena(1).btt_info.sig=ERROR"\ "bttdevice.arena(1).btt_info_backup.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/out7.log.match0000664000000000000000000000054214123364546021370 0ustar rootrootlibpmempool_bttdev/TEST7: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST7: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST6.PS10000664000000000000000000000251114123364546020064 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # libpmempool_bttdev/TEST6 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium # dax on windows doesn't support sparse files require_fs_type non-pmem # # For a large pool, util_map consumes so much memory. # require_free_physical_memory 5G # # Automatic page file size management eliminate the risk # of exceeding the available resources. # require_automatic_managed_pagefile setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" truncate -s 2T $POOL expect_normal_exit $BTTCREATE -s 2T -b 512M -t $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.sig=ERROR" ` "bttdevice.arena(1).btt_info.sig=ERROR" ` "bttdevice.arena(1).btt_info_backup.sig=ERROR" ` "bttdevice.arena(2).btt_info.sig=ERROR" ` "bttdevice.arena(2).btt_info_backup.sig=ERROR" ` "bttdevice.arena(3).btt_info.checksum=13" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST40000775000000000000000000000142514123364546017466 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST4 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind cannot trace more than 32G which is required for this test configure_valgrind memcheck force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test truncate -s1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.sig=ERROR"\ "bttdevice.arena(1).btt_info.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST70000775000000000000000000000122614123364546017470 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST7 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG $PMEMSPOIL -v $POOL "bttdevice.arena(0).btt_info.sig=BADSIGNATURE"\ "bttdevice.arena(0).btt_info.external_lbasize=10"\ "bttdevice.arena(0).btt_info.major=0x0" >> $LOG expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/out0.log.match0000664000000000000000000000042414123364546021360 0ustar rootrootlibpmempool_bttdev/TEST0: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_bttdev/TEST0: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out9.log.match0000664000000000000000000002307014123364546021373 0ustar rootroot$(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.dataoff=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.dataoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nfree=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.dataoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nfree=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.uuid=01-02 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.dataoff=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nfree=7 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.uuid=01-02 $(nW)test_libpmempool_bttdev9$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.minor=7 libpmempool_bttdev/TEST9: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST9: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST0.PS10000664000000000000000000000124214123364546020056 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # libpmempool_bttdev/TEST0 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/README0000664000000000000000000000020114123364546017544 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_bttdev/README. This directory contains a unit test for btt device. pmdk-1.11.1/src/test/libpmempool_bttdev/TEST60000775000000000000000000000171514123364546017472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST6 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind cannot trace more than 32G which is required for this test configure_valgrind memcheck force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test truncate -s2T $POOL expect_normal_exit $BTTCREATE -s 2T -b 512M -t $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.sig=ERROR"\ "bttdevice.arena(1).btt_info.sig=ERROR"\ "bttdevice.arena(1).btt_info_backup.sig=ERROR"\ "bttdevice.arena(2).btt_info.sig=ERROR"\ "bttdevice.arena(2).btt_info_backup.sig=ERROR"\ "bttdevice.arena(3).btt_info.checksum=13" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST10000775000000000000000000000112514123364546017460 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST1 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST4.PS10000664000000000000000000000221514123364546020063 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # libpmempool_bttdev/TEST4 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium # dax on windows doesn't support sparse files require_fs_type non-pmem # # For a large pool, util_map consumes so much memory. # require_free_physical_memory 3G # # Automatic page file size management eliminate the risk # of exceeding the available resources. # require_automatic_managed_pagefile setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" truncate -s 1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" ` "bttdevice.arena(0).btt_info_backup.sig=ERROR" ` "bttdevice.arena(1).btt_info.sig=ERROR" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/out11.log.match0000664000000000000000000000070314123364546021442 0ustar rootrootlibpmempool_bttdev/TEST11: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct arena 1: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 1: regenerating BTT Info header the following error can be fixed using PMEMPOOL_CHECK_ADVANCED flag arena 1: BTT Info header checksum incorrect status = cannot repair libpmempool_bttdev/TEST11: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out6.log.match0000664000000000000000000000252214123364546021367 0ustar rootrootlibpmempool_bttdev/TEST6: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 0: regenerating BTT Info header arena 0: BTT Info header checksum correct arena 0: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 0: restoring BTT Info backup from header arena 1: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 1: regenerating BTT Info header arena 1: BTT Info header checksum correct arena 1: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 1: restoring BTT Info backup from header arena 2: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 2: regenerating BTT Info header arena 2: BTT Info header checksum correct arena 2: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 2: restoring BTT Info backup from header arena 3: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 3: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 1: checking BTT Map and Flog arena 2: checking BTT Map and Flog arena 3: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST6: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST80000775000000000000000000000217214123364546017472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST8 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG declare -A btt_info_dic_err=(["sig"]="ERROR" ["uuid"]="01-02" ["flags"]="7" ["major"]="7" ["minor"]="7" ["nfree"]="7" ["infosize"]="7" ["nextoff"]="7" ["dataoff"]="7" ["infooff"]="7" ["unused"]="7" ["parent_uuid"]="03-04" ["mapoff"]="7" ["flogoff"]="7") for field in flags unused major sig nextoff infosize infooff dataoff nfree mapoff uuid parent_uuid flogoff minor do spcmd="bttdevice.arena(0).btt_info.$field=${btt_info_dic_err["$field"]}" rm -f $POOL expect_normal_exit $BTTCREATE $POOL $PMEMSPOIL -v $POOL $spcmd >> $LOG_TEMP expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL cat $LOG >> $LOG_TEMP check_file $POOL done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST8.PS10000664000000000000000000000245514123364546020075 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # libpmempool_bttdev/TEST8 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" expect_normal_exit $BTTCREATE $POOL >> $LOG $btt_info_dic_err = @{ "sig"="ERROR" "uuid"="01-02" "flags"="7" "major"="7" "minor"="7" "nfree"="7" "infosize"="7" "nextoff"="7" "dataoff"="7" "infooff"="7" "unused"="7" "parent_uuid"="03-04" "mapoff"="7" "flogoff"="7" } foreach ($field in ("flags", "unused", "major", "sig", "nextoff", "infosize", "infooff", "dataoff", "nfree", "mapoff", "uuid", "parent_uuid", "flogoff", "minor")) { $x = $btt_info_dic_err[$field] $spcmd="bttdevice.arena(0).btt_info.$field=${x}" rm $POOL -Force -ea si expect_normal_exit $BTTCREATE $POOL expect_normal_exit $PMEMSPOIL -v $POOL $spcmd >> $LOG_TEMP expect_normal_exit $EXE -r 1 -t btt $POOL cat -Encoding Ascii $LOG | out-file -append -literalpath $LOG_TEMP } check_file $POOL mv -Force $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_bttdev/libpmempool_bttdev.vcxproj.filters0000664000000000000000000000461014123364546025647 0ustar rootroot {710964b0-ff4d-4979-bb64-ca7ece05c7d6} {9eb71f49-772e-405d-9409-87398e9ea0d7} Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/libpmempool_bttdev/out1.log.match0000664000000000000000000000032114123364546021355 0ustar rootrootlibpmempool_bttdev/TEST1: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers can not find any valid BTT Info status = not consistent libpmempool_bttdev/TEST1: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST100000775000000000000000000000120614123364546017540 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST10 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.checksum=777"\ "bttdevice.arena(0).btt_info.sig=ERROR"\ "bttdevice.arena(0).btt_info_backup.checksum=777" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST20000775000000000000000000000144714123364546017470 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST2 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test expect_normal_exit $BTTCREATE $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info_backup.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG cat $LOG >> $LOG_TEMP $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.sig=ERROR" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/TEST11.PS10000664000000000000000000000217414123364546020145 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # libpmempool_bttdev/TEST11 -- test for checking btt # . ..\unittest\unittest.ps1 require_test_type medium # dax on windows doesn't support sparse files require_fs_type non-pmem # # For a large pool, util_map consumes so much memory. # require_free_physical_memory 3G # # Automatic page file size management eliminate the risk # of exceeding the available resources. # require_automatic_managed_pagefile setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE="$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" truncate -s 1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG expect_normal_exit $PMEMSPOIL $POOL "bttdevice.arena(1).btt_info.checksum=777" ` "bttdevice.arena(1).btt_info.sig=ERROR" ` "bttdevice.arena(1).btt_info_backup.checksum=777" expect_normal_exit $EXE -r 1 -t btt $POOL >> $LOG_TEMP cat -Encoding Ascii $LOG | out-file -append -Encoding Ascii -literalpath $LOG_TEMP check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_bttdev/out5.log.match0000664000000000000000000000032114123364546021361 0ustar rootrootlibpmempool_bttdev/TEST5: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers can not find any valid BTT Info status = not consistent libpmempool_bttdev/TEST5: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out3.log.match0000664000000000000000000000135614123364546021370 0ustar rootrootlibpmempool_bttdev/TEST3: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 0: regenerating BTT Info header arena 0: BTT Info header checksum correct arena 0: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 0: restoring BTT Info backup from header arena 1: BTT Info header checksum correct arena 1: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 1: restoring BTT Info backup from header checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 1: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST3: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out4.log.match0000664000000000000000000000126214123364546021365 0ustar rootrootlibpmempool_bttdev/TEST4: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 0: regenerating BTT Info header arena 0: BTT Info header checksum correct arena 0: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 0: restoring BTT Info backup from header arena 1: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 1: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 1: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST4: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out8.log.match0000664000000000000000000001411014123364546021365 0ustar rootroot$(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flags=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.unused=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.major=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.sig=ERROR libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nextoff=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infosize=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.infooff=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.dataoff=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.nfree=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.mapoff=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.uuid=01-02 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.parent_uuid=03-04 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.flogoff=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE $(nW)test_libpmempool_bttdev8$(nW)file.pool: spoil: bttdevice.arena(0).btt_info.minor=7 libpmempool_bttdev/TEST8: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST8: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/out2.log.match0000664000000000000000000000140014123364546021355 0ustar rootrootlibpmempool_bttdev/TEST2: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct arena 0: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 0: restoring BTT Info backup from header checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST2: DONE libpmempool_bttdev/TEST2: START: libpmempool_test $(nW)libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Restore BTT Info from backup? arena 0: restoring BTT Info header from backup checking BTT Map and Flog arena 0: checking BTT Map and Flog status = repaired libpmempool_bttdev/TEST2: DONE pmdk-1.11.1/src/test/libpmempool_bttdev/TEST110000775000000000000000000000143414123364546017544 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_bttdev/TEST11 -- test for checking btt # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind cannot trace more than 32G which is required for this test configure_valgrind memcheck force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG EXE=../libpmempool_api/libpmempool_test truncate -s1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG $PMEMSPOIL $POOL "bttdevice.arena(1).btt_info.checksum=777"\ "bttdevice.arena(1).btt_info.sig=ERROR"\ "bttdevice.arena(1).btt_info_backup.checksum=777" expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt $POOL >> $LOG check_file $POOL check pass pmdk-1.11.1/src/test/pmempool_dump/0000775000000000000000000000000014123364546015661 5ustar rootrootpmdk-1.11.1/src/test/pmempool_dump/TEST1.PS10000664000000000000000000000103114123364546017041 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST1 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $PMEMPOOL dump -o $LOG $POOL expect_normal_exit $PMEMPOOL dump $POOL | out-file -encoding ASCII -append -literalpath $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST5.PS10000664000000000000000000000123014123364546017046 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_dump/TEST5.PS1 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" remove_files $LOG $POOLSET="$DIR\pool.set" $POOL_PART1="$DIR\pool.part1" $POOL_PART2="$DIR\pool.part2" remove_files $POOLSET $POOL_PART1 $POOL_PART2 create_poolset $POOLSET 32M:${POOL_PART1}:z 32M:${POOL_PART2}:z expect_normal_exit $PMEMPOOL create log $POOLSET expect_normal_exit $PMEMWRITE $POOLSET PMEMPOOL_DUMP_TEST expect_normal_exit $PMEMPOOL dump $POOLSET >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST30000775000000000000000000000117614123364546016456 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST3 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create blk 512 $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL 0:w:TEST0 expect_normal_exit $PMEMPOOL$EXESUFFIX dump -r-1 -o dump.log $POOL cat dump.log | $GREP "^00000000" >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX dump -r0 $POOL | $GREP "^00000000" >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/pmempool_dump.vcxproj.filters0000664000000000000000000000313214123364546023621 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/pmempool_dump/TEST00000775000000000000000000000111314123364546016442 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST0 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit $PMEMPOOL$EXESUFFIX dump -b -o $LOG $POOL echo >> $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX dump -b $POOL >> $LOG echo >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/Makefile0000664000000000000000000000030114123364546017313 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/pmempool_dump/Makefile -- build pmempool dump unittest # USE_PMEMWRITE=y include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_dump/TEST3.PS10000664000000000000000000000123514123364546017051 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST3 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL create blk 512 $POOL expect_normal_exit $PMEMWRITE $POOL 0:w:TEST0 expect_normal_exit $PMEMPOOL dump -r-1 -o dump.log $POOL cat dump.log | findstr "^00000000" | out-file -encoding ASCII -append -literalpath $LOG expect_normal_exit $PMEMPOOL dump -r0 $POOL | findstr "^00000000" | out-file -encoding ASCII -append -literalpath $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST2.PS10000664000000000000000000000106114123364546017045 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST2 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit $PMEMWRITE $POOL TEST_test expect_normal_exit $PMEMPOOL dump '-r5,6,7,8' -o $LOG $POOL expect_normal_exit $PMEMPOOL dump '-r5-8' $POOL| out-file -encoding ASCII -append -literalpath $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST50000775000000000000000000000117314123364546016455 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST5 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem require_build_type nondebug setup POOLSET=$DIR/pool.set POOL_PART1=$DIR/pool.part1 POOL_PART2=$DIR/pool.part2 LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG create_poolset $POOLSET 32M:$POOL_PART1:z 32M:$POOL_PART2:z expect_normal_exit $PMEMPOOL create log $POOLSET expect_normal_exit $PMEMWRITE $POOLSET PMEMPOOL_DUMP_TEST expect_normal_exit $PMEMPOOL dump $POOLSET >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST6.PS10000664000000000000000000000122314123364546017051 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_dump/TEST6.PS1 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si $POOLSET="$DIR\pool.set" $POOL_PART1="$DIR\pool.part1" $POOL_PART2="$DIR\pool.part2" remove_files $POOLSET $POOL_PART1 $POOL_PART2 create_poolset $POOLSET 32M:${POOL_PART1}:z 32M:${POOL_PART2}:z expect_normal_exit $PMEMPOOL create blk 512 $POOLSET expect_normal_exit $PMEMWRITE $POOLSET 0:w:PMEMPOOL_DUMP_TEST expect_normal_exit $PMEMPOOL dump -r 0 $POOLSET >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST40000775000000000000000000000110314123364546016445 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST4 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST1TEST2TEST3TEST4 expect_normal_exit $PMEMPOOL$EXESUFFIX dump -c5 -o $LOG $POOL expect_normal_exit $PMEMPOOL$EXESUFFIX dump -c5 $POOL >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/out0.log.match0000664000000000000000000000001214123364546020337 0ustar rootrootTEST TEST pmdk-1.11.1/src/test/pmempool_dump/TEST0.PS10000664000000000000000000000113414123364546017044 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST0 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $PMEMPOOL dump -b -o $LOG $POOL echo "" | out-file -encoding ASCII -append -literalpath $LOG expect_normal_exit $PMEMPOOL dump -b $POOL | out-file -encoding ASCII -append -literalpath $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/README0000664000000000000000000000037314123364546016544 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_dump/README. This directory contains a unit test for 'pmempool dump' command. The tests in this directory check the output format of 'dump' command and verify parsing of the range format. pmdk-1.11.1/src/test/pmempool_dump/TEST60000775000000000000000000000121014123364546016446 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST6 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem require_build_type nondebug setup POOLSET=$DIR/pool.set POOL_PART1=$DIR/pool.part1 POOL_PART2=$DIR/pool.part2 LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG create_poolset $POOLSET 32M:$POOL_PART1:z 32M:$POOL_PART2:z expect_normal_exit $PMEMPOOL create blk 512 $POOLSET expect_normal_exit $PMEMWRITE $POOLSET 0:w:PMEMPOOL_DUMP_TEST expect_normal_exit $PMEMPOOL dump -r 0 $POOLSET >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST10000775000000000000000000000105314123364546016446 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST1 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit $PMEMPOOL$EXESUFFIX dump -o $LOG $POOL expect_normal_exit $PMEMPOOL$EXESUFFIX dump $POOL >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/TEST4.PS10000664000000000000000000000106114123364546017047 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST4 -- test for dump command # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out$Env:UNITTEST_NUM.log" rm $LOG -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit $PMEMWRITE $POOL TEST1TEST2TEST3TEST4 expect_normal_exit $PMEMPOOL dump -c5 -o $LOG $POOL expect_normal_exit $PMEMPOOL dump -c5 $POOL | out-file -encoding ASCII -append -literalpath $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/out6.log.match0000664000000000000000000000047614123364546020363 0ustar rootroot00000000 50 4d 45 4d 50 4f 4f 4c 5f 44 55 4d 50 5f 54 45 |PMEMPOOL_DUMP_TE| 00000010 53 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ST..............| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| pmdk-1.11.1/src/test/pmempool_dump/pmempool_dump.vcxproj0000664000000000000000000001011214123364546022146 0ustar rootroot Debug x64 Release x64 {7dc3b3dd-73ed-4602-9af3-8d7053620dea} {2A1D6AF2-7336-4966-A4B3-0BE9A24BAE00} pmempool_dump 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/pmempool_dump/out1.log.match0000664000000000000000000000023614123364546020350 0ustar rootroot00000000 54 45 53 54 |TEST | 00000000 54 45 53 54 |TEST | pmdk-1.11.1/src/test/pmempool_dump/TEST20000775000000000000000000000110014123364546016440 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_dump/TEST2 -- test for dump command # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST_test expect_normal_exit $PMEMPOOL$EXESUFFIX dump -r5,6,7,8 -o $LOG $POOL expect_normal_exit $PMEMPOOL$EXESUFFIX dump -r5-8 $POOL >> $LOG check pass pmdk-1.11.1/src/test/pmempool_dump/out5.log.match0000664000000000000000000000023614123364546020354 0ustar rootroot00000000 50 4d 45 4d 50 4f 4f 4c 5f 44 55 4d 50 5f 54 45 |PMEMPOOL_DUMP_TE| 00000010 53 54 |ST | pmdk-1.11.1/src/test/pmempool_dump/out3.log.match0000664000000000000000000000012614123364546020350 0ustar rootroot00000000 54 45 53 54 30 $(*) |TEST0$(*)| 00000000 54 45 53 54 30 $(*) |TEST0$(*)| pmdk-1.11.1/src/test/pmempool_dump/out4.log.match0000664000000000000000000000117014123364546020351 0ustar rootroot00000000 54 45 53 54 31 |TEST1 | 00000005 54 45 53 54 32 |TEST2 | 0000000a 54 45 53 54 33 |TEST3 | 0000000f 54 45 53 54 34 |TEST4 | 00000000 54 45 53 54 31 |TEST1 | 00000005 54 45 53 54 32 |TEST2 | 0000000a 54 45 53 54 33 |TEST3 | 0000000f 54 45 53 54 34 |TEST4 | pmdk-1.11.1/src/test/pmempool_dump/out2.log.match0000664000000000000000000000023614123364546020351 0ustar rootroot00000005 74 65 73 74 |test | 00000005 74 65 73 74 |test | pmdk-1.11.1/src/test/pmemset_source/0000775000000000000000000000000014123364546016036 5ustar rootrootpmdk-1.11.1/src/test/pmemset_source/pmemset_source.vcxproj0000664000000000000000000001140614123364546022507 0ustar rootroot Debug x64 Release x64 {32746E86-E475-4DF7-8F48-B5147B5ACEE1} pmemset_source 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {fbaefc34-d221-4203-8bf6-162de1a5be1c} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmemset_source/Makefile0000664000000000000000000000061514123364546017500 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmemset_source/Makefile -- build for pmemset source API unit tests # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmemset INCS += -I$(TOP)/src/libpmemset TARGET = pmemset_source OBJS += pmemset_source.o\ ut_pmemset_utils.o LIBPMEMSET=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmemset_source/TESTS.py0000775000000000000000000000620314123364546017316 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020-2021, Intel Corporation # import testframework as t from testframework import granularity as g import os @g.require_granularity(g.ANY) class PMEMSET_SOURCE(t.Test): test_type = t.Short create_file = True def run(self, ctx): if self.create_file: filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') else: filepath = os.path.join(ctx.testdir, 'testfile1') ctx.exec('pmemset_source', self.test_case, filepath) if os.path.exists(filepath): os.remove(filepath) @g.no_testdir() class PMEMSET_SOURCE_NO_DIR(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmemset_source', self.test_case) class PMEMSET_SOURCE_DIR_ONLY(t.Test): test_type = t.Short do_not_close = False def run(self, ctx): if self.do_not_close: ctx.env['UNITTEST_DO_NOT_FAIL_OPEN_FILES'] = '1' ctx.exec('pmemset_source', self.test_case, ctx.testdir) class TEST0(PMEMSET_SOURCE): """allocation of pmemset_source in case of missing memory in system""" test_case = "test_alloc_src_enomem" class TEST1(PMEMSET_SOURCE_NO_DIR): """testing pmemset_from_pmem2 with null value""" test_case = "test_set_from_pmem2_null" class TEST2(PMEMSET_SOURCE): """valid allocation of pmemset_source from pmem2""" test_case = "test_set_from_pmem2_valid" class TEST3(PMEMSET_SOURCE_NO_DIR): """test source creation from null file path""" test_case = "test_src_from_file_null" class TEST4(PMEMSET_SOURCE): """test source creation with valid file path""" test_case = "test_src_from_file_valid" class TEST5(PMEMSET_SOURCE): """test source creation with existing file and create_always flag set""" test_case = "test_src_from_file_exists_always_disp" class TEST6(PMEMSET_SOURCE): """test source creation with no existing file and create_always flag set""" test_case = "test_src_from_file_not_exists_always_disp" create_file = False class TEST7(PMEMSET_SOURCE): """test source creation with existing file and if_needed flag set""" test_case = "test_src_from_file_exists_needed_disp" class TEST8(PMEMSET_SOURCE): """test source creation with no existing file and if_needed flag set""" test_case = "test_src_from_file_not_exists_needed_disp" create_file = False class TEST9(PMEMSET_SOURCE): """test source creation with invalid flags""" test_case = "test_src_from_file_invalid_flags" class TEST10(PMEMSET_SOURCE_DIR_ONLY): """testing pmemset_from_temporary valid case""" test_case = "test_src_from_temporary_valid" class TEST11(PMEMSET_SOURCE_NO_DIR): """testing pmemset_from_temporary invalid dir""" test_case = "test_src_from_temporary_inval_dir" class TEST12(PMEMSET_SOURCE_DIR_ONLY): """testing pmemset_from_temporary and skip pmemset source delete""" test_case = "test_src_from_temporary_no_del" do_not_close = True class TEST13(PMEMSET_SOURCE): """test source creation with no existing file and truncate flag set""" test_case = "test_src_from_file_with_truncate" create_file = False pmdk-1.11.1/src/test/pmemset_source/pmemset_source.vcxproj.filters0000664000000000000000000000341214123364546024154 0ustar rootroot {09fec3b6-b58d-44bc-b6c0-03b6fac9efa1} {9b4d878f-e8be-4c99-8723-7496a31e07e8} {73b735d1-5dd0-40e0-bef8-36335e5de02a} Test Scripts Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files pmdk-1.11.1/src/test/pmemset_source/.gitignore0000664000000000000000000000001714123364546020024 0ustar rootrootpmemset_source pmdk-1.11.1/src/test/pmemset_source/pmemset_source.c0000664000000000000000000002550514123364546021243 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmemset_source.c -- pmemset_source unittests */ #include "fault_injection.h" #include "file.h" #include "libpmemset.h" #include "out.h" #include "source.h" #include "unittest.h" #include "ut_pmemset_utils.h" /* * test_set_from_pmem2_valid - test valid pmemset_source allocation */ static int test_set_from_pmem2_valid(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_set_from_pmem2_valid "); char *file = argv[0]; struct pmem2_source *src_pmem2; struct pmemset_source *src_set; int fd = OPEN(file, O_RDWR); int ret = pmem2_source_from_fd(&src_pmem2, fd); UT_ASSERTeq(ret, 0); ret = pmemset_source_from_pmem2(&src_set, src_pmem2); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src_set, NULL); ret = pmemset_source_delete(&src_set); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src_set, NULL); ret = pmem2_source_delete(&src_pmem2); UT_PMEMSET_EXPECT_RETURN(ret, 0); CLOSE(fd); return 1; } /* * test_set_from_pmem2_null- test pmemset_source_from_pmem2 with null pmem2 */ static int test_set_from_pmem2_null(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_source *src_set; int ret = pmemset_source_from_pmem2(&src_set, NULL); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_INVALID_PMEM2_SOURCE); UT_ASSERTeq(src_set, NULL); return 0; } /* * test_alloc_src_enomem - test pmemset_source allocation with error injection */ static int test_alloc_src_enomem(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_alloc_src_enomem "); char *file = argv[0]; struct pmem2_source *src_pmem2; struct pmemset_source *src_set; if (!core_fault_injection_enabled()) { return 1; } int fd = OPEN(file, O_RDWR); core_inject_fault_at(PMEM_MALLOC, 1, "pmemset_malloc"); int ret = pmem2_source_from_fd(&src_pmem2, fd); UT_ASSERTeq(ret, 0); ret = pmemset_source_from_pmem2(&src_set, src_pmem2); UT_PMEMSET_EXPECT_RETURN(ret, -ENOMEM); UT_ASSERTeq(src_set, NULL); ret = pmem2_source_delete(&src_pmem2); UT_PMEMSET_EXPECT_RETURN(ret, 0); CLOSE(fd); return 1; } /* * test_src_from_file_null - test source creation from null file path */ static int test_src_from_file_null(const struct test_case *tc, int argc, char *argv[]) { struct pmemset_source *src; int ret = pmemset_source_from_file(&src, NULL); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_INVALID_SOURCE_PATH); UT_ASSERTeq(src, NULL); return 0; } /* * test_src_from_file_valid - test source creation with valid file path */ static int test_src_from_file_valid(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_valid "); const char *file = argv[0]; struct pmemset_source *src; int ret = pmemset_source_from_file(&src, file); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_file_exists_always_disp - test source creation with * PMEMSET_SOURCE_FILE_CREATE_ALWAYS file disposition. */ static int test_src_from_file_exists_always_disp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_exists_always_disp "); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; os_off_t size_before, size_after; os_stat_t st; int ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size_before = st.st_size; flags = PMEMSET_SOURCE_FILE_CREATE_ALWAYS; ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = os_access(file, F_OK); UT_ASSERTeq(ret, 0); ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size_after = st.st_size; UT_ASSERT(size_before >= size_after); UT_ASSERT(size_after == 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_file_not_exists_always_disp - test source creation with * PMEMSET_SOURCE_FILE_CREATE_ALWAYS file disposition when file does not exist. */ static int test_src_from_file_not_exists_always_disp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_not_exists_always_disp " ""); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; os_off_t size; os_stat_t st; flags = PMEMSET_SOURCE_FILE_CREATE_ALWAYS; int ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = os_access(file, F_OK); UT_ASSERTeq(ret, 0); ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size = st.st_size; UT_ASSERT(size == 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_file_exists_needed_disp - test source creation with * PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED file disposition. */ static int test_src_from_file_exists_needed_disp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_exists_needed_disp "); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; os_off_t size_before, size_after; os_stat_t st; int ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size_before = st.st_size; flags = PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED; ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = os_access(file, F_OK); UT_ASSERTeq(ret, 0); ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size_after = st.st_size; UT_ASSERT(size_before == size_after); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_file_not_exists_needed_disp - test source creation with * PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED file disposition when file does not * exist. */ static int test_src_from_file_not_exists_needed_disp(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_not_exists_needed_disp " ""); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; os_off_t size; os_stat_t st; flags = PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED; int ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = os_access(file, F_OK); UT_ASSERTeq(ret, 0); ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size = st.st_size; UT_ASSERT(size == 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_file_invalid_flags - test source creation with * invalid flags. */ static int test_src_from_file_invalid_flags(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_invalid_flags " ""); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; flags = PMEMSET_SOURCE_FILE_CREATE_VALID_FLAGS + 1; int ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_INVALID_SOURCE_FILE_CREATE_FLAGS); UT_ASSERTeq(src, NULL); return 1; } /* * test_src_from_temporary_valid - test source from temporary created * in the provided dir */ static int test_src_from_temporary_valid(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_temporary_valid "); char *dir = argv[0]; struct pmemset_source *src_set; int ret = pmemset_source_from_temporary(&src_set, dir); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src_set, NULL); ret = pmemset_source_delete(&src_set); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src_set, NULL); return 1; } /* * test_src_from_temporary_inval_dir - test source from temporary created * in the provided invalid dir path */ static int test_src_from_temporary_inval_dir(const struct test_case *tc, int argc, char *argv[]) { if (argc != 0) UT_FATAL("usage: test_src_from_temporary_inval_dir"); char *dir = NULL; struct pmemset_source *src_set; int ret = pmemset_source_from_temporary(&src_set, dir); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_INVALID_SOURCE_PATH); UT_ASSERTeq(src_set, NULL); dir = "XYZ"; ret = pmemset_source_from_temporary(&src_set, dir); UT_PMEMSET_EXPECT_RETURN(ret, PMEMSET_E_INVALID_SOURCE_PATH); UT_ASSERTeq(src_set, NULL); return 0; } /* * test_src_from_temporary_no_del - test source from temporary created * in the provided dir but do not dlete source - tmp file sohuld not be deleted */ static int test_src_from_temporary_no_del(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_temporary_no_del "); char *dir = argv[0]; struct pmemset_source *src_set; int ret = pmemset_source_from_temporary(&src_set, dir); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src_set, NULL); return 1; } /* * test_src_from_file_with_truncate - test source creation with * PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED flag. */ static int test_src_from_file_with_truncate(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_src_from_file_with_truncate " ""); const char *file = argv[0]; struct pmemset_source *src; unsigned flags = 0; os_off_t size; os_stat_t st; flags = PMEMSET_SOURCE_FILE_CREATE_IF_NEEDED | \ PMEMSET_SOURCE_FILE_TRUNCATE_IF_NEEDED; int ret = pmemset_xsource_from_file(&src, file, flags); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(src, NULL); ret = os_access(file, F_OK); UT_ASSERTeq(ret, 0); ret = os_stat(file, &st); UT_ASSERTeq(ret, 0); size = st.st_size; UT_ASSERT(size == 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(src, NULL); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_set_from_pmem2_null), TEST_CASE(test_alloc_src_enomem), TEST_CASE(test_set_from_pmem2_valid), TEST_CASE(test_src_from_file_null), TEST_CASE(test_src_from_file_valid), TEST_CASE(test_src_from_file_exists_always_disp), TEST_CASE(test_src_from_file_not_exists_always_disp), TEST_CASE(test_src_from_file_exists_needed_disp), TEST_CASE(test_src_from_file_not_exists_needed_disp), TEST_CASE(test_src_from_file_invalid_flags), TEST_CASE(test_src_from_temporary_valid), TEST_CASE(test_src_from_temporary_inval_dir), TEST_CASE(test_src_from_temporary_no_del), TEST_CASE(test_src_from_file_with_truncate), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmemset_source"); util_init(); out_init("pmemset_source", "TEST_LOG_LEVEL", "TEST_LOG_FILE", 0, 0); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); out_fini(); DONE(NULL); } pmdk-1.11.1/src/test/pmemset_source/out12.log.match0000664000000000000000000000017414123364546020610 0ustar rootroot$(*)START: pmemset_source $(*)test_src_from_temporary_no_del$(*) open file list changed between START() and DONE() $(*)DONE pmdk-1.11.1/src/test/libpmempool_api/0000775000000000000000000000000014123364546016154 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_api/TEST7.PS10000664000000000000000000000067414123364546017356 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST7 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -r 0 -y 1 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/libpmempool_test.vcxproj0000664000000000000000000001172014123364546023150 0ustar rootroot Debug x64 Release x64 {A2A0FAEA-2B7C-4FC3-B904-1DB4DEACF88D} Win32Proj libpmempool_test 10.0.17134.0 Application true v140 Application false v140 true false $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) true $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {9186eac4-2f34-4f17-b940-6585d7869bcd} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_api/TEST1.PS10000664000000000000000000000070014123364546017336 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST1 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 0 -a 1 -r 1 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/TEST5.PS10000664000000000000000000000071014123364546017343 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST5 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 1 -b "$POOL.backup" $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/TEST9.PS10000664000000000000000000000212314123364546017347 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST9 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any require_short_path setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $pool_args=@{"blk"="blk 512"; "log"="log"} foreach ($h in $pool_args.GetEnumerator()) { echo "Pool type: $($h.Name) Params: $($h.Value)" | out-file -append -encoding ascii -literalpath $LOG_TEMP expect_normal_exit "$PMEMPOOL create $($h.Value) $POOL" >> $LOG_TEMP &$PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL cp $POOL ${POOL}_copy >> $LOG_TEMP expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 1 -r 1 -y 1 -t $($h.Name) $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP cmp $POOL ${POOL}_copy >> $LOG_TEMP rm $POOL -Force -ea si rm ${POOL}_copy -Force -ea si } rm $LOG -Force mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/out10.log.match0000664000000000000000000000113514123364546020722 0ustar rootrootlibpmempool_api$(nW)TEST10: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 0 -r 0 -y 0 $(nW) checking shutdown state shutdown state correct checking pool header incorrect pool header status = not consistent libpmempool_api$(nW)TEST10: DONE libpmempool_api$(nW)TEST10: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 0 -r 1 -y 1 $(nW) checking shutdown state shutdown state correct checking pool header incorrect pool header pool_hdr.major is not valid setting pool_hdr.major to 0x1 checking pmemlog header pmemlog header correct status = repaired libpmempool_api$(nW)TEST10: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST30000775000000000000000000000101714123364546016743 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST3 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 1 -a 0 -r 0 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST10.PS10000664000000000000000000000202614123364546017421 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST10 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" touch $LOG_TEMP rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL >> $LOG_TEMP &$PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 0 -r 0 -y 0 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP rm $POOL -Force expect_normal_exit $PMEMPOOL create log $POOL >> $LOG_TEMP &$PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 0 -r 1 -y 1 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP rm $LOG -Force mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST90000775000000000000000000000170414123364546016754 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_api/TEST9 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP declare -A pool_args=(["log"]="log" ["blk"]="blk 512") for field in log blk; do echo "Pool type: ${field} Params: ${pool_args["$field"]}" >> $LOG_TEMP expect_normal_exit $PMEMPOOL$EXESUFFIX create\ ${pool_args["$field"]} $POOL >> $LOG_TEMP $PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL cp $POOL ${POOL}_copy >> $LOG_TEMP expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 1 -r 1 -y 1 -t ${field} $POOL >> $LOG cat $LOG >> $LOG_TEMP cmp $POOL ${POOL}_copy >> $LOG_TEMP || true rm -f $POOL rm -f ${POOL}_copy done mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST120000775000000000000000000000157314123364546017032 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST12 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP ent_val=5 expect_normal_exit $BTTCREATE $POOL for((i=0;i> $LOG_TEMP $PMEMSPOIL $POOL $spcmd done spcmd="bttdevice.arena.btt_flog(0).seq=4" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd expect_normal_exit ./libpmempool_test$EXESUFFIX -r 1 -t btt $POOL >> $LOG cat $LOG >> $LOG_TEMP expect_normal_exit ./libpmempool_test$EXESUFFIX -r 1 -t btt -a 1 $POOL >> $LOG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST13.PS10000664000000000000000000000142014123364546017421 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST13 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" $LOG="out${Env:UNITTEST_NUM}.log" $LOG_TEMP="out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si rm $LOG_TEMP -Force -ea si expect_normal_exit $PMEMPOOL create log $POOL expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX -s 0 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX -s 999999 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP rm $LOG -Force mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/Makefile.inc0000664000000000000000000000051314123364546020363 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/libpmempool_api/Makefile.inc -- build libpmempool_* unittest # ../libpmempool_api/libpmempool_test: $(MAKE) -C ../libpmempool_api all all: ../libpmempool_api/libpmempool_test USE_PMEMSPOIL=y USE_BTTCREATE=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_api/TEST130000775000000000000000000000121714123364546017026 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST13 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL expect_normal_exit ./libpmempool_test$EXESUFFIX -s 0 $POOL >> $LOG cat $LOG >> $LOG_TEMP expect_normal_exit ./libpmempool_test$EXESUFFIX -s 999999 $POOL >> $LOG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST00000775000000000000000000000101714123364546016740 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST0 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 1 -a 0 -r 1 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/Makefile0000664000000000000000000000045114123364546017614 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/libpmempool_api/Makefile -- build libpmempool_api unittest # TARGET = libpmempool_test OBJS = libpmempool_test.o LIBPMEMPOOL=y USE_PMEMSPOIL=y USE_PMEMWRITE=y USE_BTTCREATE=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_api/TEST3.PS10000664000000000000000000000067714123364546017355 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST3 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 1 -a 0 -r 0 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/TEST2.PS10000664000000000000000000000067714123364546017354 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST2 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 0 -a 1 -r 0 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/libpmempool_test.c0000664000000000000000000000725114123364546021703 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * libpmempool_test -- test of libpmempool. * */ #include #include #include #include #include #include "unittest.h" /* * Exact copy of the struct pmempool_check_args from libpmempool 1.0 provided to * test libpmempool against various pmempool_check_args structure versions. */ struct pmempool_check_args_1_0 { const char *path; const char *backup_path; enum pmempool_pool_type pool_type; int flags; }; /* * check_pool -- check given pool */ static void check_pool(struct pmempool_check_args *args, size_t args_size) { const char *status2str[] = { [PMEMPOOL_CHECK_RESULT_CONSISTENT] = "consistent", [PMEMPOOL_CHECK_RESULT_NOT_CONSISTENT] = "not consistent", [PMEMPOOL_CHECK_RESULT_REPAIRED] = "repaired", [PMEMPOOL_CHECK_RESULT_CANNOT_REPAIR] = "cannot repair", [PMEMPOOL_CHECK_RESULT_ERROR] = "fatal", }; PMEMpoolcheck *ppc = pmempool_check_init(args, args_size); if (!ppc) { char buff[UT_MAX_ERR_MSG]; ut_strerror(errno, buff, UT_MAX_ERR_MSG); UT_OUT("Error: %s", buff); return; } struct pmempool_check_status *status = NULL; while ((status = pmempool_check(ppc)) != NULL) { switch (status->type) { case PMEMPOOL_CHECK_MSG_TYPE_ERROR: UT_OUT("%s", status->str.msg); break; case PMEMPOOL_CHECK_MSG_TYPE_INFO: UT_OUT("%s", status->str.msg); break; case PMEMPOOL_CHECK_MSG_TYPE_QUESTION: UT_OUT("%s", status->str.msg); status->str.answer = "yes"; break; default: pmempool_check_end(ppc); exit(EXIT_FAILURE); } } enum pmempool_check_result ret = pmempool_check_end(ppc); UT_OUT("status = %s", status2str[ret]); } /* * print_usage -- print usage of program */ static void print_usage(char *name) { UT_OUT("Usage: %s [-t ] [-r ] [-d ] " "[-y ] [-f ] [-a ] " "[-b ] ", name); } /* * set_flag -- parse the value and set the flag according to a obtained value */ static void set_flag(const char *value, int *flags, int flag) { if (atoi(value) > 0) *flags |= flag; else *flags &= ~flag; } int main(int argc, char *argv[]) { START(argc, argv, "libpmempool_test"); int opt; struct pmempool_check_args_1_0 args = { .path = NULL, .backup_path = NULL, .pool_type = PMEMPOOL_POOL_TYPE_LOG, .flags = PMEMPOOL_CHECK_FORMAT_STR | PMEMPOOL_CHECK_REPAIR | PMEMPOOL_CHECK_VERBOSE }; size_t args_size = sizeof(struct pmempool_check_args_1_0); while ((opt = getopt(argc, argv, "t:r:d:a:y:s:b:")) != -1) { switch (opt) { case 't': if (strcmp(optarg, "blk") == 0) { args.pool_type = PMEMPOOL_POOL_TYPE_BLK; } else if (strcmp(optarg, "log") == 0) { args.pool_type = PMEMPOOL_POOL_TYPE_LOG; } else if (strcmp(optarg, "obj") == 0) { args.pool_type = PMEMPOOL_POOL_TYPE_OBJ; } else if (strcmp(optarg, "btt") == 0) { args.pool_type = PMEMPOOL_POOL_TYPE_BTT; } else { args.pool_type = (uint32_t)strtoul(optarg, NULL, 0); } break; case 'r': set_flag(optarg, &args.flags, PMEMPOOL_CHECK_REPAIR); break; case 'd': set_flag(optarg, &args.flags, PMEMPOOL_CHECK_DRY_RUN); break; case 'a': set_flag(optarg, &args.flags, PMEMPOOL_CHECK_ADVANCED); break; case 'y': set_flag(optarg, &args.flags, PMEMPOOL_CHECK_ALWAYS_YES); break; case 's': args_size = strtoul(optarg, NULL, 0); break; case 'b': args.backup_path = optarg; break; default: print_usage(argv[0]); UT_FATAL("unknown option: %c", opt); } } if (optind < argc) { args.path = argv[optind]; } check_pool((struct pmempool_check_args *)&args, args_size); DONE(NULL); } pmdk-1.11.1/src/test/libpmempool_api/TEST50000775000000000000000000000102514123364546016744 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST5 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 1 -b $POOL.backup $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/out7.log.match0000664000000000000000000000023414123364546020647 0ustar rootrootlibpmempool_api$(nW)TEST7: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 0 -y 1 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST7: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST6.PS10000664000000000000000000000066314123364546017353 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST6 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX -s 0 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/TEST40000775000000000000000000000101714123364546016744 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST4 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 1 -a 1 -r 0 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST70000775000000000000000000000101014123364546016740 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST7 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX -r 0 -y 1 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/out0.log.match0000664000000000000000000000044414123364546020643 0ustar rootrootlibpmempool_api$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -a 0 -r 1 $(nW) checking shutdown state shutdown state correct checking pool header pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_api$(nW)TEST0: DONE pmdk-1.11.1/src/test/libpmempool_api/out9.log.match0000664000000000000000000000146514123364546020660 0ustar rootrootPool type: log Params: log libpmempool_api$(nW)TEST9: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -r 1 -y 1 -t log $(nW) checking shutdown state shutdown state correct checking pool header incorrect pool header pool_hdr.major is not valid setting pool_hdr.major to 0x1 checking pmemlog header pmemlog header correct status = repaired libpmempool_api$(nW)TEST9: DONE Pool type: blk Params: blk 512 libpmempool_api$(nW)TEST9: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -r 1 -y 1 -t blk $(nW) checking shutdown state shutdown state correct checking pool header incorrect pool header pool_hdr.major is not valid setting pool_hdr.major to 0x1 checking pmemblk header pmemblk header correct checking BTT Info headers BTT Layout not written status = repaired libpmempool_api$(nW)TEST9: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST0.PS10000664000000000000000000000070214123364546017337 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST0 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 1 -a 0 -r 1 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/.gitignore0000664000000000000000000000002114123364546020135 0ustar rootrootlibpmempool_test pmdk-1.11.1/src/test/libpmempool_api/README0000664000000000000000000000021414123364546017031 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_api/README. This directory contains a unit test for API of libpmempool check. pmdk-1.11.1/src/test/libpmempool_api/TEST60000775000000000000000000000100514123364546016743 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST6 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -s 0 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST10000775000000000000000000000101714123364546016741 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST1 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 0 -a 1 -r 1 $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST4.PS10000664000000000000000000000067714123364546017356 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST4 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX ` -d 1 -a 1 -r 0 $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/out11.log.match0000664000000000000000000000205214123364546020722 0ustar rootrootlibpmempool_api/TEST11: START: libpmempool_test$(nW) ./libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 0: regenerating BTT Info header the following error can be fixed using PMEMPOOL_CHECK_ADVANCED flag arena 0: BTT Info header checksum incorrect status = cannot repair libpmempool_api/TEST11: DONE libpmempool_api/TEST11: START: libpmempool_test$(nW) ./libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info? arena 0: regenerating BTT Info header arena 0: BTT Info header checksum incorrect. Do you want to regenerate BTT Info checksum? arena 0: BTT Info backup checksum incorrect. Do you want to restore it from BTT Info header? arena 0: restoring BTT Info backup from header arena 1: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 1: checking BTT Map and Flog status = repaired libpmempool_api/TEST11: DONE pmdk-1.11.1/src/test/libpmempool_api/out6.log.match0000664000000000000000000000022714123364546020650 0ustar rootrootlibpmempool_api$(nW)TEST6: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -s 0 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST6: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST80000775000000000000000000000100514123364546016745 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST8 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX -t blk $POOL >> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/out13.log.match0000664000000000000000000000067214123364546020732 0ustar rootrootlibpmempool_api$(nW)TEST13: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -s 0 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST13: DONE libpmempool_api$(nW)TEST13: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -s 999999 $(nW) checking shutdown state shutdown state correct checking pool header pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_api$(nW)TEST13: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST8.PS10000664000000000000000000000066414123364546017356 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST8 -- test for checking API # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL="$DIR\file.pool" expect_normal_exit $PMEMPOOL create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE $POOL TEST expect_normal_exit $Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX -t blk $POOL check pass pmdk-1.11.1/src/test/libpmempool_api/out1.log.match0000664000000000000000000000044314123364546020643 0ustar rootrootlibpmempool_api$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 0 -a 1 -r 1 $(*) checking shutdown state shutdown state correct checking pool header pool header correct checking pmemlog header pmemlog header correct status = consistent libpmempool_api$(nW)TEST1: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST100000775000000000000000000000160714123364546017026 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST10 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL >> $LOG_TEMP $PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL expect_normal_exit ./libpmempool_test$EXESUFFIX \ -d 0 -r 0 -y 0 $POOL >> $LOG cat $LOG >> $LOG_TEMP rm -f $POOL expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL >> $LOG_TEMP $PMEMSPOIL $POOL "pool_hdr.major=7" >> $LOG_TEMP check_file $POOL expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 0 -r 1 -y 1 $POOL >> $LOG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/TEST20000775000000000000000000000101714123364546016742 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST2 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG expect_normal_exit $PMEMPOOL$EXESUFFIX create log $POOL check_file $POOL expect_normal_exit $PMEMWRITE$EXESUFFIX $POOL TEST expect_normal_exit ./libpmempool_test$EXESUFFIX\ -d 0 -a 1 -r 0 $POOL>> $LOG check pass pmdk-1.11.1/src/test/libpmempool_api/out5.log.match0000664000000000000000000000024714123364546020651 0ustar rootrootlibpmempool_api$(nW)TEST5: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -b $(nW).backup $(nW) Error: Invalid argument libpmempool_api$(nW)TEST5: DONE pmdk-1.11.1/src/test/libpmempool_api/out3.log.match0000664000000000000000000000024114123364546020641 0ustar rootrootlibpmempool_api$(nW)TEST3: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -a 0 -r 0 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST3: DONE pmdk-1.11.1/src/test/libpmempool_api/out4.log.match0000664000000000000000000000024114123364546020642 0ustar rootrootlibpmempool_api$(nW)TEST4: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 1 -a 1 -r 0 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST4: DONE pmdk-1.11.1/src/test/libpmempool_api/out8.log.match0000664000000000000000000000023114123364546020645 0ustar rootrootlibpmempool_api$(nW)TEST8: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -t blk $(nW) Error: Invalid argument libpmempool_api$(nW)TEST8: DONE pmdk-1.11.1/src/test/libpmempool_api/libpmempool_test.vcxproj.filters0000664000000000000000000000557414123364546024631 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {ebe671a1-5994-4fb2-a32a-7d594157a7ed} {d625cd8f-94b7-45c5-b123-7c0c730edbd9} Source Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/libpmempool_api/out2.log.match0000664000000000000000000000024114123364546020640 0ustar rootrootlibpmempool_api$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -d 0 -a 1 -r 0 $(nW) Error: Invalid argument libpmempool_api$(nW)TEST2: DONE pmdk-1.11.1/src/test/libpmempool_api/out12.log.match0000664000000000000000000000270414123364546020727 0ustar rootrootbttdevice.arena.btt_map(0)=0x00000000 bttdevice.arena.btt_map(1)=0x00000001 bttdevice.arena.btt_map(2)=0x00000002 bttdevice.arena.btt_map(3)=0x00000003 bttdevice.arena.btt_map(4)=0x00000004 bttdevice.arena.btt_flog(0).seq=4 libpmempool_api/TEST12: START: libpmempool_test$(nW) ./libpmempool_test$(nW) -r 1 -t btt $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 0 $(OPT)arena 0: unmapped block 40322 $(OPX)arena 0: unmapped block 40203 arena 0: number of unmapped blocks: 1 arena 0: number of invalid BTT Flog entries: 1 the following error can be fixed using PMEMPOOL_CHECK_ADVANCED flag BTT Map and / or BTT Flog contain invalid entries status = cannot repair libpmempool_api/TEST12: DONE libpmempool_api/TEST12: START: libpmempool_test$(nW) ./libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 0 $(OPT)arena 0: unmapped block 40322 $(OPX)arena 0: unmapped block 40203 arena 0: number of unmapped blocks: 1 arena 0: number of invalid BTT Flog entries: 1 Do you want to repair invalid BTT Flog entries? $(OPT)arena 0: repairing BTT Flog at 0 with free block entry 0x40009d82 $(OPX)arena 0: repairing BTT Flog at 0 with free block entry 0x40009d0b status = repaired libpmempool_api/TEST12: DONE pmdk-1.11.1/src/test/libpmempool_api/TEST110000775000000000000000000000201514123364546017021 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_api/TEST11 -- test for checking API # . ../unittest/unittest.sh require_test_type medium require_fs_type any # this test creates huge file configure_valgrind memcheck force-disable configure_valgrind pmemcheck force-disable configure_valgrind helgrind force-disable configure_valgrind drd force-disable setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP truncate -s1T $POOL expect_normal_exit $BTTCREATE -s 1T -b 512M -t $POOL >> $LOG_TEMP $PMEMSPOIL $POOL "bttdevice.arena(0).btt_info.checksum=777"\ "bttdevice.arena(0).btt_info_backup.checksum=777" >> $LOG_TEMP check_file $POOL expect_normal_exit ./libpmempool_test$EXESUFFIX -r 1 -t btt $POOL >> $LOG cat $LOG >> $LOG_TEMP expect_normal_exit ./libpmempool_test$EXESUFFIX -r 1 -t btt -a 1 $POOL >> $LOG cat $LOG >> $LOG_TEMP mv $LOG_TEMP $LOG check pass pmdk-1.11.1/src/test/obj_bucket/0000775000000000000000000000000014123364546015113 5ustar rootrootpmdk-1.11.1/src/test/obj_bucket/TEST00000775000000000000000000000054514123364546015704 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_bucket/TEST0 -- unit test for obj_bucket interface # . ../unittest/unittest.sh require_test_type medium # this is a volatile state test configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_bucket$EXESUFFIX pass pmdk-1.11.1/src/test/obj_bucket/Makefile0000664000000000000000000000043314123364546016553 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_bucket/Makefile -- build bucket unit test # TARGET = obj_bucket OBJS = obj_bucket.o LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_bucket.c) pmdk-1.11.1/src/test/obj_bucket/obj_bucket.vcxproj.filters0000664000000000000000000000616514123364546022316 0ustar rootroot {ca2d95f3-ee39-44f6-a723-68585f03435b} {74b00710-9909-4ab2-a7b6-70e836e8ccc5} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts pmdk-1.11.1/src/test/obj_bucket/TEST0.PS10000664000000000000000000000042514123364546016300 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_bucket/TEST0 -- unit test for obj_bucket interface # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_bucket$Env:EXESUFFIX pass pmdk-1.11.1/src/test/obj_bucket/.gitignore0000664000000000000000000000001314123364546017075 0ustar rootrootobj_bucket pmdk-1.11.1/src/test/obj_bucket/obj_bucket.vcxproj0000664000000000000000000001331214123364546020637 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {8A4872D7-A234-4B9B-8215-82C6BB15F3A2} Win32Proj obj_bucket 10.0.17134.0 Application true v140 Application false v140 NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_bucket/obj_bucket.c0000664000000000000000000000711314123364546017370 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_bucket.c -- unit test for bucket */ #include "bucket.h" #include "container_ravl.h" #include "util.h" #include "unittest.h" #include "obj.h" #define TEST_CHUNK_ID 10 #define TEST_ZONE_ID 20 #define TEST_SIZE_IDX 30 #define TEST_BLOCK_OFF 40 struct container_test { struct block_container super; }; static const struct memory_block *inserted_memblock; static int container_test_insert(struct block_container *c, const struct memory_block *m) { inserted_memblock = m; return 0; } static int container_test_get_rm_bestfit(struct block_container *c, struct memory_block *m) { if (inserted_memblock == NULL) return ENOMEM; *m = *inserted_memblock; inserted_memblock = NULL; return 0; } static int container_test_get_rm_exact(struct block_container *c, const struct memory_block *m) { if (inserted_memblock == NULL) return ENOMEM; if (inserted_memblock->chunk_id == m->chunk_id) { inserted_memblock = NULL; return 0; } return ENOMEM; } static void container_test_destroy(struct block_container *c) { FREE(c); } static struct block_container_ops container_test_ops = { .insert = container_test_insert, .get_rm_exact = container_test_get_rm_exact, .get_rm_bestfit = container_test_get_rm_bestfit, .is_empty = NULL, .rm_all = NULL, .destroy = container_test_destroy, }; static struct block_container * container_new_test(void) { struct container_test *c = MALLOC(sizeof(struct container_test)); c->super.c_ops = &container_test_ops; return &c->super; } static void * mock_get_real_data(const struct memory_block *m) { return NULL; } static size_t mock_get_real_size(const struct memory_block *m) { return 0; } static const struct memory_block_ops mock_ops = { .block_size = NULL, .prep_hdr = NULL, .get_lock = NULL, .get_state = NULL, .get_user_data = NULL, .get_real_data = mock_get_real_data, .get_user_size = NULL, .get_real_size = mock_get_real_size, .write_header = NULL, .reinit_header = NULL, .get_extra = NULL, .get_flags = NULL, }; static void test_fault_injection() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "bucket_new"); struct bucket *b = bucket_new(container_new_test(), NULL); UT_ASSERTeq(b, NULL); UT_ASSERTeq(errno, ENOMEM); } static void test_bucket_insert_get(void) { struct bucket *b = bucket_new(container_new_test(), NULL); UT_ASSERT(b != NULL); struct memory_block m = {TEST_CHUNK_ID, TEST_ZONE_ID, TEST_SIZE_IDX, TEST_BLOCK_OFF}; m.m_ops = &mock_ops; /* get from empty */ UT_ASSERT(b->c_ops->get_rm_bestfit(b->container, &m) != 0); UT_ASSERT(bucket_insert_block(b, &m) == 0); UT_ASSERT(b->c_ops->get_rm_bestfit(b->container, &m) == 0); UT_ASSERT(m.chunk_id == TEST_CHUNK_ID); UT_ASSERT(m.zone_id == TEST_ZONE_ID); UT_ASSERT(m.size_idx == TEST_SIZE_IDX); UT_ASSERT(m.block_off == TEST_BLOCK_OFF); bucket_delete(b); } static void test_bucket_remove(void) { struct bucket *b = bucket_new(container_new_test(), NULL); UT_ASSERT(b != NULL); struct memory_block m = {TEST_CHUNK_ID, TEST_ZONE_ID, TEST_SIZE_IDX, TEST_BLOCK_OFF}; m.m_ops = &mock_ops; UT_ASSERT(bucket_insert_block(b, &m) == 0); UT_ASSERT(b->c_ops->get_rm_exact(b->container, &m) == 0); bucket_delete(b); } int main(int argc, char *argv[]) { START(argc, argv, "obj_bucket"); test_bucket_insert_get(); test_bucket_remove(); test_fault_injection(); DONE(NULL); } #ifdef _MSC_VER /* * Since libpmemobj is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) #endif pmdk-1.11.1/src/test/obj_root/0000775000000000000000000000000014123364546014621 5ustar rootrootpmdk-1.11.1/src/test/obj_root/obj_root.c0000664000000000000000000000242214123364546016602 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * obj_root.c -- unit tests for pmemobj_root */ #include "unittest.h" #define FILE_SIZE ((size_t)0x440000000) /* 17 GB */ int main(int argc, char *argv[]) { START(argc, argv, "obj_root"); if (argc < 2) UT_FATAL("usage: obj_root [l]"); const char *path = argv[1]; PMEMobjpool *pop = NULL; os_stat_t st; int long_test = 0; if (argc >= 3 && argv[2][0] == 'l') long_test = 1; os_stat(path, &st); UT_ASSERTeq(st.st_size, FILE_SIZE); if ((pop = pmemobj_create(path, NULL, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); errno = 0; PMEMoid oid = pmemobj_root(pop, 0); UT_ASSERT(OID_EQUALS(oid, OID_NULL)); UT_ASSERTeq(errno, EINVAL); if (long_test) { oid = pmemobj_root(pop, PMEMOBJ_MAX_ALLOC_SIZE); UT_ASSERT(!OID_EQUALS(oid, OID_NULL)); } oid = pmemobj_root(pop, 1); UT_ASSERT(!OID_EQUALS(oid, OID_NULL)); oid = pmemobj_root(pop, 0); UT_ASSERT(!OID_EQUALS(oid, OID_NULL)); errno = 0; oid = pmemobj_root(pop, FILE_SIZE); UT_ASSERT(OID_EQUALS(oid, OID_NULL)); UT_ASSERTeq(errno, ENOMEM); errno = 0; oid = pmemobj_root(pop, SIZE_MAX); UT_ASSERT(OID_EQUALS(oid, OID_NULL)); UT_ASSERTeq(errno, ENOMEM); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_root/TEST1.PS10000664000000000000000000000100414123364546016001 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_root/TEST1 -- unit test for pmemobj_root # . ..\unittest\unittest.ps1 # test type is long, because test freezes the system during execution # on AppVeyor service require_test_type long setup # required free space is larger than file size, to be sure that the test # will run require_free_space 18G create_holey_file 17G $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_root$Env:EXESUFFIX $DIR\testfile l pass pmdk-1.11.1/src/test/obj_root/obj_root.vcxproj0000664000000000000000000000660314123364546020060 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {FC2248F5-3E9E-495B-9767-87F59614047C} Win32Proj obj_root 10.0.17134.0 Application true v140 Application false v140 NotUsing NotUsing pmdk-1.11.1/src/test/obj_root/obj_root.vcxproj.filters0000664000000000000000000000143414123364546021524 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {6043ccf6-d070-43a3-867f-2aa9612ac158} ps1 Source Files Test Scripts pmdk-1.11.1/src/test/obj_root/TEST00000775000000000000000000000065414123364546015413 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_root/TEST0 -- unit test for pmemobj_root # . ../unittest/unittest.sh require_test_type medium setup # required free space is larger than file size, to be sure that the test # will run require_free_space 18G create_holey_file 17G $DIR/testfile expect_normal_exit ./obj_root$EXESUFFIX $DIR/testfile pass pmdk-1.11.1/src/test/obj_root/Makefile0000664000000000000000000000032014123364546016254 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/obj_root/Makefile -- build obj_root test # TARGET = obj_root OBJS = obj_root.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_root/TEST0.PS10000664000000000000000000000065014123364546016006 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_root/TEST0 -- unit test for pmemobj_root # . ..\unittest\unittest.ps1 require_test_type medium setup # required free space is larger than file size, to be sure that the test # will run require_free_space 18G create_holey_file 17G $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_root$Env:EXESUFFIX $DIR\testfile pass pmdk-1.11.1/src/test/obj_root/.gitignore0000664000000000000000000000001114123364546016601 0ustar rootrootobj_root pmdk-1.11.1/src/test/obj_root/README0000664000000000000000000000034114123364546015477 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_root/README. This directory contains a unit test for 'pmemobj_root' command. The tests in this directory verify creating and resizing pmemobj root with various sizes. pmdk-1.11.1/src/test/obj_root/TEST10000775000000000000000000000100214123364546015400 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_root/TEST1 -- unit test for pmemobj_root # . ../unittest/unittest.sh require_test_type long # the test takes too long under pmemcheck configure_valgrind pmemcheck force-disable setup # required free space is larger than file size, to be sure that the test # will run require_free_space 18G create_holey_file 17G $DIR/testfile expect_normal_exit ./obj_root$EXESUFFIX $DIR/testfile l pass pmdk-1.11.1/src/test/obj_pmalloc_mt/0000775000000000000000000000000014123364546015765 5ustar rootrootpmdk-1.11.1/src/test/obj_pmalloc_mt/TEST30000775000000000000000000000066314123364546016562 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_mt/TEST3 -- multithreaded allocator test # (medium drd version) # . ../unittest/unittest.sh require_valgrind 3.10 require_fs_type pmem non-pmem require_test_type long configure_valgrind drd force-enable setup PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_mt$EXESUFFIX 4 64 4 $DIR/testfile pass pmdk-1.11.1/src/test/obj_pmalloc_mt/TEST00000775000000000000000000000070014123364546016547 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_mt/TEST0 -- multithreaded allocator test # (long helgrind version) # . ../unittest/unittest.sh require_valgrind 3.10 require_fs_type pmem non-pmem require_test_type long configure_valgrind helgrind force-enable setup PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_mt$EXESUFFIX 32 1000 100 $DIR/testfile pass pmdk-1.11.1/src/test/obj_pmalloc_mt/Makefile0000664000000000000000000000037714123364546017434 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_mt/Makefile -- build obj_pmalloc_mt unit test # TARGET = obj_pmalloc_mt OBJS = obj_pmalloc_mt.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj0000664000000000000000000001201114123364546022356 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {9FF62356-30B4-42A1-8DC7-45262A18DD44} Win32Proj obj_pmalloc_mt 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_pmalloc_mt/obj_pmalloc_mt.vcxproj.filters0000664000000000000000000000645714123364546024046 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts pmdk-1.11.1/src/test/obj_pmalloc_mt/TEST0.PS10000664000000000000000000000054014123364546017150 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_mt/TEST0 -- unit test for pmalloc interface # . ..\unittest\unittest.ps1 require_fs_type any require_test_type long setup $Env:PMEM_IS_PMEM_FORCE=1 expect_normal_exit $Env:EXE_DIR\obj_pmalloc_mt$Env:EXESUFFIX 32 1000 100 $DIR\testfile pass pmdk-1.11.1/src/test/obj_pmalloc_mt/obj_pmalloc_mt.c0000664000000000000000000002164314123364546021120 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_pmalloc_mt.c -- multithreaded test of allocator */ #include #include "file.h" #include "obj.h" #include "pmalloc.h" #include "sys_util.h" #include "unittest.h" #define MAX_THREADS 32 #define MAX_OPS_PER_THREAD 1000 #define ALLOC_SIZE 104 #define REALLOC_SIZE (ALLOC_SIZE * 3) #define MIX_RERUNS 2 #define CHUNKSIZE (1 << 18) #define CHUNKS_PER_THREAD 3 static unsigned Threads; static unsigned Ops_per_thread; static unsigned Tx_per_thread; struct action { struct pobj_action pact; os_mutex_t lock; os_cond_t cond; }; struct root { uint64_t offs[MAX_THREADS][MAX_OPS_PER_THREAD]; struct action actions[MAX_THREADS][MAX_OPS_PER_THREAD]; }; struct worker_args { PMEMobjpool *pop; struct root *r; unsigned idx; }; static void * alloc_worker(void *arg) { struct worker_args *a = arg; for (unsigned i = 0; i < Ops_per_thread; ++i) { pmalloc(a->pop, &a->r->offs[a->idx][i], ALLOC_SIZE, 0, 0); UT_ASSERTne(a->r->offs[a->idx][i], 0); } return NULL; } static void * realloc_worker(void *arg) { struct worker_args *a = arg; for (unsigned i = 0; i < Ops_per_thread; ++i) { prealloc(a->pop, &a->r->offs[a->idx][i], REALLOC_SIZE, 0, 0); UT_ASSERTne(a->r->offs[a->idx][i], 0); } return NULL; } static void * free_worker(void *arg) { struct worker_args *a = arg; for (unsigned i = 0; i < Ops_per_thread; ++i) { pfree(a->pop, &a->r->offs[a->idx][i]); UT_ASSERTeq(a->r->offs[a->idx][i], 0); } return NULL; } static void * mix_worker(void *arg) { struct worker_args *a = arg; /* * The mix scenario is ran twice to increase the chances of run * contention. */ for (unsigned j = 0; j < MIX_RERUNS; ++j) { for (unsigned i = 0; i < Ops_per_thread; ++i) { pmalloc(a->pop, &a->r->offs[a->idx][i], ALLOC_SIZE, 0, 0); UT_ASSERTne(a->r->offs[a->idx][i], 0); } for (unsigned i = 0; i < Ops_per_thread; ++i) { pfree(a->pop, &a->r->offs[a->idx][i]); UT_ASSERTeq(a->r->offs[a->idx][i], 0); } } return NULL; } static void * tx_worker(void *arg) { struct worker_args *a = arg; /* * Allocate objects until exhaustion, once that happens the transaction * will automatically abort and all of the objects will be freed. */ TX_BEGIN(a->pop) { for (unsigned n = 0; ; ++n) { /* this is NOT an infinite loop */ pmemobj_tx_alloc(ALLOC_SIZE, a->idx); if (Ops_per_thread != MAX_OPS_PER_THREAD && n == Ops_per_thread) { pmemobj_tx_abort(0); } } } TX_END return NULL; } static void * tx3_worker(void *arg) { struct worker_args *a = arg; /* * Allocate N objects, abort, repeat M times. Should reveal issues in * transaction abort handling. */ for (unsigned n = 0; n < Tx_per_thread; ++n) { TX_BEGIN(a->pop) { for (unsigned i = 0; i < Ops_per_thread; ++i) { pmemobj_tx_alloc(ALLOC_SIZE, a->idx); } pmemobj_tx_abort(EINVAL); } TX_END } return NULL; } static void * alloc_free_worker(void *arg) { struct worker_args *a = arg; PMEMoid oid; for (unsigned i = 0; i < Ops_per_thread; ++i) { int err = pmemobj_alloc(a->pop, &oid, ALLOC_SIZE, 0, NULL, NULL); UT_ASSERTeq(err, 0); pmemobj_free(&oid); } return NULL; } #define OPS_PER_TX 10 #define STEP 8 #define TEST_LANES 4 static void * tx2_worker(void *arg) { struct worker_args *a = arg; for (unsigned n = 0; n < Tx_per_thread; ++n) { PMEMoid oids[OPS_PER_TX]; TX_BEGIN(a->pop) { for (int i = 0; i < OPS_PER_TX; ++i) { oids[i] = pmemobj_tx_alloc(ALLOC_SIZE, a->idx); for (unsigned j = 0; j < ALLOC_SIZE; j += STEP) { pmemobj_tx_add_range(oids[i], j, STEP); } } } TX_END TX_BEGIN(a->pop) { for (int i = 0; i < OPS_PER_TX; ++i) pmemobj_tx_free(oids[i]); } TX_ONABORT { UT_ASSERT(0); } TX_END } return NULL; } static void * action_cancel_worker(void *arg) { struct worker_args *a = arg; PMEMoid oid; for (unsigned i = 0; i < Ops_per_thread; ++i) { unsigned arr_id = a->idx / 2; struct action *act = &a->r->actions[arr_id][i]; if (a->idx % 2 == 0) { os_mutex_lock(&act->lock); oid = pmemobj_reserve(a->pop, &act->pact, ALLOC_SIZE, 0); UT_ASSERT(!OID_IS_NULL(oid)); os_cond_signal(&act->cond); os_mutex_unlock(&act->lock); } else { os_mutex_lock(&act->lock); while (act->pact.heap.offset == 0) os_cond_wait(&act->cond, &act->lock); pmemobj_cancel(a->pop, &act->pact, 1); os_mutex_unlock(&act->lock); } } return NULL; } static void * action_publish_worker(void *arg) { struct worker_args *a = arg; PMEMoid oid; for (unsigned i = 0; i < Ops_per_thread; ++i) { unsigned arr_id = a->idx / 2; struct action *act = &a->r->actions[arr_id][i]; if (a->idx % 2 == 0) { os_mutex_lock(&act->lock); oid = pmemobj_reserve(a->pop, &act->pact, ALLOC_SIZE, 0); UT_ASSERT(!OID_IS_NULL(oid)); os_cond_signal(&act->cond); os_mutex_unlock(&act->lock); } else { os_mutex_lock(&act->lock); while (act->pact.heap.offset == 0) os_cond_wait(&act->cond, &act->lock); pmemobj_publish(a->pop, &act->pact, 1); os_mutex_unlock(&act->lock); } } return NULL; } static void * action_mix_worker(void *arg) { struct worker_args *a = arg; PMEMoid oid; for (unsigned i = 0; i < Ops_per_thread; ++i) { unsigned arr_id = a->idx / 2; unsigned publish = i % 2; struct action *act = &a->r->actions[arr_id][i]; if (a->idx % 2 == 0) { os_mutex_lock(&act->lock); oid = pmemobj_reserve(a->pop, &act->pact, ALLOC_SIZE, 0); UT_ASSERT(!OID_IS_NULL(oid)); os_cond_signal(&act->cond); os_mutex_unlock(&act->lock); } else { os_mutex_lock(&act->lock); while (act->pact.heap.offset == 0) os_cond_wait(&act->cond, &act->lock); if (publish) pmemobj_publish(a->pop, &act->pact, 1); else pmemobj_cancel(a->pop, &act->pact, 1); os_mutex_unlock(&act->lock); } pmemobj_persist(a->pop, act, sizeof(*act)); } return NULL; } static void actions_clear(PMEMobjpool *pop, struct root *r) { for (unsigned i = 0; i < Threads; ++i) { for (unsigned j = 0; j < Ops_per_thread; ++j) { struct action *a = &r->actions[i][j]; util_mutex_destroy(&a->lock); util_mutex_init(&a->lock); util_cond_destroy(&a->cond); util_cond_init(&a->cond); memset(&a->pact, 0, sizeof(a->pact)); pmemobj_persist(pop, a, sizeof(*a)); } } } static void run_worker(void *(worker_func)(void *arg), struct worker_args args[]) { os_thread_t t[MAX_THREADS]; for (unsigned i = 0; i < Threads; ++i) THREAD_CREATE(&t[i], NULL, worker_func, &args[i]); for (unsigned i = 0; i < Threads; ++i) THREAD_JOIN(&t[i], NULL); } int main(int argc, char *argv[]) { START(argc, argv, "obj_pmalloc_mt"); if (argc != 5) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; Threads = ATOU(argv[1]); if (Threads > MAX_THREADS) UT_FATAL("Threads %d > %d", Threads, MAX_THREADS); Ops_per_thread = ATOU(argv[2]); if (Ops_per_thread > MAX_OPS_PER_THREAD) UT_FATAL("Ops per thread %d > %d", Threads, MAX_THREADS); Tx_per_thread = ATOU(argv[3]); int exists = util_file_exists(argv[4]); if (exists < 0) UT_FATAL("!util_file_exists"); if (!exists) { pop = pmemobj_create(argv[4], "TEST", (PMEMOBJ_MIN_POOL) + (MAX_THREADS * CHUNKSIZE * CHUNKS_PER_THREAD), 0666); if (pop == NULL) UT_FATAL("!pmemobj_create"); } else { pop = pmemobj_open(argv[4], "TEST"); if (pop == NULL) UT_FATAL("!pmemobj_open"); } PMEMoid oid = pmemobj_root(pop, sizeof(struct root)); struct root *r = pmemobj_direct(oid); UT_ASSERTne(r, NULL); struct worker_args args[MAX_THREADS]; for (unsigned i = 0; i < Threads; ++i) { args[i].pop = pop; args[i].r = r; args[i].idx = i; for (unsigned j = 0; j < Ops_per_thread; ++j) { struct action *a = &r->actions[i][j]; util_mutex_init(&a->lock); util_cond_init(&a->cond); } } run_worker(alloc_worker, args); run_worker(realloc_worker, args); run_worker(free_worker, args); run_worker(mix_worker, args); run_worker(alloc_free_worker, args); run_worker(action_cancel_worker, args); actions_clear(pop, r); run_worker(action_publish_worker, args); actions_clear(pop, r); run_worker(action_mix_worker, args); /* * Reduce the number of lanes to a value smaller than the number of * threads. This will ensure that at least some of the state of the lane * will be shared between threads. Doing this might reveal bugs related * to runtime race detection instrumentation. */ unsigned old_nlanes = pop->lanes_desc.runtime_nlanes; pop->lanes_desc.runtime_nlanes = TEST_LANES; run_worker(tx2_worker, args); pop->lanes_desc.runtime_nlanes = old_nlanes; /* * This workload might create many allocation classes due to pvector, * keep it last. */ if (Threads == MAX_THREADS) /* don't run for short tests */ run_worker(tx_worker, args); run_worker(tx3_worker, args); pmemobj_close(pop); DONE(NULL); } #ifdef _MSC_VER /* * Since libpmemobj is linked statically, we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) #endif pmdk-1.11.1/src/test/obj_pmalloc_mt/.gitignore0000664000000000000000000000001714123364546017753 0ustar rootrootobj_pmalloc_mt pmdk-1.11.1/src/test/obj_pmalloc_mt/TEST10000775000000000000000000000072214123364546016554 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_pmalloc_mt/TEST1 -- multithreaded allocator test # (medium non-helgrind/drd version) # . ../unittest/unittest.sh require_fs_type any require_test_type medium configure_valgrind drd force-disable configure_valgrind helgrind force-disable setup PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_mt$EXESUFFIX 32 1000 100 $DIR/testfile pass pmdk-1.11.1/src/test/obj_pmalloc_mt/TEST20000775000000000000000000000067714123364546016566 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pmalloc_mt/TEST2 -- multithreaded allocator test # (medium helgrind version) # . ../unittest/unittest.sh require_valgrind 3.10 require_fs_type pmem non-pmem require_test_type medium configure_valgrind helgrind force-enable setup PMEM_IS_PMEM_FORCE=1 expect_normal_exit\ ./obj_pmalloc_mt$EXESUFFIX 4 64 4 $DIR/testfile pass pmdk-1.11.1/src/test/log_basic/0000775000000000000000000000000014123364546014726 5ustar rootrootpmdk-1.11.1/src/test/log_basic/TEST1.PS10000664000000000000000000000423414123364546016116 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/log_basic/TEST1 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testfile1 ` c a n t w r t w l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST5.PS10000664000000000000000000000102014123364546016110 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_basic/TEST5 -- unit test for: # - pmemlog_nbyte # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup $Env:PMEMLOG_LOG_LEVEL = "10" create_poolset $DIR\testset1 2M:$DIR\testfile1:x expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testset1 c n l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/log_basic.c0000664000000000000000000001162714123364546017023 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2019, Intel Corporation */ /* * log_basic.c -- unit test for pmemlog_* * * usage: log_basic file operation:... * * operations are 'l' or 'h' or 'f' or 'c' or 'n' or 'a' or 'v' or 't' * or 'r' or 'w' * */ #include "unittest.h" #include "../libpmemlog/log.h" /* * do_nbyte -- call pmemlog_nbyte() & print result */ static void do_nbyte(PMEMlogpool *plp) { size_t nbyte = pmemlog_nbyte(plp); UT_OUT("usable size: %zu", nbyte); } /* * do_append -- call pmemlog_append() & print result */ static void do_append(PMEMlogpool *plp) { const char *str[6] = { "1st test string\n", "2nd test string\n", "3rd test string\n", "4th test string\n", "5th test string\n", "6th test string\n" }; for (int i = 0; i < 6; ++i) { int rv = pmemlog_append(plp, str[i], strlen(str[i])); switch (rv) { case 0: UT_OUT("append str[%i] %s", i, str[i]); break; case -1: UT_OUT("!append str[%i] %s", i, str[i]); break; default: UT_OUT("!append: wrong return value"); break; } } } /* * do_appendv -- call pmemlog_appendv() & print result */ static void do_appendv(PMEMlogpool *plp) { struct iovec iov[9] = { { .iov_base = "1st test string\n", .iov_len = 16 }, { .iov_base = "2nd test string\n", .iov_len = 16 }, { .iov_base = "3rd test string\n", .iov_len = 16 }, { .iov_base = "4th test string\n", .iov_len = 16 }, { .iov_base = "5th test string\n", .iov_len = 16 }, { .iov_base = "6th test string\n", .iov_len = 16 }, { .iov_base = "7th test string\n", .iov_len = 16 }, { .iov_base = "8th test string\n", .iov_len = 16 }, { .iov_base = "9th test string\n", .iov_len = 16 } }; int rv = pmemlog_appendv(plp, iov, 9); switch (rv) { case 0: UT_OUT("appendv"); break; case -1: UT_OUT("!appendv"); break; default: UT_OUT("!appendv: wrong return value"); break; } rv = pmemlog_appendv(plp, iov, 0); UT_ASSERTeq(rv, 0); errno = 0; rv = pmemlog_appendv(plp, iov, -3); UT_ASSERTeq(errno, EINVAL); UT_ASSERTeq(rv, -1); } /* * do_tell -- call pmemlog_tell() & print result */ static void do_tell(PMEMlogpool *plp) { os_off_t tell = pmemlog_tell(plp); UT_OUT("tell %zu", tell); } /* * do_rewind -- call pmemlog_rewind() & print result */ static void do_rewind(PMEMlogpool *plp) { pmemlog_rewind(plp); UT_OUT("rewind"); } /* * printit -- print out the 'buf' of length 'len'. * * It is a walker function for pmemlog_walk */ static int printit(const void *buf, size_t len, void *arg) { char *str = MALLOC(len + 1); strncpy(str, buf, len); str[len] = '\0'; UT_OUT("%s", str); FREE(str); return 1; } /* * do_walk -- call pmemlog_walk() & print result * * pmemlog_walk() is called twice: for chunk size 0 and 16 */ static void do_walk(PMEMlogpool *plp) { pmemlog_walk(plp, 0, printit, NULL); UT_OUT("walk all at once"); pmemlog_walk(plp, 16, printit, NULL); UT_OUT("walk by 16"); } /* * do_create -- call pmemlog_create() and check if it was successful */ static PMEMlogpool * do_create(const char *path) { PMEMlogpool *_plp = pmemlog_create(path, 0, S_IWUSR | S_IRUSR); if (_plp == NULL) UT_FATAL("!pmemlog_create: %s", path); return _plp; } /* * do_fault_injection -- inject error in first Malloc() in pmemlog_create() */ static void do_fault_injection(PMEMlogpool *plp, const char *path) { if (pmemlog_fault_injection_enabled()) { pmemlog_inject_fault_at(PMEM_MALLOC, 1, "log_runtime_init"); plp = pmemlog_create(path, 0, S_IWUSR | S_IRUSR); UT_ASSERTeq(plp, NULL); UT_ASSERTeq(errno, ENOMEM); } } /* * do_close -- call pmemlog_close() */ static void do_close(PMEMlogpool *plp) { pmemlog_close(plp); } /* * do_check -- call pmemlog_check() and check consistency */ static void do_check(const char *path) { int result = pmemlog_check(path); if (result < 0) UT_OUT("!%s: pmemlog_check", path); else if (result == 0) UT_OUT("%s: pmemlog_check: not consistent", path); } int main(int argc, char *argv[]) { PMEMlogpool *plp; START(argc, argv, "log_basic"); if (argc < 3) UT_FATAL("usage: %s file-name op:l|h|f|c|n|a|v|t|r|w", argv[0]); const char *path = argv[1]; /* go through all arguments one by one */ for (int arg = 2; arg < argc; arg++) { /* Scan the character of each argument. */ if (strchr("lhfcnavtrw", argv[arg][0]) == NULL || argv[arg][1] != '\0') UT_FATAL("op must be l or h or f or c or n or a or v\ or t or r or w"); switch (argv[arg][0]) { case 'c': plp = do_create(path); break; case 'n': do_nbyte(plp); break; case 'a': do_append(plp); break; case 'v': do_appendv(plp); break; case 't': do_tell(plp); break; case 'r': do_rewind(plp); break; case 'w': do_walk(plp); break; case 'f': do_fault_injection(plp, path); break; case 'l': do_close(plp); break; case 'h': do_check(path); break; } } DONE(NULL); } pmdk-1.11.1/src/test/log_basic/TEST30000775000000000000000000000420514123364546015517 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_basic/TEST3 -- unit test for: # - pmemlog_append # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup create_holey_file 2M $DIR/testfile1 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile1\ c a n t w r t w v n t w r t w l h check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST90000775000000000000000000000150414123364546015524 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/log_basic/TEST9 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # # Same as TEST1, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected failure, as 2M alignment is not supported # if SINGLEHDR option is not specified. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_abnormal_exit ./log_basic$EXESUFFIX $DIR/testset c a n t w r t w l h pass pmdk-1.11.1/src/test/log_basic/TEST00000775000000000000000000000425614123364546015522 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_basic/TEST0 -- unit test for: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # - fault injection # in case of empty pool and: # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup create_holey_file 2M $DIR/testfile2 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile2 f create_holey_file 2M $DIR/testfile1 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile1 c n t w r l h check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_basic/Makefile0000664000000000000000000000033614123364546016370 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/log_basic/Makefile -- build log_basic unit test # TARGET = log_basic OBJS = log_basic.o LIBPMEMLOG=y include ../Makefile.inc pmdk-1.11.1/src/test/log_basic/TEST3.PS10000664000000000000000000000427614123364546016126 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/log_basic/TEST3 -- unit test for: # - pmemlog_append # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testfile1 ` c a n t w r t w v n t w r t w l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST2.PS10000664000000000000000000000423514123364546016120 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/log_basic/TEST2 -- unit test for: # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testfile1 ` c v n t w r t w l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST50000775000000000000000000000072014123364546015517 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_basic/TEST5 -- unit test for: # - pmemlog_nbyte # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup export PMEMLOG_LOG_LEVEL=10 create_poolset $DIR/testset1 2M:$DIR/testfile1:x expect_normal_exit ./log_basic$EXESUFFIX $DIR/testset1 c n l h check_pool $DIR/testset1 check pass pmdk-1.11.1/src/test/log_basic/TEST40000775000000000000000000000431414123364546015521 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_basic/TEST4 -- unit test for: # - pmemlog_append # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium # long test, run only on pmem configure_valgrind pmemcheck force-enable setup create_holey_file 2M $DIR/testfile1 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile1\ c a n t w r t w v n t w r t w l h check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST70000775000000000000000000000116014123364546015520 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/log_basic/TEST7 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # # Same as TEST1, but run on a single Device DAX device. # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 require_fs_type any setup dax_device_zero expect_normal_exit ./log_basic$EXESUFFIX $DEVICE_DAX_PATH c a n t w r t w l h check_pool $DEVICE_DAX_PATH pass pmdk-1.11.1/src/test/log_basic/out0.log.match0000664000000000000000000000032314123364546017411 0ustar rootrootlog_basic$(nW)TEST0: START: log_basic $(nW)log_basic$(nW) $(nW)testfile1 c n t w r l h $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 tell 0 walk all at once walk by 16 rewind log_basic$(nW)TEST0: DONE pmdk-1.11.1/src/test/log_basic/TEST0.PS10000664000000000000000000000417114123364546016115 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/log_basic/TEST0 -- unit test for: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of empty pool and: # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testfile1 ` c n t w r l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/.gitignore0000664000000000000000000000001214123364546016707 0ustar rootrootlog_basic pmdk-1.11.1/src/test/log_basic/README0000664000000000000000000000133514123364546015610 0ustar rootrootPersistent Memory Development Kit This is src/test/log_basic/README. This directory contains a unit test for: - pmemlog_open - pmemlog_close - pmemlog_nbyte - pmemlog_append - pmemlog_appendv - pmemlog_tell - pmemlog_rewind - pmemlog_walk - pmemlog_check - fault injection The program in pmemlog.c takes a file name and a list of operations encoded as characters as arguments. For example: ./log_basic file1 c a v r w t n l h this will call a series of log iterations with some hardcoded arguments as described in the table below: l - pmemlog_close h - pmemlog_check f - fault injection c - pmemlog_create a - pmemlog_append v - pmemlog_appendv t - pmemlog_tell r - pmemlog_rewind w - pmemlog_walk n - pmemlog_nbyte pmdk-1.11.1/src/test/log_basic/TEST60000775000000000000000000000070714123364546015525 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_basic/TEST6 -- unit test for: # - pmemlog_nbyte # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup create_poolset $DIR/testset1 2M:$DIR/testfile1:x 2M:$DIR/testfile2:x expect_normal_exit ./log_basic$EXESUFFIX $DIR/testset1 c n l h check_pool $DIR/testset1 check pass pmdk-1.11.1/src/test/log_basic/TEST6w.PS10000664000000000000000000000100514123364546016303 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/log_basic/TEST6 -- unit test for: # - pmemlog_nbyte # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_poolset $DIR\testset1 2M:$DIR\testfile1:x 2M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testset1 c n l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST10000775000000000000000000000414014123364546015513 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_basic/TEST1 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup create_holey_file 2M $DIR/testfile1 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile1 c a n t w r t w l h check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_basic/TEST4.PS10000664000000000000000000000427614123364546016127 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/log_basic/TEST4 -- unit test for: # - pmemlog_append # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup create_holey_file 2M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\log_basic$Env:EXESUFFIX $DIR\testfile1 ` c a n t w r t w v n t w r t w l h check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/log_basic/out6.log.match0000664000000000000000000000024114123364546017416 0ustar rootrootlog_basic$(nW)TEST6: START: log_basic $(nW)log_basic$(nW) $(nW)testset1 c n l h $(OPT)usable size: 4182016 $(OPX)usable size: 3997696 log_basic$(nW)TEST6: DONE pmdk-1.11.1/src/test/log_basic/TEST80000775000000000000000000000136314123364546015526 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/log_basic/TEST8 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # # Same as TEST1, but run on a pool set that spans two Device DAX devices # with 4K alignment. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 4096 4096 setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_normal_exit ./log_basic$EXESUFFIX $DIR/testset c a n t w r t w l h check_pool $DIR/testset pass pmdk-1.11.1/src/test/log_basic/log_basic.vcxproj0000664000000000000000000000754414123364546020277 0ustar rootroot Debug x64 Release x64 {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {FBB77433-639E-42DC-9355-EA94CAE294D2} Win32Proj log_pool 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/log_basic/out6w.log.match0000664000000000000000000000020214123364546017602 0ustar rootrootlog_basic$(nW)TEST6w: START: log_basic $(nW)log_basic$(nW) $(nW)testset1 c n l h usable size: 4120576 log_basic$(nW)TEST6w: DONE pmdk-1.11.1/src/test/log_basic/out1.log.match0000664000000000000000000000121214123364546017410 0ustar rootrootlog_basic$(nW)TEST1: START: log_basic $(nW)log_basic$(nW) $(nW)testfile1 c a n t w r t w l h append str[0] 1st test string append str[1] 2nd test string append str[2] 3rd test string append str[3] 4th test string append str[4] 5th test string append str[5] 6th test string $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 tell 96 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk by 16 rewind tell 0 walk all at once walk by 16 log_basic$(nW)TEST1: DONE pmdk-1.11.1/src/test/log_basic/log_basic.vcxproj.filters0000664000000000000000000000374714123364546021747 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {be9f59bd-3dd9-4c45-8726-809fcdf7520f} ps1 {69718992-5651-4f8d-bcc3-19741fba29ca} match Source Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/log_basic/TEST100000775000000000000000000000146314123364546015600 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/log_basic/TEST10 -- unit test for: # - pmemlog_append # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # # Same as TEST1, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected success, as pool is created with SINGLEHDR option. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} \ O SINGLEHDR expect_normal_exit ./log_basic$EXESUFFIX $DIR/testset c a n t w r t w l h pass pmdk-1.11.1/src/test/log_basic/TEST20000775000000000000000000000414114123364546015515 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/log_basic/TEST2 -- unit test for: # - pmemlog_appendv # and: # - pmemlog_nbyte # - pmemlog_tell # - pmemlog_walk # - pmemlog_rewind # in case of non-empty pool and # - pmemlog_check # - pmemlog_open # - pmemlog_close # . ../unittest/unittest.sh require_test_type medium setup create_holey_file 2M $DIR/testfile1 expect_normal_exit ./log_basic$EXESUFFIX $DIR/testfile1 c v n t w r t w l h check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/log_basic/out5.log.match0000664000000000000000000000024114123364546017415 0ustar rootrootlog_basic$(nW)TEST5: START: log_basic $(nW)log_basic$(nW) $(nW)testset1 c n l h $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 log_basic$(nW)TEST5: DONE pmdk-1.11.1/src/test/log_basic/out3.log.match0000664000000000000000000000212014123364546017411 0ustar rootrootlog_basic$(nW)TEST3: START: log_basic $(nW)log_basic$(nW) $(nW)testfile1 c a n t w r t w v n t w r t w l h append str[0] 1st test string append str[1] 2nd test string append str[2] 3rd test string append str[3] 4th test string append str[4] 5th test string append str[5] 6th test string $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 tell 96 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk by 16 rewind tell 0 walk all at once walk by 16 appendv $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 tell 144 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk by 16 rewind tell 0 walk all at once walk by 16 log_basic$(nW)TEST3: DONE pmdk-1.11.1/src/test/log_basic/out4.log.match0000664000000000000000000000201614123364546017416 0ustar rootrootlog_basic$(nW)TEST4: START: log_basic $(nW)log_basic$(nW) $(nW)testfile1 c a n t w r t w v n t w r t w l h append str[0] 1st test string append str[1] 2nd test string append str[2] 3rd test string append str[3] 4th test string append str[4] 5th test string append str[5] 6th test string usable size: 2088960 tell 96 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string walk by 16 rewind tell 0 walk all at once walk by 16 appendv usable size: 2088960 tell 144 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk by 16 rewind tell 0 walk all at once walk by 16 log_basic$(nW)TEST4: DONE pmdk-1.11.1/src/test/log_basic/out2.log.match0000664000000000000000000000106014123364546017412 0ustar rootrootlog_basic$(nW)TEST2: START: log_basic $(nW)log_basic$(nW) $(nW)testfile1 c v n t w r t w l h appendv $(OPT)usable size: 2088960 $(OPX)usable size: 1966080 tell 144 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk all at once 1st test string 2nd test string 3rd test string 4th test string 5th test string 6th test string 7th test string 8th test string 9th test string walk by 16 rewind tell 0 walk all at once walk by 16 log_basic$(nW)TEST2: DONE pmdk-1.11.1/src/test/pmem2_map/0000775000000000000000000000000014123364546014661 5ustar rootrootpmdk-1.11.1/src/test/pmem2_map/pmem2_map.vcxproj0000664000000000000000000001341014123364546020152 0ustar rootroot Debug x64 Release x64 {D9A70E35-0C85-4A09-ACA8-B15B21B66F50} pmem2_map 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_map/pmem2_map.vcxproj.filters0000664000000000000000000000723414123364546021630 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {4557bbd3-f8c2-4d53-821f-ec79100e2b50} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Test Scripts pmdk-1.11.1/src/test/pmem2_map/pmem2_map.c0000664000000000000000000005253314123364546016712 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2021, Intel Corporation */ /* * pmem2_map.c -- pmem2_map unittests */ #include #include "config.h" #include "pmem2_utils.h" #include "source.h" #include "map.h" #include "out.h" #include "pmem2.h" #include "unittest.h" #include "ut_pmem2.h" #include "ut_pmem2_setup.h" #define KILOBYTE (1 << 10) #define MEGABYTE (1 << 20) #ifdef _WIN32 #define HIDWORD(x) ((DWORD)((x) >> 32)) #define LODWORD(x) ((DWORD)((x) & 0xFFFFFFFF)) /* * prepare_map -- map accordingly to the config * * XXX it is assumed pmem2_config contains exact arguments e.g. * length won't be altered by the file size. */ static void prepare_map(struct pmem2_map **map_ptr, struct pmem2_config *cfg, struct pmem2_source *src) { struct pmem2_map *map = malloc(sizeof(*map)); UT_ASSERTne(map, NULL); UT_ASSERTeq(src->type, PMEM2_SOURCE_HANDLE); size_t max_size = cfg->length + cfg->offset; HANDLE mh = CreateFileMapping(src->value.handle, NULL, PAGE_READWRITE, HIDWORD(max_size), LODWORD(max_size), NULL); UT_ASSERTne(mh, NULL); UT_ASSERTne(GetLastError(), ERROR_ALREADY_EXISTS); map->addr = MapViewOfFileEx(mh, FILE_MAP_ALL_ACCESS, HIDWORD(cfg->offset), LODWORD(cfg->offset), cfg->length, NULL); UT_ASSERTne(map->addr, NULL); UT_ASSERTne(CloseHandle(mh), 0); map->reserved_length = map->content_length = cfg->length; map->effective_granularity = PMEM2_GRANULARITY_PAGE; map->reserv = NULL; *map_ptr = map; UT_ASSERTeq(pmem2_register_mapping(map), 0); } #else /* * prepare_map -- map accordingly to the config * * XXX this function currently calls mmap(3) without MAP_SYNC so the only * mapping granularity is PMEM2_GRANULARITY_PAGE. * * XXX it is assumed pmem2_config contains exact mmap(3) arguments e.g. * length won't be altered by the file size. */ static void prepare_map(struct pmem2_map **map_ptr, struct pmem2_config *cfg, struct pmem2_source *src) { int flags = MAP_SHARED; int proto = PROT_READ | PROT_WRITE; off_t offset = (off_t)cfg->offset; UT_ASSERTeq((size_t)offset, cfg->offset); struct pmem2_map *map = malloc(sizeof(*map)); UT_ASSERTne(map, NULL); UT_ASSERTeq(src->type, PMEM2_SOURCE_FD); map->addr = mmap(NULL, cfg->length, proto, flags, src->value.fd, offset); UT_ASSERTne(map->addr, MAP_FAILED); map->source.value.ftype = PMEM2_FTYPE_REG; map->reserved_length = map->content_length = cfg->length; map->effective_granularity = PMEM2_GRANULARITY_PAGE; map->reserv = NULL; *map_ptr = map; UT_ASSERTeq(pmem2_register_mapping(map), 0); } #endif /* * unmap_map -- unmap the mapping according to pmem2_map struct */ static void unmap_map(struct pmem2_map *map) { #ifdef _WIN32 UT_ASSERTne(UnmapViewOfFile(map->addr), 0); #else UT_ASSERTeq(munmap(map->addr, map->reserved_length), 0); #endif UT_ASSERTeq(pmem2_unregister_mapping(map), 0); } /* * get_align_by_name -- fetch map alignment for an unopened file */ static size_t get_align_by_name(const char *filename) { struct pmem2_source *src; size_t align; int fd = OPEN(filename, O_RDONLY); PMEM2_SOURCE_FROM_FD(&src, fd); PMEM2_SOURCE_ALIGNMENT(src, &align); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return align; } /* * test_map_rdrw_file - map a O_RDWR file */ static int test_map_rdrw_file(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_rdrw_file "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_RDWR); struct pmem2_map *map; int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); unmap_map(map); FREE(map); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * test_map_rdonly_file - map a O_RDONLY file */ static int test_map_rdonly_file(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_rdonly_file "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_READ); struct pmem2_map *map; int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_NO_ACCESS); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * map_valid_ranges_common -- map valid range and validate its length * Includes cleanup. */ static void map_valid_ranges_common(const char *file, size_t offset, size_t length, size_t val_length) { struct pmem2_config cfg; struct pmem2_source *src; struct pmem2_map *map; int ret = 0; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, length, offset, FH_RDWR); ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(map->content_length, val_length); unmap_map(map); FREE(map); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); } /* * test_map_valid_ranges - map valid memory ranges */ static int test_map_valid_ranges(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_valid_ranges "); char *file = argv[0]; size_t align = get_align_by_name(file); size_t size = ATOUL(argv[1]); size_t size2 = ALIGN_DOWN(size / 2, align); /* the config WITHOUT provided length allows mapping the whole file */ map_valid_ranges_common(file, 0, 0, size); /* the config WITH provided length allows mapping the whole file */ map_valid_ranges_common(file, 0, size, size); /* the config with provided length different than the file length */ map_valid_ranges_common(file, 0, size2, size2); /* verify the config with provided length and a valid offset */ map_valid_ranges_common(file, align, size2, size2); return 2; } /* * test_map_invalid_ranges - map invalid memory ranges */ static int test_map_invalid_ranges(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_invalid_ranges "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; size_t size = ATOUL(argv[1]); size_t offset = 0; struct pmem2_map *map; int ret = 0; struct FHandle *fh; /* the mapping + the offset > the file size */ size_t size2 = ALIGN_DOWN(size / 2, get_align_by_name(file)); #if defined(__PPC64__) offset = size2 + (64 * MEGABYTE); #else offset = size2 + (4 * MEGABYTE); #endif ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, size2, offset, FH_RDWR); ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_RANGE); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); /* the mapping size > the file size */ offset = size * 2; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, offset, FH_RDWR); ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_RANGE); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } /* * test_map_invalid_alignment - map using invalid alignment in the offset */ static int test_map_invalid_alignment(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_invalid_args "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; size_t size = ATOUL(argv[1]); size_t length = size / 2; struct pmem2_map *map; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, length, KILOBYTE, FH_RDWR); int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_OFFSET_UNALIGNED); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } /* * test_map_invalid_fd - map using a invalid file descriptor */ static int test_map_invalid_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_invalid_args "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; size_t size = ATOUL(argv[1]); size_t length = size / 2; struct pmem2_map *map; struct FHandle *fh; /* the invalid file descriptor */ ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, length, 0, FH_RDWR); UT_FH_CLOSE(fh); int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_INVALID_FILE_HANDLE); PMEM2_SOURCE_DELETE(&src); return 2; } /* * test_map_unaligned_length - map a file of length which is not page-aligned */ static int test_map_unaligned_length(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_unaligned_length "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; size_t length = ATOUL(argv[1]); struct pmem2_map *map; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, length, 0, FH_RDWR); int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_LENGTH_UNALIGNED); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } /* * test_unmap_valid - unmap valid pmem2 mapping */ static int test_unmap_valid(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_unmap_valid "); char *file = argv[0]; size_t size = ATOUL(argv[1]); struct pmem2_config cfg; struct pmem2_source *src; struct pmem2_map *map = NULL; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, size, 0, FH_RDWR); prepare_map(&map, &cfg, src); /* unmap the valid mapping */ int ret = pmem2_map_delete(&map); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(map, NULL); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } typedef void (*spoil_func)(struct pmem2_map *map); /* * unmap_invalid_common - unmap an invalid pmem2 mapping */ static int unmap_invalid_common(const char *file, size_t size, spoil_func spoil, int exp_ret) { struct pmem2_config cfg; struct pmem2_source *src; struct pmem2_map *map = NULL; struct pmem2_map map_copy; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, size, 0, FH_RDWR); prepare_map(&map, &cfg, src); /* backup the map and spoil it */ memcpy(&map_copy, map, sizeof(*map)); spoil(map); /* unmap the invalid mapping */ int ret = pmem2_map_delete(&map); UT_PMEM2_EXPECT_RETURN(ret, exp_ret); FREE(map); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } static void map_spoil_set_zero_length(struct pmem2_map *map) { map->reserved_length = 0; map->content_length = 0; } static void map_spoil_set_unaligned_addr(struct pmem2_map *map) { map->addr = (void *)((uintptr_t)map->addr + 1); map->reserved_length -= 1; } static void map_spoil_by_unmap(struct pmem2_map *map) { unmap_map(map); } /* * test_unmap_zero_length - unmap a pmem2 mapping with an invalid length */ static int test_unmap_zero_length(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_unmap_zero_length "); char *file = argv[0]; size_t size = ATOUL(argv[1]); unmap_invalid_common(file, size, map_spoil_set_zero_length, PMEM2_E_MAPPING_NOT_FOUND); return 2; } /* * test_unmap_unaligned_addr - unmap a pmem2 mapping with an unaligned address */ static int test_unmap_unaligned_addr(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_unmap_unaligned_addr "); char *file = argv[0]; size_t size = ATOUL(argv[1]); unmap_invalid_common(file, size, map_spoil_set_unaligned_addr, -EINVAL); return 2; } /* * test_unmap_unaligned_addr - double unmap a pmem2 mapping */ static int test_unmap_unmapped(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_unmap_unmapped "); char *file = argv[0]; size_t size = ATOUL(argv[1]); unmap_invalid_common(file, size, map_spoil_by_unmap, PMEM2_E_MAPPING_NOT_FOUND); return 2; } /* * test_map_get_address -- check pmem2_map_get_address func */ static int test_map_get_address(const struct test_case *tc, int argc, char *argv[]) { void *ret_addr; void *ref_addr = (void *)0x12345; struct pmem2_map map; map.addr = ref_addr; ret_addr = pmem2_map_get_address(&map); UT_ASSERTeq(ret_addr, ref_addr); return 0; } /* * test_map_get_size -- check pmem2_map_get_size func */ static int test_map_get_size(const struct test_case *tc, int argc, char *argv[]) { size_t ret_size; size_t ref_size = 16384; struct pmem2_map map; map.content_length = ref_size; ret_size = pmem2_map_get_size(&map); UT_ASSERTeq(ret_size, ref_size); return 0; } /* * test_get_granularity_simple - simply get the previously stored value */ static int test_get_granularity_simple(const struct test_case *tc, int argc, char *argv[]) { struct pmem2_map map; map.effective_granularity = PMEM2_GRANULARITY_BYTE; enum pmem2_granularity ret = pmem2_map_get_store_granularity(&map); UT_ASSERTeq(ret, PMEM2_GRANULARITY_BYTE); return 0; } /* * test_map_larger_than_unaligned_file_size - map a file which size is not * aligned */ static int test_map_larger_than_unaligned_file_size(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_larger_than_unaligned_file_size" " "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; size_t length = ATOUL(argv[1]); struct pmem2_map *map; struct FHandle *fh; size_t alignment; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_RDWR); PMEM2_SOURCE_ALIGNMENT(src, &alignment); /* validate file length is unaligned */ UT_ASSERTne(length % alignment, 0); /* align up the required mapping length */ cfg.length = ALIGN_UP(length, alignment); int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_MAP_RANGE); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } /* * test_map_zero_file_size - map using zero file size, do not set length * in config, expect failure */ static int test_map_zero_file_size(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_zero_file_size "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); if (fd < 0) UT_FATAL("open: %s", file); struct pmem2_config cfg; pmem2_config_init(&cfg); /* mapping length is left unset */ cfg.offset = 0; cfg.requested_max_granularity = PMEM2_GRANULARITY_PAGE; struct pmem2_source *src; PMEM2_SOURCE_FROM_FD(&src, fd); struct pmem2_map *map; int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_SOURCE_EMPTY); PMEM2_SOURCE_DELETE(&src); CLOSE(fd); return 2; } static void do_map_and_copy_data(struct pmem2_config *cfg, struct pmem2_source *src, struct pmem2_map **map, const char *data) { int ret = pmem2_map_new(map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(*map); void *addr = pmem2_map_get_address(*map); memcpy_fn(addr, data, strlen(data), 0); UT_ASSERTeq(memcmp(addr, data, strlen(data)), 0); } static const char *word1 = "Persistent or nonpersistent: that is the question."; static const char *word2 = "Nonpersistent: that is the answer."; /* * test_map_sharing_shared - map file with the PMEM2_SHARED option and check if * data was written; the file is not reopened */ static int test_map_sharing_shared(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_sharing_shared "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_RDWR); struct pmem2_map *map1 = NULL; do_map_and_copy_data(&cfg, src, &map1, word1); struct pmem2_map *map2 = NULL; do_map_and_copy_data(&cfg, src, &map2, word2); void *addr1 = pmem2_map_get_address(map1); /* check if changes in shared mapping affect other mapping */ UT_ASSERTeq(memcmp(addr1, word2, strlen(word2)), 0); UT_ASSERTne(memcmp(addr1, word1, strlen(word1)), 0); unmap_map(map2); unmap_map(map1); FREE(map2); FREE(map1); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * test_map_sharing_private - map file with the PMEM2_PRIVATE option and * check if data wasn't written; the file is not reopen */ static int test_map_sharing_private(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_sharing_private "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_RDWR); struct pmem2_map *map1 = NULL; do_map_and_copy_data(&cfg, src, &map1, word1); struct pmem2_map *map2 = NULL; pmem2_config_set_sharing(&cfg, PMEM2_PRIVATE); do_map_and_copy_data(&cfg, src, &map2, word2); void *addr1 = pmem2_map_get_address(map1); /* check if changes in private mapping do not affect other mapping */ UT_ASSERTne(memcmp(addr1, word2, strlen(word2)), 0); UT_ASSERTeq(memcmp(addr1, word1, strlen(word1)), 0); unmap_map(map2); unmap_map(map1); FREE(map2); FREE(map1); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * test_map_sharing_private_with_reopened_fd - map file, with the PMEM2_PRIVATE * option and check if data wasn't written; the file is reopened before every * mapping */ static int test_map_sharing_private_with_reopened_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL( "usage: test_map_sharing_private_with_reopened_fd "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh1; ut_pmem2_prepare_config(&cfg, &src, &fh1, FH_FD, file, 0, 0, FH_RDWR); struct pmem2_map *map1; do_map_and_copy_data(&cfg, src, &map1, word1); UT_FH_CLOSE(fh1); struct FHandle *fh2; ut_pmem2_prepare_config(&cfg, &src, &fh2, FH_FD, file, 0, 0, FH_RDWR); struct pmem2_map *map2; pmem2_config_set_sharing(&cfg, PMEM2_PRIVATE); do_map_and_copy_data(&cfg, src, &map2, word2); UT_FH_CLOSE(fh2); void *addr1 = pmem2_map_get_address(map1); /* check if changes in private mapping do not affect other mapping */ UT_ASSERTne(memcmp(addr1, word2, strlen(word2)), 0); UT_ASSERTeq(memcmp(addr1, word1, strlen(word1)), 0); unmap_map(map2); unmap_map(map1); FREE(map2); FREE(map1); PMEM2_SOURCE_DELETE(&src); return 1; } /* * test_map_sharing_private_rdonly_file - map O_RDONLY file with * PMEM2_PRIVATE sharing */ static int test_map_sharing_private_rdonly_file(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_sharing_private_rdonly_file "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_READ); pmem2_config_set_sharing(&cfg, PMEM2_PRIVATE); struct pmem2_map *map = NULL; do_map_and_copy_data(&cfg, src, &map, word2); unmap_map(map); FREE(map); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * test_map_sharing_private_devdax - map DAX device with PMEM2_PRIVATE sharing */ static int test_map_sharing_private_devdax(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_map_sharing_private_devdax "); char *file = argv[0]; struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, 0, 0, FH_RDWR); pmem2_config_set_sharing(&cfg, PMEM2_PRIVATE); struct pmem2_map *map = NULL; int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, PMEM2_E_SRC_DEVDAX_PRIVATE); UT_ASSERTeq(map, NULL); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 1; } /* * test_map_huge_alignment - tests whether pmem2_map correctly utilizes * huge pages where possible. */ static int test_map_huge_alignment(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_map_huge_alignment "); char *file = argv[0]; size_t size = ATOUL(argv[1]); struct pmem2_config cfg; struct pmem2_source *src; struct FHandle *fh; ut_pmem2_prepare_config(&cfg, &src, &fh, FH_FD, file, size, 0, FH_RDWR); struct pmem2_map *map; int ret = pmem2_map_new(&map, &cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); #define PAGESIZE_HUGE ((1 << 20) * 2) void *addr = pmem2_map_get_address(map); uintptr_t addru = (uintptr_t)addr; if (pmem2_map_get_size(map) >= PAGESIZE_HUGE) { UT_ASSERTeq(addru % PAGESIZE_HUGE, 0); } else { UT_ASSERTeq(addru % Pagesize, 0); } #undef PAGESIZE_HUGE unmap_map(map); FREE(map); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); return 2; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_map_rdrw_file), TEST_CASE(test_map_rdonly_file), TEST_CASE(test_map_valid_ranges), TEST_CASE(test_map_invalid_ranges), TEST_CASE(test_map_invalid_alignment), TEST_CASE(test_map_invalid_fd), TEST_CASE(test_map_unaligned_length), TEST_CASE(test_unmap_valid), TEST_CASE(test_unmap_zero_length), TEST_CASE(test_unmap_unaligned_addr), TEST_CASE(test_unmap_unmapped), TEST_CASE(test_map_get_address), TEST_CASE(test_map_get_size), TEST_CASE(test_get_granularity_simple), TEST_CASE(test_map_larger_than_unaligned_file_size), TEST_CASE(test_map_zero_file_size), TEST_CASE(test_map_sharing_shared), TEST_CASE(test_map_sharing_private), TEST_CASE(test_map_sharing_private_with_reopened_fd), TEST_CASE(test_map_sharing_private_rdonly_file), TEST_CASE(test_map_sharing_private_devdax), TEST_CASE(test_map_huge_alignment), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_map"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } #ifdef _MSC_VER MSVC_CONSTR(libpmem2_init) MSVC_DESTR(libpmem2_fini) #endif pmdk-1.11.1/src/test/pmem2_map/Makefile0000664000000000000000000000057014123364546016323 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # # src/test/pmem2_map/Makefile -- build pmem2_map unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_map OBJS += pmem2_map.o\ ut_pmem2_utils.o\ ut_pmem2_source.o\ ut_pmem2_setup.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_map/TESTS.py0000775000000000000000000001271314123364546016144 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation # import os import testframework as t class PMEM2_MAP(t.Test): test_type = t.Short filesize = 16 * t.MiB with_size = True def run(self, ctx): filepath = ctx.create_holey_file(self.filesize, 'testfile',) if self.with_size: filesize = os.stat(filepath).st_size ctx.exec('pmem2_map', self.test_case, filepath, filesize) else: ctx.exec('pmem2_map', self.test_case, filepath) class PMEM2_MAP_NO_FILE(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem2_map', self.test_case) @t.windows_exclude @t.require_devdax(t.DevDax('devdax1')) class PMEM2_MAP_DEVDAX(t.Test): test_type = t.Short with_size = True def run(self, ctx): dd = ctx.devdaxes.devdax1 if self.with_size: ctx.exec('pmem2_map', self.test_case, dd.path, dd.size) else: ctx.exec('pmem2_map', self.test_case, dd.path) class TEST0(PMEM2_MAP): """map a O_RDWR file""" test_case = "test_map_rdrw_file" with_size = False class TEST1(PMEM2_MAP_DEVDAX): """DevDax map a O_RDWR file""" test_case = "test_map_rdrw_file" with_size = False class TEST2(PMEM2_MAP): """map a O_RDONLY file""" test_case = "test_map_rdonly_file" with_size = False class TEST3(PMEM2_MAP_DEVDAX): """DevDax map a O_RDONLY file""" test_case = "test_map_rdonly_file" with_size = False class TEST4(PMEM2_MAP): """map valid memory ranges""" test_case = "test_map_valid_ranges" class TEST5(PMEM2_MAP_DEVDAX): """DevDax map valid memory ranges""" test_case = "test_map_valid_ranges" class TEST6(PMEM2_MAP): """map invalid memory ranges""" test_case = "test_map_invalid_ranges" class TEST7(PMEM2_MAP_DEVDAX): """DevDax map invalid memory ranges""" test_case = "test_map_invalid_ranges" class TEST8(PMEM2_MAP): """map using invalid alignment in the offset""" test_case = "test_map_invalid_alignment" class TEST9(PMEM2_MAP_DEVDAX): """DevDax map using invalid alignment in the offset""" test_case = "test_map_invalid_alignment" class TEST10(PMEM2_MAP): """map using a invalid file descriptor""" test_case = "test_map_invalid_fd" class TEST11(PMEM2_MAP): """unmap valid pmem2 mapping""" test_case = "test_unmap_valid" class TEST12(PMEM2_MAP_DEVDAX): """DevDax unmap valid pmem2 mapping""" test_case = "test_unmap_valid" class TEST13(PMEM2_MAP): """unmap a pmem2 mapping with an invalid length""" test_case = "test_unmap_zero_length" class TEST14(PMEM2_MAP_DEVDAX): """DevDax unmap a pmem2 mapping with an invalid length""" test_case = "test_unmap_zero_length" # UnmapViewOfFile does not care about the address alignment @t.windows_exclude class TEST15(PMEM2_MAP): """unmap a pmem2 mapping with an unaligned address""" test_case = "test_unmap_unaligned_addr" class TEST16(PMEM2_MAP_DEVDAX): """DevDax unmap a pmem2 mapping with an unaligned address""" test_case = "test_unmap_unaligned_addr" # munmap does not fail if the mapping does not exist @t.windows_only class TEST17(PMEM2_MAP): """double unmap a pmem2 mapping""" test_case = "test_unmap_unmapped" class TEST18(PMEM2_MAP_NO_FILE): """test for pmem2_map_get_address""" test_case = "test_map_get_address" class TEST19(PMEM2_MAP_NO_FILE): """test for pmem2_map_get_size""" test_case = "test_map_get_size" class TEST20(PMEM2_MAP_NO_FILE): """simply get the previously stored value of granularity""" test_case = "test_get_granularity_simple" class TEST21(PMEM2_MAP): """map a file of length which is not page-aligned""" test_case = "test_map_unaligned_length" filesize = 3 * t.KiB class TEST22(PMEM2_MAP): """map a file which size is not aligned""" test_case = "test_map_larger_than_unaligned_file_size" filesize = 16 * t.MiB - 1 class TEST23(PMEM2_MAP): """ map a file with zero size, do not provide length to pmem2_map config """ test_case = "test_map_zero_file_size" filesize = 0 class TEST24(PMEM2_MAP): """ map a file with PMEM2_SHARED sharing, changes in the mapping are visible in another mapping """ test_case = "test_map_sharing_shared" with_size = False class TEST25(PMEM2_MAP): """ map a file with PMEM2_PRIVATE sharing, changes in the mapping are not visible in another mapping """ test_case = "test_map_sharing_private" with_size = False class TEST26(PMEM2_MAP): """ map a file with PMEM2_PRIVATE sharing, changes in the mapping are not visible in another mapping, fd is reopened before each mapping """ test_case = "test_map_sharing_private_with_reopened_fd" with_size = False class TEST27(PMEM2_MAP): """ map O_RDONLY file with PMEM2_PRIVATE sharing """ test_case = "test_map_sharing_private_rdonly_file" with_size = False class TEST28(PMEM2_MAP_DEVDAX): """DevDax file with PMEM2_PRIVATE sharing""" test_case = "test_map_sharing_private_devdax" with_size = False @t.linux_only @t.require_architectures('x86_64') class TEST29(PMEM2_MAP): """map alignment test for huge pages""" test_case = "test_map_huge_alignment" filesize = 16 * t.MiB @t.linux_only @t.require_architectures('x86_64') class TEST30(PMEM2_MAP): """map alignment test for small pages""" test_case = "test_map_huge_alignment" filesize = 16 * t.KiB pmdk-1.11.1/src/test/pmem2_map/.gitignore0000664000000000000000000000001214123364546016642 0ustar rootrootpmem2_map pmdk-1.11.1/src/test/obj_debug/0000775000000000000000000000000014123364546014724 5ustar rootrootpmdk-1.11.1/src/test/obj_debug/obj_debug.vcxproj.filters0000664000000000000000000000347214123364546021736 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 {b539ef93-f1f6-4c62-b624-1a07e6615e21} match Test Files Test Files Test Files Test Files Match Files Match Files Match Files Match Files Match Files Match Files Test Files Test Files Source Files pmdk-1.11.1/src/test/obj_debug/obj_debug.vcxproj0000664000000000000000000001022414123364546020260 0ustar rootroot Debug x64 Release x64 {85DBDA9B-AEF6-43E7-B8B5-05FF2BEC61A3} Win32Proj obj_debug 10.0.17134.0 Application true v140 Application false v140 true NotUsing Disabled CompileAsCpp NotUsing MaxSpeed CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_debug/TEST1.PS10000664000000000000000000000074414123364546016116 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST1 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup $Env:PMEMOBJ_LOG_LEVEL = "4" expect_normal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX $DIR\testfile1 l sls -Path pmemobj$Env:UNITTEST_NUM.log -Pattern "_pobj_debug_notice" | ` %{$_.Line} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/TEST5.PS10000664000000000000000000000062114123364546016114 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_debug/TEST5 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup $FUNCS=18 For ($i=0; $i -lt $FUNCS; $i++) { expect_abnormal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX ` $DIR/testfile1 s $i 2>$null } pass pmdk-1.11.1/src/test/obj_debug/TEST30000775000000000000000000000055314123364546015517 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST3 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any setup expect_abnormal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 p 2> /dev/null pass pmdk-1.11.1/src/test/obj_debug/TEST00000775000000000000000000000071314123364546015512 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST0 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any setup export PMEMOBJ_LOG_LEVEL=4 expect_normal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 f $GREP _pobj_debug_notice ./pmemobj$UNITTEST_NUM.log > grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/Makefile0000664000000000000000000000041214123364546016361 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/Makefile -- build obj_debug unit test # TARGET = obj_debug OBJS = obj_debug.o LIBPMEMOBJ=y BUILD_STATIC_NONDEBUG=n include ../Makefile.inc CFLAGS += -DDEBUG pmdk-1.11.1/src/test/obj_debug/TEST3.PS10000664000000000000000000000053314123364546016114 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST3 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup expect_abnormal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX ` $DIR\testfile1 p 2>$null pass pmdk-1.11.1/src/test/obj_debug/grep0.log.match0000664000000000000000000000162414123364546017542 0ustar rootroot: <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_FOREACH in $(*)obj_debug.c:$(N)) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_FOREACH_SAFE in $(*)obj_debug.c:$(N)) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_FOREACH in $(*)obj_debug.c:$(N)) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_FOREACH_SAFE in $(*)obj_debug.c:$(N)) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_LIST_FOREACH in $(*)obj_debug.c:$(N)) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (POBJ_LIST_FOREACH_REVERSE in $(*)obj_debug.c:$(N)) pmdk-1.11.1/src/test/obj_debug/TEST2.PS10000664000000000000000000000074414123364546016117 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST2 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup $Env:PMEMOBJ_LOG_LEVEL = "4" expect_normal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX $DIR\testfile1 a sls -Path pmemobj$Env:UNITTEST_NUM.log -Pattern "_pobj_debug_notice" | ` %{$_.Line} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/TEST50000775000000000000000000000065114123364546015520 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_debug/TEST5 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any FUNCS=17 setup for op_index in $(seq 0 $FUNCS); do expect_abnormal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 s $op_index 2> /dev/null done pass pmdk-1.11.1/src/test/obj_debug/TEST40000775000000000000000000000055314123364546015520 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST4 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any setup expect_abnormal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 n 2> /dev/null pass pmdk-1.11.1/src/test/obj_debug/out0.log.match0000664000000000000000000000014614123364546017412 0ustar rootrootobj_debug$(nW)TEST0: START: obj_debug $(nW)obj_debug$(nW) $(nW)testfile1 f obj_debug$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_debug/TEST0.PS10000664000000000000000000000074414123364546016115 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST0 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup $Env:PMEMOBJ_LOG_LEVEL = "4" expect_normal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX $DIR\testfile1 f sls -Path pmemobj$Env:UNITTEST_NUM.log -Pattern "_pobj_debug_notice" | ` %{$_.Line} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/obj_debug.c0000664000000000000000000001764214123364546017022 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * obj_debug.c -- unit test for debug features * * usage: obj_debug file operation [op_index]:... * * operations are 'f' or 'l' or 'r' or 'a' or 'n' or 's' * */ #include #include #include #include "unittest.h" #include "libpmemobj.h" #define LAYOUT_NAME "layout_obj_debug" TOID_DECLARE_ROOT(struct root); TOID_DECLARE(struct tobj, 0); TOID_DECLARE(struct int3_s, 1); struct root { POBJ_LIST_HEAD(listhead, struct tobj) lhead, lhead2; uint32_t val; }; struct tobj { POBJ_LIST_ENTRY(struct tobj) next; }; struct int3_s { uint32_t i1; uint32_t i2; uint32_t i3; }; typedef void (*func)(PMEMobjpool *pop, void *sync, void *cond); static void test_FOREACH(const char *path) { PMEMobjpool *pop = NULL; PMEMoid varoid, nvaroid; TOID(struct root) root; TOID(struct tobj) var, nvar; #define COMMANDS_FOREACH()\ do {\ POBJ_FOREACH(pop, varoid) {}\ POBJ_FOREACH_SAFE(pop, varoid, nvaroid) {}\ POBJ_FOREACH_TYPE(pop, var) {}\ POBJ_FOREACH_SAFE_TYPE(pop, var, nvar) {}\ POBJ_LIST_FOREACH(var, &D_RW(root)->lhead, next) {}\ POBJ_LIST_FOREACH_REVERSE(var, &D_RW(root)->lhead, next) {}\ } while (0) if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); TOID_ASSIGN(root, pmemobj_root(pop, sizeof(struct root))); POBJ_LIST_INSERT_NEW_HEAD(pop, &D_RW(root)->lhead, next, sizeof(struct tobj), NULL, NULL); COMMANDS_FOREACH(); TX_BEGIN(pop) { COMMANDS_FOREACH(); } TX_ONABORT { UT_ASSERT(0); } TX_END COMMANDS_FOREACH(); pmemobj_close(pop); } static void test_lists(const char *path) { PMEMobjpool *pop = NULL; TOID(struct root) root; TOID(struct tobj) elm; #define COMMANDS_LISTS()\ do {\ POBJ_LIST_INSERT_NEW_HEAD(pop, &D_RW(root)->lhead, next,\ sizeof(struct tobj), NULL, NULL);\ POBJ_NEW(pop, &elm, struct tobj, NULL, NULL);\ POBJ_LIST_INSERT_AFTER(pop, &D_RW(root)->lhead,\ POBJ_LIST_FIRST(&D_RW(root)->lhead), elm, next);\ POBJ_LIST_MOVE_ELEMENT_HEAD(pop, &D_RW(root)->lhead,\ &D_RW(root)->lhead2, elm, next, next);\ POBJ_LIST_REMOVE(pop, &D_RW(root)->lhead2, elm, next);\ POBJ_FREE(&elm);\ } while (0) if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); TOID_ASSIGN(root, pmemobj_root(pop, sizeof(struct root))); COMMANDS_LISTS(); TX_BEGIN(pop) { COMMANDS_LISTS(); } TX_ONABORT { UT_ASSERT(0); } TX_END COMMANDS_LISTS(); pmemobj_close(pop); } static int int3_constructor(PMEMobjpool *pop, void *ptr, void *arg) { struct int3_s *args = (struct int3_s *)arg; struct int3_s *val = (struct int3_s *)ptr; val->i1 = args->i1; val->i2 = args->i2; val->i3 = args->i3; pmemobj_persist(pop, val, sizeof(*val)); return 0; } static void test_alloc_construct(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); TX_BEGIN(pop) { struct int3_s args = { 1, 2, 3 }; PMEMoid allocation; pmemobj_alloc(pop, &allocation, sizeof(allocation), 1, int3_constructor, &args); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_close(pop); } static void test_double_free(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid oid, oid2; int err = pmemobj_zalloc(pop, &oid, 100, 0); UT_ASSERTeq(err, 0); UT_ASSERT(!OID_IS_NULL(oid)); oid2 = oid; pmemobj_free(&oid); pmemobj_free(&oid2); } static int test_constr(PMEMobjpool *pop, void *ptr, void *arg) { PMEMoid oid; pmemobj_alloc(pop, &oid, 1, 1, test_constr, NULL); return 0; } static void test_alloc_in_constructor(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid oid; pmemobj_alloc(pop, &oid, 1, 1, test_constr, NULL); } static void test_mutex_lock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_mutex_lock(pop, (PMEMmutex *)sync); } static void test_mutex_unlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_mutex_unlock(pop, (PMEMmutex *)sync); } static void test_mutex_trylock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_mutex_trylock(pop, (PMEMmutex *)sync); } static void test_mutex_timedlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_mutex_timedlock(pop, (PMEMmutex *)sync, NULL); } static void test_mutex_zero(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_mutex_zero(pop, (PMEMmutex *)sync); } static void test_rwlock_rdlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_rdlock(pop, (PMEMrwlock *)sync); } static void test_rwlock_wrlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_wrlock(pop, (PMEMrwlock *)sync); } static void test_rwlock_timedrdlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_timedrdlock(pop, (PMEMrwlock *)sync, NULL); } static void test_rwlock_timedwrlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_timedwrlock(pop, (PMEMrwlock *)sync, NULL); } static void test_rwlock_tryrdlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_tryrdlock(pop, (PMEMrwlock *)sync); } static void test_rwlock_trywrlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_trywrlock(pop, (PMEMrwlock *)sync); } static void test_rwlock_unlock(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_unlock(pop, (PMEMrwlock *)sync); } static void test_rwlock_zero(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_rwlock_zero(pop, (PMEMrwlock *)sync); } static void test_cond_wait(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_cond_wait(pop, (PMEMcond *)cond, (PMEMmutex *)sync); } static void test_cond_signal(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_cond_signal(pop, (PMEMcond *)cond); } static void test_cond_broadcast(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_cond_broadcast(pop, (PMEMcond *)cond); } static void test_cond_timedwait(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_cond_timedwait(pop, (PMEMcond *)cond, (PMEMmutex *)sync, NULL); } static void test_cond_zero(PMEMobjpool *pop, void *sync, void *cond) { pmemobj_cond_zero(pop, (PMEMcond *)cond); } static void test_sync_pop_check(unsigned long op_index) { PMEMobjpool *pop = (PMEMobjpool *)(uintptr_t)0x1; func to_test[] = { test_mutex_lock, test_mutex_unlock, test_mutex_trylock, test_mutex_timedlock, test_mutex_zero, test_rwlock_rdlock, test_rwlock_wrlock, test_rwlock_timedrdlock, test_rwlock_timedwrlock, test_rwlock_tryrdlock, test_rwlock_trywrlock, test_rwlock_unlock, test_rwlock_zero, test_cond_wait, test_cond_signal, test_cond_broadcast, test_cond_timedwait, test_cond_zero }; if (op_index >= (sizeof(to_test) / sizeof(to_test[0]))) UT_FATAL("Invalid op_index provided"); PMEMmutex stack_sync; PMEMcond stack_cond; to_test[op_index](pop, &stack_sync, &stack_cond); } int main(int argc, char *argv[]) { START(argc, argv, "obj_debug"); if (argc < 3) UT_FATAL("usage: %s file-name op:f|l|r|a|s [op_index]", argv[0]); const char *path = argv[1]; if (strchr("flrapns", argv[2][0]) == NULL || argv[2][1] != '\0') UT_FATAL("op must be f or l or r or a or p or n or s"); unsigned long op_index; char *tailptr; switch (argv[2][0]) { case 'f': test_FOREACH(path); break; case 'l': test_lists(path); break; case 'a': test_alloc_construct(path); break; case 'p': test_double_free(path); break; case 'n': test_alloc_in_constructor(path); break; case 's': if (argc != 4) UT_FATAL("Provide an op_index with option s"); op_index = strtoul(argv[3], &tailptr, 10); if (tailptr[0] != '\0') UT_FATAL("Wrong op_index format"); test_sync_pop_check(op_index); break; } DONE(NULL); } pmdk-1.11.1/src/test/obj_debug/.gitignore0000664000000000000000000000001214123364546016705 0ustar rootrootobj_debug pmdk-1.11.1/src/test/obj_debug/README0000664000000000000000000000156114123364546015607 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_debug/README. This directory contains unit tests for debug features. The program in obj_debug.c takes a file name and an operation encoded by a character as arguments. For example: ./obj_debug file1 f The following characters and operations can be used: f - tests notice messages for FOREACH macros: - POBJ_FOREACH - POBJ_FOREACH_SAFE - POBJ_FOREACH_TYPE - POBJ_FOREACH_SAFE_TYPE - POBJ_LIST_FOREACH - POBJ_LIST_FOREACH_REVERSE l - tests notice messages for the non-TX functions: - pmemobj_alloc - pmemobj_free - pmemobj_list_insert_new - pmemobj_list_insert - pmemobj_list_move - pmemobj_list_remove r - tests notice messages for the function: - pmemobj_tx_add_common a - tests notice of atomic allocation in tx: - pmemobj_alloc s - tests debug checks in the thread synchronization API pmdk-1.11.1/src/test/obj_debug/TEST10000775000000000000000000000071314123364546015513 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST1 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any setup export PMEMOBJ_LOG_LEVEL=4 expect_normal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 l $GREP _pobj_debug_notice ./pmemobj$UNITTEST_NUM.log > grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/TEST4.PS10000664000000000000000000000053314123364546016115 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_debug/TEST4 -- unit test for debug features # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug require_fs_type any setup expect_abnormal_exit $Env:EXE_DIR\obj_debug$Env:EXESUFFIX ` $DIR/testfile1 n 2>$null pass pmdk-1.11.1/src/test/obj_debug/grep1.log.match0000664000000000000000000000140714123364546017542 0ustar rootroot: <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_list_insert_new) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_alloc) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_list_insert) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_list_move) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_list_remove) : <4> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_free) pmdk-1.11.1/src/test/obj_debug/out1.log.match0000664000000000000000000000014614123364546017413 0ustar rootrootobj_debug$(nW)TEST1: START: obj_debug $(nW)obj_debug$(nW) $(nW)testfile1 l obj_debug$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_debug/grep2.log.match0000664000000000000000000000020014123364546017531 0ustar rootroot: <$(N)> [obj.c:$(N) _pobj_debug_notice]$(W)Notice: non-transactional API used inside a transaction (pmemobj_alloc) pmdk-1.11.1/src/test/obj_debug/TEST20000775000000000000000000000104314123364546015511 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_debug/TEST2 -- unit test for debug features # . ../unittest/unittest.sh require_test_type medium require_build_type debug static-debug require_fs_type any # test causes 5 pmemcheck errors by design configure_valgrind pmemcheck force-disable setup export PMEMOBJ_LOG_LEVEL=4 expect_normal_exit ./obj_debug$EXESUFFIX $DIR/testfile1 a $GREP "_pobj_debug_notice" ./pmemobj$UNITTEST_NUM.log > grep$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_debug/out2.log.match0000664000000000000000000000014614123364546017414 0ustar rootrootobj_debug$(nW)TEST2: START: obj_debug $(nW)obj_debug$(nW) $(nW)testfile1 a obj_debug$(nW)TEST2: DONE pmdk-1.11.1/src/test/set_funcs/0000775000000000000000000000000014123364546014775 5ustar rootrootpmdk-1.11.1/src/test/set_funcs/TEST00000775000000000000000000000047114123364546015564 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/set_funcs/TEST0 -- unit test for pmem*_set_funcs # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup expect_normal_exit ./set_funcs$EXESUFFIX $DIR/testfile $DIR pass pmdk-1.11.1/src/test/set_funcs/set_funcs.vcxproj0000664000000000000000000000747114123364546020414 0ustar rootroot Debug x64 Release x64 {6D7C1169-3246-465F-B630-ECFEF4F3179A} Win32Proj set_funcs 10.0.17134.0 Application true v140 Application false v140 {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/set_funcs/Makefile0000664000000000000000000000040214123364546016431 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/set_funcs/Makefile -- build set_funcs unit test # TARGET = set_funcs OBJS = set_funcs.o LIBPMEM=y LIBPMEMOBJ=y LIBPMEMBLK=y LIBPMEMLOG=y include ../Makefile.inc pmdk-1.11.1/src/test/set_funcs/set_funcs.c0000664000000000000000000001524414123364546017140 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * set_funcs.c -- unit test for pmem*_set_funcs() */ #include "unittest.h" #define EXISTING_FILE "/root" #define NON_ZERO_POOL_SIZE 1 #define GUARD 0x2BEE5AFEULL #define EXTRA sizeof(GUARD) #define OBJ 0 #define BLK 1 #define LOG 2 static struct counters { int mallocs; int frees; int reallocs; int reallocs_null; int strdups; } cnt[5]; static void * test_malloc(size_t size) { unsigned long long *p = malloc(size + EXTRA); UT_ASSERTne(p, NULL); *p = GUARD; return ++p; } static void test_free(void *ptr) { if (ptr == NULL) return; unsigned long long *p = ptr; --p; UT_ASSERTeq(*p, GUARD); free(p); } static void * test_realloc(void *ptr, size_t size) { unsigned long long *p; if (ptr != NULL) { p = ptr; --p; UT_ASSERTeq(*p, GUARD); p = realloc(p, size + EXTRA); } else { p = malloc(size + EXTRA); } UT_ASSERTne(p, NULL); *p = GUARD; return ++p; } static char * test_strdup(const char *s) { if (s == NULL) return NULL; size_t size = strlen(s) + 1; unsigned long long *p = malloc(size + EXTRA); UT_ASSERTne(p, NULL); *p = GUARD; ++p; strcpy((char *)p, s); return (char *)p; } static void * obj_malloc(size_t size) { cnt[OBJ].mallocs++; return test_malloc(size); } static void obj_free(void *ptr) { if (ptr) cnt[OBJ].frees++; test_free(ptr); } static void * obj_realloc(void *ptr, size_t size) { if (ptr == NULL) cnt[OBJ].reallocs_null++; else cnt[OBJ].reallocs++; return test_realloc(ptr, size); } static char * obj_strdup(const char *s) { cnt[OBJ].strdups++; return test_strdup(s); } static void * blk_malloc(size_t size) { cnt[BLK].mallocs++; return test_malloc(size); } static void blk_free(void *ptr) { if (ptr) cnt[BLK].frees++; test_free(ptr); } static void * blk_realloc(void *ptr, size_t size) { if (ptr == NULL) cnt[BLK].reallocs_null++; else cnt[BLK].reallocs++; return test_realloc(ptr, size); } static char * blk_strdup(const char *s) { cnt[BLK].strdups++; return test_strdup(s); } static void * log_malloc(size_t size) { cnt[LOG].mallocs++; return test_malloc(size); } static void log_free(void *ptr) { if (ptr) cnt[LOG].frees++; test_free(ptr); } static void * log_realloc(void *ptr, size_t size) { if (ptr == NULL) cnt[LOG].reallocs_null++; else cnt[LOG].reallocs++; return test_realloc(ptr, size); } static char * log_strdup(const char *s) { cnt[LOG].strdups++; return test_strdup(s); } /* * There are a few allocations made at first call to pmemobj_open() or * pmemobj_create(). They are related to some global structures * holding a list of all open pools. These allocation are not released on * pmemobj_close(), but in the library destructor. So, we need to take them * into account when detecting memory leaks. * * obj_init/obj_pool_init: * critnib_new - Malloc + Zalloc * ctree_new - Malloc * lane_info_ht_boot/lane_info_create: * critnib_new - Malloc + Zalloc */ #define OBJ_EXTRA_NALLOC 6 static void test_obj(const char *path) { pmemobj_set_funcs(obj_malloc, obj_free, obj_realloc, obj_strdup); /* * Generate ERR() call, that calls malloc() once, * but only when it is called for the first time * (free() is called in the destructor of the library). */ pmemobj_create(EXISTING_FILE, "", NON_ZERO_POOL_SIZE, 0); memset(cnt, 0, sizeof(cnt)); PMEMobjpool *pop; pop = pmemobj_create(path, NULL, PMEMOBJ_MIN_POOL, 0600); PMEMoid oid; if (pmemobj_alloc(pop, &oid, 10, 0, NULL, NULL)) UT_FATAL("!alloc"); if (pmemobj_realloc(pop, &oid, 100, 0)) UT_FATAL("!realloc"); pmemobj_free(&oid); pmemobj_close(pop); UT_OUT("obj_mallocs: %d", cnt[OBJ].mallocs); UT_OUT("obj_frees: %d", cnt[OBJ].frees); UT_OUT("obj_reallocs: %d", cnt[OBJ].reallocs); UT_OUT("obj_reallocs_null: %d", cnt[OBJ].reallocs_null); UT_OUT("obj_strdups: %d", cnt[OBJ].strdups); if (cnt[OBJ].mallocs == 0 || cnt[OBJ].frees == 0) UT_FATAL("OBJ mallocs: %d, frees: %d", cnt[OBJ].mallocs, cnt[OBJ].frees); for (int i = 0; i < 5; ++i) { if (i == OBJ) continue; if (cnt[i].mallocs || cnt[i].frees) UT_FATAL("OBJ allocation used %d functions", i); } if (cnt[OBJ].mallocs + cnt[OBJ].strdups + cnt[OBJ].reallocs_null != cnt[OBJ].frees + OBJ_EXTRA_NALLOC) UT_FATAL("OBJ memory leak"); UNLINK(path); } static void test_blk(const char *path) { pmemblk_set_funcs(blk_malloc, blk_free, blk_realloc, blk_strdup); /* * Generate ERR() call, that calls malloc() once, * but only when it is called for the first time * (free() is called in the destructor of the library). */ pmemblk_create(EXISTING_FILE, 0, NON_ZERO_POOL_SIZE, 0); memset(cnt, 0, sizeof(cnt)); PMEMblkpool *blk = pmemblk_create(path, 512, PMEMBLK_MIN_POOL, 0600); pmemblk_close(blk); UT_OUT("blk_mallocs: %d", cnt[BLK].mallocs); UT_OUT("blk_frees: %d", cnt[BLK].frees); UT_OUT("blk_reallocs: %d", cnt[BLK].reallocs); UT_OUT("blk_reallocs_null: %d", cnt[BLK].reallocs_null); UT_OUT("blk_strdups: %d", cnt[BLK].strdups); if (cnt[BLK].mallocs == 0 || cnt[BLK].frees == 0) UT_FATAL("BLK mallocs: %d, frees: %d", cnt[BLK].mallocs, cnt[BLK].frees); for (int i = 0; i < 5; ++i) { if (i == BLK) continue; if (cnt[i].mallocs || cnt[i].frees) UT_FATAL("BLK allocation used %d functions", i); } if (cnt[BLK].mallocs + cnt[BLK].strdups + cnt[BLK].reallocs_null != cnt[BLK].frees) UT_FATAL("BLK memory leak"); UNLINK(path); } static void test_log(const char *path) { pmemlog_set_funcs(log_malloc, log_free, log_realloc, log_strdup); /* * Generate ERR() call, that calls malloc() once, * but only when it is called for the first time * (free() is called in the destructor of the library). */ pmemlog_create(EXISTING_FILE, NON_ZERO_POOL_SIZE, 0); memset(cnt, 0, sizeof(cnt)); PMEMlogpool *log = pmemlog_create(path, PMEMLOG_MIN_POOL, 0600); pmemlog_close(log); UT_OUT("log_mallocs: %d", cnt[LOG].mallocs); UT_OUT("log_frees: %d", cnt[LOG].frees); UT_OUT("log_reallocs: %d", cnt[LOG].reallocs); UT_OUT("log_reallocs_null: %d", cnt[LOG].reallocs_null); UT_OUT("log_strdups: %d", cnt[LOG].strdups); if (cnt[LOG].mallocs == 0 || cnt[LOG].frees == 0) UT_FATAL("LOG mallocs: %d, frees: %d", cnt[LOG].mallocs, cnt[LOG].frees); for (int i = 0; i < 5; ++i) { if (i == LOG) continue; if (cnt[i].mallocs || cnt[i].frees) UT_FATAL("LOG allocation used %d functions", i); } if (cnt[LOG].mallocs + cnt[LOG].strdups + cnt[LOG].reallocs_null != cnt[LOG].frees) UT_FATAL("LOG memory leak"); UNLINK(path); } int main(int argc, char *argv[]) { START(argc, argv, "set_funcs"); if (argc < 3) UT_FATAL("usage: %s file dir", argv[0]); test_obj(argv[1]); test_blk(argv[1]); test_log(argv[1]); DONE(NULL); } pmdk-1.11.1/src/test/set_funcs/TEST0.PS10000664000000000000000000000046514123364546016166 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/set_funcs/TEST0 -- unit test for pmem*_set_funcs # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup expect_normal_exit $Env:EXE_DIR\set_funcs$Env:EXESUFFIX $DIR\testfile $DIR pass pmdk-1.11.1/src/test/set_funcs/.gitignore0000664000000000000000000000001214123364546016756 0ustar rootrootset_funcs pmdk-1.11.1/src/test/set_funcs/set_funcs.vcxproj.filters0000664000000000000000000000122614123364546022053 0ustar rootroot {b80fb68c-bae8-4552-93e3-9e3b52ccf381} {0ac97c68-4204-4fac-b810-2708c5111c30} Source Files Test Scripts pmdk-1.11.1/src/test/obj_reorder_basic/0000775000000000000000000000000014123364546016441 5ustar rootrootpmdk-1.11.1/src/test/obj_reorder_basic/obj_reorder_basic.c0000664000000000000000000000405614123364546022247 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2020, Intel Corporation */ /* * obj_reorder_basic.c -- a simple unit test for store reordering * * usage: obj_reorder_basic file w|c * w - write data * c - check data consistency * */ #include "unittest.h" #include "util.h" #include "valgrind_internal.h" #define LAYOUT_NAME "intro_1" #define MAX_BUF_LEN 10 #define BUF_VALUE 'a' struct my_root { size_t len; char buf[MAX_BUF_LEN]; }; /* * write_consistent -- (internal) write data in a consistent manner */ static void write_consistent(struct pmemobjpool *pop) { PMEMoid root = pmemobj_root(pop, sizeof(struct my_root)); struct my_root *rootp = pmemobj_direct(root); char buf[MAX_BUF_LEN]; memset(buf, BUF_VALUE, sizeof(buf)); buf[MAX_BUF_LEN - 1] = '\0'; rootp->len = strlen(buf); pmemobj_persist(pop, &rootp->len, sizeof(rootp->len)); pmemobj_memcpy_persist(pop, rootp->buf, buf, rootp->len); } /* * check_consistency -- (internal) check buf consistency */ static int check_consistency(struct pmemobjpool *pop) { PMEMoid root = pmemobj_root(pop, sizeof(struct my_root)); struct my_root *rootp = pmemobj_direct(root); if (rootp->len == strlen(rootp->buf) && rootp->len != 0) for (int i = 0; i < MAX_BUF_LEN - 1; ++i) if (rootp->buf[i] != BUF_VALUE) return 1; return 0; } int main(int argc, char *argv[]) { START(argc, argv, "obj_reorder_basic"); util_init(); if (argc != 3 || strchr("wc", argv[1][0]) == 0 || argv[1][1] != '\0') UT_FATAL("usage: %s w|c file", argv[0]); char opt = argv[1][0]; if (opt == 'c') { int y = 1; pmemobj_ctl_set(NULL, "copy_on_write.at_open", &y); } PMEMobjpool *pop = pmemobj_open(argv[2], LAYOUT_NAME); UT_ASSERT(pop != NULL); VALGRIND_EMIT_LOG("PMREORDER_MARKER_WRITE.BEGIN"); switch (opt) { case 'w': { write_consistent(pop); break; } case 'c': { int ret = check_consistency(pop); pmemobj_close(pop); END(ret); } default: UT_FATAL("Unrecognized option %c", opt); } VALGRIND_EMIT_LOG("PMREORDER_MARKER_WRITE.END"); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_reorder_basic/TEST00000775000000000000000000000230514123364546017226 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_reorder_basic/TEST0 -- unit test for the reordering script # . ../unittest/unittest.sh # it doesn't make sense to run in local directory require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup export PMEMOBJ_LOG_LEVEL=10 POOL_SIZE=$((32*1024*1024)) expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout intro_1 obj $DIR/testfile -s $POOL_SIZE BIN="./obj_reorder_basic$EXESUFFIX" PMEMCHECK_CMD="$BIN w $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success ReorderFull "PMREORDER_MARKER_WRITE=ReorderPartial" "$PMREORDER_CMD" $GREP -c "pmemobj_open.BEGIN" store_log$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_open.END" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_root_construct.BEGIN" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_root_construct.END" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/obj_reorder_basic/Makefile0000664000000000000000000000046314123364546020104 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_reorder_basic/Makefile -- build obj_reorder_basic # unit test # TARGET = obj_reorder_basic OBJS = obj_reorder_basic.o LIBPMEMOBJ=y # included for VALGRIND_EMIT_LOG LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_reorder_basic/grep0.log.match0000664000000000000000000000001014123364546021243 0ustar rootroot0 0 0 0 pmdk-1.11.1/src/test/obj_reorder_basic/.gitignore0000664000000000000000000000002214123364546020423 0ustar rootrootobj_reorder_basic pmdk-1.11.1/src/test/obj_reorder_basic/README0000664000000000000000000000063514123364546017325 0ustar rootrootThis is src/test/obj_reorder_basic/README. This directory contains a basic pmemobj reordering unit test. SYNOPSIS: obj_reorder_basic w|c file DESCRIPTION: obj_reorder_basic is a basic unit test for verifying the basic functionality of the pmemobj library. OPTIONS: file is '$DIR/testfile1' for all tests. w: write data to the pool c: check pool consistency This test is based on the string_store example. pmdk-1.11.1/src/test/obj_reorder_basic/TEST10000775000000000000000000000241014123364546017224 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_reorder_basic/TEST1 -- unit test for the reordering script # with PMREORDER_EMIT_LOG flag enabled # . ../unittest/unittest.sh # it doesn't make sense to run in local directory require_fs_type pmem non-pmem require_build_type debug require_test_type medium require_pmemcheck_version_ge 1 0 require_pmemcheck_version_lt 2 0 require_pmreorder setup export PMEMOBJ_LOG_LEVEL=10 export PMREORDER_EMIT_LOG=1 POOL_SIZE=$((32*1024*1024)) expect_normal_exit $PMEMPOOL$EXESUFFIX create --layout intro_1 obj $DIR/testfile -s $POOL_SIZE BIN="./obj_reorder_basic$EXESUFFIX" PMEMCHECK_CMD="$BIN w $DIR/testfile" PMREORDER_CMD="$BIN c" pmreorder_create_store_log $DIR/testfile "$PMEMCHECK_CMD" pmreorder_expect_success ReorderFull "PMREORDER_MARKER_WRITE=ReorderPartial" "$PMREORDER_CMD" $GREP -c "pmemobj_open.BEGIN" store_log$UNITTEST_NUM.log > grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_open.END" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_root_construct.BEGIN" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true $GREP -c "pmemobj_root_construct.END" store_log$UNITTEST_NUM.log >> grep$UNITTEST_NUM.log || true check pass pmdk-1.11.1/src/test/obj_reorder_basic/grep1.log.match0000664000000000000000000000001014123364546021244 0ustar rootroot1 1 1 1 pmdk-1.11.1/src/test/common_badblock.sh0000664000000000000000000005040114123364546016451 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2020, Intel Corporation # # src/test/common_badblock.sh -- commons for the following tests: # - util_badblock # - pmempool_create # - pmempool_info # LOG=out${UNITTEST_NUM}.log UNITTEST_DIRNAME=$(echo $UNITTEST_NAME | cut -d'/' -f1) COMMAND_MOUNTED_DIRS="\ mount | grep -e $UNITTEST_DIRNAME | cut -d' ' -f1 | xargs && true" COMMAND_NDCTL_NFIT_TEST_INIT="\ sudo modprobe nfit_test &>>$PREP_LOG_FILE && \ sudo ndctl disable-region all &>>$PREP_LOG_FILE && \ sudo ndctl zero-labels all &>>$PREP_LOG_FILE && \ sudo ndctl enable-region all &>>$PREP_LOG_FILE" COMMAND_NDCTL_NFIT_TEST_FINI="\ sudo ndctl disable-region all &>>$PREP_LOG_FILE && \ sudo modprobe -r nfit_test &>>$PREP_LOG_FILE" # # badblock_test_init -- initialize badblock test based on underlying hardware # # Input arguments: # 1) device type (dax_device|block_device) # 2) mount directory (in case of block device type) # function badblock_test_init() { case "$1" in dax_device|block_device) ;; *) usage "bad device type: $1" ;; esac DEVTYPE=$1 if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then ndctl_nfit_test_init fi if [ "$DEVTYPE" == "dax_device" ]; then DEVICE=$(badblock_test_get_dax_device) elif [ "$DEVTYPE" == "block_device" ]; then DEVICE=$(badblock_test_get_block_device) prepare_mount_dir $DEVICE $2 fi NAMESPACE=$(ndctl_get_namespace_of_device $DEVICE) FULLDEV="/dev/$DEVICE" # current unit tests support only block sizes less or equal 4096 bytes require_max_block_size $FULLDEV 4096 } # # badblock_test_init_node -- initialize badblock test based on underlying # hardware on a remote node # # Input arguments: # 1) remote node number # 2) device type (dax_device|block_device) # 3) for block device: mount directory # for dax device on real pmem: dax device index on a given node # function badblock_test_init_node() { case "$2" in dax_device|block_device) ;; *) usage "bad device type: $2" ;; esac DEVTYPE=$2 if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then ndctl_nfit_test_init_node $1 fi if [ "$DEVTYPE" == "dax_device" ]; then DEVICE=$(badblock_test_get_dax_device_node $1 $3) elif [ "$DEVTYPE" == "block_device" ]; then DEVICE=$(badblock_test_get_block_device_node $1) prepare_mount_dir_node $1 $DEVICE $3 fi NAMESPACE=$(ndctl_get_namespace_of_device_node $1 $DEVICE) FULLDEV="/dev/$DEVICE" } # # badblock_test_get_dax_device -- get name of the dax device # function badblock_test_get_dax_device() { DEVICE="" if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then DEVICE=$(ndctl_nfit_test_get_dax_device) elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then DEVICE=$(real_pmem_get_dax_device) fi echo $DEVICE } # # badblock_test_get_dax_device_node -- get name of the dax device on a given # remote node # Input arguments: # 1) remote node number # 2) For real pmem: device dax index on a given node # function badblock_test_get_dax_device_node() { DEVICE="" if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then DEVICE=$(ndctl_nfit_test_get_dax_device_node $1) elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then DEVICE=$(real_pmem_get_dax_device_node $1 $2) fi echo $DEVICE } # # badblock_test_get_block_device -- get name of the block device # function badblock_test_get_block_device() { DEVICE="" if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then DEVICE=$(ndctl_nfit_test_get_block_device) elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then DEVICE=$(real_pmem_get_block_device) fi echo "$DEVICE" } # # badblock_test_get_block_device_node -- get name of the block device on a given # remote node # function badblock_test_get_block_device_node() { DEVICE="" if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then DEVICE=$(ndctl_nfit_test_get_block_device_node $1) elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then DEVICE=$(real_pmem_get_block_device_node $1) fi echo "$DEVICE" } # # prepare_mount_dir -- prepare the mount directory for provided device # # Input arguments: # 1) device name # 2) mount directory # function prepare_mount_dir() { if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then local FULLDEV="/dev/$1" ndctl_nfit_test_mount_pmem $FULLDEV $2 elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then if [ ! -d $2 ]; then mkdir -p $2 fi fi } # # prepare_mount_dir_node -- prepare the mount directory for provided device # on a given remote node # # Input arguments: # 1) remote node number # 2) device name # 3) mount directory # function prepare_mount_dir_node() { if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then local FULLDEV="/dev/$2" ndctl_nfit_test_mount_pmem_node $1 $FULLDEV $3 elif [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then if [ ! -d $3 ]; then run_on_node $1 "mkdir -p $3" fi fi } # # real_pmem_get_dax_device -- get real pmem dax device name # function real_pmem_get_dax_device() { local FULLDEV=${DEVICE_DAX_PATH[0]} DEVICE=${FULLDEV##*/} echo $DEVICE } # # real_pmem_get_dax_device_node -- get real pmem dax device name on a given # remote node # # Input arguments: # 1) remote node number # 2) device dax index number # function real_pmem_get_dax_device_node() { local node=$1 local devdax_index=$2 local device_dax_path=(${NODE_DEVICE_DAX_PATH[$node]}) local FULLDEV=${device_dax_path[$devdax_index]} DEVICE=${FULLDEV##*/} echo $DEVICE } # # real_pmem_get_block_device -- get real pmem block device name # function real_pmem_get_block_device() { local FULL_DEV=$(mount | grep $PMEM_FS_DIR | cut -f 1 -d" ") DEVICE=${FULL_DEV##*/} echo $DEVICE } # # real_pmem_get_block_device_node -- get real pmem block device name on a given # remote node # function real_pmem_get_block_device_node() { local FULL_DEV=$(expect_normal_exit run_on_node $1 mount | grep $PMEM_FS_DIR | cut -f 1 -d" ") DEVICE=${FULL_DEV##*/} echo $DEVICE } # # ndctl_nfit_test_init -- reset all regions and reload the nfit_test module # function ndctl_nfit_test_init() { sudo ndctl disable-region all &>>$PREP_LOG_FILE if ! sudo modprobe -r nfit_test &>>$PREP_LOG_FILE; then MOUNTED_DIRS="$(eval $COMMAND_MOUNTED_DIRS)" [ "$MOUNTED_DIRS" ] && sudo umount $MOUNTED_DIRS sudo ndctl disable-region all &>>$PREP_LOG_FILE sudo modprobe -r nfit_test fi expect_normal_exit $COMMAND_NDCTL_NFIT_TEST_INIT } # # ndctl_nfit_test_init_node -- reset all regions and reload the nfit_test # module on a remote node # function ndctl_nfit_test_init_node() { run_on_node $1 "sudo ndctl disable-region all &>>$PREP_LOG_FILE" if ! run_on_node $1 "sudo modprobe -r nfit_test &>>$PREP_LOG_FILE"; then MOUNTED_DIRS="$(run_on_node $1 $COMMAND_MOUNTED_DIRS)" run_on_node $1 "\ [ \"$MOUNTED_DIRS\" ] && sudo umount $MOUNTED_DIRS; \ sudo ndctl disable-region all &>>$PREP_LOG_FILE; \ sudo modprobe -r nfit_test" fi expect_normal_exit run_on_node $1 "$COMMAND_NDCTL_NFIT_TEST_INIT" } # # badblock_test_fini -- clean badblock test based on underlying hardware # # Input arguments: # 1) pmem mount directory to be umounted (optional) # function badblock_test_fini() { if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then ndctl_nfit_test_fini $1 fi } # # badblock_test_fini_node() -- clean badblock test based on underlying hardware # on a given remote node # # Input arguments: # 1) node number # 2) pmem mount directory to be umounted (optional) # function badblock_test_fini_node() { if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ]; then ndctl_nfit_test_fini_node $1 $2 fi } # # ndctl_nfit_test_fini -- clean badblock test ran on nfit_test based on underlying hardware # function ndctl_nfit_test_fini() { MOUNT_DIR=$1 [ $MOUNT_DIR ] && sudo umount $MOUNT_DIR &>> $PREP_LOG_FILE expect_normal_exit $COMMAND_NDCTL_NFIT_TEST_FINI } # # ndctl_nfit_test_fini_node -- disable all regions, remove the nfit_test module # and (optionally) umount the pmem block device on a remote node # # Input arguments: # 1) node number # 2) pmem mount directory to be umounted # function ndctl_nfit_test_fini_node() { MOUNT_DIR=$2 [ $MOUNT_DIR ] && expect_normal_exit run_on_node $1 "sudo umount $MOUNT_DIR &>> $PREP_LOG_FILE" expect_normal_exit run_on_node $1 "$COMMAND_NDCTL_NFIT_TEST_FINI" } # # ndctl_nfit_test_mount_pmem -- mount a pmem block device # # Input arguments: # 1) path of a pmem block device # 2) mount directory # function ndctl_nfit_test_mount_pmem() { FULLDEV=$1 MOUNT_DIR=$2 expect_normal_exit "\ sudo mkfs.ext4 $FULLDEV &>>$PREP_LOG_FILE && \ sudo mkdir -p $MOUNT_DIR &>>$PREP_LOG_FILE && \ sudo mount $FULLDEV $MOUNT_DIR &>>$PREP_LOG_FILE && \ sudo chmod 0777 $MOUNT_DIR" } # # ndctl_nfit_test_mount_pmem_node -- mount a pmem block device on a remote node # # Input arguments: # 1) number of a node # 2) path of a pmem block device # 3) mount directory # function ndctl_nfit_test_mount_pmem_node() { FULLDEV=$2 MOUNT_DIR=$3 expect_normal_exit run_on_node $1 "\ sudo mkfs.ext4 $FULLDEV &>>$PREP_LOG_FILE && \ sudo mkdir -p $MOUNT_DIR &>>$PREP_LOG_FILE && \ sudo mount $FULLDEV $MOUNT_DIR &>>$PREP_LOG_FILE && \ sudo chmod 0777 $MOUNT_DIR" } # # ndctl_nfit_test_get_device -- create a namespace and get name of the pmem device # of the nfit_test module # # Input argument: # 1) mode of the namespace (devdax or fsdax) # function ndctl_nfit_test_get_device() { MODE=$1 DEVTYPE="" [ "$MODE" == "devdax" ] && DEVTYPE="chardev" [ "$MODE" == "fsdax" ] && DEVTYPE="blockdev" [ "$DEVTYPE" == "" ] && echo "ERROR: wrong namespace mode: $MODE" >&2 && exit 1 BUS="nfit_test.0" REGION=$(ndctl list -b $BUS -t pmem -Ri | sed "/dev/!d;s/[\", ]//g;s/dev://g" | tail -1) DEVICE=$(sudo ndctl create-namespace -b $BUS -r $REGION -f -m $MODE -a 4096 | sed "/$DEVTYPE/!d;s/[\", ]//g;s/$DEVTYPE://g") echo $DEVICE } # # ndctl_nfit_test_get_device_node -- create a namespace and get name of the pmem device # of the nfit_test module on a remote node # # Input argument: # 1) mode of the namespace (devdax or fsdax) # function ndctl_nfit_test_get_device_node() { MODE=$2 DEVTYPE="" [ "$MODE" == "devdax" ] && DEVTYPE="chardev" [ "$MODE" == "fsdax" ] && DEVTYPE="blockdev" [ "$DEVTYPE" == "" ] && echo "ERROR: wrong namespace mode: $MODE" >&2 && exit 1 BUS="nfit_test.0" REGION=$(expect_normal_exit run_on_node $1 ndctl list -b $BUS -t pmem -Ri | sed "/dev/!d;s/[\", ]//g;s/dev://g" | tail -1) DEVICE=$(expect_normal_exit run_on_node $1 sudo ndctl create-namespace -b $BUS -r $REGION -f -m $MODE -a 4096 | sed "/$DEVTYPE/!d;s/[\", ]//g;s/$DEVTYPE://g") echo $DEVICE } # # ndctl_nfit_test_get_dax_device -- create a namespace and get name of the dax device # of the nfit_test module # function ndctl_nfit_test_get_dax_device() { # XXX needed by libndctl (it should be removed when it is not needed) sudo chmod o+rw /dev/ndctl* DEVICE=$(ndctl_nfit_test_get_device devdax) sudo chmod o+rw /dev/$DEVICE echo $DEVICE } # # ndctl_nfit_test_get_dax_device_node -- create a namespace and get name of # the pmem dax device of the nfit_test # module on a remote node # function ndctl_nfit_test_get_dax_device_node() { DEVICE=$(ndctl_nfit_test_get_device_node $1 devdax) echo $DEVICE } # # ndctl_nfit_test_get_block_device -- create a namespace and get name of the pmem block device # of the nfit_test module # function ndctl_nfit_test_get_block_device() { DEVICE=$(ndctl_nfit_test_get_device fsdax) echo $DEVICE } # # ndctl_nfit_test_get_block_device_node -- create a namespace and get name of # the pmem block device of the nfit_test # module on a remote node # function ndctl_nfit_test_get_block_device_node() { DEVICE=$(ndctl_nfit_test_get_device_node $1 fsdax) echo $DEVICE } # # ndctl_nfit_test_grant_access -- grant accesses required by libndctl # # XXX needed by libndctl (it should be removed when these extra access rights are not needed) # # Input argument: # 1) a name of pmem device # function ndctl_nfit_test_grant_access() { BUS="nfit_test.0" REGION=$(ndctl list -b $BUS -t pmem -Ri | sed "/dev/!d;s/[\", ]//g;s/dev://g" | tail -1) expect_normal_exit "\ sudo chmod o+rw /dev/nmem* && \ sudo chmod o+r /sys/bus/nd/devices/ndbus*/$REGION/*/resource && \ sudo chmod o+r /sys/bus/nd/devices/ndbus*/$REGION/resource" } # # ndctl_nfit_test_grant_access_node -- grant accesses required by libndctl on a node # # XXX needed by libndctl (it should be removed when these extra access rights are not needed) # # Input arguments: # 1) node number # 2) name of pmem device # function ndctl_nfit_test_grant_access_node() { BUS="nfit_test.0" REGION=$(expect_normal_exit run_on_node $1 ndctl list -b $BUS -t pmem -Ri | sed "/dev/!d;s/[\", ]//g;s/dev://g" | tail -1) expect_normal_exit run_on_node $1 "\ sudo chmod o+rw /dev/nmem* && \ sudo chmod o+r /sys/bus/nd/devices/ndbus*/$REGION/*/resource && \ sudo chmod o+r /sys/bus/nd/devices/ndbus*/$REGION/resource" } # # ndctl_requires_extra_access -- checks whether ndctl will require extra # file permissions for bad-block iteration # # Input argument: # 1) Mode of the namespace # function ndctl_requires_extra_access() { # Tests require additional permissions for badblock iteration if they # are ran on device dax or with ndctl version prior to v63. if [ "$1" != "fsdax" ] || ! is_ndctl_enabled $PMEMPOOL$EXESUFFIX ; then return 0 fi return 1 } # # ndctl_nfit_test_get_namespace_of_device -- get namespace of the pmem device # # Input argument: # 1) a name of pmem device # function ndctl_get_namespace_of_device() { local DEVICE=$1 NAMESPACE=$(ndctl list | grep -e "$DEVICE" -e namespace | grep -B1 -e "$DEVICE" | head -n1 | cut -d'"' -f4) MODE=$(ndctl list -n "$NAMESPACE" | grep mode | cut -d'"' -f4) if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ] && ndctl_requires_extra_access $MODE; then ndctl_nfit_test_grant_access $DEVICE fi echo "$NAMESPACE" } # # ndctl_nfit_test_get_namespace_of_device_node -- get namespace of the pmem device on a remote node # # Input arguments: # 1) node number # 2) name of pmem device # function ndctl_get_namespace_of_device_node() { local DEVICE=$2 NAMESPACE=$(expect_normal_exit run_on_node $1 ndctl list | grep -e "$DEVICE" -e namespace | grep -B1 -e "$DEVICE" | head -n1 | cut -d'"' -f4) MODE=$(expect_normal_exit run_on_node $1 ndctl list -n "$NAMESPACE" | grep mode | cut -d'"' -f4) if [ "$BADBLOCK_TEST_TYPE" == "nfit_test" ] && ndctl_requires_extra_access $MODE; then ndctl_nfit_test_grant_access_node $1 $DEVICE fi echo $NAMESPACE } # # ndctl_inject_error -- inject error (bad blocks) to the namespace # # Input arguments: # 1) namespace # 2) the first bad block # 3) number of bad blocks # function ndctl_inject_error() { local namespace=$1 local block=$2 local count=$3 echo "# sudo ndctl inject-error --block=$block --count=$count $namespace" >> $PREP_LOG_FILE expect_normal_exit "sudo ndctl inject-error --block=$block --count=$count $namespace" &>> $PREP_LOG_FILE echo "# sudo ndctl start-scrub" >> $PREP_LOG_FILE expect_normal_exit "sudo ndctl start-scrub" &>> $PREP_LOG_FILE echo "# sudo ndctl wait-scrub" >> $PREP_LOG_FILE expect_normal_exit "sudo ndctl wait-scrub" &>> $PREP_LOG_FILE echo "(done: ndctl wait-scrub)" >> $PREP_LOG_FILE } # # ndctl_inject_error_node -- inject error (bad blocks) to the namespace on # a given remote node # # Input arguments: # 1) node # 2) namespace # 3) the first bad block # 4) number of bad blocks # function ndctl_inject_error_node() { local node=$1 local namespace=$2 local block=$3 local count=$4 echo "# sudo ndctl inject-error --block=$block --count=$count $namespace" >> $PREP_LOG_FILE expect_normal_exit run_on_node $node "sudo ndctl inject-error --block=$block --count=$count $namespace" &>> $PREP_LOG_FILE echo "# sudo ndctl start-scrub" >> $PREP_LOG_FILE expect_normal_exit run_on_node $node "sudo ndctl start-scrub" &>> $PREP_LOG_FILE echo "# sudo ndctl wait-scrub" >> $PREP_LOG_FILE expect_normal_exit run_on_node $node "sudo ndctl wait-scrub" &>> $PREP_LOG_FILE echo "(done: ndctl wait-scrub)" >> $PREP_LOG_FILE } # # ndctl_uninject_error -- clear bad block error present in the namespace # # Input arguments: # 1) full device name (error clearing process requires writing to device) # 2) namespace # 3) the first bad block # 4) number of bad blocks # function ndctl_uninject_error() { # explicit uninjection is not required on nfit_test since any error # injections made during the tests are eventually cleaned up in _fini # function by reloading the whole namespace if [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then local fulldev=$1 local namespace=$2 local block=$3 local count=$4 expect_normal_exit "sudo ndctl inject-error --uninject --block=$block --count=$count $namespace >> $PREP_LOG_FILE 2>&1" if [ "$DEVTYPE" == "block_device" ]; then expect_normal_exit "sudo dd if=/dev/zero of=$fulldev bs=512 seek=$block count=$count \ oflag=direct >> $PREP_LOG_FILE 2>&1" elif [ "$DEVTYPE" == "dax_device" ]; then expect_normal_exit "$DAXIO$EXESUFFIX -i /dev/zero -o $fulldev -s $block -l $count >> $PREP_LOG_FILE 2>&1" fi fi } # # ndctl_uninject_error_node -- clear bad block error present in the # namespace on a given remote node # # Input arguments: # 1) node # 2) full device name (error clearing process requires writing to device) # 3) namespace # 4) the first bad block # 5) number of bad blocks # function ndctl_uninject_error_node() { # explicit uninjection is not required on nfit_test since any error # injections made during the tests are eventually cleaned up in _fini # function by reloading the whole namespace if [ "$BADBLOCK_TEST_TYPE" == "real_pmem" ]; then local node=$1 local fulldev=$2 local namespace=$3 local block=$4 local count=$5 expect_normal_exit run_on_node $node "sudo ndctl inject-error --uninject --block=$block --count=$count \ $namespace >> $PREP_LOG_FILE 2>&1" if [ "$DEVTYPE" == "block_device" ]; then expect_normal_exit run_on_node $node "sudo dd if=/dev/zero of=$fulldev bs=512 seek=$block count=$count \ oflag=direct >> $PREP_LOG_FILE 2>&1" elif [ "$DEVTYPE" == "dax_device" ]; then expect_normal_exit run_on_node $node "$DAXIO$EXESUFFIX -i /dev/zero -o $fulldev -s $block -l $count \ >> $PREP_LOG_FILE 2>&1" fi fi } # # print_bad_blocks -- print all bad blocks (count, offset and length) # in the given namespace or "No bad blocks found" # if there are no bad blocks # # Input arguments: # 1) namespace # function print_bad_blocks { # XXX sudo should be removed when it is not needed sudo ndctl list -M -n $1 | \ grep -e "badblock_count" -e "offset" -e "length" >> $LOG \ || echo "No bad blocks found" >> $LOG } # # expect_bad_blocks -- verify if there are required bad blocks # in the given namespace and fail if they are not there # # Input arguments: # 1) namespace # function expect_bad_blocks { # XXX sudo should be removed when it is not needed sudo ndctl list -M -n $1 | grep -e "badblock_count" -e "offset" -e "length" >> $LOG && true if [ $? -ne 0 ]; then # XXX sudo should be removed when it is not needed sudo ndctl list -M &>> $PREP_LOG_FILE && true msg "=====================================================================" msg "Error occurred, the preparation log ($PREP_LOG_FILE) is listed below:" msg "" cat $PREP_LOG_FILE msg "=====================================================================" msg "" fatal "Error: ndctl failed to inject or retain bad blocks" fi } # # expect_bad_blocks_node -- verify if there are required bad blocks # in the given namespace on the given node # and fail if they are not there # # Input arguments: # 1) node number # 2) namespace # function expect_bad_blocks_node { # XXX sudo should be removed when it is not needed expect_normal_exit run_on_node $1 sudo ndctl list -M -n $2 | \ grep -e "badblock_count" -e "offset" -e "length" >> $LOG \ || fatal "Error: ndctl failed to inject or retain bad blocks (node $1)" } pmdk-1.11.1/src/test/obj_toid/0000775000000000000000000000000014123364546014575 5ustar rootrootpmdk-1.11.1/src/test/obj_toid/obj_toid.vcxproj0000664000000000000000000000724214123364546020010 0ustar rootroot Debug x64 Release x64 {296F3C5D-3951-423E-8E2F-FD4A37958C72} Win32Proj obj_toid 10.0.17134.0 Application true v140 Application false v140 true Disabled CompileAsCpp MaxSpeed CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_toid/obj_toid.c0000664000000000000000000000326414123364546016537 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2017, Intel Corporation */ /* * obj_toid.c -- unit test for TOID_VALID, DIRECT_RO, DIRECT_RW macros */ #include #include "unittest.h" #define LAYOUT_NAME "toid" #define TEST_NUM 5 TOID_DECLARE(struct obj, 0); struct obj { int id; }; /* * do_toid_valid -- validates if type number is equal to object's metadata */ static void do_toid_valid(PMEMobjpool *pop) { TOID(struct obj) obj; POBJ_NEW(pop, &obj, struct obj, NULL, NULL); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(TOID_VALID(obj)); POBJ_FREE(&obj); } /* * do_toid_no_valid -- validates if type number is not equal to * object's metadata */ static void do_toid_no_valid(PMEMobjpool *pop) { TOID(struct obj) obj; int ret = pmemobj_alloc(pop, &obj.oid, sizeof(struct obj), TEST_NUM, NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERT(!TOID_VALID(obj)); POBJ_FREE(&obj); } /* * do_direct_simple - checks if DIRECT_RW and DIRECT_RO macros correctly * write and read from member of structure represented by TOID */ static void do_direct_simple(PMEMobjpool *pop) { TOID(struct obj) obj; POBJ_NEW(pop, &obj, struct obj, NULL, NULL); D_RW(obj)->id = TEST_NUM; pmemobj_persist(pop, &D_RW(obj)->id, sizeof(D_RW(obj)->id)); UT_ASSERTeq(D_RO(obj)->id, TEST_NUM); POBJ_FREE(&obj); } int main(int argc, char *argv[]) { START(argc, argv, "obj_toid"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); do_toid_valid(pop); do_toid_no_valid(pop); do_direct_simple(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_toid/TEST00000775000000000000000000000043714123364546015366 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_toid/TEST0 -- unit test for obj_toid # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_toid$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_toid/Makefile0000664000000000000000000000033214123364546016233 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_toid/Makefile -- build obj_toid unit test # TARGET = obj_toid OBJS = obj_toid.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_toid/out0.log.match0000664000000000000000000000014014123364546017255 0ustar rootrootobj_toid$(nW)TEST0: START: obj_toid $(nW)obj_toid$(nW) $(nW)testfile1 obj_toid$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_toid/TEST0.PS10000664000000000000000000000043314123364546015761 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_toid/TEST0 -- unit test for obj_toid # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_toid$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_toid/.gitignore0000664000000000000000000000001214123364546016556 0ustar rootrootobj_toid pmdk-1.11.1/src/test/obj_toid/obj_toid.vcxproj.filters0000664000000000000000000000166414123364546021461 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {e74a05c1-b2bf-4318-829a-10db2517a15b} {693031e2-57bc-43c3-91d7-4c5215858a25} Source Files Test scripts Match Files pmdk-1.11.1/src/test/libpmempool_map_flog/0000775000000000000000000000000014123364546017167 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_map_flog/libpmempool_map_flog.vcxproj.filters0000664000000000000000000000216414123364546026441 0ustar rootroot {710964b0-ff4d-4979-bb64-ca7ece05c7d6} {9eb71f49-772e-405d-9409-87398e9ea0d7} Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/libpmempool_map_flog/TEST1.PS10000664000000000000000000000303714123364546020357 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST1 -- test for checking map and flog # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL = "$DIR\file.pool" $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE = "$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" $map_err = @{ "Initial"="0" "Error"="4" "Zeroed"="8" "Normal"="C" } $ent_val = 6 foreach ($field in ("Zeroed", "Error", "Initial", "Normal")) { expect_normal_exit $BTTCREATE $POOL $x = $map_err[$field] for ($i=0; $i -lt $ent_val; $i++) { $spcmd = "bttdevice.arena.btt_map($i)=0x${x}000000${i}" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd } # duplicated entry $spcmd = "bttdevice.arena.btt_map(6)=0x${x}0000003" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd # lba number is higher then internal nlba $spcmd = "bttdevice.arena.btt_map(2)=0x${x}000FFFF" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE -r 1 -t btt -a 1 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP } mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/TEST30000775000000000000000000000261714123364546017765 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST3 -- test for checking map and flog # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test ent_val=10 expect_normal_exit $BTTCREATE $POOL for((i=0;i> $LOG_TEMP $PMEMSPOIL $POOL $spcmd done spcmd="bttdevice.arena.btt_map(5)=0xC0000002" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_map(6)=0xC0000002" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_map(7)=0xC0000002" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_map(10)=0xC0000002" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_map(11)=0xC0000002" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_map(12)=0xC0000003" echo $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt -a 1 $POOL cat $LOG >> $LOG_TEMP expect_normal_exit $PMEMPOOL$EXESUFFIX info $POOL -f btt -m\ | $GREP "error" >> $LOG_TEMP mv $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/TEST00000775000000000000000000000163214123364546017756 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST0 -- test for checking map and flog # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test declare -A map_err=(["Initial"]="0" ["Error"]="4" ["Zeroed"]="8" ["Normal"]="C") ent_val=2 for field in Zeroed Error Initial Normal; do for((i=0;i> $LOG_TEMP $PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt -a 1 $POOL cat $LOG >> $LOG_TEMP done done mv $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/libpmempool_map_flog.vcxproj0000664000000000000000000001061714123364546024774 0ustar rootroot Debug x64 Release x64 {ED2A831F-4AAF-4CF7-A953-3C45B0EC1BE6} Win32Proj libpmempool_map_flog 10.0.17134.0 Application true v140 Application false v140 true Level3 Disabled NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC Level3 MaxSpeed true true NTDDI_VERSION=NTDDI_WIN10_RS1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true platform.h CompileAsC true {a2a0faea-2b7c-4fc3-b904-1db4deacf88d} pmdk-1.11.1/src/test/libpmempool_map_flog/Makefile0000664000000000000000000000031214123364546020623 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/libpmempool_map_flog/Makefile -- build libpmempool_map_flog unittest # include ../libpmempool_api/Makefile.inc pmdk-1.11.1/src/test/libpmempool_map_flog/TEST3.PS10000664000000000000000000000364414123364546020365 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST3 -- test for checking map and flog # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL = "$DIR\file.pool" $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE = "$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" $ent_val = 10 expect_normal_exit $BTTCREATE $POOL for ($i=0; $i -lt $ent_val; $i++) { $spcmd = "bttdevice.arena.btt_map($i)=0xC000000${i}" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd } $spcmd = "bttdevice.arena.btt_map(5)=0xC0000002" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_map(6)=0xC0000002" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_map(7)=0xC0000002" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_map(10)=0xC0000002" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_map(11)=0xC0000002" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_map(12)=0xC0000003" echo $spcmd | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE -r 1 -t btt -a 1 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP expect_normal_exit $PMEMPOOL info $POOL -f btt -m | ` Select-String -encoding ASCII -Pattern "error" | %{$_.Line} | out-file -append -encoding ascii -literalpath $LOG_TEMP mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/TEST2.PS10000664000000000000000000000426014123364546020357 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST2 -- test for checking map and flog # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL = "$DIR\file.pool" $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE = "$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" $map_err = @{ "Initial"="0" "Error"="4" "Zeroed"="8" "Normal"="C" } $ent_val = 9 foreach ($field in ("Zeroed", "Error", "Initial", "Normal")) { expect_normal_exit $BTTCREATE $POOL $x = $map_err[$field] for ($i=0; $i -lt $ent_val; $i++) { $spcmd = "bttdevice.arena.btt_map($i)=0x${x}000000${i}" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd } $spcmd = "bttdevice.arena.btt_flog(3).seq=4" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_flog(4).old_map=0x${x}000FFFF" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_flog(5).new_map=0x${x}000FFFF" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_flog(6).old_map=0x${x}0000001" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_flog(7).new_map=0x${x}0000002" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd $spcmd = "bttdevice.arena.btt_flog(8).new_map=0x${x}0000069" echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE -r 1 -t btt -a 1 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP } mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/out0.log.match0000664000000000000000000000704614123364546021663 0ustar rootrootZeroed: bttdevice.arena.btt_map(0)=0x80000000 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST0: DONE Zeroed: bttdevice.arena.btt_map(0)=0x80000001 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: BTT Map entry 1 duplicated at 1 arena 0: unmapped block 0 arena 0: number of unmapped blocks: 1 arena 0: number of invalid BTT Map entries: 1 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000001 at 0 BTT Map entry arena 0: storing 0x40000000 at 1 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST0: DONE Error: bttdevice.arena.btt_map(0)=0x40000000 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST0: DONE Error: bttdevice.arena.btt_map(0)=0x40000001 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: BTT Map entry 1 duplicated at 1 arena 0: unmapped block 0 arena 0: number of unmapped blocks: 1 arena 0: number of invalid BTT Map entries: 1 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000001 at 0 BTT Map entry arena 0: storing 0x40000000 at 1 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST0: DONE Initial: bttdevice.arena.btt_map(0)=0x00000000 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST0: DONE Initial: bttdevice.arena.btt_map(0)=0x00000001 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST0: DONE Normal: bttdevice.arena.btt_map(0)=0xC0000000 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST0: DONE Normal: bttdevice.arena.btt_map(0)=0xC0000001 libpmempool_map_flog$(nW)TEST0: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: BTT Map entry 1 duplicated at 1 arena 0: unmapped block 0 arena 0: number of unmapped blocks: 1 arena 0: number of invalid BTT Map entries: 1 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000001 at 0 BTT Map entry arena 0: storing 0x40000000 at 1 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST0: DONE pmdk-1.11.1/src/test/libpmempool_map_flog/TEST0.PS10000664000000000000000000000221514123364546020353 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST0 -- test for checking map and flog # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $POOL = "$DIR\file.pool" $LOG = "out${Env:UNITTEST_NUM}.log" $LOG_TEMP = "out${Env:UNITTEST_NUM}_part.log" rm $LOG -Force -ea si touch $LOG rm $LOG_TEMP -Force -ea si touch $LOG_TEMP $EXE = "$Env:EXE_DIR\libpmempool_test$Env:EXESUFFIX" $map_err = @{ "Initial"="0" "Error"="4" "Zeroed"="8" "Normal"="C" } $ent_val = 2 foreach ($field in ("Zeroed", "Error", "Initial", "Normal")) { $x = $map_err[$field] for ($i=0; $i -lt $ent_val; $i++) { $spcmd = "bttdevice.arena.btt_map(0)=0x${x}000000${i}" expect_normal_exit $BTTCREATE $POOL echo "${field}: $spcmd" | out-file -append -encoding ascii -literalpath $LOG_TEMP &$PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE -r 1 -t btt -a 1 $POOL cat -Encoding Ascii $LOG | out-file -append -encoding ascii -literalpath $LOG_TEMP } } mv -Force $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/README0000664000000000000000000000026014123364546020045 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_map_flog/README. This directory contains a unit test for libpmempool check in context of map and flog defects. pmdk-1.11.1/src/test/libpmempool_map_flog/TEST10000775000000000000000000000233114123364546017754 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST1 -- test for checking map and flog # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test declare -A map_err=(["Initial"]="0" ["Error"]="4" ["Zeroed"]="8" ["Normal"]="C") ent_val=6 for field in Zeroed Error Initial Normal; do expect_normal_exit $BTTCREATE $POOL for((i=0;i> $LOG_TEMP $PMEMSPOIL $POOL $spcmd done # duplicated entry spcmd="bttdevice.arena.btt_map(6)=0x${map_err["$field"]}0000003" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd # lba number is higher then internal nlba spcmd="bttdevice.arena.btt_map(2)=0x${map_err["$field"]}000FFFF" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt -a 1 $POOL cat $LOG >> $LOG_TEMP done mv $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/out1.log.match0000664000000000000000000000742514123364546021665 0ustar rootrootZeroed: bttdevice.arena.btt_map(0)=0x80000000 Zeroed: bttdevice.arena.btt_map(1)=0x80000001 Zeroed: bttdevice.arena.btt_map(2)=0x80000002 Zeroed: bttdevice.arena.btt_map(3)=0x80000003 Zeroed: bttdevice.arena.btt_map(4)=0x80000004 Zeroed: bttdevice.arena.btt_map(5)=0x80000005 Zeroed: bttdevice.arena.btt_map(6)=0x80000003 Zeroed: bttdevice.arena.btt_map(2)=0x8000FFFF libpmempool_map_flog$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Map entry at 2 arena 0: BTT Map entry 3 duplicated at 6 arena 0: unmapped block 2 arena 0: unmapped block 6 arena 0: number of unmapped blocks: 2 arena 0: number of invalid BTT Map entries: 2 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000003 at 3 BTT Map entry arena 0: storing 0x40000006 at 6 BTT Map entry arena 0: storing 0x40000002 at 2 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST1: DONE Error: bttdevice.arena.btt_map(0)=0x40000000 Error: bttdevice.arena.btt_map(1)=0x40000001 Error: bttdevice.arena.btt_map(2)=0x40000002 Error: bttdevice.arena.btt_map(3)=0x40000003 Error: bttdevice.arena.btt_map(4)=0x40000004 Error: bttdevice.arena.btt_map(5)=0x40000005 Error: bttdevice.arena.btt_map(6)=0x40000003 Error: bttdevice.arena.btt_map(2)=0x4000FFFF libpmempool_map_flog$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Map entry at 2 arena 0: BTT Map entry 3 duplicated at 6 arena 0: unmapped block 2 arena 0: unmapped block 6 arena 0: number of unmapped blocks: 2 arena 0: number of invalid BTT Map entries: 2 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000003 at 3 BTT Map entry arena 0: storing 0x40000006 at 6 BTT Map entry arena 0: storing 0x40000002 at 2 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST1: DONE Initial: bttdevice.arena.btt_map(0)=0x00000000 Initial: bttdevice.arena.btt_map(1)=0x00000001 Initial: bttdevice.arena.btt_map(2)=0x00000002 Initial: bttdevice.arena.btt_map(3)=0x00000003 Initial: bttdevice.arena.btt_map(4)=0x00000004 Initial: bttdevice.arena.btt_map(5)=0x00000005 Initial: bttdevice.arena.btt_map(6)=0x00000003 Initial: bttdevice.arena.btt_map(2)=0x0000FFFF libpmempool_map_flog$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog status = consistent libpmempool_map_flog$(nW)TEST1: DONE Normal: bttdevice.arena.btt_map(0)=0xC0000000 Normal: bttdevice.arena.btt_map(1)=0xC0000001 Normal: bttdevice.arena.btt_map(2)=0xC0000002 Normal: bttdevice.arena.btt_map(3)=0xC0000003 Normal: bttdevice.arena.btt_map(4)=0xC0000004 Normal: bttdevice.arena.btt_map(5)=0xC0000005 Normal: bttdevice.arena.btt_map(6)=0xC0000003 Normal: bttdevice.arena.btt_map(2)=0xC000FFFF libpmempool_map_flog$(nW)TEST1: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Map entry at 2 arena 0: BTT Map entry 3 duplicated at 6 arena 0: unmapped block 2 arena 0: unmapped block 6 arena 0: number of unmapped blocks: 2 arena 0: number of invalid BTT Map entries: 2 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000003 at 3 BTT Map entry arena 0: storing 0x40000006 at 6 BTT Map entry arena 0: storing 0x40000002 at 2 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST1: DONE pmdk-1.11.1/src/test/libpmempool_map_flog/TEST20000775000000000000000000000326014123364546017757 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_map_flog/TEST2 -- test for checking map and flog # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup POOL=$DIR/file.pool LOG=out${UNITTEST_NUM}.log LOG_TEMP=out${UNITTEST_NUM}_part.log rm -f $LOG && touch $LOG rm -f $LOG_TEMP && touch $LOG_TEMP EXE=../libpmempool_api/libpmempool_test declare -A map_err=(["Initial"]="0" ["Error"]="4" ["Zeroed"]="8" ["Normal"]="C") ent_val=9 for field in Zeroed Error Initial Normal; do expect_normal_exit $BTTCREATE $POOL for((i=0;i> $LOG_TEMP $PMEMSPOIL $POOL $spcmd done spcmd="bttdevice.arena.btt_flog(3).seq=4" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_flog(4).old_map=0x${map_err["$field"]}000FFFF" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_flog(5).new_map=0x${map_err["$field"]}000FFFF" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_flog(6).old_map=0x${map_err["$field"]}0000001" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_flog(7).new_map=0x${map_err["$field"]}0000002" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd spcmd="bttdevice.arena.btt_flog(8).new_map=0x${map_err["$field"]}0000069" echo ${field}: $spcmd >> $LOG_TEMP $PMEMSPOIL $POOL $spcmd expect_normal_exit $EXE$EXESUFFIX -r 1 -t btt -a 1 $POOL cat $LOG >> $LOG_TEMP done mv $LOG_TEMP $LOG check_file $POOL check pass pmdk-1.11.1/src/test/libpmempool_map_flog/out3.log.match0000664000000000000000000000410114123364546021653 0ustar rootrootbttdevice.arena.btt_map(0)=0xC0000000 bttdevice.arena.btt_map(1)=0xC0000001 bttdevice.arena.btt_map(2)=0xC0000002 bttdevice.arena.btt_map(3)=0xC0000003 bttdevice.arena.btt_map(4)=0xC0000004 bttdevice.arena.btt_map(5)=0xC0000005 bttdevice.arena.btt_map(6)=0xC0000006 bttdevice.arena.btt_map(7)=0xC0000007 bttdevice.arena.btt_map(8)=0xC0000008 bttdevice.arena.btt_map(9)=0xC0000009 bttdevice.arena.btt_map(5)=0xC0000002 bttdevice.arena.btt_map(6)=0xC0000002 bttdevice.arena.btt_map(7)=0xC0000002 bttdevice.arena.btt_map(10)=0xC0000002 bttdevice.arena.btt_map(11)=0xC0000002 bttdevice.arena.btt_map(12)=0xC0000003 libpmempool_map_flog$(nW)TEST3: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: BTT Map entry 2 duplicated at 5 arena 0: BTT Map entry 2 duplicated at 6 arena 0: BTT Map entry 2 duplicated at 7 arena 0: BTT Map entry 2 duplicated at 10 arena 0: BTT Map entry 2 duplicated at 11 arena 0: BTT Map entry 3 duplicated at 12 arena 0: unmapped block 5 arena 0: unmapped block 6 arena 0: unmapped block 7 arena 0: unmapped block 10 arena 0: unmapped block 11 arena 0: unmapped block 12 arena 0: number of unmapped blocks: 6 arena 0: number of invalid BTT Map entries: 6 Do you want to repair invalid BTT Map entries? arena 0: storing 0x40000002 at 2 BTT Map entry arena 0: storing 0x40000003 at 3 BTT Map entry arena 0: storing 0x4000000c at 12 BTT Map entry arena 0: storing 0x4000000b at 11 BTT Map entry arena 0: storing 0x4000000a at 10 BTT Map entry arena 0: storing 0x40000007 at 7 BTT Map entry arena 0: storing 0x40000006 at 6 BTT Map entry arena 0: storing 0x40000005 at 5 BTT Map entry status = repaired libpmempool_map_flog$(nW)TEST3: DONE 0000000002: 0x00000002 state: error 0000000003: 0x00000003 state: error 0000000005: 0x00000005 state: error 0000000006: 0x00000006 state: error 0000000007: 0x00000007 state: error 0000000010: 0x0000000a state: error 0000000011: 0x0000000b state: error 0000000012: 0x0000000c state: error pmdk-1.11.1/src/test/libpmempool_map_flog/out2.log.match0000664000000000000000000001677414123364546021675 0ustar rootrootZeroed: bttdevice.arena.btt_map(0)=0x80000000 Zeroed: bttdevice.arena.btt_map(1)=0x80000001 Zeroed: bttdevice.arena.btt_map(2)=0x80000002 Zeroed: bttdevice.arena.btt_map(3)=0x80000003 Zeroed: bttdevice.arena.btt_map(4)=0x80000004 Zeroed: bttdevice.arena.btt_map(5)=0x80000005 Zeroed: bttdevice.arena.btt_map(6)=0x80000006 Zeroed: bttdevice.arena.btt_map(7)=0x80000007 Zeroed: bttdevice.arena.btt_map(8)=0x80000008 Zeroed: bttdevice.arena.btt_flog(3).seq=4 Zeroed: bttdevice.arena.btt_flog(4).old_map=0x8000FFFF Zeroed: bttdevice.arena.btt_flog(5).new_map=0x8000FFFF Zeroed: bttdevice.arena.btt_flog(6).old_map=0x80000001 Zeroed: bttdevice.arena.btt_flog(7).new_map=0x80000002 Zeroed: bttdevice.arena.btt_flog(8).new_map=0x80000069 libpmempool_map_flog$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 3 arena 0: invalid BTT Flog entry at 4 arena 0: invalid BTT Flog entry at 5 $(OPT)arena 0: unmapped block 40325 $(OPX)arena 0: unmapped block 40206 $(OPT)arena 0: unmapped block 40326 $(OPX)arena 0: unmapped block 40207 $(OPT)arena 0: unmapped block 40327 $(OPX)arena 0: unmapped block 40208 arena 0: number of unmapped blocks: 3 arena 0: number of invalid BTT Flog entries: 3 Do you want to repair invalid BTT Flog entries? $(OPT)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d87 $(OPX)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d10 $(OPT)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d86 $(OPX)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d0f $(OPT)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d85 $(OPX)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d0e status = repaired libpmempool_map_flog$(nW)TEST2: DONE Error: bttdevice.arena.btt_map(0)=0x40000000 Error: bttdevice.arena.btt_map(1)=0x40000001 Error: bttdevice.arena.btt_map(2)=0x40000002 Error: bttdevice.arena.btt_map(3)=0x40000003 Error: bttdevice.arena.btt_map(4)=0x40000004 Error: bttdevice.arena.btt_map(5)=0x40000005 Error: bttdevice.arena.btt_map(6)=0x40000006 Error: bttdevice.arena.btt_map(7)=0x40000007 Error: bttdevice.arena.btt_map(8)=0x40000008 Error: bttdevice.arena.btt_flog(3).seq=4 Error: bttdevice.arena.btt_flog(4).old_map=0x4000FFFF Error: bttdevice.arena.btt_flog(5).new_map=0x4000FFFF Error: bttdevice.arena.btt_flog(6).old_map=0x40000001 Error: bttdevice.arena.btt_flog(7).new_map=0x40000002 Error: bttdevice.arena.btt_flog(8).new_map=0x40000069 libpmempool_map_flog$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 3 arena 0: invalid BTT Flog entry at 4 arena 0: invalid BTT Flog entry at 5 $(OPT)arena 0: unmapped block 40325 $(OPX)arena 0: unmapped block 40206 $(OPT)arena 0: unmapped block 40326 $(OPX)arena 0: unmapped block 40207 $(OPT)arena 0: unmapped block 40327 $(OPX)arena 0: unmapped block 40208 arena 0: number of unmapped blocks: 3 arena 0: number of invalid BTT Flog entries: 3 Do you want to repair invalid BTT Flog entries? $(OPT)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d87 $(OPX)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d10 $(OPT)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d86 $(OPX)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d0f $(OPT)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d85 $(OPX)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d0e status = repaired libpmempool_map_flog$(nW)TEST2: DONE Initial: bttdevice.arena.btt_map(0)=0x00000000 Initial: bttdevice.arena.btt_map(1)=0x00000001 Initial: bttdevice.arena.btt_map(2)=0x00000002 Initial: bttdevice.arena.btt_map(3)=0x00000003 Initial: bttdevice.arena.btt_map(4)=0x00000004 Initial: bttdevice.arena.btt_map(5)=0x00000005 Initial: bttdevice.arena.btt_map(6)=0x00000006 Initial: bttdevice.arena.btt_map(7)=0x00000007 Initial: bttdevice.arena.btt_map(8)=0x00000008 Initial: bttdevice.arena.btt_flog(3).seq=4 Initial: bttdevice.arena.btt_flog(4).old_map=0x0000FFFF Initial: bttdevice.arena.btt_flog(5).new_map=0x0000FFFF Initial: bttdevice.arena.btt_flog(6).old_map=0x00000001 Initial: bttdevice.arena.btt_flog(7).new_map=0x00000002 Initial: bttdevice.arena.btt_flog(8).new_map=0x00000069 libpmempool_map_flog$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 3 arena 0: invalid BTT Flog entry at 4 arena 0: invalid BTT Flog entry at 5 $(OPT)arena 0: unmapped block 40325 $(OPX)arena 0: unmapped block 40206 $(OPT)arena 0: unmapped block 40326 $(OPX)arena 0: unmapped block 40207 $(OPT)arena 0: unmapped block 40327 $(OPX)arena 0: unmapped block 40208 arena 0: number of unmapped blocks: 3 arena 0: number of invalid BTT Flog entries: 3 Do you want to repair invalid BTT Flog entries? $(OPT)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d87 $(OPX)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d10 $(OPT)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d86 $(OPX)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d0f $(OPT)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d85 $(OPX)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d0e status = repaired libpmempool_map_flog$(nW)TEST2: DONE Normal: bttdevice.arena.btt_map(0)=0xC0000000 Normal: bttdevice.arena.btt_map(1)=0xC0000001 Normal: bttdevice.arena.btt_map(2)=0xC0000002 Normal: bttdevice.arena.btt_map(3)=0xC0000003 Normal: bttdevice.arena.btt_map(4)=0xC0000004 Normal: bttdevice.arena.btt_map(5)=0xC0000005 Normal: bttdevice.arena.btt_map(6)=0xC0000006 Normal: bttdevice.arena.btt_map(7)=0xC0000007 Normal: bttdevice.arena.btt_map(8)=0xC0000008 Normal: bttdevice.arena.btt_flog(3).seq=4 Normal: bttdevice.arena.btt_flog(4).old_map=0xC000FFFF Normal: bttdevice.arena.btt_flog(5).new_map=0xC000FFFF Normal: bttdevice.arena.btt_flog(6).old_map=0xC0000001 Normal: bttdevice.arena.btt_flog(7).new_map=0xC0000002 Normal: bttdevice.arena.btt_flog(8).new_map=0xC0000069 libpmempool_map_flog$(nW)TEST2: START: libpmempool_test$(nW) $(nW)libpmempool_test$(nW) -r 1 -t btt -a 1 $(nW) checking BTT Info headers arena 0: BTT Info header checksum correct checking BTT Map and Flog arena 0: checking BTT Map and Flog arena 0: invalid BTT Flog entry at 3 arena 0: invalid BTT Flog entry at 4 arena 0: invalid BTT Flog entry at 5 $(OPT)arena 0: unmapped block 40325 $(OPX)arena 0: unmapped block 40206 $(OPT)arena 0: unmapped block 40326 $(OPX)arena 0: unmapped block 40207 $(OPT)arena 0: unmapped block 40327 $(OPX)arena 0: unmapped block 40208 arena 0: number of unmapped blocks: 3 arena 0: number of invalid BTT Flog entries: 3 Do you want to repair invalid BTT Flog entries? $(OPT)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d87 $(OPX)arena 0: repairing BTT Flog at 5 with free block entry 0x40009d10 $(OPT)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d86 $(OPX)arena 0: repairing BTT Flog at 4 with free block entry 0x40009d0f $(OPT)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d85 $(OPX)arena 0: repairing BTT Flog at 3 with free block entry 0x40009d0e status = repaired libpmempool_map_flog$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_tx_strdup/0000775000000000000000000000000014123364546015672 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_strdup/obj_tx_strdup.c0000664000000000000000000002551714123364546020736 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_tx_strdup.c -- unit test for pmemobj_tx_strdup */ #include #include #include #include "unittest.h" #define LAYOUT_NAME "tx_strdup" TOID_DECLARE(char, 0); TOID_DECLARE(wchar_t, 1); enum type_number { TYPE_NO_TX, TYPE_WCS_NO_TX, TYPE_COMMIT, TYPE_WCS_COMMIT, TYPE_ABORT, TYPE_WCS_ABORT, TYPE_FREE_COMMIT, TYPE_WCS_FREE_COMMIT, TYPE_FREE_ABORT, TYPE_WCS_FREE_ABORT, TYPE_COMMIT_NESTED1, TYPE_WCS_COMMIT_NESTED1, TYPE_COMMIT_NESTED2, TYPE_WCS_COMMIT_NESTED2, TYPE_ABORT_NESTED1, TYPE_WCS_ABORT_NESTED1, TYPE_ABORT_NESTED2, TYPE_WCS_ABORT_NESTED2, TYPE_ABORT_AFTER_NESTED1, TYPE_WCS_ABORT_AFTER_NESTED1, TYPE_ABORT_AFTER_NESTED2, TYPE_WCS_ABORT_AFTER_NESTED2, TYPE_NOFLUSH, TYPE_WCS_NOFLUSH, }; #define TEST_STR_1 "Test string 1" #define TEST_STR_2 "Test string 2" #define TEST_WCS_1 L"Test string 3" #define TEST_WCS_2 L"Test string 4" #define MAX_FUNC 2 typedef void (*fn_tx_strdup)(TOID(char) *str, const char *s, unsigned type_num); typedef void (*fn_tx_wcsdup)(TOID(wchar_t) *wcs, const wchar_t *s, unsigned type_num); static unsigned counter; /* * tx_strdup -- duplicate a string using pmemobj_tx_strdup */ static void tx_strdup(TOID(char) *str, const char *s, unsigned type_num) { TOID_ASSIGN(*str, pmemobj_tx_strdup(s, type_num)); } /* * tx_wcsdup -- duplicate a string using pmemobj_tx_wcsdup */ static void tx_wcsdup(TOID(wchar_t) *wcs, const wchar_t *s, unsigned type_num) { TOID_ASSIGN(*wcs, pmemobj_tx_wcsdup(s, type_num)); } /* * tx_strdup_macro -- duplicate a string using macro */ static void tx_strdup_macro(TOID(char) *str, const char *s, unsigned type_num) { TOID_ASSIGN(*str, TX_STRDUP(s, type_num)); } /* * tx_wcsdup_macro -- duplicate a wide character string using macro */ static void tx_wcsdup_macro(TOID(wchar_t) *wcs, const wchar_t *s, unsigned type_num) { TOID_ASSIGN(*wcs, TX_WCSDUP(s, type_num)); } static fn_tx_strdup do_tx_strdup[MAX_FUNC] = {tx_strdup, tx_strdup_macro}; static fn_tx_wcsdup do_tx_wcsdup[MAX_FUNC] = {tx_wcsdup, tx_wcsdup_macro}; /* * do_tx_strdup_commit -- duplicate a string and commit the transaction */ static void do_tx_strdup_commit(PMEMobjpool *pop) { TOID(char) str; TOID(wchar_t) wcs; TX_BEGIN(pop) { do_tx_strdup[counter](&str, TEST_STR_1, TYPE_COMMIT); do_tx_wcsdup[counter](&wcs, TEST_WCS_1, TYPE_WCS_COMMIT); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERT(!TOID_IS_NULL(wcs)); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT)); TOID_ASSIGN(wcs, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_COMMIT)); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERTeq(strcmp(TEST_STR_1, D_RO(str)), 0); UT_ASSERTeq(wcscmp(TEST_WCS_1, D_RO(wcs)), 0); } /* * do_tx_strdup_abort -- duplicate a string and abort the transaction */ static void do_tx_strdup_abort(PMEMobjpool *pop) { TOID(char) str; TOID(wchar_t) wcs; TX_BEGIN(pop) { do_tx_strdup[counter](&str, TEST_STR_1, TYPE_ABORT); do_tx_wcsdup[counter](&wcs, TEST_WCS_1, TYPE_WCS_ABORT); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERT(!TOID_IS_NULL(wcs)); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); TOID_ASSIGN(wcs, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT)); UT_ASSERT(TOID_IS_NULL(str)); UT_ASSERT(TOID_IS_NULL(wcs)); } /* * do_tx_strdup_null -- duplicate a NULL string to trigger tx abort */ static void do_tx_strdup_null(PMEMobjpool *pop) { TOID(char) str; TOID(wchar_t) wcs; TX_BEGIN(pop) { do_tx_strdup[counter](&str, NULL, TYPE_ABORT); do_tx_wcsdup[counter](&wcs, NULL, TYPE_WCS_ABORT); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); TOID_ASSIGN(wcs, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT)); UT_ASSERT(TOID_IS_NULL(str)); UT_ASSERT(TOID_IS_NULL(wcs)); TX_BEGIN(pop) { pmemobj_tx_xstrdup(NULL, TYPE_ABORT, POBJ_XALLOC_NO_ABORT); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_strdup(NULL, TYPE_ABORT); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_xstrdup(NULL, TYPE_ABORT, 0); } TX_ONCOMMIT { UT_ASSERTeq(errno, EINVAL); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_strdup_free_commit -- duplicate a string, free and commit the * transaction */ static void do_tx_strdup_free_commit(PMEMobjpool *pop) { TOID(char) str; TOID(wchar_t) wcs; TX_BEGIN(pop) { do_tx_strdup[counter](&str, TEST_STR_1, TYPE_FREE_COMMIT); do_tx_wcsdup[counter](&wcs, TEST_WCS_1, TYPE_WCS_FREE_COMMIT); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERT(!TOID_IS_NULL(wcs)); int ret = pmemobj_tx_free(str.oid); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_free(wcs.oid); UT_ASSERTeq(ret, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str, POBJ_FIRST_TYPE_NUM(pop, TYPE_FREE_COMMIT)); TOID_ASSIGN(wcs, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_FREE_COMMIT)); UT_ASSERT(TOID_IS_NULL(str)); UT_ASSERT(TOID_IS_NULL(wcs)); } /* * do_tx_strdup_free_abort -- duplicate a string, free and abort the * transaction */ static void do_tx_strdup_free_abort(PMEMobjpool *pop) { TOID(char) str; TOID(wchar_t) wcs; TX_BEGIN(pop) { do_tx_strdup[counter](&str, TEST_STR_1, TYPE_FREE_ABORT); do_tx_wcsdup[counter](&wcs, TEST_WCS_1, TYPE_WCS_FREE_ABORT); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERT(!TOID_IS_NULL(wcs)); int ret = pmemobj_tx_free(str.oid); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_free(wcs.oid); UT_ASSERTeq(ret, 0); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str, POBJ_FIRST_TYPE_NUM(pop, TYPE_FREE_ABORT)); TOID_ASSIGN(wcs, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_FREE_ABORT)); UT_ASSERT(TOID_IS_NULL(str)); UT_ASSERT(TOID_IS_NULL(wcs)); } /* * do_tx_strdup_commit_nested -- duplicate two string suing nested * transaction and commit the transaction */ static void do_tx_strdup_commit_nested(PMEMobjpool *pop) { TOID(char) str1; TOID(char) str2; TOID(wchar_t) wcs1; TOID(wchar_t) wcs2; TX_BEGIN(pop) { do_tx_strdup[counter](&str1, TEST_STR_1, TYPE_COMMIT_NESTED1); do_tx_wcsdup[counter](&wcs1, TEST_WCS_1, TYPE_WCS_COMMIT_NESTED1); UT_ASSERT(!TOID_IS_NULL(str1)); UT_ASSERT(!TOID_IS_NULL(wcs1)); TX_BEGIN(pop) { do_tx_strdup[counter](&str2, TEST_STR_2, TYPE_COMMIT_NESTED2); do_tx_wcsdup[counter](&wcs2, TEST_WCS_2, TYPE_WCS_COMMIT_NESTED2); UT_ASSERT(!TOID_IS_NULL(str2)); UT_ASSERT(!TOID_IS_NULL(wcs2)); } TX_ONABORT { UT_ASSERT(0); } TX_END } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str1, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_NESTED1)); TOID_ASSIGN(wcs1, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_COMMIT_NESTED1)); UT_ASSERT(!TOID_IS_NULL(str1)); UT_ASSERT(!TOID_IS_NULL(wcs1)); UT_ASSERTeq(strcmp(TEST_STR_1, D_RO(str1)), 0); UT_ASSERTeq(wcscmp(TEST_WCS_1, D_RO(wcs1)), 0); TOID_ASSIGN(str2, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_NESTED2)); TOID_ASSIGN(wcs2, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_COMMIT_NESTED2)); UT_ASSERT(!TOID_IS_NULL(str2)); UT_ASSERT(!TOID_IS_NULL(wcs2)); UT_ASSERTeq(strcmp(TEST_STR_2, D_RO(str2)), 0); UT_ASSERTeq(wcscmp(TEST_WCS_2, D_RO(wcs2)), 0); } /* * do_tx_strdup_commit_abort -- duplicate two string suing nested * transaction and abort the transaction */ static void do_tx_strdup_abort_nested(PMEMobjpool *pop) { TOID(char) str1; TOID(char) str2; TOID(wchar_t) wcs1; TOID(wchar_t) wcs2; TX_BEGIN(pop) { do_tx_strdup[counter](&str1, TEST_STR_1, TYPE_ABORT_NESTED1); do_tx_wcsdup[counter](&wcs1, TEST_WCS_1, TYPE_WCS_ABORT_NESTED1); UT_ASSERT(!TOID_IS_NULL(str1)); UT_ASSERT(!TOID_IS_NULL(wcs1)); TX_BEGIN(pop) { do_tx_strdup[counter](&str2, TEST_STR_2, TYPE_ABORT_NESTED2); do_tx_wcsdup[counter](&wcs2, TEST_WCS_2, TYPE_WCS_ABORT_NESTED2); UT_ASSERT(!TOID_IS_NULL(str2)); UT_ASSERT(!TOID_IS_NULL(wcs2)); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str1, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_NESTED1)); TOID_ASSIGN(wcs1, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT_NESTED1)); UT_ASSERT(TOID_IS_NULL(str1)); UT_ASSERT(TOID_IS_NULL(wcs1)); TOID_ASSIGN(str2, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_NESTED2)); TOID_ASSIGN(wcs2, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT_NESTED2)); UT_ASSERT(TOID_IS_NULL(str2)); UT_ASSERT(TOID_IS_NULL(wcs2)); } /* * do_tx_strdup_commit_abort -- duplicate two string suing nested * transaction and abort after the nested transaction */ static void do_tx_strdup_abort_after_nested(PMEMobjpool *pop) { TOID(char) str1; TOID(char) str2; TOID(wchar_t) wcs1; TOID(wchar_t) wcs2; TX_BEGIN(pop) { do_tx_strdup[counter](&str1, TEST_STR_1, TYPE_ABORT_AFTER_NESTED1); do_tx_wcsdup[counter](&wcs1, TEST_WCS_1, TYPE_WCS_ABORT_AFTER_NESTED1); UT_ASSERT(!TOID_IS_NULL(str1)); UT_ASSERT(!TOID_IS_NULL(wcs1)); TX_BEGIN(pop) { do_tx_strdup[counter](&str2, TEST_STR_2, TYPE_ABORT_AFTER_NESTED2); do_tx_wcsdup[counter](&wcs2, TEST_WCS_2, TYPE_WCS_ABORT_AFTER_NESTED2); UT_ASSERT(!TOID_IS_NULL(str2)); UT_ASSERT(!TOID_IS_NULL(wcs2)); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(str1, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_AFTER_NESTED1)); TOID_ASSIGN(wcs1, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT_AFTER_NESTED1)); UT_ASSERT(TOID_IS_NULL(str1)); UT_ASSERT(TOID_IS_NULL(wcs1)); TOID_ASSIGN(str2, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_AFTER_NESTED2)); TOID_ASSIGN(wcs2, POBJ_FIRST_TYPE_NUM(pop, TYPE_WCS_ABORT_AFTER_NESTED2)); UT_ASSERT(TOID_IS_NULL(str2)); UT_ASSERT(TOID_IS_NULL(wcs2)); } /* * do_tx_strdup_noflush -- allocates zeroed object */ static void do_tx_strdup_noflush(PMEMobjpool *pop) { TX_BEGIN(pop) { errno = 0; pmemobj_tx_xstrdup(TEST_STR_1, TYPE_NOFLUSH, POBJ_XALLOC_NO_FLUSH); pmemobj_tx_xwcsdup(TEST_WCS_1, TYPE_WCS_NOFLUSH, POBJ_XALLOC_NO_FLUSH); } TX_ONCOMMIT { UT_ASSERTeq(errno, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_strdup"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); for (counter = 0; counter < MAX_FUNC; counter++) { do_tx_strdup_commit(pop); do_tx_strdup_abort(pop); do_tx_strdup_null(pop); do_tx_strdup_free_commit(pop); do_tx_strdup_free_abort(pop); do_tx_strdup_commit_nested(pop); do_tx_strdup_abort_nested(pop); do_tx_strdup_abort_after_nested(pop); } do_tx_strdup_noflush(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_strdup/obj_tx_strdup.vcxproj.filters0000664000000000000000000000200114123364546023635 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c4b22285-5bef-4223-a211-3457e2bd2d62} match {78703bb4-35c9-478a-9388-0080c34ccb96} ps1 Source Files Match Files Test Scripts pmdk-1.11.1/src/test/obj_tx_strdup/TEST00000775000000000000000000000053714123364546016464 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # # src/test/obj_tx_strdup/TEST0 -- unit test for pmemobj_tx_strdup # . ../unittest/unittest.sh require_test_type medium configure_valgrind pmemcheck force-disable setup expect_normal_exit ./obj_tx_strdup$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_strdup/Makefile0000664000000000000000000000035614123364546017336 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_strdup/Makefile -- build obj_tx_strdup unit test # TARGET = obj_tx_strdup OBJS = obj_tx_strdup.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_strdup/out0.log.match0000664000000000000000000000016414123364546020360 0ustar rootrootobj_tx_strdup$(nW)TEST0: START: obj_tx_strdup $(nW)obj_tx_strdup$(nW) $(nW)testfile1 obj_tx_strdup$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_strdup/TEST0.PS10000664000000000000000000000355214123364546017063 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\obj_tx_strdup\TEST0 -- unit test for pmemobj_tx_strdup # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_tx_strdup$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_tx_strdup/pmemcheck1.log.match0000664000000000000000000000261114123364546021505 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: ./obj_tx_strdup$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 2 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*): __memcpy$(*) ==$(*)== by 0x$(*): constructor_tx_alloc (tx.c:$(*)) ==$(*)== by 0x$(*): alloc_prep_block (palloc.c:$(*)) ==$(*)== by 0x$(*): palloc_reservation_create (palloc.c:$(*)) ==$(*)== by 0x$(*): palloc_reserve (palloc.c:$(*)) ==$(*)== by 0x$(*): tx_alloc_common (tx.c:$(*)) ==$(*)== by 0x$(*): pmemobj_tx_xstrdup (tx.c:$(*)) ==$(*)== by 0x$(*): do_tx_strdup_noflush (obj_tx_strdup.c:$(*)) ==$(*)== by 0x$(*): main (obj_tx_strdup.c:$(*)) ==$(*)== Address: 0x$(*) size: 14 state: DIRTY ==$(*)== [1] at 0x$(*): __memcpy$(*) ==$(*)== by 0x$(*): constructor_tx_alloc (tx.c:$(*)) ==$(*)== by 0x$(*): alloc_prep_block (palloc.c:$(*)) ==$(*)== by 0x$(*): palloc_reservation_create (palloc.c:$(*)) ==$(*)== by 0x$(*): palloc_reserve (palloc.c:$(*)) ==$(*)== by 0x$(*): tx_alloc_common (tx.c:$(*)) ==$(*)== by 0x$(*): pmemobj_tx_xwcsdup (tx.c:$(*)) ==$(*)== by 0x$(*): do_tx_strdup_noflush (obj_tx_strdup.c:$(*)) ==$(*)== by 0x$(*): main (obj_tx_strdup.c:$(*)) ==$(*)== Address: 0x$(*) size: 56 state: DIRTY ==$(*)== Total memory not made persistent: 70 ==$(*)== ERROR SUMMARY: 2 errors pmdk-1.11.1/src/test/obj_tx_strdup/.gitignore0000664000000000000000000000001614123364546017657 0ustar rootrootobj_tx_strdup pmdk-1.11.1/src/test/obj_tx_strdup/obj_tx_strdup.vcxproj0000664000000000000000000000756514123364546022212 0ustar rootroot Debug x64 Release x64 {643B82A1-D009-46A9-92A0-2883399B05C2} Win32Proj obj_tx_strdup 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) CompileAsCpp CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_strdup/TEST10000775000000000000000000000101014123364546016450 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # # src/test/obj_tx_strdup/TEST1 -- unit test for pmemobj_tx_strdup # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type pmem # This test relies on libc debug symbols being installed for reliable # error reporting. # XXX Figure out how to detect it. configure_valgrind pmemcheck force-enable setup expect_normal_exit ./obj_tx_strdup$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_strdup/out1.log.match0000664000000000000000000000016414123364546020361 0ustar rootrootobj_tx_strdup$(nW)TEST1: START: obj_tx_strdup $(nW)obj_tx_strdup$(nW) $(nW)testfile1 obj_tx_strdup$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmemset_memset/0000775000000000000000000000000014123364546016030 5ustar rootrootpmdk-1.11.1/src/test/pmemset_memset/Makefile0000664000000000000000000000067714123364546017502 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # # src/test/pmemset_memcpy/Makefile -- build pmemset_memcpy test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/test/pmem2_memset INCS += -I$(TOP)/src/libpmem2 TARGET = pmemset_memset OBJS += pmemset_memset.o\ memset_common.o\ ut_pmemset_utils.o LIBPMEMSET=internal-debug include ../Makefile.inc CFLAGS += -I$(TOP)/src/test/pmem2_memset pmdk-1.11.1/src/test/pmemset_memset/pmemset_memset.c0000664000000000000000000000463714123364546021232 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2021, Intel Corporation */ /* * pmemset_memset.c -- test for doing a memset from libpmemset * * usage: pmemset_memset file offset length * */ #include "unittest.h" #include "file.h" #include "ut_pmemset_utils.h" #include "memset_common.h" static void do_memset_variants(int fd, char *dest, const char *file_name, size_t dest_off, size_t bytes, set_persist_fn sp, set_memset_fn sm, struct pmemset *set) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memset(fd, dest, file_name, dest_off, bytes, NULL, Flags[i], NULL, sp, sm, set); if (Flags[i] & PMEMOBJ_F_MEM_NOFLUSH) sp(set, dest, bytes); } } int main(int argc, char *argv[]) { int fd; int ret; char *dest; struct pmem2_source *pmem2_src; struct pmemset_part *part; struct pmemset_source *ssrc; struct pmemset *set; struct pmemset_config *cfg; struct pmemset_part_descriptor desc; if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_memset %s %s %s %savx %savx512f", argv[2], argv[3], thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); ret = pmem2_source_from_fd(&pmem2_src, fd); UT_ASSERTeq(ret, 0); ret = pmemset_source_from_pmem2(&ssrc, pmem2_src); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(ssrc, NULL); ret = pmemset_config_new(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); ret = pmemset_config_set_required_store_granularity(cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_new(&part, set, ssrc, 0, 4 * 1024 * 1024); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_map(&part, NULL, &desc); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTeq(part, NULL); dest = desc.addr; size_t dest_off = strtoul(argv[2], NULL, 0); size_t bytes = strtoul(argv[3], NULL, 0); do_memset_variants(fd, dest, argv[1], dest_off, bytes, pmemset_persist, pmemset_memset, set); ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_config_delete(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_delete(&ssrc); UT_PMEMSET_EXPECT_RETURN(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmemset_memset/TESTS.py0000775000000000000000000000302514123364546017307 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # from collections import namedtuple import testframework as t TC = namedtuple('TC', ['offset', 'length']) class PmemsetMemset(t.Test): test_type = t.Short filesize = 4 * t.MiB envs0 = () envs1 = () test_cases = ( TC(offset=0, length=8), TC(offset=13, length=4096) ) def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' for env in self.envs1: ctx.env[env] = '1' if ctx.wc_workaround() == 'on': ctx.env['PMEM_WC_WORKAROUND'] = '1' elif ctx.wc_workaround() == 'off': ctx.env['PMEM_WC_WORKAROUND'] = '0' for tc in self.test_cases: filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmemset_memset', filepath, tc.offset, tc.length) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST0(PmemsetMemset): pass @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST1(PmemsetMemset): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST2(PmemsetMemset): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) @t.add_params('wc_workaround', ['default']) class TEST3(PmemsetMemset): envs1 = ("PMEM_NO_MOVNT",) @t.add_params('wc_workaround', ['default']) class TEST4(PmemsetMemset): envs1 = ("PMEM_NO_MOVNT", "PMEM_NO_GENERIC_MEMCPY") pmdk-1.11.1/src/test/pmemset_memset/.gitignore0000664000000000000000000000001714123364546020016 0ustar rootrootpmemset_memset pmdk-1.11.1/src/test/pmemset_memset/pmemset_memset.vcxproj0000664000000000000000000001011014123364546022462 0ustar rootroot Debug x64 Release x64 {992E3C37-74C6-4E57-AB07-367CD4BFE834} Win32Proj pmemset_memset 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\test\pmem2_memset;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\test\pmem2_memset;%(AdditionalIncludeDirectories) {f596c36c-5c96-4f08-b420-8908af500954} {fbaefc34-d221-4203-8bf6-162de1a5be1c} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmemset_memset/pmemset_memset.vcxproj.filters0000664000000000000000000000247714123364546024152 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2d237952-c50b-4d8c-a83f-e28a96d88887} {dd5ab98c-405a-4d74-8bd8-70d914146b8d} Source Files Source Files Source Files Test Scripts Header Files Header Files pmdk-1.11.1/src/test/obj_tx_lock/0000775000000000000000000000000014123364546015301 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_lock/TEST00000775000000000000000000000070214123364546016065 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_lock/TEST0 -- unit test for pmemobj_tx_lock() # with DRD disabled # . ../unittest/unittest.sh require_test_type medium configure_valgrind drd force-disable setup expect_normal_exit ./obj_tx_lock$EXESUFFIX $DIR/testfile1 f expect_normal_exit ./obj_tx_lock$EXESUFFIX $DIR/testfile2 l n a pass pmdk-1.11.1/src/test/obj_tx_lock/Makefile0000664000000000000000000000036514123364546016745 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_lock/Makefile -- build obj_tx_locks unit test # TARGET = obj_tx_lock OBJS = obj_tx_lock.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_lock/obj_tx_lock.c0000664000000000000000000001553314123364546017751 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * obj_tx_lock.c -- unit test for pmemobj_tx_lock() */ #include "unittest.h" #include "libpmemobj.h" #include "obj.h" #define LAYOUT_NAME "obj_tx_lock" #define NUM_LOCKS 2 struct transaction_data { PMEMmutex mutexes[NUM_LOCKS]; PMEMrwlock rwlocks[NUM_LOCKS]; }; static PMEMobjpool *Pop; #define DO_LOCK(mtx, rwlock)\ pmemobj_tx_lock(TX_PARAM_MUTEX, &(mtx)[0]);\ pmemobj_tx_lock(TX_PARAM_MUTEX, &(mtx)[1]);\ pmemobj_tx_lock(TX_PARAM_RWLOCK, &(rwlock)[0]);\ pmemobj_tx_lock(TX_PARAM_RWLOCK, &(rwlock)[1]) #define IS_UNLOCKED(pop, mtx, rwlock)\ ret = 0;\ ret += pmemobj_mutex_trylock((pop), &(mtx)[0]);\ ret += pmemobj_mutex_trylock((pop), &(mtx)[1]);\ ret += pmemobj_rwlock_trywrlock((pop), &(rwlock)[0]);\ ret += pmemobj_rwlock_trywrlock((pop), &(rwlock)[1]);\ UT_ASSERTeq(ret, 0);\ pmemobj_mutex_unlock((pop), &(mtx)[0]);\ pmemobj_mutex_unlock((pop), &(mtx)[1]);\ pmemobj_rwlock_unlock((pop), &(rwlock)[0]);\ pmemobj_rwlock_unlock((pop), &(rwlock)[1]) #define IS_LOCKED(pop, mtx, rwlock)\ ret = pmemobj_mutex_trylock((pop), &(mtx)[0]);\ UT_ASSERT(ret != 0);\ ret = pmemobj_mutex_trylock((pop), &(mtx)[1]);\ UT_ASSERT(ret != 0);\ ret = pmemobj_rwlock_trywrlock((pop), &(rwlock)[0]);\ UT_ASSERT(ret != 0);\ ret = pmemobj_rwlock_trywrlock((pop), &(rwlock)[1]);\ UT_ASSERT(ret != 0) /* * do_tx_add_locks -- (internal) transaction where locks are added after * transaction begins */ static void * do_tx_add_locks(struct transaction_data *data) { int ret; IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); TX_BEGIN(Pop) { DO_LOCK(data->mutexes, data->rwlocks); IS_LOCKED(Pop, data->mutexes, data->rwlocks); } TX_ONABORT { /* not called */ UT_ASSERT(0); } TX_END IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); return NULL; } /* * do_tx_add_locks_nested -- (internal) transaction where locks * are added after nested transaction begins */ static void * do_tx_add_locks_nested(struct transaction_data *data) { int ret; TX_BEGIN(Pop) { IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); TX_BEGIN(Pop) { DO_LOCK(data->mutexes, data->rwlocks); IS_LOCKED(Pop, data->mutexes, data->rwlocks); } TX_END IS_LOCKED(Pop, data->mutexes, data->rwlocks); } TX_ONABORT { UT_ASSERT(0); } TX_END IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); return NULL; } /* * do_tx_add_locks_nested_all -- (internal) transaction where all locks * are added in both transactions after transaction begins */ static void * do_tx_add_locks_nested_all(struct transaction_data *data) { int ret; TX_BEGIN(Pop) { IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); DO_LOCK(data->mutexes, data->rwlocks); IS_LOCKED(Pop, data->mutexes, data->rwlocks); TX_BEGIN(Pop) { IS_LOCKED(Pop, data->mutexes, data->rwlocks); DO_LOCK(data->mutexes, data->rwlocks); IS_LOCKED(Pop, data->mutexes, data->rwlocks); } TX_END IS_LOCKED(Pop, data->mutexes, data->rwlocks); } TX_ONABORT { UT_ASSERT(0); } TX_END IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); return NULL; } /* * do_tx_add_taken_lock -- (internal) verify that failed tx_lock doesn't add * the lock to transaction */ static void * do_tx_add_taken_lock(struct transaction_data *data) { /* wrlocks on Windows don't detect self-deadlocks */ #ifdef _WIN32 (void) data; #else UT_ASSERTeq(pmemobj_rwlock_wrlock(Pop, &data->rwlocks[0]), 0); TX_BEGIN(Pop) { UT_ASSERTne(pmemobj_tx_lock(TX_PARAM_RWLOCK, &data->rwlocks[0]), 0); } TX_END UT_ASSERTne(pmemobj_rwlock_trywrlock(Pop, &data->rwlocks[0]), 0); UT_ASSERTeq(pmemobj_rwlock_unlock(Pop, &data->rwlocks[0]), 0); #endif return NULL; } /* * do_tx_lock_fail -- call pmemobj_tx_lock with POBJ_TX_NO_ABORT flag * and taken lock */ static void * do_tx_lock_fail(struct transaction_data *data) { /* wrlocks on Windows don't detect self-deadlocks */ #ifdef _WIN32 (void) data; #else UT_ASSERTeq(pmemobj_rwlock_wrlock(Pop, &data->rwlocks[0]), 0); int ret = 0; /* return errno and abort transaction */ TX_BEGIN(Pop) { pmemobj_tx_xlock(TX_PARAM_RWLOCK, &data->rwlocks[0], 0); } TX_ONABORT { UT_ASSERTne(errno, 0); UT_ASSERTeq(pmemobj_rwlock_unlock(Pop, &data->rwlocks[0]), 0); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END /* return ret without abort transaction */ UT_ASSERTeq(pmemobj_rwlock_wrlock(Pop, &data->rwlocks[0]), 0); TX_BEGIN(Pop) { ret = pmemobj_tx_xlock(TX_PARAM_RWLOCK, &data->rwlocks[0], POBJ_XLOCK_NO_ABORT); } TX_ONCOMMIT { UT_ASSERTne(ret, 0); UT_ASSERTeq(pmemobj_rwlock_unlock(Pop, &data->rwlocks[0]), 0); } TX_ONABORT { UT_ASSERT(0); } TX_END /* return ret without abort transaction */ UT_ASSERTeq(pmemobj_rwlock_wrlock(Pop, &data->rwlocks[0]), 0); TX_BEGIN(Pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); ret = pmemobj_tx_lock(TX_PARAM_RWLOCK, &data->rwlocks[0]); } TX_ONCOMMIT { UT_ASSERTne(ret, 0); UT_ASSERTeq(pmemobj_rwlock_unlock(Pop, &data->rwlocks[0]), 0); } TX_ONABORT { UT_ASSERT(0); } TX_END /* return ret without abort transaction */ UT_ASSERTeq(pmemobj_rwlock_wrlock(Pop, &data->rwlocks[0]), 0); TX_BEGIN(Pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); ret = pmemobj_tx_xlock(TX_PARAM_RWLOCK, &data->rwlocks[0], 0); } TX_ONCOMMIT { UT_ASSERTne(ret, 0); UT_ASSERTeq(pmemobj_rwlock_unlock(Pop, &data->rwlocks[0]), 0); } TX_ONABORT { UT_ASSERT(0); } TX_END #endif return NULL; } static void do_fault_injection(struct transaction_data *data) { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "add_to_tx_and_lock"); int ret; IS_UNLOCKED(Pop, data->mutexes, data->rwlocks); TX_BEGIN(Pop) { int err = pmemobj_tx_lock(TX_PARAM_MUTEX, &data->mutexes[0]); if (err) pmemobj_tx_abort(err); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { UT_ASSERTeq(errno, ENOMEM); } TX_END } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_lock"); if (argc < 3) UT_FATAL("usage: %s [l|n|a|t|f|w]", argv[0]); if ((Pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); PMEMoid root = pmemobj_root(Pop, sizeof(struct transaction_data)); struct transaction_data *test_obj = (struct transaction_data *)pmemobj_direct(root); /* go through all arguments one by one */ for (int arg = 2; arg < argc; arg++) { /* Scan the character of each argument. */ if (strchr("lnatfw", argv[arg][0]) == NULL || argv[arg][1] != '\0') UT_FATAL("op must be l or n or a or t or f or w"); switch (argv[arg][0]) { case 'l': do_tx_add_locks(test_obj); break; case 'n': do_tx_add_locks_nested(test_obj); break; case 'a': do_tx_add_locks_nested_all(test_obj); break; case 't': do_tx_add_taken_lock(test_obj); break; case 'f': do_fault_injection(test_obj); break; case 'w': do_tx_lock_fail(test_obj); break; } } pmemobj_close(Pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_lock/TEST0.PS10000664000000000000000000000354714123364546016476 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_lock/TEST0 -- unit test for pmemobj_tx_lock() # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_tx_lock$Env:EXESUFFIX $DIR\testfile1 l n a t pass pmdk-1.11.1/src/test/obj_tx_lock/.gitignore0000664000000000000000000000001414123364546017264 0ustar rootrootobj_tx_lock pmdk-1.11.1/src/test/obj_tx_lock/obj_tx_lock.vcxproj0000664000000000000000000000764314123364546021225 0ustar rootroot Debug x64 Release x64 {D88187D2-1977-4C5F-B0CD-83C69BD6C1BC} Win32Proj obj_tx_lock 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)libpmemobj;$(IncludePath) $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled true {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_lock/obj_tx_lock.vcxproj.filters0000664000000000000000000000134114123364546022661 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {d0083c2f-ab69-4381-8e88-7bc309910a32} Source Files Test Scripts pmdk-1.11.1/src/test/obj_tx_lock/TEST10000775000000000000000000000066514123364546016076 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_tx_lock/TEST1 -- unit test for pmemobj_tx_lock() with DRD # and Helgrind disabled # . ../unittest/unittest.sh require_test_type medium configure_valgrind drd force-disable configure_valgrind helgrind force-disable setup expect_normal_exit ./obj_tx_lock$EXESUFFIX $DIR/testfile1 t w pass pmdk-1.11.1/src/test/blk_rw/0000775000000000000000000000000014123364546014264 5ustar rootrootpmdk-1.11.1/src/test/blk_rw/out18.log.match0000664000000000000000000000052114123364546017040 0ustar rootrootblk_rw$(nW)TEST18: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 o w:0 r:4 r:3 r:2 r:1 r:0 w:0 r:0 512 block size 512 usable blocks 2080329 write lba 0: {1} read lba 4: {5} read lba 3: {4} read lba 2: {3} read lba 1: {2} read lba 0: {1} write lba 0: {2} read lba 0: {2} blk_rw$(nW)TEST18: DONE pmdk-1.11.1/src/test/blk_rw/TEST180000775000000000000000000000132314123364546015141 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST18 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST4 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # write re-use test case truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:0 w:1 w:2 w:3 w:4 r:4 r:3 r:2 r:1 r:0 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 o\ w:0 r:4 r:3 r:2 r:1 r:0 w:0 r:0 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST230000775000000000000000000000115414123364546015137 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST23 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST9 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR/testset1 1G:$DIR/testfile1:x 1G:$DIR/testfile2:x expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset1 c\ w:-1 r:-1 z:-1 e:-1 check pass pmdk-1.11.1/src/test/blk_rw/TEST220000775000000000000000000000123114123364546015132 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST22 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST8 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR/testset1 1G:$DIR/testfile1:x 1G:$DIR/testfile2:x expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset1 c\ w:0 w:1 r:1 r:0\ w:4161096 r:4161096 check_pool $DIR/testfile2 check pass pmdk-1.11.1/src/test/blk_rw/out15.log.match0000664000000000000000000000057214123364546017043 0ustar rootrootblk_rw$(nW)TEST15: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c r:0 r:1 r:4161480 r:2134997087 r:2134997088 z:0 z:4161480 512 block size 512 usable blocks 2134997088 read lba 0: {0} read lba 1: {0} read lba 4161480: {0} read lba 2134997087: {0} read lba 2134997088: Invalid argument set_zero lba 0 set_zero lba 4161480 blk_rw$(nW)TEST15: DONE pmdk-1.11.1/src/test/blk_rw/TEST1.PS10000664000000000000000000000445314123364546015457 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST1 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm setup # multi-arena case create_holey_file 1026G $DIR\testfile1 # # All reads to an unwritten block pool should return zeros. # Block 2134997326 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` r:0 r:1 r:4161480 r:2134997325 r:2134997326 z:0 z:4161480 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST5.PS10000664000000000000000000000434014123364546015456 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST5 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results create_holey_file 1G $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` w:100 w:200 w:300 w:400 ` r:100 r:200 r:300 r:400 ` w:100 z:200 w:300 z:400 ` r:100 r:200 r:300 r:400 ` e:100 w:200 e:300 w:400 ` r:100 r:200 r:300 r:400 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST160000775000000000000000000000163014123364546015140 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST16 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST2 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm # this test creates huge file configure_valgrind force-disable setup # multi-arena case truncate -s 1026G $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 268696557 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 4096 $DIR/testfile1 c\ r:0 r:1 r:4161480 r:268696520 r:268696521 z:0 z:4161480 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/blk_rw.vcxproj0000664000000000000000000000740214123364546017164 0ustar rootroot Debug x64 Release x64 {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {6851356E-A5D9-46A6-8262-A7E208729F18} Win32Proj blk_rw 10.0.17134.0 Application true v140 Application false v140 true pmdk-1.11.1/src/test/blk_rw/blk_rw.vcxproj.filters0000664000000000000000000000444714123364546020641 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {38c181e1-1287-4473-b7f0-49c90a982765} match {6e05b2b1-1812-4c4e-9d1c-419880e4e751} ps1 Source Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts pmdk-1.11.1/src/test/blk_rw/out16.log.match0000664000000000000000000000057014123364546017042 0ustar rootrootblk_rw$(nW)TEST16: START: blk_rw $(nW)blk_rw$(nW) 4096 $(nW)testfile1 c r:0 r:1 r:4161480 r:268696520 r:268696521 z:0 z:4161480 4096 block size 4096 usable blocks 268696521 read lba 0: {0} read lba 1: {0} read lba 4161480: {0} read lba 268696520: {0} read lba 268696521: Invalid argument set_zero lba 0 set_zero lba 4161480 blk_rw$(nW)TEST16: DONE pmdk-1.11.1/src/test/blk_rw/TEST170000775000000000000000000000115314123364546015141 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST17 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST3 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena write case truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:0 r:1 r:0 w:1 r:0 r:1 r:2 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST30000775000000000000000000000101314123364546015047 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST3 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena write case truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:0 r:1 r:0 w:1 r:0 r:1 r:2 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST90000775000000000000000000000101414123364546015056 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_rw/TEST9 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR/testset1 1G:$DIR/testfile1:x 1G:$DIR/testfile2:x expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset1 c\ w:-1 r:-1 z:-1 e:-1 check pass pmdk-1.11.1/src/test/blk_rw/out23.log.match0000664000000000000000000000045014123364546017035 0ustar rootrootblk_rw$(nW)TEST23: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:-1 r:-1 z:-1 e:-1 512 block size 512 usable blocks 4161097 write lba -1: Invalid argument read lba -1: Invalid argument set_zero lba -1: Invalid argument set_error lba -1: Invalid argument blk_rw$(nW)TEST23: DONE pmdk-1.11.1/src/test/blk_rw/TEST120000775000000000000000000000130414123364546015132 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_rw/TEST12 -- unit test for pmemblk_read/write/set_zero/set_error # # Same as TEST10, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected failure, as 2M alignment is not supported # if NODHRS option is not specified. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_abnormal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 pass pmdk-1.11.1/src/test/blk_rw/blk_rw.c0000664000000000000000000000532514123364546015715 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * blk_rw.c -- unit test for pmemblk_read/write/set_zero/set_error * * usage: blk_rw bsize file func operation:lba... * * func is 'c' or 'o' (create or open) * operations are 'r' or 'w' or 'z' or 'e' * */ #include "unittest.h" static size_t Bsize; /* * construct -- build a buffer for writing */ static void construct(unsigned char *buf) { static int ord = 1; for (int i = 0; i < Bsize; i++) buf[i] = ord; ord++; if (ord > 255) ord = 1; } /* * ident -- identify what a buffer holds */ static char * ident(unsigned char *buf) { static char descr[100]; unsigned val = *buf; for (int i = 1; i < Bsize; i++) if (buf[i] != val) { sprintf(descr, "{%u} TORN at byte %d", val, i); return descr; } sprintf(descr, "{%u}", val); return descr; } int main(int argc, char *argv[]) { START(argc, argv, "blk_rw"); if (argc < 5) UT_FATAL("usage: %s bsize file func op:lba...", argv[0]); Bsize = strtoul(argv[1], NULL, 0); const char *path = argv[2]; PMEMblkpool *handle; switch (*argv[3]) { case 'c': handle = pmemblk_create(path, Bsize, 0, S_IWUSR | S_IRUSR); if (handle == NULL) UT_FATAL("!%s: pmemblk_create", path); break; case 'o': handle = pmemblk_open(path, Bsize); if (handle == NULL) UT_FATAL("!%s: pmemblk_open", path); break; } UT_OUT("%s block size %zu usable blocks %zu", argv[1], Bsize, pmemblk_nblock(handle)); unsigned char *buf = MALLOC(Bsize); if (buf == NULL) UT_FATAL("cannot allocate buf"); /* map each file argument with the given map type */ for (int arg = 4; arg < argc; arg++) { if (strchr("rwze", argv[arg][0]) == NULL || argv[arg][1] != ':') UT_FATAL("op must be r: or w: or z: or e:"); os_off_t lba = strtol(&argv[arg][2], NULL, 0); switch (argv[arg][0]) { case 'r': if (pmemblk_read(handle, buf, lba) < 0) UT_OUT("!read lba %jd", lba); else UT_OUT("read lba %jd: %s", lba, ident(buf)); break; case 'w': construct(buf); if (pmemblk_write(handle, buf, lba) < 0) UT_OUT("!write lba %jd", lba); else UT_OUT("write lba %jd: %s", lba, ident(buf)); break; case 'z': if (pmemblk_set_zero(handle, lba) < 0) UT_OUT("!set_zero lba %jd", lba); else UT_OUT("set_zero lba %jd", lba); break; case 'e': if (pmemblk_set_error(handle, lba) < 0) UT_OUT("!set_error lba %jd", lba); else UT_OUT("set_error lba %jd", lba); break; } } FREE(buf); pmemblk_close(handle); int result = pmemblk_check(path, Bsize); if (result < 0) UT_OUT("!%s: pmemblk_check", path); else if (result == 0) UT_OUT("%s: pmemblk_check: not consistent", path); DONE(NULL); } pmdk-1.11.1/src/test/blk_rw/TEST8w.PS10000664000000000000000000000447214123364546015656 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST8 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR\testset1 1G:$DIR\testfile1:x 1G:$DIR\testfile2:x # # XXX: This test would fail with STATUS_CONFLICTING_ADDRESSES, because # while mapping multiple files to a contiguous virtual range we don't # retry if we the chosen range is already reserved by someone else. # expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testset1 c ` w:0 w:1 r:1 r:0 ` w:4161325 r:4161325 check_pool $DIR\testfile2 check pass pmdk-1.11.1/src/test/blk_rw/TEST130000775000000000000000000000126514123364546015141 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_rw/TEST13 -- unit test for pmemblk_read/write/set_zero/set_error # # Same as TEST10, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected success, as pool is created with SINGLEHDR option. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} \ O SINGLEHDR expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 pass pmdk-1.11.1/src/test/blk_rw/TEST200000775000000000000000000000131414123364546015132 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST20 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST6 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ e:1 r:1\ e:2 w:2 r:2\ z:3 e:3 r:3\ e:4 z:4 r:4\ w:5 e:5 z:5 r:5\ w:6 z:6 e:6 r:6 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST00000775000000000000000000000453014123364546015053 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_rw/TEST0 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena and minimum pmemblk pool file case MIN_POOL_SIZE=$((16*1024*1024 + 64*1024)) truncate -s $MIN_POOL_SIZE $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 32313 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/Makefile0000664000000000000000000000032214123364546015721 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/Makefile -- build blk_rw unit test # TARGET = blk_rw OBJS = blk_rw.o LIBPMEMBLK=y include ../Makefile.inc pmdk-1.11.1/src/test/blk_rw/TEST3.PS10000664000000000000000000000407414123364546015460 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST3 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena write case create_holey_file 1G $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` w:0 r:1 r:0 w:1 r:0 r:1 r:2 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST2.PS10000664000000000000000000000445114123364546015456 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST2 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm setup # multi-arena case create_holey_file 1026G $DIR\testfile1 # # All reads to an unwritten block pool should return zeros. # Block 268696551 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 4096 $DIR\testfile1 c ` r:0 r:1 r:4161480 r:268696550 r:268696551 z:0 z:4161480 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST50000775000000000000000000000125214123364546015056 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST5 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:100 w:200 w:300 w:400\ r:100 r:200 r:300 r:400\ w:100 z:200 w:300 z:400\ r:100 r:200 r:300 r:400\ e:100 w:200 e:300 w:400\ r:100 r:200 r:300 r:400 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out7.log.match0000664000000000000000000000113414123364546016757 0ustar rootrootblk_rw$(nW)TEST7: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c e:1 r:1 e:2 w:2 r:2 z:3 e:3 r:3 e:4 z:4 r:4 w:5 e:5 z:5 r:5 w:6 z:6 e:6 r:6 512 block size 512 usable blocks 259784 set_error lba 1 read lba 1: Input/output error set_error lba 2 write lba 2: {1} read lba 2: {1} set_zero lba 3 set_error lba 3 read lba 3: Input/output error set_error lba 4 set_zero lba 4 read lba 4: {0} write lba 5: {2} set_error lba 5 set_zero lba 5 read lba 5: {0} write lba 6: {3} set_zero lba 6 set_error lba 6 read lba 6: Input/output error blk_rw$(nW)TEST7: DONE pmdk-1.11.1/src/test/blk_rw/TEST6.PS10000664000000000000000000000424214123364546015460 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST6 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results create_holey_file 1G $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` e:1 r:1 ` e:2 w:2 r:2 ` z:3 e:3 r:3 ` e:4 z:4 r:4 ` w:5 e:5 z:5 r:5 ` w:6 z:6 e:6 r:6 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST40000775000000000000000000000116314123364546015056 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST4 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh exclude_ppc64 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # write re-use test case truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:0 w:1 w:2 w:3 w:4 r:4 r:3 r:2 r:1 r:0 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 o\ w:0 r:4 r:3 r:2 r:1 r:0 w:0 r:0 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST70000775000000000000000000000117314123364546015062 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_rw/TEST7 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh # long test, run only on pmem exclude_ppc64 require_fs_type pmem require_test_type long configure_valgrind pmemcheck force-enable setup # mix writes with set_zero and set_error and check results truncate -s 128M $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ e:1 r:1\ e:2 w:2 r:2\ z:3 e:3 r:3\ e:4 z:4 r:4\ w:5 e:5 z:5 r:5\ w:6 z:6 e:6 r:6 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out0.log.match0000664000000000000000000000050714123364546016753 0ustar rootrootblk_rw$(nW)TEST0: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 512 block size 512 usable blocks 32313 read lba 0: {0} read lba 1: {0} read lba 32201: {0} read lba 32313: Invalid argument set_zero lba 0 set_zero lba 1 read lba 0: {0} blk_rw$(nW)TEST0: DONE pmdk-1.11.1/src/test/blk_rw/TEST210000775000000000000000000000133314123364546015134 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST21 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST7 for ppc64le platform. # . ../unittest/unittest.sh # long test, run only on pmem require_ppc64 require_fs_type pmem require_test_type long configure_valgrind pmemcheck force-enable setup # mix writes with set_zero and set_error and check results truncate -s 128M $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ e:1 r:1\ e:2 w:2 r:2\ z:3 e:3 r:3\ e:4 z:4 r:4\ w:5 e:5 z:5 r:5\ w:6 z:6 e:6 r:6 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out9.log.match0000664000000000000000000000044614123364546016766 0ustar rootrootblk_rw$(nW)TEST9: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:-1 r:-1 z:-1 e:-1 512 block size 512 usable blocks 4161454 write lba -1: Invalid argument read lba -1: Invalid argument set_zero lba -1: Invalid argument set_error lba -1: Invalid argument blk_rw$(nW)TEST9: DONE pmdk-1.11.1/src/test/blk_rw/TEST9w.PS10000664000000000000000000000441414123364546015653 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST9 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR\testset1 1G:$DIR\testfile1:x 1G:$DIR\testfile2:x # # XXX: This test would fail with STATUS_CONFLICTING_ADDRESSES, because # while mapping multiple files to a contiguous virtual range we don't # retry if we the chosen range is already reserved by someone else. # expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testset1 c ` w:-1 r:-1 z:-1 e:-1 check pass pmdk-1.11.1/src/test/blk_rw/TEST0.PS10000664000000000000000000000457614123364546015464 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST0 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena and minimum pmemblk pool file case # MIN_POOL_SIZE = 16MB + 64KB $MIN_POOL_SIZE = ((16*1024*1024 + 64*1024).ToString() + "b") create_holey_file $MIN_POOL_SIZE $DIR\testfile1 # # All reads to an unwritten block pool should return zeros. # Block 32313 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out14.log.match0000664000000000000000000000051114123364546017033 0ustar rootrootblk_rw$(nW)TEST14: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 512 block size 512 usable blocks 32202 read lba 0: {0} read lba 1: {0} read lba 32201: {0} read lba 32313: Invalid argument set_zero lba 0 set_zero lba 1 read lba 0: {0} blk_rw$(nW)TEST14: DONE pmdk-1.11.1/src/test/blk_rw/out8w.log.match0000664000000000000000000000046614123364546017156 0ustar rootrootblk_rw$(nW)TEST8w: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:0 w:1 r:1 r:0 w:4161325 r:4161325 512 block size 512 usable blocks 4161335 write lba 0: {1} write lba 1: {2} read lba 1: {2} read lba 0: {1} write lba 4161325: {3} read lba 4161325: {3} blk_rw$(nW)TEST8w: DONE pmdk-1.11.1/src/test/blk_rw/out17.log.match0000664000000000000000000000047014123364546017042 0ustar rootrootblk_rw$(nW)TEST17: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c w:0 r:1 r:0 w:1 r:0 r:1 r:2 512 block size 512 usable blocks 2080329 write lba 0: {1} read lba 1: {0} read lba 0: {1} write lba 1: {2} read lba 0: {1} read lba 1: {2} read lba 2: {0} blk_rw$(nW)TEST17: DONE pmdk-1.11.1/src/test/blk_rw/TEST190000775000000000000000000000141214123364546015141 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST19 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST5 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ w:100 w:200 w:300 w:400\ r:100 r:200 r:300 r:400\ w:100 z:200 w:300 z:400\ r:100 r:200 r:300 r:400\ e:100 w:200 e:300 w:400\ r:100 r:200 r:300 r:400 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/.gitignore0000664000000000000000000000000714123364546016251 0ustar rootrootblk_rw pmdk-1.11.1/src/test/blk_rw/README0000664000000000000000000000134214123364546015144 0ustar rootrootPersistent Memory Development Kit This is src/test/blk_rw/README. This directory contains a unit test for pmemblk_read/write/set_zero/set_error. The program in blk_rw.c takes a block size, file and a list of operation:LBA pairs. For example: ./blk_rw 4096 file1 r:0 w:5 z:9 e:100 this will call pmemblk_open() on file1 and then pmemblk_read() for LBA 0, pmemblk_write() for LBA 5, pmemblk_set_zero() for LBA 9, and pmem_set_error() for LAB 100. Each block written is filled up with the ordinal number of the write operation (a block full of 8-bit 1s, then a block filled with 8-bit 2s, etc.). When a block is read, the number it was filled with is reported (and the program verifies the entire block is filled with that number). pmdk-1.11.1/src/test/blk_rw/out20.log.match0000664000000000000000000000113714123364546017035 0ustar rootrootblk_rw$(nW)TEST20: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c e:1 r:1 e:2 w:2 r:2 z:3 e:3 r:3 e:4 z:4 r:4 w:5 e:5 z:5 r:5 w:6 z:6 e:6 r:6 512 block size 512 usable blocks 2080329 set_error lba 1 read lba 1: Input/output error set_error lba 2 write lba 2: {1} read lba 2: {1} set_zero lba 3 set_error lba 3 read lba 3: Input/output error set_error lba 4 set_zero lba 4 read lba 4: {0} write lba 5: {2} set_error lba 5 set_zero lba 5 read lba 5: {0} write lba 6: {3} set_zero lba 6 set_error lba 6 read lba 6: Input/output error blk_rw$(nW)TEST20: DONE pmdk-1.11.1/src/test/blk_rw/TEST150000775000000000000000000000163214123364546015141 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright 2019, IBM Corporation # # src/test/blk_rw/TEST15 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST1 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm # this test creates huge file configure_valgrind force-disable setup # multi-arena case truncate -s 1026G $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 2134997374 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ r:0 r:1 r:4161480 r:2134997087 r:2134997088 z:0 z:4161480 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST140000775000000000000000000000466514123364546015151 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # Copyright 2019, IBM Corporation # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/blk_rw/TEST14 -- unit test for pmemblk_read/write/set_zero/set_error # # This test is equivalent of TEST0 for ppc64le platform. # . ../unittest/unittest.sh require_test_type medium require_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # single arena and minimum pmemblk pool file case MIN_POOL_SIZE=$((16*1024*1024 + 128*1024)) truncate -s $MIN_POOL_SIZE $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 32313 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST60000775000000000000000000000115414123364546015060 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST6 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # mix writes with set_zero and set_error and check results truncate -s 1G $DIR/testfile1 expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ e:1 r:1\ e:2 w:2 r:2\ z:3 e:3 r:3\ e:4 z:4 r:4\ w:5 e:5 z:5 r:5\ w:6 z:6 e:6 r:6 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST10000775000000000000000000000147214123364546015056 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST1 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm # this test creates huge file configure_valgrind force-disable setup # multi-arena case truncate -s 1026G $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 2134997374 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testfile1 c\ r:0 r:1 r:4161480 r:2134997325 r:2134997326 z:0 z:4161480 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/TEST4.PS10000664000000000000000000000426414123364546015462 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\blk_rw\TEST4 -- unit test for pmemblk_read\write\set_zero\set_error # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup # write re-use test case create_holey_file 1G $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 c ` w:0 w:1 w:2 w:3 w:4 r:4 r:3 r:2 r:1 r:0 expect_normal_exit $Env:EXE_DIR\blk_rw$Env:EXESUFFIX 512 $DIR\testfile1 o ` w:0 r:4 r:3 r:2 r:1 r:0 w:0 r:0 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out6.log.match0000664000000000000000000000113514123364546016757 0ustar rootrootblk_rw$(nW)TEST6: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c e:1 r:1 e:2 w:2 r:2 z:3 e:3 r:3 e:4 z:4 r:4 w:5 e:5 z:5 r:5 w:6 z:6 e:6 r:6 512 block size 512 usable blocks 2080567 set_error lba 1 read lba 1: Input/output error set_error lba 2 write lba 2: {1} read lba 2: {1} set_zero lba 3 set_error lba 3 read lba 3: Input/output error set_error lba 4 set_zero lba 4 read lba 4: {0} write lba 5: {2} set_error lba 5 set_zero lba 5 read lba 5: {0} write lba 6: {3} set_zero lba 6 set_error lba 6 read lba 6: Input/output error blk_rw$(nW)TEST6: DONE pmdk-1.11.1/src/test/blk_rw/out9w.log.match0000664000000000000000000000045014123364546017150 0ustar rootrootblk_rw$(nW)TEST9w: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:-1 r:-1 z:-1 e:-1 512 block size 512 usable blocks 4161335 write lba -1: Invalid argument read lba -1: Invalid argument set_zero lba -1: Invalid argument set_error lba -1: Invalid argument blk_rw$(nW)TEST9w: DONE pmdk-1.11.1/src/test/blk_rw/TEST80000775000000000000000000000107114123364546015060 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_rw/TEST8 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem setup require_free_space 2G create_poolset $DIR/testset1 1G:$DIR/testfile1:x 1G:$DIR/testfile2:x expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset1 c\ w:0 w:1 r:1 r:0\ w:4161445 r:4161445 check_pool $DIR/testfile2 check pass pmdk-1.11.1/src/test/blk_rw/out22.log.match0000664000000000000000000000046614123364546017043 0ustar rootrootblk_rw$(nW)TEST22: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:0 w:1 r:1 r:0 w:4161096 r:4161096 512 block size 512 usable blocks 4161097 write lba 0: {1} write lba 1: {2} read lba 1: {2} read lba 0: {1} write lba 4161096: {3} read lba 4161096: {3} blk_rw$(nW)TEST22: DONE pmdk-1.11.1/src/test/blk_rw/out1.log.match0000664000000000000000000000057014123364546016754 0ustar rootrootblk_rw$(nW)TEST1: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c r:0 r:1 r:4161480 r:2134997325 r:2134997326 z:0 z:4161480 512 block size 512 usable blocks 2134997326 read lba 0: {0} read lba 1: {0} read lba 4161480: {0} read lba 2134997325: {0} read lba 2134997326: Invalid argument set_zero lba 0 set_zero lba 4161480 blk_rw$(nW)TEST1: DONE pmdk-1.11.1/src/test/blk_rw/TEST100000775000000000000000000000076214123364546015137 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/blk_rw/TEST10 -- unit test for pmemblk_read/write/set_zero/set_error # # Same as TEST0, but run on a single Device DAX device. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_devices 1 setup dax_device_zero expect_normal_exit ./blk_rw$EXESUFFIX 512 $DEVICE_DAX_PATH c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 check_pool $DEVICE_DAX_PATH pass pmdk-1.11.1/src/test/blk_rw/TEST20000775000000000000000000000147014123364546015055 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2019, Intel Corporation # # src/test/blk_rw/TEST2 -- unit test for pmemblk_read/write/set_zero/set_error # . ../unittest/unittest.sh require_test_type medium exclude_ppc64 # doesn't make sense to run in local directory require_fs_type pmem non-pmem require_unlimited_vm # this test creates huge file configure_valgrind force-disable setup # multi-arena case truncate -s 1026G $DIR/testfile1 # # All reads to an unwritten block pool should return zeros. # Block 268696557 is out of range and should return EINVAL. # Attempts to zero uninitialized blocks are nops (should succeed). # expect_normal_exit ./blk_rw$EXESUFFIX 4096 $DIR/testfile1 c\ r:0 r:1 r:4161480 r:268696550 r:268696551 z:0 z:4161480 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/blk_rw/out5.log.match0000664000000000000000000000151114123364546016754 0ustar rootrootblk_rw$(nW)TEST5: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c w:100 w:200 w:300 w:400 r:100 r:200 r:300 r:400 w:100 z:200 w:300 z:400 r:100 r:200 r:300 r:400 e:100 w:200 e:300 w:400 r:100 r:200 r:300 r:400 512 block size 512 usable blocks 2080567 write lba 100: {1} write lba 200: {2} write lba 300: {3} write lba 400: {4} read lba 100: {1} read lba 200: {2} read lba 300: {3} read lba 400: {4} write lba 100: {5} set_zero lba 200 write lba 300: {6} set_zero lba 400 read lba 100: {5} read lba 200: {0} read lba 300: {6} read lba 400: {0} set_error lba 100 write lba 200: {7} set_error lba 300 write lba 400: {8} read lba 100: Input/output error read lba 200: {7} read lba 300: Input/output error read lba 400: {8} blk_rw$(nW)TEST5: DONE pmdk-1.11.1/src/test/blk_rw/out3.log.match0000664000000000000000000000046614123364546016762 0ustar rootrootblk_rw$(nW)TEST3: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c w:0 r:1 r:0 w:1 r:0 r:1 r:2 512 block size 512 usable blocks 2080567 write lba 0: {1} read lba 1: {0} read lba 0: {1} write lba 1: {2} read lba 0: {1} read lba 1: {2} read lba 2: {0} blk_rw$(nW)TEST3: DONE pmdk-1.11.1/src/test/blk_rw/out4.log.match0000664000000000000000000000051714123364546016760 0ustar rootrootblk_rw$(nW)TEST4: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 o w:0 r:4 r:3 r:2 r:1 r:0 w:0 r:0 512 block size 512 usable blocks 2080567 write lba 0: {1} read lba 4: {5} read lba 3: {4} read lba 2: {3} read lba 1: {2} read lba 0: {1} write lba 0: {2} read lba 0: {2} blk_rw$(nW)TEST4: DONE pmdk-1.11.1/src/test/blk_rw/out8.log.match0000664000000000000000000000046414123364546016765 0ustar rootrootblk_rw$(nW)TEST8: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testset1 c w:0 w:1 r:1 r:0 w:4161445 r:4161445 512 block size 512 usable blocks 4161454 write lba 0: {1} write lba 1: {2} read lba 1: {2} read lba 0: {1} write lba 4161445: {3} read lba 4161445: {3} blk_rw$(nW)TEST8: DONE pmdk-1.11.1/src/test/blk_rw/out2.log.match0000664000000000000000000000056614123364546016762 0ustar rootrootblk_rw$(nW)TEST2: START: blk_rw $(nW)blk_rw$(nW) 4096 $(nW)testfile1 c r:0 r:1 r:4161480 r:268696550 r:268696551 z:0 z:4161480 4096 block size 4096 usable blocks 268696551 read lba 0: {0} read lba 1: {0} read lba 4161480: {0} read lba 268696550: {0} read lba 268696551: Invalid argument set_zero lba 0 set_zero lba 4161480 blk_rw$(nW)TEST2: DONE pmdk-1.11.1/src/test/blk_rw/out19.log.match0000664000000000000000000000151314123364546017043 0ustar rootrootblk_rw$(nW)TEST19: START: blk_rw $(nW)blk_rw$(nW) 512 $(nW)testfile1 c w:100 w:200 w:300 w:400 r:100 r:200 r:300 r:400 w:100 z:200 w:300 z:400 r:100 r:200 r:300 r:400 e:100 w:200 e:300 w:400 r:100 r:200 r:300 r:400 512 block size 512 usable blocks 2080329 write lba 100: {1} write lba 200: {2} write lba 300: {3} write lba 400: {4} read lba 100: {1} read lba 200: {2} read lba 300: {3} read lba 400: {4} write lba 100: {5} set_zero lba 200 write lba 300: {6} set_zero lba 400 read lba 100: {5} read lba 200: {0} read lba 300: {6} read lba 400: {0} set_error lba 100 write lba 200: {7} set_error lba 300 write lba 400: {8} read lba 100: Input/output error read lba 200: {7} read lba 300: Input/output error read lba 400: {8} blk_rw$(nW)TEST19: DONE pmdk-1.11.1/src/test/blk_rw/TEST110000775000000000000000000000116514123364546015136 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/blk_rw/TEST11 -- unit test for pmemblk_read/write/set_zero/set_error # # Same as TEST10, but run on a pool set that spans two Device DAX devices # with 4K alignment. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 4096 4096 setup dax_device_zero create_poolset $DIR/testset AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_normal_exit ./blk_rw$EXESUFFIX 512 $DIR/testset c\ r:0 r:1 r:32201 r:32313 z:0 z:1 r:0 check_pool DIR/testset pass pmdk-1.11.1/src/test/obj_pmemcheck/0000775000000000000000000000000014123364546015572 5ustar rootrootpmdk-1.11.1/src/test/obj_pmemcheck/pmemcheck0.log.match0000664000000000000000000000073714123364546021413 0ustar rootroot==$(N)== pmemcheck-$(*), a simple persistent store checker ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: $(*) ==$(N)== Parent PID: $(N) ==$(N)== ==$(N)== [0] Mapping base: 0x$(X) size: $(N) ==$(N)== [1] Mapping base: 0x$(X) size: $(N) ==$(N)== [2] Mapping base: 0x$(X) size: $(N) ==$(N)== [0] Mapping base: 0x$(X) size: $(N) ==$(N)== [1] Mapping base: 0x$(X) size: $(N) ==$(N)== ==$(N)== Number of stores not made persistent: 0 ==$(N)== ERROR SUMMARY: 0 errors pmdk-1.11.1/src/test/obj_pmemcheck/obj_pmemcheck.c0000664000000000000000000000214714123364546020530 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ #include "unittest.h" #include "valgrind_internal.h" struct foo { PMEMmutex bar; }; static void test_mutex_pmem_mapping_register(PMEMobjpool *pop) { PMEMoid foo; int ret = pmemobj_alloc(pop, &foo, sizeof(struct foo), 0, NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(foo)); struct foo *foop = pmemobj_direct(foo); ret = pmemobj_mutex_lock(pop, &foop->bar); /* foo->bar has been removed from pmem mappings collection */ VALGRIND_PRINT_PMEM_MAPPINGS; UT_ASSERTeq(ret, 0); ret = pmemobj_mutex_unlock(pop, &foop->bar); UT_ASSERTeq(ret, 0); pmemobj_free(&foo); /* the entire foo object has been re-registered as pmem mapping */ VALGRIND_PRINT_PMEM_MAPPINGS; } int main(int argc, char *argv[]) { START(argc, argv, "obj_pmemcheck"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], "pmemcheck", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); test_mutex_pmem_mapping_register(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_pmemcheck/TEST00000775000000000000000000000124714123364546016363 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pmemcheck/TEST0 -- unit test for obj_pmemcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type any # Valgrind merges errors which have the same last 4 stack frames. With non-debug # builds the depth of the stack trace depends on how much compiler optimized it. # So always use debug build to take a compiler out of the picture and get # deterministic stack traces. require_build_type debug require_valgrind 3.10 configure_valgrind pmemcheck force-enable setup expect_normal_exit ./obj_pmemcheck$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pmemcheck/Makefile0000664000000000000000000000037414123364546017236 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pmemcheck/Makefile -- build obj_pmemcheck unit test # TARGET = obj_pmemcheck OBJS = obj_pmemcheck.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_pmemcheck/.gitignore0000664000000000000000000000001614123364546017557 0ustar rootrootobj_pmemcheck pmdk-1.11.1/src/test/pmem2_memmove/0000775000000000000000000000000014123364546015551 5ustar rootrootpmdk-1.11.1/src/test/pmem2_memmove/Makefile0000664000000000000000000000060214123364546017207 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_memmove/Makefile -- build pmem2_memmove test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_memmove OBJS += pmem2_memmove.o\ memmove_common.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_memmove/pmem2_memmove.vcxproj.filters0000664000000000000000000000275714123364546023415 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {2d237952-c50b-4d8c-a83f-e28a96d88887} {dd5ab98c-405a-4d74-8bd8-70d914146b8d} Source Files Source Files Source Files Source Files Source Files Test Scripts Header Files Header Files pmdk-1.11.1/src/test/pmem2_memmove/pmem2_memmove.c0000664000000000000000000000621714123364546020470 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * pmem2_memmove.c -- test for doing a memmove * * usage: * pmem2_memmove file b:length [d:{offset}] [s:offset] [o:{1|2} S:{overlap}] * */ #include "unittest.h" #include "ut_pmem2.h" #include "file.h" #include "memmove_common.h" static void do_memmove_variants(char *dst, char *src, const char *file_name, size_t dest_off, size_t src_off, size_t bytes, persist_fn p, memmove_fn fn) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memmove(dst, src, file_name, dest_off, src_off, bytes, fn, Flags[i], p, NULL, NULL, NULL); } } int main(int argc, char *argv[]) { int fd; char *dst; char *src; char *src_orig; size_t dst_off = 0; size_t src_off = 0; size_t bytes = 0; int who = 0; size_t mapped_len; struct pmem2_config *cfg; struct pmem2_source *psrc; struct pmem2_map *map; const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_memmove %s %s %s %s %savx %savx512f", argc > 2 ? argv[2] : "null", argc > 3 ? argv[3] : "null", argc > 4 ? argv[4] : "null", thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); if (argc < 3) USAGE(); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&psrc, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, psrc); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); pmem2_persist_fn persist = pmem2_get_persist_fn(map); mapped_len = pmem2_map_get_size(map); dst = pmem2_map_get_address(map); if (dst == NULL) UT_FATAL("!could not map file: %s", argv[1]); pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); for (int arg = 2; arg < argc; arg++) { if (strchr("dsbo", argv[arg][0]) == NULL || argv[arg][1] != ':') UT_FATAL("op must be d: or s: or b: or o:"); size_t val = STRTOUL(&argv[arg][2], NULL, 0); switch (argv[arg][0]) { case 'd': if (val <= 0) UT_FATAL("bad offset (%lu) with d: option", val); dst_off = val; break; case 's': if (val <= 0) UT_FATAL("bad offset (%lu) with s: option", val); src_off = val; break; case 'b': if (val <= 0) UT_FATAL("bad length (%lu) with b: option", val); bytes = val; break; case 'o': if (val != 1 && val != 0) UT_FATAL("bad val (%lu) with o: option", val); who = (int)val; break; } } if (who == 0) { src_orig = src = dst + mapped_len / 2; UT_ASSERT(src > dst); do_memmove_variants(dst, src, argv[1], dst_off, src_off, bytes, persist, memmove_fn); /* dest > src */ src = dst; dst = src_orig; if (dst <= src) UT_FATAL("cannot map files in memory order"); do_memmove_variants(dst, src, argv[1], dst_off, src_off, bytes, persist, memmove_fn); } else { /* use the same buffer for source and destination */ memset(dst, 0, bytes); persist(dst, bytes); do_memmove_variants(dst, dst, argv[1], dst_off, src_off, bytes, persist, memmove_fn); } ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_memmove/TESTS.py0000775000000000000000000000377314123364546017042 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t class Pmem2Memmove(t.Test): test_type = t.Short filesize = 4 * t.MiB envs0 = () envs1 = () test_cases = [ # No offset, no overlap ['b:4096'], # aligned dest, unaligned source, no overlap ['s:7', 'b:4096'], # unaligned dest, unaligned source, no overlap ['d:7', 's:13', 'b:4096'], # all aligned, src overlaps dest ['b:4096', 's:23', 'o:1'], # unaligned destination ['b:4096', 'd:21'], # unaligned source and dest ['b:4096', 'd:21', 's:7'], # overlap of src, aligned src and dest ['b:4096', 'o:1', 's:20'], # overlap of src, aligned src, unaligned dest ['b:4096', 'd:13', 'o:1', 's:20'], # dest overlaps src, unaligned dest, aligned src ['b:2048', 'd:33', 'o:1'], # dest overlaps src, aligned dest and src ['b:4096', 'o:1', 'd:20'], # aligned dest, no overlap, small length ['b:8'], # small length, offset 1 byte from 64 byte boundary ['b:4', 'd:63'], # overlap, src < dest, small length (ensures a copy backwards, # with number of bytes to align < length) ['o:1', 'd:2', 'b:8'] ] def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' for env in self.envs1: ctx.env[env] = '1' for tc in self.test_cases: filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmem2_memmove', filepath, *tc) class TEST0(Pmem2Memmove): pass @t.require_architectures('x86_64') class TEST1(Pmem2Memmove): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') class TEST2(Pmem2Memmove): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) class TEST3(Pmem2Memmove): envs1 = ("PMEM_NO_MOVNT",) class TEST4(Pmem2Memmove): envs1 = ("PMEM_NO_MOVNT", "PMEM_NO_GENERIC_MEMCPY") pmdk-1.11.1/src/test/pmem2_memmove/.gitignore0000664000000000000000000000001614123364546017536 0ustar rootrootpmem2_memmove pmdk-1.11.1/src/test/pmem2_memmove/memmove_common.h0000664000000000000000000000210114123364546020731 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020-2021, Intel Corporation */ /* * memmove_common.h -- header file for common memmove_common test utilities */ #ifndef MEMMOVE_COMMON_H #define MEMMOVE_COMMON_H 1 #include "unittest.h" #include "file.h" extern unsigned Flags[10]; #define USAGE() do { UT_FATAL("usage: %s file b:length [d:{offset}] "\ "[s:{offset}] [o:{0|1}]", argv[0]); } while (0) typedef void *(*memmove_fn)(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *(*set_memmove_fn)(struct pmemset *set, void *pmemdest, void *src, size_t len, unsigned flags); typedef void (*persist_fn)(const void *ptr, size_t len); typedef int (*set_persist_fn)(struct pmemset *set, void *ptr, size_t len); void do_memmove(char *dst, char *src, const char *file_name, size_t dest_off, size_t src_off, size_t bytes, memmove_fn fn, unsigned flags, persist_fn p, struct pmemset *set, set_persist_fn sp, set_memmove_fn sm); void verify_contents(const char *file_name, int test, const char *buf1, const char *buf2, size_t len); #endif pmdk-1.11.1/src/test/pmem2_memmove/pmem2_memmove.vcxproj0000664000000000000000000000735414123364546021744 0ustar rootroot Debug x64 Release x64 {4EE3C4D6-F707-4A05-8032-8FC2A44D29E8} Win32Proj pmem_memmove 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_memmove/memmove_common.c0000664000000000000000000001031414123364546020731 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * memmove_common.c -- common part for tests doing a persistent memmove */ #include "unittest.h" #include "memmove_common.h" /* * verify_contents -- verify that buffers match, if they don't - print contents * of both and abort the test */ void verify_contents(const char *file_name, int test, const char *buf1, const char *buf2, size_t len) { if (memcmp(buf1, buf2, len) == 0) return; for (size_t i = 0; i < len; ++i) UT_ERR("%04zu 0x%02x 0x%02x %s", i, (uint8_t)buf1[i], (uint8_t)buf2[i], buf1[i] != buf2[i] ? "!!!" : ""); UT_FATAL("%s %d: %zu bytes do not match with memcmp", file_name, test, len); } /* * do_persist - performs selected persist function */ static void do_persist(struct pmemset *set, set_persist_fn sp, persist_fn p, char *ptr, size_t len) { if (set) sp(set, ptr, len); else p(ptr, len); } /* * do_memmove_s - performs selected memmove function */ static void * do_memmove_s(struct pmemset *set, set_memmove_fn sm, memmove_fn m, char *ptr1, char *ptr2, size_t len, unsigned flags) { if (set) return sm(set, ptr1, ptr2, len, flags); else return m(ptr1, ptr2, len, flags); } /* * do_memmove: Worker function for memmove. * * Always work within the boundary of bytes. Fill in 1/2 of the src * memory with the pattern we want to write. This allows us to check * that we did not overwrite anything we were not supposed to in the * dest. Use the non pmem version of the memset/memcpy commands * so as not to introduce any possible side affects. */ void do_memmove(char *dst, char *src, const char *file_name, size_t dest_off, size_t src_off, size_t bytes, memmove_fn fn, unsigned flags, persist_fn persist, struct pmemset *set, set_persist_fn set_persist, set_memmove_fn set_memmove) { void *ret; char *srcshadow = MALLOC(dest_off + src_off + bytes); char *dstshadow = srcshadow; if (src != dst) dstshadow = MALLOC(dest_off + src_off + bytes); char old; memset(src, 0x11, bytes); memset(dst, 0x22, bytes); memset(src, 0x33, bytes / 4); memset(src + bytes / 4, 0x44, bytes / 4); do_persist(set, set_persist, persist, src, bytes); do_persist(set, set_persist, persist, dst, bytes); memcpy(srcshadow, src, bytes); memcpy(dstshadow, dst, bytes); /* TEST 1, dest == src */ old = *(char *)(dst + dest_off); ret = do_memmove_s(set, set_memmove, fn, dst + dest_off, dst + dest_off, bytes / 2, flags); UT_ASSERTeq(ret, dst + dest_off); UT_ASSERTeq(*(char *)(dst + dest_off), old); /* do the same using regular memmove and verify that buffers match */ memmove(dstshadow + dest_off, dstshadow + dest_off, bytes / 2); verify_contents(file_name, 0, dstshadow, dst, bytes); verify_contents(file_name, 1, srcshadow, src, bytes); /* TEST 2, len == 0 */ old = *(char *)(dst + dest_off); ret = do_memmove_s(set, set_memmove, fn, dst + dest_off, src + src_off, 0, flags); UT_ASSERTeq(ret, dst + dest_off); UT_ASSERTeq(*(char *)(dst + dest_off), old); /* do the same using regular memmove and verify that buffers match */ memmove(dstshadow + dest_off, srcshadow + src_off, 0); verify_contents(file_name, 2, dstshadow, dst, bytes); verify_contents(file_name, 3, srcshadow, src, bytes); /* TEST 3, len == bytes / 2 */ ret = do_memmove_s(set, set_memmove, fn, dst + dest_off, src + src_off, bytes / 2, flags); UT_ASSERTeq(ret, dst + dest_off); if (flags & PMEM_F_MEM_NOFLUSH) { /* for pmemcheck */ do_persist(set, set_persist, persist, dst + dest_off, bytes / 2); } /* do the same using regular memmove and verify that buffers match */ memmove(dstshadow + dest_off, srcshadow + src_off, bytes / 2); verify_contents(file_name, 4, dstshadow, dst, bytes); verify_contents(file_name, 5, srcshadow, src, bytes); FREE(srcshadow); if (dstshadow != srcshadow) FREE(dstshadow); } unsigned Flags[] = { 0, PMEM_F_MEM_NODRAIN, PMEM_F_MEM_NONTEMPORAL, PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_NODRAIN, PMEM_F_MEM_WC, PMEM_F_MEM_WB, PMEM_F_MEM_NOFLUSH, /* all possible flags */ PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB, }; pmdk-1.11.1/src/test/pmem_has_auto_flush/0000775000000000000000000000000014123364546017026 5ustar rootrootpmdk-1.11.1/src/test/pmem_has_auto_flush/pmem_has_auto_flush.c0000664000000000000000000000104614123364546023215 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * pmem_has_auto_flush.c -- unit test for pmem_has_auto_flush() function * * this test checks if function pmem_has_auto_flush handle sysfs path * and persistence_domain file in proper way */ #include #include "unittest.h" int main(int argc, char *argv[]) { START(argc, argv, "pmem_has_auto_flush"); if (argc != 1) UT_FATAL("usage: %s path", argv[0]); int ret = pmem_has_auto_flush(); UT_OUT("pmem_has_auto_flush %d", ret); DONE(NULL); } pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST30000775000000000000000000000142514123364546017620 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST3- unit test for pmem_has_auto_flush # # tests regions without persistence_domain inside # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond000 $ROOT/regiond111 ln -sf $ROOT/regiond000 $ROOT/region000 ln -sf $ROOT/regiond111 $ROOT/region111 touch $ROOT/regiond000/persistent $ROOT/regiond111/domain \ $ROOT/regiond000/abcd $ROOT/regiond111/abcd \ $ROOT/regiond000/persistent2 $ROOT/regiond111/region_id \ $ROOT/regiond000/tempname $ROOT/regiond111/defg expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST00000775000000000000000000000124414123364546017614 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST0 -- unit test for pmem_has_auto_flush # # tests multiple empty regions with symlinks # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT mkdir -p $ROOT/regiond0 $ROOT/regiond1 $ROOT/regiond2 $ROOT/regiond3 ln -sf $ROOT/regiond0 $ROOT/region0 ln -sf $ROOT/regiond1 $ROOT/region1 ln -sf $ROOT/regiond2 $ROOT/region2 ln -sf $ROOT/regiond3 $ROOT/region3 expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/Makefile0000664000000000000000000000060414123364546020466 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # src/test/pmem_has_auto_flush/Makefile -- build pmem_has_auto_flush test # include ../../common.inc LIBPMEMCOMMON=internal-debug LIBPMEM=internal-debug TARGET = pmem_has_auto_flush OBJS = pmem_has_auto_flush.o \ mocks_posix.o include ../Makefile.inc LDFLAGS += $(call extract_funcs, mocks_posix.c) pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST50000775000000000000000000000170614123364546017624 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST5 -- unit test for pmem_has_auto_flush # # tests regions with mixed - empty persistence_domain file # and persistence_domain with other type # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond000 $ROOT/regiond111 ln -sf $ROOT/regiond000 $ROOT/region000 ln -sf $ROOT/regiond111 $ROOT/region111 touch $ROOT/regiond000/persistent $ROOT/regiond111/domain \ $ROOT/regiond000/abcd $ROOT/regiond111/abcd \ $ROOT/regiond000/persistence_domain $ROOT/regiond111/persistence_domain \ $ROOT/regiond000/tempname $ROOT/regiond111/defg echo "" > $ROOT/regiond000/persistence_domain echo "memory_controller" > $ROOT/regiond111/persistence_domain expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/out7.log.match0000664000000000000000000000023014123364546021515 0ustar rootrootpmem_has_auto_flush$(nW)TEST7: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST7: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST40000775000000000000000000000162114123364546017617 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST4 -- unit test for pmem_has_auto_flush # # tests regions with empty persistence_domain file inside # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond000 $ROOT/regiond111 ln -sf $ROOT/regiond000 $ROOT/region000 ln -sf $ROOT/regiond111 $ROOT/region111 touch $ROOT/regiond000/persistent $ROOT/regiond111/domain \ $ROOT/regiond000/abcd $ROOT/regiond111/abcd \ $ROOT/regiond000/persistence_domain $ROOT/regiond111/persistence_domain \ $ROOT/regiond000/tempname $ROOT/regiond111/defg echo " \n" > $ROOT/regiond000/persistence_domain echo " \n" > $ROOT/regiond111/persistence_domain expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST70000775000000000000000000000166114123364546017626 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST7 -- unit test for pmem_has_auto_flush # # tests regions with improper values in all persistence_domain files # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond000 $ROOT/regiond111 ln -sf $ROOT/regiond000 $ROOT/region000 ln -sf $ROOT/regiond111 $ROOT/region111 touch $ROOT/regiond000/persistent $ROOT/regiond111/domain \ $ROOT/regiond000/abcd $ROOT/regiond111/abcd \ $ROOT/regiond000/persistence_domain $ROOT/regiond111/persistence_domain \ $ROOT/regiond000/tempname $ROOT/regiond111/defg echo "cpu_caches" > $ROOT/regiond000/persistence_domain echo "memory_controller" > $ROOT/regiond111/persistence_domain expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/out0.log.match0000664000000000000000000000023014123364546021506 0ustar rootrootpmem_has_auto_flush$(nW)TEST0: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST0: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/.gitignore0000664000000000000000000000002414123364546021012 0ustar rootrootpmem_has_auto_flush pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST60000775000000000000000000000174514123364546017630 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST6 -- unit test for pmem_has_auto_flush # # test regions with proper value in all persistence_domain files # this is the only case when pmem_has_auto_flush should return 1 # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond000 $ROOT/regiond111 ln -sf $ROOT/regiond000 $ROOT/region000 ln -sf $ROOT/regiond111 $ROOT/region111 touch $ROOT/regiond000/persistent $ROOT/regiond111/domain \ $ROOT/regiond000/abcd $ROOT/regiond111/abcd \ $ROOT/regiond000/persistence_domain $ROOT/regiond111/persistence_domain \ $ROOT/regiond000/tempname $ROOT/regiond111/defg echo "cpu_cache" > $ROOT/regiond000/persistence_domain echo "cpu_cache" > $ROOT/regiond111/persistence_domain expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST10000775000000000000000000000067714123364546017626 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST1 -- unit test for pmem_has_auto_flush # # tests case when there is no regions inside # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/out6.log.match0000664000000000000000000000023014123364546021514 0ustar rootrootpmem_has_auto_flush$(nW)TEST6: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 1 pmem_has_auto_flush$(nW)TEST6: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST80000775000000000000000000000163614123364546017631 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST8 -- unit test for pmem_has_auto_flush # # tests regions with one improper and one proper value in persistence_domain files # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond0 $ROOT/regiond1 ln -sf $ROOT/regiond0 $ROOT/region0 ln -sf $ROOT/regiond1 $ROOT/region1 touch $ROOT/regiond0/persistent $ROOT/regiond1/domain \ $ROOT/regiond0/abcd $ROOT/regiond1/abcd \ $ROOT/regiond0/persistence_domain $ROOT/regiond1/persistence_domain \ $ROOT/regiond0/tempname $ROOT/regiond1/defg echo "cpu_cache" > $ROOT/regiond1/persistence_domain echo "memory_controller" > $ROOT/regiond0/persistence_domain expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/out1.log.match0000664000000000000000000000023014123364546021507 0ustar rootrootpmem_has_auto_flush$(nW)TEST1: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/TEST20000775000000000000000000000100014123364546017604 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/pmem_has_auto_flush/TEST2 -- unit test for pmem_has_auto_flush # # tests regions which are not sym links # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem setup ROOT=$DIR/pmem_has_auto_flush/root export BUS_DEVICE_PATH=$ROOT mkdir -p $ROOT/regiond0 $ROOT/regiond1 $ROOT/regiond2 $ROOT/regiond3 expect_normal_exit ./pmem_has_auto_flush$EXESUFFIX check pass pmdk-1.11.1/src/test/pmem_has_auto_flush/out5.log.match0000664000000000000000000000023014123364546021513 0ustar rootrootpmem_has_auto_flush$(nW)TEST5: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST5: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/out3.log.match0000664000000000000000000000023014123364546021511 0ustar rootrootpmem_has_auto_flush$(nW)TEST3: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST3: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/mocks_posix.c0000664000000000000000000000313314123364546021530 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * mocks_posix.c -- mocked functions used in pmem_has_auto_flush.c */ #include #include "fs.h" #include "unittest.h" #define BUS_DEVICE_PATH "/sys/bus/nd/devices" /* * open -- open mock */ FUNC_MOCK(open, int, const char *path, int flags, ...) FUNC_MOCK_RUN_DEFAULT { va_list ap; va_start(ap, flags); int mode = va_arg(ap, int); va_end(ap); if (!strstr(path, BUS_DEVICE_PATH)) return _FUNC_REAL(open)(path, flags, mode); const char *prefix = os_getenv("BUS_DEVICE_PATH"); char path2[PATH_MAX] = { 0 }; strcat(path2, prefix); strcat(path2, path + strlen(BUS_DEVICE_PATH)); return _FUNC_REAL(open)(path2, flags, mode); } FUNC_MOCK_END struct fs { FTS *ft; struct fs_entry entry; }; /* * fs_new -- creates fs traversal instance */ FUNC_MOCK(fs_new, struct fs *, const char *path) FUNC_MOCK_RUN_DEFAULT { if (!strstr(path, BUS_DEVICE_PATH)) return _FUNC_REAL(fs_new)(path); const char *prefix = os_getenv("BUS_DEVICE_PATH"); char path2[PATH_MAX] = { 0 }; strcat(path2, prefix); strcat(path2, path + strlen(BUS_DEVICE_PATH)); return _FUNC_REAL(fs_new)(path2); } FUNC_MOCK_END /* * os_stat -- os_stat mock to handle sysfs path */ FUNC_MOCK(os_stat, int, const char *path, os_stat_t *buf) FUNC_MOCK_RUN_DEFAULT { if (!strstr(path, BUS_DEVICE_PATH)) return _FUNC_REAL(os_stat)(path, buf); const char *prefix = os_getenv("BUS_DEVICE_PATH"); char path2[PATH_MAX] = { 0 }; strcat(path2, prefix); strcat(path2, path + strlen(BUS_DEVICE_PATH)); return _FUNC_REAL(os_stat)(path2, buf); } FUNC_MOCK_END pmdk-1.11.1/src/test/pmem_has_auto_flush/out4.log.match0000664000000000000000000000023014123364546021512 0ustar rootrootpmem_has_auto_flush$(nW)TEST4: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST4: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/out8.log.match0000664000000000000000000000023014123364546021516 0ustar rootrootpmem_has_auto_flush$(nW)TEST8: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST8: DONE pmdk-1.11.1/src/test/pmem_has_auto_flush/out2.log.match0000664000000000000000000000023014123364546021510 0ustar rootrootpmem_has_auto_flush$(nW)TEST2: START: pmem_has_auto_flush$(nW) $(nW)pmem_has_auto_flush$(nW) pmem_has_auto_flush 0 pmem_has_auto_flush$(nW)TEST2: DONE pmdk-1.11.1/src/test/util_is_poolset/0000775000000000000000000000000014123364546016221 5ustar rootrootpmdk-1.11.1/src/test/util_is_poolset/TEST00000775000000000000000000000120014123364546016777 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_is_poolset/TEST0 -- unit test for util_is_poolset # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup create_poolset $DIR/pool.set 32K:$DIR/testfile:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.obj echo "NOT_PMEMPOOLSET" > $DIR/not_pool.set echo "PMEMPOOL" > $DIR/too_short.set touch $DIR/empty.set expect_normal_exit ./util_is_poolset$EXESUFFIX\ $DIR/pool.set\ $DIR/not_pool.set\ $DIR/too_short.set\ $DIR/pool.obj\ $DIR/empty.set\ $DIR/not_exist.set check pass pmdk-1.11.1/src/test/util_is_poolset/util_is_poolset.vcxproj0000664000000000000000000000654314123364546023063 0ustar rootroot Debug x64 Release x64 {F0B613C4-1D9A-4259-BD0E-C1B9FF2AA3A0} Win32Proj util_is_poolset 10.0.17134.0 Application true v140 v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_is_poolset/Makefile0000664000000000000000000000037314123364546017664 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/util_is_poolset/Makefile -- build util_is_poolset unit test # # TARGET = util_is_poolset OBJS = util_is_poolset.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_is_poolset/out0.log.match0000664000000000000000000000064014123364546020706 0ustar rootrootutil_is_poolset$(nW)TEST0: START: util_is_poolset $(nW)util_is_poolset$(nW) $(*)pool.set $(*)not_pool.set $(*)too_short.set $(*)pool.obj $(*)empty.set $(*)not_exist.set util_is_poolset($(*)pool.set): 1 util_is_poolset($(*)not_pool.set): 0 util_is_poolset($(*)too_short.set): 0 util_is_poolset($(*)pool.obj): 0 util_is_poolset($(*)empty.set): 0 util_is_poolset($(*)not_exist.set): -1 util_is_poolset$(nW)TEST0: DONE pmdk-1.11.1/src/test/util_is_poolset/TEST0.PS10000664000000000000000000000132614123364546017407 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/util_is_poolset/TEST0 -- unit test for util_is_poolset # # # parameter handling # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\pool.set 32K:$DIR\testfile:x expect_normal_exit $PMEMPOOL create obj $DIR\pool.obj Set-Content -literalpath $DIR\not_pool.set -Value "NON_PMEMPOOLSET" Set-Content -literalpath $DIR\too_short.set -Value "PMEMPOOL" touch $DIR\empty.set expect_normal_exit $Env:EXE_DIR\util_is_poolset$Env:EXESUFFIX ` $DIR\pool.set ` $DIR\not_pool.set ` $DIR\too_short.set ` $DIR\pool.obj ` $DIR\empty.set ` $DIR\not_exist.set check pass pmdk-1.11.1/src/test/util_is_poolset/.gitignore0000664000000000000000000000002014123364546020201 0ustar rootrootutil_is_poolset pmdk-1.11.1/src/test/util_is_poolset/README0000664000000000000000000000051114123364546017076 0ustar rootrootPersistent Memory Development Kit This is src/test/util_is_poolset/README. This directory contains a unit test for util_is_poolset(). The program in util_is_poolset.c takes a file name(s) as arguments: For example: ./util_is_poolset pool.set1 pool.set2 This will call util_is_poolset() on all files and print result value. pmdk-1.11.1/src/test/util_is_poolset/util_is_poolset.vcxproj.filters0000664000000000000000000000167314123364546024531 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {75a39b85-30aa-4368-b381-5ee2e20664ef} {0043ed39-e1cb-4c0b-a822-1209b66ba120} Source Files Test Scripts Match Files pmdk-1.11.1/src/test/util_is_poolset/util_is_poolset.c0000664000000000000000000000150214123364546021600 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016, Intel Corporation */ /* * util_is_poolset.c -- unit test for util_is_poolset * * usage: util_is_poolset file */ #include "unittest.h" #include "set.h" #include "pmemcommon.h" #include #define LOG_PREFIX "ut" #define LOG_LEVEL_VAR "TEST_LOG_LEVEL" #define LOG_FILE_VAR "TEST_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 int main(int argc, char *argv[]) { START(argc, argv, "util_is_poolset"); common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); if (argc < 2) UT_FATAL("usage: %s file...", argv[0]); for (int i = 1; i < argc; i++) { char *fname = argv[i]; int is_poolset = util_is_poolset_file(fname); UT_OUT("util_is_poolset(%s): %d", fname, is_poolset); } common_fini(); DONE(NULL); } pmdk-1.11.1/src/test/ex_libpmem2/0000775000000000000000000000000014123364546015207 5ustar rootrootpmdk-1.11.1/src/test/ex_libpmem2/ex_libpmem2.vcxproj.filters0000664000000000000000000000063114123364546022476 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} Test Scripts pmdk-1.11.1/src/test/ex_libpmem2/ex_libpmem2.vcxproj0000664000000000000000000000765314123364546021042 0ustar rootroot Debug x64 Release x64 {d2964b88-eb05-4ebf-acda-44596fbfecb6} {a9add224-1755-407f-906d-c13ec37ff7b0} {3ec20bdd-2e48-4291-a9ee-d0675af77c7f} {C2D5E690-748B-4138-B572-1774B99A8572} ex_libpmem2 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/ex_libpmem2/Makefile0000664000000000000000000000050114123364546016643 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation # # src/test/ex_libpmem2/Makefile -- build ex_libpmem2 unittest # all: $(EXAMPLES) $(MAKE) -C $(EX_LIBPMEM2) include ../Makefile.inc EXAMPLES=$(EX_LIBPMEM2)/basic\ $(EX_LIBPMEM2)/advanced\ $(EX_LIBPMEM2)/log\ $(EX_LIBPMEM2)/ringbuf pmdk-1.11.1/src/test/ex_libpmem2/TESTS.py0000775000000000000000000000542414123364546016473 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2021, Intel Corporation # import futils import testframework as t @t.require_build(['debug', 'release']) class EX_LIBPMEM2(t.Test): test_type = t.Medium file_size = 1 * t.MiB offset = str(97 * t.KiB) length = str(65 * t.KiB) class TEST0(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'basic') file_path = ctx.create_non_zero_file(self.file_size, 'testfile0') ctx.exec(example_path, file_path) class TEST1(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'advanced') file_path = ctx.create_non_zero_file(self.file_size, 'testfile0') ctx.exec(example_path, file_path, self.offset, self.length) class TEST2(EX_LIBPMEM2): file_size = 16 * t.MiB def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'log') file_path = ctx.create_holey_file(self.file_size, 'testfile0') args = ['appendv', '4', 'PMDK ', 'is ', 'the best ', 'open source ', 'append', 'project in the world.', 'dump', 'rewind', 'dump', 'appendv', '2', 'End of ', 'file.', 'dump'] ctx.exec(example_path, file_path, *args, stdout_file='out2.log') class TEST3(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'redo') file_path = ctx.create_holey_file(self.file_size, 'testfile0') for x in range(1, 100): ctx.exec(example_path, "add", file_path, x, x) ctx.exec(example_path, "check", file_path) ctx.exec(example_path, "print", file_path, stdout_file='out3.log') class TEST4(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'map_multiple_files') args = [] for x in range(1, 10): file_path = ctx.create_holey_file(self.file_size, 'testfile{}'.format(x)) args.append(file_path) ctx.exec(example_path, *args, stdout_file='out4.log') class TEST5(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'unsafe_shutdown') file_path = ctx.create_holey_file(self.file_size, 'testfile0') ctx.exec(example_path, "write", file_path, "foobar") ctx.exec(example_path, "read", file_path, stdout_file='out5.log') @t.windows_exclude class TEST6(EX_LIBPMEM2): def run(self, ctx): example_path = futils.get_example_path(ctx, 'pmem2', 'ringbuf') file_path = ctx.create_holey_file(self.file_size, 'testfile0') ctx.exec(example_path, file_path, 10000, 4096, stdout_file='out6.log') pmdk-1.11.1/src/test/ex_libpmem2/README0000664000000000000000000000031314123364546016064 0ustar rootrootPersistent Memory Development Kit This is src/test/ex_libpmem2/README. This directory contains unit tests for libpmem2 examples. The unit tests utilizes examples from src/examples/libpmem2 directory. pmdk-1.11.1/src/test/ex_libpmem2/out5.log.match0000664000000000000000000000041114123364546017675 0ustar rootroot$(OPT)pmem2_source_device_usc: Unsafe shutdown count is not supported for this source $(OPT)pmem2_source_device_usc: Getting unsafe shutdown count is not supported on this system $(OPT)pmem2_source_device_usc: Cannot read device usc - ndctl is not available foobar pmdk-1.11.1/src/test/ex_libpmem2/out2.log.match0000664000000000000000000000010114123364546017666 0ustar rootrootPMDK is the best open source project in the world. End of file. pmdk-1.11.1/src/test/obj_basic_integration/0000775000000000000000000000000014123364546017322 5ustar rootrootpmdk-1.11.1/src/test/obj_basic_integration/obj_basic_integration.c0000664000000000000000000004257014123364546024014 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_basic_integration.c -- Basic integration tests * */ #include #include "unittest.h" #include "obj.h" #define TEST_STR "abcdefgh" #define TEST_STR_LEN 8 #define TEST_VALUE 5 /* * Layout definition */ POBJ_LAYOUT_BEGIN(basic); POBJ_LAYOUT_ROOT(basic, struct dummy_root); POBJ_LAYOUT_TOID(basic, struct dummy_node); POBJ_LAYOUT_TOID(basic, struct dummy_node_c); POBJ_LAYOUT_END(basic); struct dummy_node { int value; char teststr[TEST_STR_LEN]; POBJ_LIST_ENTRY(struct dummy_node) plist; POBJ_LIST_ENTRY(struct dummy_node) plist_m; }; struct dummy_node_c { int value; char teststr[TEST_STR_LEN]; POBJ_LIST_ENTRY(struct dummy_node) plist; POBJ_LIST_ENTRY(struct dummy_node) plist_m; }; struct dummy_root { int value; PMEMmutex lock; TOID(struct dummy_node) node; POBJ_LIST_HEAD(dummy_list, struct dummy_node) dummies; POBJ_LIST_HEAD(moved_list, struct dummy_node) moved; }; static int dummy_node_constructor(PMEMobjpool *pop, void *ptr, void *arg) { struct dummy_node *n = (struct dummy_node *)ptr; int *test_val = (int *)arg; n->value = *test_val; pmemobj_persist(pop, &n->value, sizeof(n->value)); return 0; } static void test_alloc_api(PMEMobjpool *pop) { TOID(struct dummy_node) node_zeroed; TOID(struct dummy_node_c) node_constructed; POBJ_ZNEW(pop, &node_zeroed, struct dummy_node); UT_ASSERT_rt(OID_INSTANCEOF(node_zeroed.oid, struct dummy_node)); int *test_val = (int *)MALLOC(sizeof(*test_val)); *test_val = TEST_VALUE; POBJ_NEW(pop, &node_constructed, struct dummy_node_c, dummy_node_constructor, test_val); FREE(test_val); TOID(struct dummy_node) iter; POBJ_FOREACH_TYPE(pop, iter) { UT_ASSERTeq(D_RO(iter)->value, 0); } TOID(struct dummy_node_c) iter_c; POBJ_FOREACH_TYPE(pop, iter_c) { UT_ASSERTeq(D_RO(iter_c)->value, TEST_VALUE); } PMEMoid oid_iter; int nodes_count = 0; POBJ_FOREACH(pop, oid_iter) { nodes_count++; } UT_ASSERTne(nodes_count, 0); POBJ_FREE(&node_zeroed); POBJ_FREE(&node_constructed); nodes_count = 0; POBJ_FOREACH(pop, oid_iter) { nodes_count++; } UT_ASSERTeq(nodes_count, 0); int val = 10; POBJ_ALLOC(pop, &node_constructed, struct dummy_node_c, sizeof(struct dummy_node_c), dummy_node_constructor, &val); POBJ_REALLOC(pop, &node_constructed, struct dummy_node_c, sizeof(struct dummy_node_c) + 1000); UT_ASSERTeq(pmemobj_type_num(node_constructed.oid), TOID_TYPE_NUM(struct dummy_node_c)); POBJ_ZREALLOC(pop, &node_constructed, struct dummy_node_c, sizeof(struct dummy_node_c) + 2000); UT_ASSERTeq(pmemobj_type_num(node_constructed.oid), TOID_TYPE_NUM(struct dummy_node_c)); POBJ_FREE(&node_constructed); POBJ_ZALLOC(pop, &node_zeroed, struct dummy_node, sizeof(struct dummy_node)); POBJ_FREE(&node_zeroed); PMEMoid oid = OID_NULL; POBJ_FREE(&oid); int err = 0; err = pmemobj_alloc(pop, NULL, SIZE_MAX, 0, NULL, NULL); UT_ASSERTeq(err, -1); UT_ASSERTeq(errno, ENOMEM); err = pmemobj_zalloc(pop, NULL, SIZE_MAX, 0); UT_ASSERTeq(err, -1); UT_ASSERTeq(errno, ENOMEM); err = pmemobj_alloc(pop, NULL, PMEMOBJ_MAX_ALLOC_SIZE + 1, 0, NULL, NULL); UT_ASSERTeq(err, -1); UT_ASSERTeq(errno, ENOMEM); err = pmemobj_zalloc(pop, NULL, PMEMOBJ_MAX_ALLOC_SIZE + 1, 0); UT_ASSERTeq(err, -1); UT_ASSERTeq(errno, ENOMEM); } static void test_realloc_api(PMEMobjpool *pop) { PMEMoid oid = OID_NULL; int ret; ret = pmemobj_alloc(pop, &oid, 128, 0, NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("alloc: %u, size: %zu", 128, pmemobj_alloc_usable_size(oid)); /* grow */ ret = pmemobj_realloc(pop, &oid, 655360, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 128, 655360, pmemobj_alloc_usable_size(oid)); /* shrink */ ret = pmemobj_realloc(pop, &oid, 1, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 655360, 1, pmemobj_alloc_usable_size(oid)); /* free */ ret = pmemobj_realloc(pop, &oid, 0, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(OID_IS_NULL(oid)); UT_OUT("free"); /* alloc */ ret = pmemobj_realloc(pop, &oid, 777, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 0, 777, pmemobj_alloc_usable_size(oid)); /* shrink */ ret = pmemobj_realloc(pop, &oid, 1, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 777, 1, pmemobj_alloc_usable_size(oid)); pmemobj_free(&oid); UT_ASSERT(OID_IS_NULL(oid)); UT_ASSERTeq(pmemobj_alloc_usable_size(oid), 0); UT_OUT("free"); /* alloc */ ret = pmemobj_realloc(pop, &oid, 1, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 0, 1, pmemobj_alloc_usable_size(oid)); /* do nothing */ ret = pmemobj_realloc(pop, &oid, 1, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); UT_OUT("realloc: %u => %u, size: %zu", 1, 1, pmemobj_alloc_usable_size(oid)); pmemobj_free(&oid); UT_ASSERT(OID_IS_NULL(oid)); UT_OUT("free"); /* do nothing */ ret = pmemobj_realloc(pop, &oid, 0, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(OID_IS_NULL(oid)); /* alloc */ ret = pmemobj_realloc(pop, &oid, 1, 0); UT_ASSERTeq(ret, 0); UT_ASSERT(!OID_IS_NULL(oid)); /* grow beyond reasonable size */ ret = pmemobj_realloc(pop, &oid, SIZE_MAX, 0); UT_ASSERTeq(ret, -1); UT_ASSERTeq(errno, ENOMEM); ret = pmemobj_realloc(pop, &oid, PMEMOBJ_MAX_ALLOC_SIZE + 1, 0); UT_ASSERTeq(ret, -1); UT_ASSERTeq(errno, ENOMEM); pmemobj_free(&oid); UT_ASSERT(OID_IS_NULL(oid)); } static void test_list_api(PMEMobjpool *pop) { TOID(struct dummy_root) root; root = POBJ_ROOT(pop, struct dummy_root); int nodes_count = 0; UT_ASSERTeq(pmemobj_type_num(root.oid), POBJ_ROOT_TYPE_NUM); UT_COMPILE_ERROR_ON(TOID_TYPE_NUM_OF(root) != POBJ_ROOT_TYPE_NUM); TOID(struct dummy_node) first; TOID(struct dummy_node) iter; POBJ_LIST_FOREACH_REVERSE(iter, &D_RO(root)->dummies, plist) { UT_OUT("POBJ_LIST_FOREACH_REVERSE: dummy_node %d", D_RO(iter)->value); nodes_count++; } UT_ASSERTeq(nodes_count, 0); int test_val = TEST_VALUE; PMEMoid ret; /* should fail */ ret = POBJ_LIST_INSERT_NEW_HEAD(pop, &D_RW(root)->dummies, plist, SIZE_MAX, dummy_node_constructor, &test_val); UT_ASSERTeq(errno, ENOMEM); UT_ASSERT(OID_IS_NULL(ret)); errno = 0; ret = POBJ_LIST_INSERT_NEW_HEAD(pop, &D_RW(root)->dummies, plist, PMEMOBJ_MAX_ALLOC_SIZE + 1, dummy_node_constructor, &test_val); UT_ASSERTeq(errno, ENOMEM); UT_ASSERT(OID_IS_NULL(ret)); POBJ_LIST_INSERT_NEW_HEAD(pop, &D_RW(root)->dummies, plist, sizeof(struct dummy_node), dummy_node_constructor, &test_val); test_val++; POBJ_LIST_INSERT_NEW_TAIL(pop, &D_RW(root)->dummies, plist, sizeof(struct dummy_node), dummy_node_constructor, &test_val); TOID(struct dummy_node) inserted = POBJ_LIST_FIRST(&D_RW(root)->dummies); UT_ASSERTeq(pmemobj_type_num(inserted.oid), TOID_TYPE_NUM(struct dummy_node)); TOID(struct dummy_node) node; POBJ_ZNEW(pop, &node, struct dummy_node); POBJ_LIST_INSERT_HEAD(pop, &D_RW(root)->dummies, node, plist); nodes_count = 0; POBJ_LIST_FOREACH(iter, &D_RO(root)->dummies, plist) { UT_OUT("POBJ_LIST_FOREACH: dummy_node %d", D_RO(iter)->value); nodes_count++; } UT_ASSERTeq(nodes_count, 3); /* now do the same, but w/o using FOREACH macro */ nodes_count = 0; first = POBJ_LIST_FIRST(&D_RO(root)->dummies); iter = first; do { UT_OUT("POBJ_LIST_NEXT: dummy_node %d", D_RO(iter)->value); nodes_count++; iter = POBJ_LIST_NEXT(iter, plist); } while (!TOID_EQUALS(iter, first)); UT_ASSERTeq(nodes_count, 3); POBJ_LIST_MOVE_ELEMENT_HEAD(pop, &D_RW(root)->dummies, &D_RW(root)->moved, node, plist, plist_m); UT_ASSERTeq(POBJ_LIST_EMPTY(&D_RW(root)->moved), 0); POBJ_LIST_MOVE_ELEMENT_HEAD(pop, &D_RW(root)->moved, &D_RW(root)->dummies, node, plist_m, plist); POBJ_LIST_MOVE_ELEMENT_TAIL(pop, &D_RW(root)->dummies, &D_RW(root)->moved, node, plist, plist_m); UT_ASSERTeq(POBJ_LIST_EMPTY(&D_RW(root)->moved), 0); POBJ_LIST_MOVE_ELEMENT_TAIL(pop, &D_RW(root)->moved, &D_RW(root)->dummies, node, plist_m, plist); POBJ_LIST_REMOVE(pop, &D_RW(root)->dummies, node, plist); POBJ_LIST_INSERT_TAIL(pop, &D_RW(root)->dummies, node, plist); POBJ_LIST_REMOVE_FREE(pop, &D_RW(root)->dummies, node, plist); nodes_count = 0; POBJ_LIST_FOREACH_REVERSE(iter, &D_RO(root)->dummies, plist) { UT_OUT("POBJ_LIST_FOREACH_REVERSE: dummy_node %d", D_RO(iter)->value); nodes_count++; } UT_ASSERTeq(nodes_count, 2); /* now do the same, but w/o using FOREACH macro */ nodes_count = 0; first = POBJ_LIST_FIRST(&D_RO(root)->dummies); iter = first; do { UT_OUT("POBJ_LIST_PREV: dummy_node %d", D_RO(iter)->value); nodes_count++; iter = POBJ_LIST_PREV(iter, plist); } while (!TOID_EQUALS(iter, first)); UT_ASSERTeq(nodes_count, 2); test_val++; POBJ_LIST_INSERT_NEW_AFTER(pop, &D_RW(root)->dummies, POBJ_LIST_FIRST(&D_RO(root)->dummies), plist, sizeof(struct dummy_node), dummy_node_constructor, &test_val); test_val++; POBJ_LIST_INSERT_NEW_BEFORE(pop, &D_RW(root)->dummies, POBJ_LIST_LAST(&D_RO(root)->dummies, plist), plist, sizeof(struct dummy_node), dummy_node_constructor, &test_val); nodes_count = 0; POBJ_LIST_FOREACH_REVERSE(iter, &D_RO(root)->dummies, plist) { UT_OUT("POBJ_LIST_FOREACH_REVERSE: dummy_node %d", D_RO(iter)->value); nodes_count++; } UT_ASSERTeq(nodes_count, 4); /* now do the same, but w/o using FOREACH macro */ nodes_count = 0; first = POBJ_LIST_LAST(&D_RO(root)->dummies, plist); iter = first; do { UT_OUT("POBJ_LIST_PREV: dummy_node %d", D_RO(iter)->value); nodes_count++; iter = POBJ_LIST_PREV(iter, plist); } while (!TOID_EQUALS(iter, first)); UT_ASSERTeq(nodes_count, 4); } static void test_tx_api(PMEMobjpool *pop) { TOID(struct dummy_root) root; TOID_ASSIGN(root, pmemobj_root(pop, sizeof(struct dummy_root))); int *vstate = NULL; /* volatile state */ TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { vstate = (int *)MALLOC(sizeof(*vstate)); *vstate = TEST_VALUE; TX_ADD(root); D_RW(root)->value = *vstate; TOID_ASSIGN(D_RW(root)->node, OID_NULL); } TX_FINALLY { FREE(vstate); vstate = NULL; } TX_END UT_ASSERTeq(vstate, NULL); UT_ASSERTeq(D_RW(root)->value, TEST_VALUE); TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); D_RW(root)->node = TX_ALLOC(struct dummy_node, SIZE_MAX); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); UT_ASSERTeq(errno, ENOMEM); } TX_END errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { D_RW(root)->node = TX_ZALLOC(struct dummy_node, SIZE_MAX); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); UT_ASSERTeq(errno, ENOMEM); } TX_END errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { D_RW(root)->node = TX_XALLOC(struct dummy_node, SIZE_MAX, POBJ_XALLOC_ZERO); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); UT_ASSERTeq(errno, ENOMEM); } TX_END errno = 0; TX_BEGIN_LOCK(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { D_RW(root)->node = TX_ALLOC(struct dummy_node, PMEMOBJ_MAX_ALLOC_SIZE + 1); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); UT_ASSERTeq(errno, ENOMEM); } TX_END errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { D_RW(root)->node = TX_ZALLOC(struct dummy_node, PMEMOBJ_MAX_ALLOC_SIZE + 1); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); UT_ASSERTeq(errno, ENOMEM); } TX_END errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); D_RW(root)->node = TX_ZNEW(struct dummy_node); D_RW(root)->node = TX_REALLOC(D_RO(root)->node, SIZE_MAX); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERTeq(errno, ENOMEM); } TX_END UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); D_RW(root)->node = TX_ZNEW(struct dummy_node); D_RW(root)->node = TX_REALLOC(D_RO(root)->node, PMEMOBJ_MAX_ALLOC_SIZE + 1); UT_ASSERT(0); /* should not get to this point */ } TX_ONABORT { UT_ASSERTeq(errno, ENOMEM); } TX_END UT_ASSERT(TOID_IS_NULL(D_RO(root)->node)); errno = 0; TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); D_RW(root)->node = TX_ZNEW(struct dummy_node); TX_MEMSET(D_RW(D_RW(root)->node)->teststr, 'a', TEST_STR_LEN); TX_MEMCPY(D_RW(D_RW(root)->node)->teststr, TEST_STR, TEST_STR_LEN); TX_SET(D_RW(root)->node, value, TEST_VALUE); } TX_END UT_ASSERTeq(D_RW(D_RW(root)->node)->value, TEST_VALUE); UT_ASSERT(strncmp(D_RW(D_RW(root)->node)->teststr, TEST_STR, TEST_STR_LEN) == 0); TX_BEGIN_PARAM(pop, TX_PARAM_MUTEX, &D_RW(root)->lock) { TX_ADD(root); UT_ASSERT(!TOID_IS_NULL(D_RW(root)->node)); TX_FREE(D_RW(root)->node); D_RW(root)->node = TOID_NULL(struct dummy_node); TOID_ASSIGN(D_RW(root)->node, OID_NULL); } TX_END errno = 0; TX_BEGIN(pop) { TX_BEGIN(NULL) { } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(errno == EFAULT); } TX_END errno = 0; TX_BEGIN(pop) { TX_BEGIN((PMEMobjpool *)(uintptr_t)7) { } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(errno == EINVAL); } TX_END UT_OUT("%s", pmemobj_errormsg()); TX_BEGIN(pop) { pmemobj_tx_abort(ECANCELED); } TX_END UT_OUT("%s", pmemobj_errormsg()); } static void test_action_api(PMEMobjpool *pop) { struct pobj_action act[2]; uint64_t dest_value = 0; PMEMoid oid = pmemobj_reserve(pop, &act[0], 1, 1); pmemobj_set_value(pop, &act[1], &dest_value, 1); pmemobj_publish(pop, act, 2); UT_ASSERTeq(dest_value, 1); pmemobj_free(&oid); UT_ASSERT(OID_IS_NULL(oid)); oid = pmemobj_reserve(pop, &act[0], 1, 1); TX_BEGIN(pop) { pmemobj_tx_publish(act, 1); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_free(&oid); UT_ASSERT(OID_IS_NULL(oid)); dest_value = 0; oid = pmemobj_reserve(pop, &act[0], 1, 1); pmemobj_set_value(pop, &act[1], &dest_value, 1); pmemobj_cancel(pop, act, 2); UT_ASSERTeq(dest_value, 0); TOID(struct dummy_node) n = POBJ_RESERVE_NEW(pop, struct dummy_node, &act[0]); TOID(struct dummy_node_c) c = POBJ_RESERVE_ALLOC(pop, struct dummy_node_c, sizeof(struct dummy_node_c), &act[1]); pmemobj_publish(pop, act, 2); /* valgrind would warn in case they were not allocated */ D_RW(n)->value = 1; D_RW(c)->value = 1; pmemobj_persist(pop, D_RW(n), sizeof(struct dummy_node)); pmemobj_persist(pop, D_RW(c), sizeof(struct dummy_node_c)); } static void test_offsetof(void) { TOID(struct dummy_root) r; TOID(struct dummy_node) n; UT_COMPILE_ERROR_ON(TOID_OFFSETOF(r, value) != offsetof(struct dummy_root, value)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(r, lock) != offsetof(struct dummy_root, lock)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(r, node) != offsetof(struct dummy_root, node)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(r, dummies) != offsetof(struct dummy_root, dummies)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(r, moved) != offsetof(struct dummy_root, moved)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(n, value) != offsetof(struct dummy_node, value)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(n, teststr) != offsetof(struct dummy_node, teststr)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(n, plist) != offsetof(struct dummy_node, plist)); UT_COMPILE_ERROR_ON(TOID_OFFSETOF(n, plist_m) != offsetof(struct dummy_node, plist_m)); } static void test_layout(void) { /* get number of declared types when there are no types declared */ POBJ_LAYOUT_BEGIN(mylayout); POBJ_LAYOUT_END(mylayout); size_t number_of_declared_types = POBJ_LAYOUT_TYPES_NUM(mylayout); UT_ASSERTeq(number_of_declared_types, 0); } static void test_root_size(PMEMobjpool *pop) { UT_ASSERTeq(pmemobj_root_size(pop), 0); size_t alloc_size = sizeof(struct dummy_root); pmemobj_root(pop, alloc_size); UT_ASSERTeq(pmemobj_root_size(pop), sizeof(struct dummy_root)); } int main(int argc, char *argv[]) { START(argc, argv, "obj_basic_integration"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(basic) != 2); if (argc < 2 || argc > 3) UT_FATAL("usage: %s file-name [inject_fault]", argv[0]); const char *path = argv[1]; const char *opt = argv[2]; PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(basic), 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); test_root_size(pop); test_alloc_api(pop); test_realloc_api(pop); test_list_api(pop); test_tx_api(pop); test_action_api(pop); test_offsetof(); test_layout(); pmemobj_close(pop); /* fault injection */ if (argc == 3 && strcmp(opt, "inject_fault") == 0) { if (pmemobj_fault_injection_enabled()) { pmemobj_inject_fault_at(PMEM_MALLOC, 1, "heap_check_remote"); pop = pmemobj_open(path, POBJ_LAYOUT_NAME(basic)); UT_ASSERTeq(pop, NULL); UT_ASSERTeq(errno, ENOMEM); } } if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(basic))) == NULL) UT_FATAL("!pmemobj_open: %s", path); /* second open should fail, checks file locking */ if ((pmemobj_open(path, POBJ_LAYOUT_NAME(basic))) != NULL) UT_FATAL("!pmemobj_open: %s", path); pmemobj_close(pop); int result = pmemobj_check(path, POBJ_LAYOUT_NAME(basic)); if (result < 0) UT_OUT("!%s: pmemobj_check", path); else if (result == 0) UT_OUT("%s: pmemobj_check: not consistent", path); DONE(NULL); } pmdk-1.11.1/src/test/obj_basic_integration/obj_basic_integration.vcxproj0000664000000000000000000001112414123364546025254 0ustar rootroot Debug x64 Release x64 {58386481-30B7-40FC-96AF-0723A4A7B228} Win32Proj obj_basic_integration 10.0.17134.0 Application true v140 Application false v140 true $(SolutionDir)libpmemobj;$(IncludePath) $(SolutionDir)libpmemobj;$(IncludePath) NotUsing Disabled CompileAsCpp NotUsing MaxSpeed stdafx.h CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_basic_integration/TEST30000775000000000000000000000064214123364546020114 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium setup create_poolset $DIR/testset1 16M:$DIR/testfile1:x r 16M:$DIR/testfile2:x expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testset1 compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST90000775000000000000000000000056514123364546020126 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_dax_devices 2 setup dax_device_zero create_poolset $DIR/testset1 \ AUTO:${DEVICE_DAX_PATH[0]}:x \ r \ AUTO:${DEVICE_DAX_PATH[1]}:x expect_normal_exit ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/TEST120000775000000000000000000000123114123364546020167 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_basic_integration/TEST12 -- basic integration tests for libpmemobj # # Same as TEST0, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected failure, as 2M alignment is not supported # if SINGLEHDR option is not specified. # . ../unittest/unittest.sh require_test_type medium require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset1 AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_abnormal_exit ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/Makefile.inc0000664000000000000000000000064114123364546021533 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/obj_basic_integration/Makefile.inc -- build obj_basic_integration, # obj_rpmem_basic_integration and obj_rpmem_basic_integration_multiple # unit tests # include ../Makefile.inc ../obj_basic_integration/obj_basic_integration: $(MAKE) -C ../obj_basic_integration all all: ../obj_basic_integration/obj_basic_integration pmdk-1.11.1/src/test/obj_basic_integration/TEST130000775000000000000000000000125714123364546020200 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_basic_integration/TEST13 -- basic integration tests for libpmemobj # # Same as TEST0, but run on a pool set that spans two Device DAX devices # with 2M alignment. Expected success, as pool is created with SINGLEHDR option. # if SINGLEHDR option is not specified. # . ../unittest/unittest.sh require_test_type medium require_dax_device_alignments 2097152 2097152 # 2MiB setup dax_device_zero create_poolset $DIR/testset1 AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} \ O SINGLEHDR expect_normal_exit ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/TEST00000775000000000000000000000362314123364546020113 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium # covered by TEST5 configure_valgrind memcheck force-disable setup create_holey_file 16M $DIR/testfile1 expect_normal_exit ./obj_basic_integration$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_basic_integration/Makefile0000664000000000000000000000044414123364546020764 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_basic_integration/Makefile -- build obj_basic_integration test # TARGET = obj_basic_integration OBJS = obj_basic_integration.o LIBPMEMOBJ=y include ../Makefile.inc INCS += -I../../libpmemobj pmdk-1.11.1/src/test/obj_basic_integration/TEST3.PS10000664000000000000000000000101014123364546020501 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_basic_integration/TEST3 -- unit test for # pmemobj APIs # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\testset1 16M:$DIR\testfile1:x r 16M:$DIR\testfile2:x expect_normal_exit $Env:EXE_DIR\obj_basic_integration$Env:EXESUFFIX ` $DIR\testset1 ` compare_replicas "-soOaAb -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST2.PS10000664000000000000000000000067114123364546020514 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_basic_integration/TEST2 -- unit test for # pmemobj APIs # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\testset1 8M:$DIR\testfile1:x 8M:$DIR\testfile2:x ` r 16M:$DIR\testfile3:x expect_normal_exit $Env:EXE_DIR\obj_basic_integration$Env:EXESUFFIX ` $DIR\testset1 ` check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST50000775000000000000000000000363514123364546020123 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup create_holey_file 16M $DIR/testfile1 expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_basic_integration/TEST40000775000000000000000000000103314123364546020110 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium setup create_poolset $DIR/testset1 16M:$DIR/testfile1 \ r 18M:$DIR/testfile2 \ r 20M:$DIR/testfile3 expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testset1 compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile2 > diff$UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" \ $DIR/testfile1 $DIR/testfile3 >> diff$UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_basic_integration/strace10.log.match0000664000000000000000000000002614123364546022540 0ustar rootroot+++ exited with 0 +++ pmdk-1.11.1/src/test/obj_basic_integration/TEST70000775000000000000000000000052314123364546020116 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 # covered by TEST5 configure_valgrind memcheck force-disable setup dax_device_zero expect_normal_exit ./obj_basic_integration$EXESUFFIX $DEVICE_DAX_PATH pass pmdk-1.11.1/src/test/obj_basic_integration/out0.log.match0000664000000000000000000000203414123364546022006 0ustar rootrootobj_basic_integration$(nW)TEST0: START: obj_basic_integration $(nW)obj_basic_integration$(nW) $(nW)testfile1 alloc: 128, size: $(N) realloc: 128 => 655360, size: $(N) realloc: 655360 => 1, size: $(N) free realloc: 0 => 777, size: $(N) realloc: 777 => 1, size: $(N) free realloc: 0 => 1, size: $(N) realloc: 1 => 1, size: $(N) free POBJ_LIST_FOREACH: dummy_node 0 POBJ_LIST_FOREACH: dummy_node 5 POBJ_LIST_FOREACH: dummy_node 6 POBJ_LIST_NEXT: dummy_node 0 POBJ_LIST_NEXT: dummy_node 5 POBJ_LIST_NEXT: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 8 POBJ_LIST_FOREACH_REVERSE: dummy_node 7 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_PREV: dummy_node 8 POBJ_LIST_PREV: dummy_node 7 POBJ_LIST_PREV: dummy_node 5 nested transaction for different pool explicit transaction abort: Operation canceled obj_basic_integration$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_basic_integration/TESTS.py0000775000000000000000000000070314123364546020601 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation import testframework as t class BASIC(t.Test): test_type = t.Medium def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile1') ctx.exec('obj_basic_integration', filepath) @t.require_valgrind_disabled('memcheck') class TEST0(BASIC): pass @t.require_valgrind_enabled('pmemcheck') class TEST1(BASIC): pass pmdk-1.11.1/src/test/obj_basic_integration/TEST0.PS10000664000000000000000000000057414123364546020514 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_basic_integration/TEST0 -- unit test for # pmemobj APIs # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_holey_file 16M $DIR\testfile1 expect_normal_exit $Env:EXE_DIR\obj_basic_integration$Env:EXESUFFIX ` $DIR\testfile1 ` check pass pmdk-1.11.1/src/test/obj_basic_integration/.gitignore0000664000000000000000000000002614123364546021310 0ustar rootrootobj_basic_integration pmdk-1.11.1/src/test/obj_basic_integration/config.sh0000664000000000000000000000043614123364546021126 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # obj_basic_integration/config.sh -- test configuration # # Extend timeout for this test, as it may take a few minutes # when run on a non-pmem file system. CONF_GLOBAL_TIMEOUT='10m' pmdk-1.11.1/src/test/obj_basic_integration/TEST60000775000000000000000000000063214123364546020116 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-enable export PMEMOBJ_VG_CHECK_UNDEF=1 setup create_poolset $DIR/testset1 8M:$DIR/testfile1:x 8M:$DIR/testfile2:x \ r 16M:$DIR/testfile3:x expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/TEST10000775000000000000000000000360114123364546020110 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # . ../unittest/unittest.sh require_test_type medium configure_valgrind pmemcheck force-enable setup create_holey_file 16M $DIR/testfile1 expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST4.PS10000664000000000000000000000120214123364546020505 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # # src/test/obj_basic_integration/TEST4 -- unit test for # pmemobj APIs # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup create_poolset $DIR\testset1 16M:$DIR\testfile1 ` r 18M:$DIR\testfile2 ` r 20M:$DIR\testfile3 expect_normal_exit ` $Env:EXE_DIR\obj_basic_integration$Env:EXESUFFIX $DIR\testset1 compare_replicas "-soOaAb -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile2 > diff$Env:UNITTEST_NUM.log compare_replicas "-soOaAb -l -Z -H -C" ` $DIR\testfile1 $DIR\testfile3 >> diff$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST80000775000000000000000000000050614123364546020120 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 setup dax_device_zero create_poolset $DIR/testset1 AUTO:$DEVICE_DAX_PATH expect_normal_exit ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/obj_basic_integration.vcxproj.filters0000664000000000000000000000311614123364546026725 0ustar rootroot {c0f52631-8f99-42f0-8d94-07ddeba87436} ps1 {fdf90df9-299e-4772-9987-80b460bd2573} {7782ecac-f1e4-49cb-b06c-0fc343dd3a97} match Source Files Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/obj_basic_integration/out1.log.match0000664000000000000000000000203414123364546022007 0ustar rootrootobj_basic_integration$(nW)TEST1: START: obj_basic_integration $(nW)obj_basic_integration$(nW) $(nW)testfile1 alloc: 128, size: $(N) realloc: 128 => 655360, size: $(N) realloc: 655360 => 1, size: $(N) free realloc: 0 => 777, size: $(N) realloc: 777 => 1, size: $(N) free realloc: 0 => 1, size: $(N) realloc: 1 => 1, size: $(N) free POBJ_LIST_FOREACH: dummy_node 0 POBJ_LIST_FOREACH: dummy_node 5 POBJ_LIST_FOREACH: dummy_node 6 POBJ_LIST_NEXT: dummy_node 0 POBJ_LIST_NEXT: dummy_node 5 POBJ_LIST_NEXT: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 8 POBJ_LIST_FOREACH_REVERSE: dummy_node 7 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_PREV: dummy_node 8 POBJ_LIST_PREV: dummy_node 7 POBJ_LIST_PREV: dummy_node 5 nested transaction for different pool explicit transaction abort: Operation canceled obj_basic_integration$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_basic_integration/TEST100000775000000000000000000000065714123364546020200 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium require_command $STRACE require_dax_devices 1 require_no_asan # covered by TEST5 configure_valgrind memcheck force-disable setup dax_device_zero expect_normal_exit $STRACE -emsync -ostrace$UNITTEST_NUM.log \ ./obj_basic_integration$EXESUFFIX $DEVICE_DAX_PATH check pass pmdk-1.11.1/src/test/obj_basic_integration/TEST20000775000000000000000000000052714123364546020115 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation . ../unittest/unittest.sh require_test_type medium setup create_poolset $DIR/testset1 8M:$DIR/testfile1:x 8M:$DIR/testfile2:x \ r 16M:$DIR/testfile3:x expect_normal_exit\ ./obj_basic_integration$EXESUFFIX $DIR/testset1 check pass pmdk-1.11.1/src/test/obj_basic_integration/out3.log.match0000664000000000000000000000203314123364546022010 0ustar rootrootobj_basic_integration$(nW)TEST3: START: obj_basic_integration $(nW)obj_basic_integration$(nW) $(nW)testset1 alloc: 128, size: $(N) realloc: 128 => 655360, size: $(N) realloc: 655360 => 1, size: $(N) free realloc: 0 => 777, size: $(N) realloc: 777 => 1, size: $(N) free realloc: 0 => 1, size: $(N) realloc: 1 => 1, size: $(N) free POBJ_LIST_FOREACH: dummy_node 0 POBJ_LIST_FOREACH: dummy_node 5 POBJ_LIST_FOREACH: dummy_node 6 POBJ_LIST_NEXT: dummy_node 0 POBJ_LIST_NEXT: dummy_node 5 POBJ_LIST_NEXT: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 8 POBJ_LIST_FOREACH_REVERSE: dummy_node 7 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_PREV: dummy_node 8 POBJ_LIST_PREV: dummy_node 7 POBJ_LIST_PREV: dummy_node 5 nested transaction for different pool explicit transaction abort: Operation canceled obj_basic_integration$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_basic_integration/out4.log.match0000664000000000000000000000203314123364546022011 0ustar rootrootobj_basic_integration$(nW)TEST4: START: obj_basic_integration $(nW)obj_basic_integration$(nW) $(nW)testset1 alloc: 128, size: $(N) realloc: 128 => 655360, size: $(N) realloc: 655360 => 1, size: $(N) free realloc: 0 => 777, size: $(N) realloc: 777 => 1, size: $(N) free realloc: 0 => 1, size: $(N) realloc: 1 => 1, size: $(N) free POBJ_LIST_FOREACH: dummy_node 0 POBJ_LIST_FOREACH: dummy_node 5 POBJ_LIST_FOREACH: dummy_node 6 POBJ_LIST_NEXT: dummy_node 0 POBJ_LIST_NEXT: dummy_node 5 POBJ_LIST_NEXT: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 8 POBJ_LIST_FOREACH_REVERSE: dummy_node 7 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_PREV: dummy_node 8 POBJ_LIST_PREV: dummy_node 7 POBJ_LIST_PREV: dummy_node 5 nested transaction for different pool explicit transaction abort: Operation canceled obj_basic_integration$(nW)TEST4: DONE pmdk-1.11.1/src/test/obj_basic_integration/diff3.log.match0000664000000000000000000000000014123364546022101 0ustar rootrootpmdk-1.11.1/src/test/obj_basic_integration/out2.log.match0000664000000000000000000000203314123364546022007 0ustar rootrootobj_basic_integration$(nW)TEST2: START: obj_basic_integration $(nW)obj_basic_integration$(nW) $(nW)testset1 alloc: 128, size: $(N) realloc: 128 => 655360, size: $(N) realloc: 655360 => 1, size: $(N) free realloc: 0 => 777, size: $(N) realloc: 777 => 1, size: $(N) free realloc: 0 => 1, size: $(N) realloc: 1 => 1, size: $(N) free POBJ_LIST_FOREACH: dummy_node 0 POBJ_LIST_FOREACH: dummy_node 5 POBJ_LIST_FOREACH: dummy_node 6 POBJ_LIST_NEXT: dummy_node 0 POBJ_LIST_NEXT: dummy_node 5 POBJ_LIST_NEXT: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 6 POBJ_LIST_FOREACH_REVERSE: dummy_node 8 POBJ_LIST_FOREACH_REVERSE: dummy_node 7 POBJ_LIST_FOREACH_REVERSE: dummy_node 5 POBJ_LIST_PREV: dummy_node 6 POBJ_LIST_PREV: dummy_node 8 POBJ_LIST_PREV: dummy_node 7 POBJ_LIST_PREV: dummy_node 5 nested transaction for different pool explicit transaction abort: Operation canceled obj_basic_integration$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_basic_integration/TEST110000775000000000000000000000105714123364546020174 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_basic_integration/TEST11 -- basic integration tests for libpmemobj # # Same as TEST0, but run on a pool set that spans two Device DAX devices # with 4K alignment. # . ../unittest/unittest.sh require_test_type medium require_dax_device_alignments 4096 4096 setup dax_device_zero create_poolset $DIR/testset1 AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_normal_exit ./obj_basic_integration$EXESUFFIX $DIR/testset1 pass pmdk-1.11.1/src/test/obj_basic_integration/diff4.log.match0000664000000000000000000000000014123364546022102 0ustar rootrootpmdk-1.11.1/src/test/pmemset_event/0000775000000000000000000000000014123364546015657 5ustar rootrootpmdk-1.11.1/src/test/pmemset_event/Makefile0000664000000000000000000000045614123364546017324 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # # src/test/pmemset_event/Makefile -- build pmemset_event test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmemset_event OBJS = pmemset_event.o \ ut_pmemset_utils.o LIBPMEMSET=y include ../Makefile.inc pmdk-1.11.1/src/test/pmemset_event/pmemset_event.c0000664000000000000000000001534214123364546020703 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmemset_events.c -- pmemset_events unittests */ #include #ifndef _WIN32 #include #endif #include "fault_injection.h" #include "unittest.h" #include "ut_pmemset_utils.h" /* * create_config - create and initialize config */ static void create_config(struct pmemset_config **cfg) { int ret = pmemset_config_new(cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); ret = pmemset_config_set_required_store_granularity(*cfg, PMEM2_GRANULARITY_PAGE); UT_PMEMSET_EXPECT_RETURN(ret, 0); UT_ASSERTne(cfg, NULL); } /* * map -- map pmemset_source */ static void map(struct pmemset *set, struct pmemset_source *src, struct pmemset_part_descriptor *desc) { struct pmemset_part *part; int ret = pmemset_part_new(&part, set, src, 0, 0); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_part_map(&part, NULL, desc); UT_PMEMSET_EXPECT_RETURN(ret, 0); } /* * cleanup -- perform cleanup after the test */ static void cleanup(struct pmemset *set, struct pmemset_config *cfg, struct pmemset_source *src, struct pmem2_source *pmem2_src, int fd) { int ret = pmemset_delete(&set); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_config_delete(&cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_delete(&src); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmem2_source_delete(&pmem2_src); UT_PMEMSET_EXPECT_RETURN(ret, 0); CLOSE(fd); } struct persist_args { void *addr; size_t len; int drains; }; /* * persist_callback -- callback used in pmemset_persist_event test */ static int persist_callback(struct pmemset *set, struct pmemset_event_context *ctx, void *arg) { if (ctx->type == PMEMSET_EVENT_FLUSH) { struct persist_args *persist = arg; persist->addr = ctx->data.flush.addr; persist->len = ctx->data.flush.len; } if (ctx->type == PMEMSET_EVENT_DRAIN) { struct persist_args *persist = arg; persist->drains++; } return 0; } #define MASK_ADDR (void *)0xFFBADFF #define MASK_LEN 0xFFFF /* * test_pmemset_persist_event -- test PMEMSET_EVENT_FLUSH and * PMEMSET_EVENT_DRAIN events */ static int test_pmemset_persist_event(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_pmemset_flush_event "); char *file = argv[0]; struct pmem2_source *pmem2_src; struct pmemset *set; struct pmemset_config *cfg; struct pmemset_source *src; struct pmemset_part_descriptor desc; struct persist_args args; args.drains = 0; int fd = OPEN(file, O_RDWR); int ret = pmem2_source_from_fd(&pmem2_src, fd); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_from_pmem2(&src, pmem2_src); UT_PMEMSET_EXPECT_RETURN(ret, 0); create_config(&cfg); pmemset_config_set_event_callback(cfg, &persist_callback, &args); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); map(set, src, &desc); pmemset_flush(set, desc.addr, desc.size); UT_ASSERTeq(desc.addr, args.addr); UT_ASSERTeq(desc.size, args.len); UT_ASSERTeq(args.drains, 0); args.addr = MASK_ADDR; args.len = MASK_LEN; pmemset_drain(set); UT_ASSERTeq(args.addr, MASK_ADDR); UT_ASSERTeq(args.len, MASK_LEN); UT_ASSERTeq(args.drains, 1); void *new_addr = (char *)desc.addr + 100; size_t new_size = desc.size - 100; pmemset_persist(set, new_addr, new_size); UT_ASSERTeq(args.addr, new_addr); UT_ASSERTeq(args.len, new_size); UT_ASSERTeq(args.drains, 2); cleanup(set, cfg, src, pmem2_src, fd); return 1; } struct copy_args { int count; int drains; }; /* * copy_callback -- callback used in pmemset_copy_event test */ static int copy_callback(struct pmemset *set, struct pmemset_event_context *ctx, void *arg) { struct copy_args *copy = arg; if (ctx->type == PMEMSET_EVENT_FLUSH) UT_FATAL( "pmemset_copy|pmemset_mov|pmemset_set should not fire flush event"); if (ctx->type == PMEMSET_EVENT_DRAIN) { copy->drains++; return 0; } char *dest; char *src; size_t len; if (ctx->type == PMEMSET_EVENT_SET) { copy->count++; char *addr = ctx->data.set.dest; char value = (char)ctx->data.set.value; if (addr[0] != value) return 0; dest = addr; src = addr + 1; len = ctx->data.set.len - 1; } else if (ctx->type == PMEMSET_EVENT_COPY) { copy->count++; dest = ctx->data.copy.dest; src = ctx->data.copy.src; len = ctx->data.copy.len; } else if (ctx->type == PMEMSET_EVENT_MOVE) { copy->count++; dest = ctx->data.move.dest; src = ctx->data.move.src; len = ctx->data.move.len; } else { return 0; } if (memcmp(dest, src, len) == 0) goto fatal; return 0; fatal: UT_FATAL( "PMEMSET_EVENT_COPY|MOVE|SET should be fired before the operation"); } #define DATA_SIZE 10000 /* * test_pmemset_copy_event -- test PMEMSET_EVENT_COPY PMEMSET_EVENT_MOVE and * PMEMSET_EVENT_SET events */ static int test_pmemset_copy_event(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL("usage: test_pmemset_flush_event "); char *file = argv[0]; struct pmem2_source *pmem2_src; struct pmemset *set; struct pmemset_config *cfg; struct pmemset_source *src; struct pmemset_part_descriptor desc; struct copy_args args; args.drains = 0; args.count = 0; int fd = OPEN(file, O_RDWR); int ret = pmem2_source_from_fd(&pmem2_src, fd); UT_PMEMSET_EXPECT_RETURN(ret, 0); ret = pmemset_source_from_pmem2(&src, pmem2_src); UT_PMEMSET_EXPECT_RETURN(ret, 0); create_config(&cfg); pmemset_config_set_event_callback(cfg, ©_callback, &args); ret = pmemset_new(&set, cfg); UT_PMEMSET_EXPECT_RETURN(ret, 0); map(set, src, &desc); char *addr = desc.addr; pmemset_memset(set, addr, 0xBB, DATA_SIZE, 0); UT_ASSERTeq(args.drains, 1); UT_ASSERTeq(args.count, 1); pmemset_memcpy(set, addr + DATA_SIZE, addr, DATA_SIZE, 0); UT_ASSERTeq(args.drains, 2); UT_ASSERTeq(args.count, 2); pmemset_memmove(set, addr + DATA_SIZE * 2, addr + DATA_SIZE, DATA_SIZE, 0); UT_ASSERTeq(args.drains, 3); UT_ASSERTeq(args.count, 3); pmemset_memset(set, addr, 0xFF, DATA_SIZE, PMEMSET_F_MEM_NODRAIN); UT_ASSERTeq(args.drains, 3); UT_ASSERTeq(args.count, 4); pmemset_memcpy(set, addr + DATA_SIZE, addr, DATA_SIZE, PMEMSET_F_MEM_NODRAIN); UT_ASSERTeq(args.drains, 3); UT_ASSERTeq(args.count, 5); pmemset_memmove(set, addr + DATA_SIZE * 2, addr + DATA_SIZE, DATA_SIZE, PMEMSET_F_MEM_NODRAIN); UT_ASSERTeq(args.drains, 3); UT_ASSERTeq(args.count, 6); pmemset_drain(set); cleanup(set, cfg, src, pmem2_src, fd); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_pmemset_persist_event), TEST_CASE(test_pmemset_copy_event), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmemset_event"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmemset_event/pmemset_event.vcxproj.filters0000664000000000000000000000223214123364546023615 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {de4f559b-32c6-4ca5-8595-5783009a8756} Test Scripts Source Files Source Files Header Files pmdk-1.11.1/src/test/pmemset_event/TESTS.py0000664000000000000000000000107014123364546017131 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2021, Intel Corporation # import testframework as t from testframework import granularity as g @g.require_granularity(g.ANY) class PmemsetEvent(t.Test): test_type = t.Short filesize = 8 * t.MiB def run(self, ctx): filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmemset_event', self.test_case, filepath) class TEST1(PmemsetEvent): test_case = "test_pmemset_persist_event" class TEST2(PmemsetEvent): test_case = "test_pmemset_copy_event" pmdk-1.11.1/src/test/pmemset_event/.gitignore0000664000000000000000000000001614123364546017644 0ustar rootrootpmemset_event pmdk-1.11.1/src/test/pmemset_event/pmemset_event.vcxproj0000664000000000000000000001056614123364546022157 0ustar rootroot Debug x64 Release x64 {C5F4585B-C619-48C8-B1CB-DBCFE08CFD50} pmemset_event 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmemset;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {fbaefc34-d221-4203-8bf6-162de1a5be1c} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_alloc/0000775000000000000000000000000014123364546015443 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_alloc/obj_tx_alloc.vcxproj0000664000000000000000000001002714123364546021517 0ustar rootroot Debug x64 Release x64 {4C429783-0B01-449F-A36F-C2019233890B} Win32Proj obj_tx_alloc 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled CompileAsCpp CompileAsCpp {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_alloc/TEST00000775000000000000000000000410714123364546016232 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_alloc/TEST0 -- unit test for pmemobj_tx_alloc # . ../unittest/unittest.sh require_test_type medium # Pmemcheck is disabled here. The next test case (TEST1) will run the same test # under pmemcheck configure_valgrind pmemcheck force-disable setup SIZE=$(obj_pool_desc_size) create_nonzeroed_file 16M ${SIZE} $DIR/testfile1 expect_normal_exit ./obj_tx_alloc$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_alloc/Makefile0000664000000000000000000000037214123364546017105 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_alloc/Makefile -- build obj_tx_alloc unit test # TARGET = obj_tx_alloc OBJS = obj_tx_alloc.o LIBPMEMCOMMON=y LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_alloc/out0.log.match0000664000000000000000000000016014123364546020125 0ustar rootrootobj_tx_alloc$(nW)TEST0: START: obj_tx_alloc $(nW)obj_tx_alloc$(nW) $(nW)testfile1 obj_tx_alloc$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_alloc/TEST0.PS10000664000000000000000000000362414123364546016634 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\obj_tx_alloc\TEST0 -- unit test for pmemobj_tx_alloc # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 16M 8K $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\obj_tx_alloc$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_tx_alloc/pmemcheck1.log.match0000664000000000000000000000415214123364546021260 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: ./obj_tx_alloc$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 1 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*): do_tx_xalloc_noflush (obj_tx_alloc.c:$(*)) ==$(*)== by 0x$(*): main (obj_tx_alloc.c:$(*)) ==$(*)== Address: 0x$(*) size: 1 state: DIRTY ==$(*)== Total memory not made persistent: 1 ==$(*)== ERROR SUMMARY: 1 errors pmdk-1.11.1/src/test/obj_tx_alloc/.gitignore0000664000000000000000000000001514123364546017427 0ustar rootrootobj_tx_alloc pmdk-1.11.1/src/test/obj_tx_alloc/TEST10000775000000000000000000000411014123364546016225 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_alloc/TEST1 -- unit test for pmemobj_tx_alloc with # valgrind pmemcheck tool # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem configure_valgrind pmemcheck force-enable export VALGRIND_OPTS="--mult-stores=no" setup SIZE=$(obj_pool_desc_size) create_nonzeroed_file 32M ${SIZE} $DIR/testfile1 expect_normal_exit ./obj_tx_alloc$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_alloc/obj_tx_alloc.vcxproj.filters0000664000000000000000000000200014123364546023156 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {a70a4a8d-d2b3-4f85-bee3-20ebc4cf1fcf} match {05ecde08-c9ae-4ba2-aeb9-bb6a0473ee9b} ps1 Source Files Match Files Test Scripts pmdk-1.11.1/src/test/obj_tx_alloc/obj_tx_alloc.c0000664000000000000000000005027314123364546020255 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_tx_alloc.c -- unit test for pmemobj_tx_alloc and pmemobj_tx_zalloc */ #include #include #include #include "unittest.h" #include "libpmemobj.h" #include "util.h" #include "valgrind_internal.h" #define LAYOUT_NAME "tx_alloc" #define TEST_VALUE_1 1 #define TEST_VALUE_2 2 #define OBJ_SIZE (200 * 1024) enum type_number { TYPE_NO_TX, TYPE_COMMIT, TYPE_ABORT, TYPE_ZEROED_COMMIT, TYPE_ZEROED_ABORT, TYPE_XCOMMIT, TYPE_XABORT, TYPE_XZEROED_COMMIT, TYPE_XZEROED_ABORT, TYPE_XNOFLUSHED_COMMIT, TYPE_COMMIT_NESTED1, TYPE_COMMIT_NESTED2, TYPE_ABORT_NESTED1, TYPE_ABORT_NESTED2, TYPE_ABORT_AFTER_NESTED1, TYPE_ABORT_AFTER_NESTED2, TYPE_OOM, }; TOID_DECLARE(struct object, TYPE_OOM); struct object { size_t value; char data[OBJ_SIZE - sizeof(size_t)]; }; /* * do_tx_alloc_oom -- allocates objects until OOM */ static void do_tx_alloc_oom(PMEMobjpool *pop) { int do_alloc = 1; size_t alloc_cnt = 0; do { TX_BEGIN(pop) { TOID(struct object) obj = TX_NEW(struct object); D_RW(obj)->value = alloc_cnt; } TX_ONCOMMIT { alloc_cnt++; } TX_ONABORT { do_alloc = 0; } TX_END } while (do_alloc); size_t bitmap_size = howmany(alloc_cnt, 8); char *bitmap = (char *)MALLOC(bitmap_size); memset(bitmap, 0, bitmap_size); size_t obj_cnt = 0; TOID(struct object) i; POBJ_FOREACH_TYPE(pop, i) { UT_ASSERT(D_RO(i)->value < alloc_cnt); UT_ASSERT(!isset(bitmap, D_RO(i)->value)); setbit(bitmap, D_RO(i)->value); obj_cnt++; } FREE(bitmap); UT_ASSERTeq(obj_cnt, alloc_cnt); TOID(struct object) o = POBJ_FIRST(pop, struct object); while (!TOID_IS_NULL(o)) { TOID(struct object) next = POBJ_NEXT(o); POBJ_FREE(&o); o = next; } } /* * do_tx_alloc_abort_after_nested -- aborts transaction after allocation * in nested transaction */ static void do_tx_alloc_abort_after_nested(PMEMobjpool *pop) { TOID(struct object) obj1; TOID(struct object) obj2; TX_BEGIN(pop) { TOID_ASSIGN(obj1, pmemobj_tx_alloc(sizeof(struct object), TYPE_ABORT_AFTER_NESTED1)); UT_ASSERT(!TOID_IS_NULL(obj1)); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { TOID_ASSIGN(obj2, pmemobj_tx_zalloc( sizeof(struct object), TYPE_ABORT_AFTER_NESTED2)); UT_ASSERT(!TOID_IS_NULL(obj2)); UT_ASSERT(util_is_zeroed(D_RO(obj2), sizeof(struct object))); D_RW(obj2)->value = TEST_VALUE_2; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj2)->value, TEST_VALUE_2); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj1, OID_NULL); TOID_ASSIGN(obj2, OID_NULL); } TX_END TOID(struct object) first; /* check the obj1 object */ UT_ASSERT(TOID_IS_NULL(obj1)); first.oid = POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_AFTER_NESTED1); UT_ASSERT(TOID_IS_NULL(first)); /* check the obj2 object */ UT_ASSERT(TOID_IS_NULL(obj2)); first.oid = POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_AFTER_NESTED2); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_alloc_abort_nested -- aborts transaction in nested transaction */ static void do_tx_alloc_abort_nested(PMEMobjpool *pop) { TOID(struct object) obj1; TOID(struct object) obj2; TX_BEGIN(pop) { TOID_ASSIGN(obj1, pmemobj_tx_alloc(sizeof(struct object), TYPE_ABORT_NESTED1)); UT_ASSERT(!TOID_IS_NULL(obj1)); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { TOID_ASSIGN(obj2, pmemobj_tx_zalloc( sizeof(struct object), TYPE_ABORT_NESTED2)); UT_ASSERT(!TOID_IS_NULL(obj2)); UT_ASSERT(util_is_zeroed(D_RO(obj2), sizeof(struct object))); D_RW(obj2)->value = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj2, OID_NULL); } TX_END } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj1, OID_NULL); } TX_END TOID(struct object) first; /* check the obj1 object */ UT_ASSERT(TOID_IS_NULL(obj1)); first.oid = POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_NESTED1); UT_ASSERT(TOID_IS_NULL(first)); /* check the obj2 object */ UT_ASSERT(TOID_IS_NULL(obj2)); first.oid = POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_NESTED2); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_alloc_commit_nested -- allocates two objects, one in nested transaction */ static void do_tx_alloc_commit_nested(PMEMobjpool *pop) { TOID(struct object) obj1; TOID(struct object) obj2; TX_BEGIN(pop) { TOID_ASSIGN(obj1, pmemobj_tx_alloc(sizeof(struct object), TYPE_COMMIT_NESTED1)); UT_ASSERT(!TOID_IS_NULL(obj1)); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { TOID_ASSIGN(obj2, pmemobj_tx_zalloc( sizeof(struct object), TYPE_COMMIT_NESTED2)); UT_ASSERT(!TOID_IS_NULL(obj2)); UT_ASSERT(util_is_zeroed(D_RO(obj2), sizeof(struct object))); D_RW(obj2)->value = TEST_VALUE_2; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj1)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj2)->value, TEST_VALUE_2); } TX_ONABORT { UT_ASSERT(0); } TX_END } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj1)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj2)->value, TEST_VALUE_2); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID(struct object) first; TOID(struct object) next; /* check the obj1 object */ TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_NESTED1)); UT_ASSERT(TOID_EQUALS(first, obj1)); UT_ASSERTeq(D_RO(first)->value, TEST_VALUE_1); TOID_ASSIGN(next, POBJ_NEXT_TYPE_NUM(first.oid)); UT_ASSERT(TOID_IS_NULL(next)); /* check the obj2 object */ TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_NESTED2)); UT_ASSERT(TOID_EQUALS(first, obj2)); UT_ASSERTeq(D_RO(first)->value, TEST_VALUE_2); TOID_ASSIGN(next, POBJ_NEXT_TYPE_NUM(first.oid)); UT_ASSERT(TOID_IS_NULL(next)); } /* * do_tx_alloc_abort -- allocates an object and aborts the transaction */ static void do_tx_alloc_abort(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_alloc(sizeof(struct object), TYPE_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_alloc_zerolen -- allocates an object of zero size to trigger tx abort */ static void do_tx_alloc_zerolen(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_alloc(0, TYPE_ABORT)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_alloc_huge -- allocates a huge object to trigger tx abort */ static void do_tx_alloc_huge(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_alloc(PMEMOBJ_MAX_ALLOC_SIZE + 1, TYPE_ABORT)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_alloc_commit -- allocates and object */ static void do_tx_alloc_commit(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_alloc(sizeof(struct object), TYPE_COMMIT)); UT_ASSERT(!TOID_IS_NULL(obj)); D_RW(obj)->value = TEST_VALUE_1; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT)); UT_ASSERT(TOID_EQUALS(first, obj)); UT_ASSERTeq(D_RO(first)->value, D_RO(obj)->value); TOID(struct object) next; next = POBJ_NEXT(first); UT_ASSERT(TOID_IS_NULL(next)); } /* * do_tx_zalloc_abort -- allocates a zeroed object and aborts the transaction */ static void do_tx_zalloc_abort(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zalloc(sizeof(struct object), TYPE_ZEROED_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(util_is_zeroed(D_RO(obj), sizeof(struct object))); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_zalloc_zerolen -- allocate an object of zero size to trigger tx abort */ static void do_tx_zalloc_zerolen(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zalloc(0, TYPE_ZEROED_ABORT)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_zalloc_huge -- allocates a huge object to trigger tx abort */ static void do_tx_zalloc_huge(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zalloc(PMEMOBJ_MAX_ALLOC_SIZE + 1, TYPE_ZEROED_ABORT)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_zalloc_commit -- allocates zeroed object */ static void do_tx_zalloc_commit(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zalloc(sizeof(struct object), TYPE_ZEROED_COMMIT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(util_is_zeroed(D_RO(obj), sizeof(struct object))); D_RW(obj)->value = TEST_VALUE_1; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_ZEROED_COMMIT)); UT_ASSERT(TOID_EQUALS(first, obj)); UT_ASSERTeq(D_RO(first)->value, D_RO(obj)->value); TOID(struct object) next; next = POBJ_NEXT(first); UT_ASSERT(TOID_IS_NULL(next)); } /* * do_tx_xalloc_abort -- allocates a zeroed object and aborts the transaction */ static void do_tx_xalloc_abort(PMEMobjpool *pop) { /* xalloc 0 */ TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(sizeof(struct object), TYPE_XABORT, 0)); UT_ASSERT(!TOID_IS_NULL(obj)); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XABORT)); UT_ASSERT(TOID_IS_NULL(first)); /* xalloc ZERO */ TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(sizeof(struct object), TYPE_XZEROED_ABORT, POBJ_XALLOC_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(util_is_zeroed(D_RO(obj), sizeof(struct object))); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_xalloc_zerolen -- allocate an object of zero size to trigger tx abort */ static void do_tx_xalloc_zerolen(PMEMobjpool *pop) { /* xalloc 0 */ TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(0, TYPE_XABORT, 0)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); /* xalloc 0 with POBJ_XALLOC_NO_ABORT flag */ TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(0, TYPE_XABORT, POBJ_XALLOC_NO_ABORT)); } TX_ONCOMMIT { TOID_ASSIGN(obj, OID_NULL); } TX_ONABORT { UT_ASSERT(0); /* should not get to this point */ } TX_END UT_ASSERT(TOID_IS_NULL(obj)); /* alloc 0 with pmemobj_tx_set_failure_behavior called */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); TOID_ASSIGN(obj, pmemobj_tx_alloc(0, TYPE_XABORT)); } TX_ONCOMMIT { TOID_ASSIGN(obj, OID_NULL); } TX_ONABORT { UT_ASSERT(0); /* should not get to this point */ } TX_END UT_ASSERT(TOID_IS_NULL(obj)); /* xalloc 0 with pmemobj_tx_set_failure_behavior called */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); TOID_ASSIGN(obj, pmemobj_tx_xalloc(0, TYPE_XABORT, 0)); } TX_ONCOMMIT { TOID_ASSIGN(obj, OID_NULL); } TX_ONABORT { UT_ASSERT(0); /* should not get to this point */ } TX_END UT_ASSERT(TOID_IS_NULL(obj)); /* zalloc 0 with pmemobj_tx_set_failure_behavior called */ TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); TOID_ASSIGN(obj, pmemobj_tx_zalloc(0, TYPE_XABORT)); } TX_ONCOMMIT { TOID_ASSIGN(obj, OID_NULL); } TX_ONABORT { UT_ASSERT(0); /* should not get to this point */ } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XABORT)); UT_ASSERT(TOID_IS_NULL(first)); /* xalloc ZERO */ TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(0, TYPE_XZEROED_ABORT, POBJ_XALLOC_ZERO)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); } /* * do_tx_xalloc_huge -- allocates a huge object to trigger tx abort */ static void do_tx_xalloc_huge(PMEMobjpool *pop) { /* xalloc 0 */ TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(PMEMOBJ_MAX_ALLOC_SIZE + 1, TYPE_XABORT, 0)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XABORT)); UT_ASSERT(TOID_IS_NULL(first)); /* xalloc ZERO */ TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(PMEMOBJ_MAX_ALLOC_SIZE + 1, TYPE_XZEROED_ABORT, POBJ_XALLOC_ZERO)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { TOID_ASSIGN(obj, OID_NULL); } TX_END UT_ASSERT(TOID_IS_NULL(obj)); TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XZEROED_ABORT)); UT_ASSERT(TOID_IS_NULL(first)); /* * do xalloc until overfilled and then * free last successful allocation */ uint64_t tot_allocated = 0, alloc_size = (5 * 1024 *1024); int rc = 0; PMEMoid oid, prev_oid; POBJ_FOREACH_SAFE(pop, oid, prev_oid) { pmemobj_free(&oid); } TOID_ASSIGN(first, pmemobj_first(pop)); UT_ASSERT(TOID_IS_NULL(first)); TX_BEGIN(pop) { while (rc == 0) { oid = pmemobj_tx_xalloc(alloc_size, 0, POBJ_XALLOC_NO_ABORT); if (oid.off == 0) rc = -1; else { tot_allocated += alloc_size; prev_oid = oid; } } rc = pmemobj_tx_free(prev_oid); } TX_ONCOMMIT { UT_ASSERTeq(errno, ENOMEM); UT_ASSERTeq(rc, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_xalloc_commit -- allocates zeroed object */ static void do_tx_xalloc_commit(PMEMobjpool *pop) { /* xalloc 0 */ TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(sizeof(struct object), TYPE_XCOMMIT, 0)); UT_ASSERT(!TOID_IS_NULL(obj)); D_RW(obj)->value = TEST_VALUE_1; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XCOMMIT)); UT_ASSERT(TOID_EQUALS(first, obj)); UT_ASSERTeq(D_RO(first)->value, D_RO(obj)->value); TOID(struct object) next; TOID_ASSIGN(next, POBJ_NEXT_TYPE_NUM(first.oid)); UT_ASSERT(TOID_IS_NULL(next)); /* xalloc ZERO */ TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(sizeof(struct object), TYPE_XZEROED_COMMIT, POBJ_XALLOC_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(util_is_zeroed(D_RO(obj), sizeof(struct object))); D_RW(obj)->value = TEST_VALUE_1; } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XZEROED_COMMIT)); UT_ASSERT(TOID_EQUALS(first, obj)); UT_ASSERTeq(D_RO(first)->value, D_RO(obj)->value); TOID_ASSIGN(next, POBJ_NEXT_TYPE_NUM(first.oid)); UT_ASSERT(TOID_IS_NULL(next)); } /* * do_tx_xalloc_noflush -- allocates zeroed object */ static void do_tx_xalloc_noflush(PMEMobjpool *pop) { TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_xalloc(sizeof(struct object), TYPE_XNOFLUSHED_COMMIT, POBJ_XALLOC_NO_FLUSH)); UT_ASSERT(!TOID_IS_NULL(obj)); D_RW(obj)->data[OBJ_SIZE - sizeof(size_t) - 1] = TEST_VALUE_1; /* let pmemcheck find we didn't flush it */ } TX_ONCOMMIT { UT_ASSERTeq(D_RO(obj)->data[OBJ_SIZE - sizeof(size_t) - 1], TEST_VALUE_1); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID(struct object) first; TOID_ASSIGN(first, POBJ_FIRST_TYPE_NUM(pop, TYPE_XNOFLUSHED_COMMIT)); UT_ASSERT(TOID_EQUALS(first, obj)); UT_ASSERTeq(D_RO(first)->data[OBJ_SIZE - sizeof(size_t) - 1], D_RO(obj)->data[OBJ_SIZE - sizeof(size_t) - 1]); TOID(struct object) next; TOID_ASSIGN(next, POBJ_NEXT_TYPE_NUM(first.oid)); UT_ASSERT(TOID_IS_NULL(next)); } /* * do_tx_root -- retrieve root inside of transaction */ static void do_tx_root(PMEMobjpool *pop) { size_t root_size = 24; TX_BEGIN(pop) { PMEMoid root = pmemobj_root(pop, root_size); UT_ASSERT(!OID_IS_NULL(root)); UT_ASSERT(util_is_zeroed(pmemobj_direct(root), root_size)); UT_ASSERTeq(root_size, pmemobj_root_size(pop)); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_alloc_many -- allocates many objects inside of a single transaction */ static void do_tx_alloc_many(PMEMobjpool *pop) { #define TX_ALLOC_COUNT 70 /* bigger than max reservations */ PMEMoid oid, oid2; POBJ_FOREACH_SAFE(pop, oid, oid2) { pmemobj_free(&oid); } TOID(struct object) first; TOID_ASSIGN(first, pmemobj_first(pop)); UT_ASSERT(TOID_IS_NULL(first)); PMEMoid oids[TX_ALLOC_COUNT]; TX_BEGIN(pop) { for (int i = 0; i < TX_ALLOC_COUNT; ++i) { oids[i] = pmemobj_tx_alloc(1, 0); UT_ASSERT(!OID_IS_NULL(oids[i])); } } TX_ONABORT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { /* empty tx to make sure there's no leftover state */ } TX_ONABORT { UT_ASSERT(0); } TX_END TX_BEGIN(pop) { for (int i = 0; i < TX_ALLOC_COUNT; ++i) { pmemobj_tx_free(oids[i]); } } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(first, pmemobj_first(pop)); UT_ASSERT(TOID_IS_NULL(first)); #undef TX_ALLOC_COUNT } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_alloc"); util_init(); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); do_tx_root(pop); VALGRIND_WRITE_STATS; /* alloc */ do_tx_alloc_commit(pop); VALGRIND_WRITE_STATS; do_tx_alloc_abort(pop); VALGRIND_WRITE_STATS; do_tx_alloc_zerolen(pop); VALGRIND_WRITE_STATS; do_tx_alloc_huge(pop); VALGRIND_WRITE_STATS; /* zalloc */ do_tx_zalloc_commit(pop); VALGRIND_WRITE_STATS; do_tx_zalloc_abort(pop); VALGRIND_WRITE_STATS; do_tx_zalloc_zerolen(pop); VALGRIND_WRITE_STATS; do_tx_zalloc_huge(pop); VALGRIND_WRITE_STATS; /* xalloc */ do_tx_xalloc_commit(pop); VALGRIND_WRITE_STATS; do_tx_xalloc_abort(pop); VALGRIND_WRITE_STATS; do_tx_xalloc_zerolen(pop); VALGRIND_WRITE_STATS; do_tx_xalloc_huge(pop); VALGRIND_WRITE_STATS; /* alloc */ do_tx_alloc_commit_nested(pop); VALGRIND_WRITE_STATS; do_tx_alloc_abort_nested(pop); VALGRIND_WRITE_STATS; do_tx_alloc_abort_after_nested(pop); VALGRIND_WRITE_STATS; do_tx_alloc_oom(pop); VALGRIND_WRITE_STATS; do_tx_alloc_many(pop); VALGRIND_WRITE_STATS; do_tx_xalloc_noflush(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_alloc/out1.log.match0000664000000000000000000000016014123364546020126 0ustar rootrootobj_tx_alloc$(nW)TEST1: START: obj_tx_alloc $(nW)obj_tx_alloc$(nW) $(nW)testfile1 obj_tx_alloc$(nW)TEST1: DONE pmdk-1.11.1/src/test/win_poolset_unmap/0000775000000000000000000000000014123364546016546 5ustar rootrootpmdk-1.11.1/src/test/win_poolset_unmap/win_poolset_unmap.vcxproj.filters0000664000000000000000000000156514123364546025403 0ustar rootroot {0da09383-3374-4523-b95d-d943028e8202} {143e1ed0-937d-4741-bcbf-bb3deb28d17a} {3f4370d4-0ac7-4311-ba0d-46a163ff2cfd} Source Files Test Scripts Match Files pmdk-1.11.1/src/test/win_poolset_unmap/grep0.log.match0000664000000000000000000000053214123364546021361 0ustar rootroot: <$(N)> [win_mmap.c:$(N) mmap_unreserve] addr $(nW) len 8388608 : <$(N)> [win_mmap.c:$(N) mmap_unreserve] freed reservation - addr: $(nW), size: 8388608 : <$(N)> [win_mmap.c:$(N) mmap_unreserve] addr $(nW) len 44040192 : <$(N)> [win_mmap.c:$(N) mmap_unreserve] freed reservation - addr: $(nW), size: 44040192 pmdk-1.11.1/src/test/win_poolset_unmap/TEST0.PS10000664000000000000000000000111314123364546017726 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/win_poolset_unmap/TEST0 -- unit test for win_mmap # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any require_build_type debug setup $Env:PMEM_LOG_LEVEL=15 mkdir $DIR\dirset | Out-Null create_poolset $DIR\testset 50M:$DIR\dirset O SINGLEHDR expect_normal_exit $Env:EXE_DIR\win_poolset_unmap$Env:EXESUFFIX $DIR\testset Get-Content pmem$Env:UNITTEST_NUM.log | Where-Object ` {$_ -match "win_mmap.c:[0-9]* mmap_unreserve"} > grep$Env:UNITTEST_NUM.log check pass pmdk-1.11.1/src/test/win_poolset_unmap/win_poolset_unmap.vcxproj0000664000000000000000000000664114123364546023734 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {810DB909-6581-42D8-9616-906888F12149} Win32Proj win_poolset_unmap 10.0.17134.0 Application true v140 Application false v140 NotUsing NotUsing pmdk-1.11.1/src/test/win_poolset_unmap/win_poolset_unmap.c0000664000000000000000000000410514123364546022454 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * win_poolset_unmap.c -- test for windows mmap destructor. * * It checks whether all mappings are properly unmpapped and memory is properly * unreserved when auto growing pool is used. */ #include "unittest.h" #include "os.h" #include "libpmemobj.h" #define KILOBYTE (1 << 10) #define MEGABYTE (1 << 20) #define LAYOUT_NAME "poolset_unmap" int main(int argc, char *argv[]) { START(argc, argv, "win_poolset_unmap"); if (argc != 2) UT_FATAL("usage: %s path", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); MEMORY_BASIC_INFORMATION basic_info; SIZE_T bytes_returned; SIZE_T offset = 0; bytes_returned = VirtualQuery(pop, &basic_info, sizeof(basic_info)); /* * When opening pool, we try to remove all permissions on header. * If this action fails VirtualQuery will return one region with * size 8MB. If it succeeds, RegionSize will be equal to 4KB due * to different header and rest of the mapping permissions. */ if (basic_info.RegionSize == 4 * KILOBYTE) { /* header */ UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.State, MEM_COMMIT); offset += basic_info.RegionSize; /* first part */ bytes_returned = VirtualQuery((char *)pop + offset, &basic_info, sizeof(basic_info)); UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.RegionSize, 8 * MEGABYTE - 4 * KILOBYTE); UT_ASSERTeq(basic_info.State, MEM_COMMIT); } else { /* first part with header */ UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.RegionSize, 8 * MEGABYTE); UT_ASSERTeq(basic_info.State, MEM_COMMIT); } offset += basic_info.RegionSize; /* reservation after first part */ bytes_returned = VirtualQuery((char *)pop + offset, &basic_info, sizeof(basic_info)); UT_ASSERTeq(bytes_returned, sizeof(basic_info)); UT_ASSERTeq(basic_info.RegionSize, (50 - 8) * MEGABYTE); UT_ASSERTeq(basic_info.State, MEM_RESERVE); DONE(NULL); } pmdk-1.11.1/src/test/win_poolset_unmap/win_poolset_unmap.filters0000664000000000000000000000171014123364546023701 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {6043ccf6-d070-43a3-867f-2aa9612ac158} ps1 {9e75d124-4f98-4b16-ad1d-f62881ec9f30} match Source Files Test Scripts pmdk-1.11.1/src/test/pmem2_movnt_align/0000775000000000000000000000000014123364546016421 5ustar rootrootpmdk-1.11.1/src/test/pmem2_movnt_align/pmem2_movnt_align.vcxproj0000664000000000000000000000776314123364546023470 0ustar rootroot Debug x64 Release x64 {9233FC80-B51C-4A89-AF58-5AE86C068F6A} Win32Proj pmem2_movnt_align 10.0.17134.0 Application true v140 Application false v140 true Disabled $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) MaxSpeed $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_movnt_align/pmem2_movnt_align.c0000664000000000000000000001225414123364546022206 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_movnt_align.c -- test for functions with non-temporal stores * * usage: pmem2_movnt_align file [C|F|B|S] * * C - pmem2_memcpy() * B - pmem2_memmove() in backward direction * F - pmem2_memmove() in forward direction * S - pmem2_memset() */ #include #include #include #include "libpmem2.h" #include "unittest.h" #include "movnt_align_common.h" #include "ut_pmem2.h" static pmem2_memset_fn memset_fn; static pmem2_memcpy_fn memcpy_fn; static pmem2_memmove_fn memmove_fn; static void check_memmove_variants(size_t doff, size_t soff, size_t len) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memmove(doff, soff, len, memmove_fn, Flags[i]); } static void check_memcpy_variants(size_t doff, size_t soff, size_t len) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memcpy(doff, soff, len, memcpy_fn, Flags[i]); } static void check_memset_variants(size_t off, size_t len) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) check_memset(off, len, memset_fn, Flags[i]); } int main(int argc, char *argv[]) { if (argc != 3) UT_FATAL("usage: %s file type", argv[0]); struct pmem2_config *cfg; struct pmem2_source *src; struct pmem2_map *map; int fd; char type = argv[2][0]; const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_movnt_align %c %s %savx %savx512f", type, thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&src, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); memset_fn = pmem2_get_memset_fn(map); memcpy_fn = pmem2_get_memcpy_fn(map); memmove_fn = pmem2_get_memmove_fn(map); ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); size_t page_size = Ut_pagesize; size_t s; switch (type) { case 'C': /* memcpy */ /* mmap with guard pages */ Src = MMAP_ANON_ALIGNED(N_BYTES, 0); Dst = MMAP_ANON_ALIGNED(N_BYTES, 0); if (Src == NULL || Dst == NULL) UT_FATAL("!mmap"); Scratch = MALLOC(N_BYTES); /* check memcpy with 0 size */ check_memcpy_variants(0, 0, 0); /* check memcpy with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(0, 0, N_BYTES - s); /* check memcpy with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(s, 0, N_BYTES - s); /* check memcpy with unaligned begin and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memcpy_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Src, N_BYTES); MUNMAP_ANON_ALIGNED(Dst, N_BYTES); FREE(Scratch); break; case 'B': /* memmove backward */ /* mmap with guard pages */ Src = MMAP_ANON_ALIGNED(2 * N_BYTES - page_size, 0); Dst = Src + N_BYTES - page_size; if (Src == NULL) UT_FATAL("!mmap"); /* check memmove in backward direction with 0 size */ check_memmove_variants(0, 0, 0); /* check memmove in backward direction with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(0, 0, N_BYTES - s); /* check memmove in backward direction with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, 0, N_BYTES - s); /* * check memmove in backward direction with unaligned begin * and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Src, 2 * N_BYTES - page_size); break; case 'F': /* memmove forward */ /* mmap with guard pages */ Dst = MMAP_ANON_ALIGNED(2 * N_BYTES - page_size, 0); Src = Dst + N_BYTES - page_size; if (Src == NULL) UT_FATAL("!mmap"); /* check memmove in forward direction with 0 size */ check_memmove_variants(0, 0, 0); /* check memmove in forward direction with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(0, 0, N_BYTES - s); /* check memmove in forward direction with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, 0, N_BYTES - s); /* * check memmove in forward direction with unaligned begin * and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memmove_variants(s, s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Dst, 2 * N_BYTES - page_size); break; case 'S': /* memset */ /* mmap with guard pages */ Dst = MMAP_ANON_ALIGNED(N_BYTES, 0); if (Dst == NULL) UT_FATAL("!mmap"); Scratch = MALLOC(N_BYTES); /* check memset with 0 size */ check_memset_variants(0, 0); /* check memset with unaligned size */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(0, N_BYTES - s); /* check memset with unaligned begin */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(s, N_BYTES - s); /* check memset with unaligned begin and end */ for (s = 0; s < CACHELINE_SIZE; s++) check_memset_variants(s, N_BYTES - 2 * s); MUNMAP_ANON_ALIGNED(Dst, N_BYTES); FREE(Scratch); break; default: UT_FATAL("!wrong type of test"); break; } DONE(NULL); } pmdk-1.11.1/src/test/pmem2_movnt_align/movnt_align_common.h0000664000000000000000000000174014123364546022461 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020, Intel Corporation */ /* * movnt_align_common.h -- header file for common movnt_align test utilities */ #ifndef MOVNT_ALIGN_COMMON_H #define MOVNT_ALIGN_COMMON_H 1 #include "unittest.h" #include "file.h" #define N_BYTES (Ut_pagesize * 2) extern char *Src; extern char *Dst; extern char *Scratch; extern unsigned Flags[10]; typedef void *(*mem_fn)(void *, const void *, size_t); typedef void *pmem_memcpy_fn(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *pmem_memmove_fn(void *pmemdest, const void *src, size_t len, unsigned flags); typedef void *pmem_memset_fn(void *pmemdest, int c, size_t len, unsigned flags); void check_memmove(size_t doff, size_t soff, size_t len, pmem_memmove_fn fn, unsigned flags); void check_memcpy(size_t doff, size_t soff, size_t len, pmem_memcpy_fn fn, unsigned flags); void check_memset(size_t off, size_t len, pmem_memset_fn fn, unsigned flags); #endif pmdk-1.11.1/src/test/pmem2_movnt_align/pmem2_movnt_align.vcxproj.filters0000664000000000000000000000303614123364546025124 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {84215fd4-bb77-4e9b-b9b6-38ad838e1cfe} PS1 {b9326830-dcd8-4ffd-9ea1-e509e63067e8} Source Files Source Files Source Files Source Files Source Files Test Scripts Header Files Header Files pmdk-1.11.1/src/test/pmem2_movnt_align/Makefile0000664000000000000000000000062514123364546020064 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_movnt_align/Makefile -- build pmem2_movnt_align test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_movnt_align OBJS = pmem2_movnt_align.o\ movnt_align_common.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_movnt_align/TESTS.py0000775000000000000000000000435114123364546017703 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t class MovntAlignCommon(t.Test): test_type = t.Short filesize = 4 * t.MiB def run_cases(self, ctx): ctx.exec('pmem2_movnt_align', self.filepath, "C") ctx.exec('pmem2_movnt_align', self.filepath, "F") ctx.exec('pmem2_movnt_align', self.filepath, "B") ctx.exec('pmem2_movnt_align', self.filepath, "S") def run(self, ctx): self.filepath = ctx.create_holey_file(self.filesize, 'testfile',) self.run_cases(ctx) class Pmem2MovntAlign(MovntAlignCommon): threshold = None threshold_values = ['0', '99999'] envs0 = () def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' super().run(ctx) for tv in self.threshold_values: ctx.env['PMEM_MOVNT_THRESHOLD'] = tv self.run_cases(ctx) @t.require_valgrind_enabled('pmemcheck') class MovntAlignCommonValgrind(Pmem2MovntAlign): test_type = t.Medium def run(self, ctx): ctx.env['VALGRIND_OPTS'] = "--mult-stores=yes" super().run(ctx) class TEST0(Pmem2MovntAlign): pass @t.require_architectures('x86_64') class TEST1(Pmem2MovntAlign): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') class TEST2(Pmem2MovntAlign): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) class TEST3(MovntAlignCommon): def run(self, ctx): ctx.env['PMEM_NO_MOVNT'] = '1' super().run(ctx) class TEST4(MovntAlignCommon): def run(self, ctx): ctx.env['PMEM_NO_MOVNT'] = '1' ctx.env['PMEM_NO_GENERIC_MEMCPY'] = '1' super().run(ctx) class TEST5(MovntAlignCommonValgrind): pass @t.require_architectures('x86_64') class TEST6(MovntAlignCommonValgrind): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') class TEST7(MovntAlignCommonValgrind): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) class TEST8(MovntAlignCommonValgrind): def run(self, ctx): ctx.env['PMEM_NO_MOVNT'] = '1' super().run(ctx) class TEST9(MovntAlignCommonValgrind): def run(self, ctx): ctx.env['PMEM_NO_MOVNT'] = '1' ctx.env['PMEM_NO_GENERIC_MEMCPY'] = '1' super().run(ctx) pmdk-1.11.1/src/test/pmem2_movnt_align/.gitignore0000664000000000000000000000002214123364546020403 0ustar rootrootpmem2_movnt_align pmdk-1.11.1/src/test/pmem2_movnt_align/movnt_align_common.c0000664000000000000000000000344614123364546022461 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * movnt_align_common.c -- common part for tests doing a persistent movnt align */ #include "unittest.h" #include "movnt_align_common.h" char *Src; char *Dst; char *Scratch; /* * check_memmove -- invoke check function with pmem_memmove_persist */ void check_memmove(size_t doff, size_t soff, size_t len, pmem_memmove_fn fn, unsigned flags) { memset(Dst + doff, 1, len); memset(Src + soff, 0, len); fn(Dst + doff, Src + soff, len, flags); if (memcmp(Dst + doff, Src + soff, len)) UT_FATAL("memcpy/memmove failed"); } /* * check_memmove -- invoke check function with pmem_memcpy_persist */ void check_memcpy(size_t doff, size_t soff, size_t len, pmem_memcpy_fn fn, unsigned flags) { memset(Dst, 2, N_BYTES); memset(Src, 3, N_BYTES); memset(Scratch, 2, N_BYTES); memset(Dst + doff, 1, len); memset(Src + soff, 0, len); memcpy(Scratch + doff, Src + soff, len); fn(Dst + doff, Src + soff, len, flags); if (memcmp(Dst, Scratch, N_BYTES)) UT_FATAL("memcpy/memmove failed"); } /* * check_memset -- check pmem_memset_no_drain function */ void check_memset(size_t off, size_t len, pmem_memset_fn fn, unsigned flags) { memset(Scratch, 2, N_BYTES); memset(Scratch + off, 1, len); memset(Dst, 2, N_BYTES); fn(Dst + off, 1, len, flags); if (memcmp(Dst, Scratch, N_BYTES)) UT_FATAL("memset failed"); } unsigned Flags[] = { 0, PMEM_F_MEM_NODRAIN, PMEM_F_MEM_NONTEMPORAL, PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_NODRAIN, PMEM_F_MEM_WC, PMEM_F_MEM_WB, PMEM_F_MEM_NOFLUSH, /* all possible flags */ PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB, }; pmdk-1.11.1/src/test/obj_check_remote/0000775000000000000000000000000014123364546016266 5ustar rootrootpmdk-1.11.1/src/test/obj_check_remote/obj_check_remote.c0000664000000000000000000000253414123364546021720 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * obj_check_remote.c -- unit tests for pmemobj_check_remote */ #include #include "unittest.h" #include "libpmemobj.h" struct vector { int x; int y; int z; }; int main(int argc, char *argv[]) { START(argc, argv, "obj_check_remote"); if (argc < 3) UT_FATAL("insufficient number of arguments"); const char *path = argv[1]; const char *action = argv[2]; const char *layout = NULL; PMEMobjpool *pop = NULL; if (strcmp(action, "abort") == 0) { pop = pmemobj_open(path, layout); if (pop == NULL) UT_FATAL("usage: %s filename abort|check", argv[0]); PMEMoid root = pmemobj_root(pop, sizeof(struct vector)); struct vector *vectorp = pmemobj_direct(root); TX_BEGIN(pop) { pmemobj_tx_add_range(root, 0, sizeof(struct vector)); vectorp->x = 5; vectorp->y = 10; vectorp->z = 15; } TX_ONABORT { UT_ASSERT(0); } TX_END int *to_modify = &vectorp->x; TX_BEGIN(pop) { pmemobj_tx_add_range_direct(to_modify, sizeof(int)); *to_modify = 30; pmemobj_persist(pop, to_modify, sizeof(*to_modify)); abort(); } TX_END } else if (strcmp(action, "check") == 0) { int ret = pmemobj_check(path, layout); if (ret == 1) return 0; else return ret; } else { UT_FATAL("%s is not a valid action", action); } return 0; } pmdk-1.11.1/src/test/obj_check_remote/TEST00000775000000000000000000000410114123364546017047 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_check_remote/TEST0 -- unit test which checks if remote # replicas were removed from poolset and were not modified by # pmemobj_check. (pmemobj_check used to rely on copy on write (MAP_PRIVATE) # for all replicas but it have never worked for remote ones) # . ../unittest/unittest.sh require_test_type medium require_command md5sum setup require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER PID_FILE=rpmemd.pid init_rpmem_on_node 1 0:$PID_FILE # binary for this test EXE=obj_check_remote # define files and directories TEST_SET_LOCAL="testset_local" TEST_SET_REMOTE="testset_remote" # remove files created by previous test rm_files_from_node 1 ${NODE_DIR[1]}/testfile1 rm_files_from_node 1 ${NODE_DIR[1]}/testfile2 rm_files_from_node 1 ${NODE_DIR[1]}/testfile3 rm_files_from_node 1 ${NODE_DIR[1]}/testfile4 rm_files_from_node 0 ${NODE_DIR[0]}/testfile5 rm_files_from_node 0 ${NODE_DIR[0]}/testfile6 create_poolset $DIR/$TEST_SET_LOCAL 32M:${NODE_DIR[1]}/testfile1:z 32M:${NODE_DIR[1]}/testfile2:z \ R 32M:${NODE_DIR[1]}/testfile3:z 32M:${NODE_DIR[1]}/testfile4:z \ m ${NODE_ADDR[0]}:$TEST_SET_REMOTE create_poolset $DIR/$TEST_SET_REMOTE 32M:${NODE_DIR[0]}/testfile5:z 32M:${NODE_DIR[0]}/testfile6:z copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}/$TEST_SET_LOCAL expect_abnormal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}/$TEST_SET_LOCAL abort # before file copy rpmemd has to finish work expect_abnormal_exit wait_on_node 0 $PID_FILE copy_files_from_node 0 $DIR ${NODE_DIR[0]}/testfile5 REPAB=`md5sum -b $DIR/testfile5` expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}/$TEST_SET_LOCAL check copy_files_from_node 0 $DIR ${NODE_DIR[0]}/testfile5 REPCHECK=`md5sum -b $DIR/testfile5` if [ "$REPAB" != "$REPCHECK" ] then fatal "$REPAB != $REPCHECK" fi check pass pmdk-1.11.1/src/test/obj_check_remote/Makefile0000664000000000000000000000041014123364546017721 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_check_remote/Makefile -- build obj_check_remote test # TARGET = obj_check_remote OBJS = obj_check_remote.o LIBPMEMOBJ=y SCP_TO_REMOTE_NODES = y include ../Makefile.inc pmdk-1.11.1/src/test/obj_check_remote/.gitignore0000664000000000000000000000002114123364546020247 0ustar rootrootobj_check_remote pmdk-1.11.1/src/test/obj_check_remote/config.sh0000664000000000000000000000047114123364546020071 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # obj_check_remote/config.sh -- test configuration # CONF_GLOBAL_FS_TYPE=any CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_TEST_TYPE=medium CONF_GLOBAL_RPMEM_PROVIDER=sockets CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/obj_strdup/0000775000000000000000000000000014123364546015157 5ustar rootrootpmdk-1.11.1/src/test/obj_strdup/TEST00000775000000000000000000000044214123364546015744 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_strdup/TEST0 -- unit test for pmemobj_strdup # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_strdup$EXESUFFIX $DIR/testfile1 pass pmdk-1.11.1/src/test/obj_strdup/Makefile0000664000000000000000000000034214123364546016616 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_strdup/Makefile -- build obj_strdup unit test # TARGET = obj_strdup OBJS = obj_strdup.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_strdup/obj_strdup.c0000664000000000000000000001163114123364546017500 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_strdup.c -- unit test for pmemobj_strdup */ #include #include #include #include "unittest.h" #include "libpmemobj.h" #define LAYOUT_NAME "strdup" TOID_DECLARE(char, 0); TOID_DECLARE(wchar_t, 1); enum type_number { TYPE_SIMPLE, TYPE_NULL, TYPE_SIMPLE_ALLOC, TYPE_SIMPLE_ALLOC_1, TYPE_SIMPLE_ALLOC_2, TYPE_NULL_ALLOC, TYPE_NULL_ALLOC_1, }; #define TEST_STR_1 "Test string 1" #define TEST_STR_2 "Test string 2" #define TEST_WCS_1 L"Test string 3" #define TEST_WCS_2 L"Test string 4" #define TEST_STR_EMPTY "" #define TEST_WCS_EMPTY L"" /* * do_strdup -- duplicate a string to not allocated toid using pmemobj_strdup */ static void do_strdup(PMEMobjpool *pop) { TOID(char) str = TOID_NULL(char); TOID(wchar_t) wcs = TOID_NULL(wchar_t); pmemobj_strdup(pop, &str.oid, TEST_STR_1, TYPE_SIMPLE); pmemobj_wcsdup(pop, &wcs.oid, TEST_WCS_1, TYPE_SIMPLE); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERT(!TOID_IS_NULL(wcs)); UT_ASSERTeq(strcmp(D_RO(str), TEST_STR_1), 0); UT_ASSERTeq(wcscmp(D_RO(wcs), TEST_WCS_1), 0); } /* * do_strdup_null -- duplicate a NULL string to not allocated toid */ static void do_strdup_null(PMEMobjpool *pop) { TOID(char) str = TOID_NULL(char); TOID(wchar_t) wcs = TOID_NULL(wchar_t); pmemobj_strdup(pop, &str.oid, NULL, TYPE_NULL); pmemobj_wcsdup(pop, &wcs.oid, NULL, TYPE_NULL); UT_ASSERT(TOID_IS_NULL(str)); UT_ASSERT(TOID_IS_NULL(wcs)); } /* * do_alloc -- allocate toid and duplicate a string */ static TOID(char) do_alloc(PMEMobjpool *pop, const char *s, unsigned type_num) { TOID(char) str; POBJ_ZNEW(pop, &str, char); pmemobj_strdup(pop, &str.oid, s, type_num); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERTeq(strcmp(D_RO(str), s), 0); return str; } /* * do_wcs_alloc -- allocate toid and duplicate a wide character string */ static TOID(wchar_t) do_wcs_alloc(PMEMobjpool *pop, const wchar_t *s, unsigned type_num) { TOID(wchar_t) str; POBJ_ZNEW(pop, &str, wchar_t); pmemobj_wcsdup(pop, &str.oid, s, type_num); UT_ASSERT(!TOID_IS_NULL(str)); UT_ASSERTeq(wcscmp(D_RO(str), s), 0); return str; } /* * do_strdup_alloc -- duplicate a string to allocated toid */ static void do_strdup_alloc(PMEMobjpool *pop) { TOID(char) str1 = do_alloc(pop, TEST_STR_1, TYPE_SIMPLE_ALLOC_1); TOID(wchar_t) wcs1 = do_wcs_alloc(pop, TEST_WCS_1, TYPE_SIMPLE_ALLOC_1); TOID(char) str2 = do_alloc(pop, TEST_STR_2, TYPE_SIMPLE_ALLOC_2); TOID(wchar_t) wcs2 = do_wcs_alloc(pop, TEST_WCS_2, TYPE_SIMPLE_ALLOC_2); pmemobj_strdup(pop, &str1.oid, D_RO(str2), TYPE_SIMPLE_ALLOC); pmemobj_wcsdup(pop, &wcs1.oid, D_RO(wcs2), TYPE_SIMPLE_ALLOC); UT_ASSERTeq(strcmp(D_RO(str1), D_RO(str2)), 0); UT_ASSERTeq(wcscmp(D_RO(wcs1), D_RO(wcs2)), 0); } /* * do_strdup_null_alloc -- duplicate a NULL string to allocated toid */ static void do_strdup_null_alloc(PMEMobjpool *pop) { TOID(char) str1 = do_alloc(pop, TEST_STR_1, TYPE_NULL_ALLOC_1); TOID(wchar_t) wcs1 = do_wcs_alloc(pop, TEST_WCS_1, TYPE_NULL_ALLOC_1); TOID(char) str2 = TOID_NULL(char); TOID(wchar_t) wcs2 = TOID_NULL(wchar_t); pmemobj_strdup(pop, &str1.oid, D_RO(str2), TYPE_NULL_ALLOC); pmemobj_wcsdup(pop, &wcs1.oid, D_RO(wcs2), TYPE_NULL_ALLOC); UT_ASSERT(!TOID_IS_NULL(str1)); UT_ASSERT(!TOID_IS_NULL(wcs1)); } /* * do_strdup_uint64_range -- duplicate string with * type number equal to range of unsigned long long int */ static void do_strdup_uint64_range(PMEMobjpool *pop) { TOID(char) str1; TOID(char) str2 = do_alloc(pop, TEST_STR_2, TYPE_SIMPLE_ALLOC_1); TOID(char) str3; TOID(char) str4 = do_alloc(pop, TEST_STR_2, TYPE_SIMPLE_ALLOC_1); pmemobj_strdup(pop, &str1.oid, D_RO(str2), UINT64_MAX); pmemobj_strdup(pop, &str3.oid, D_RO(str4), UINT64_MAX - 1); UT_ASSERTeq(strcmp(D_RO(str1), D_RO(str2)), 0); UT_ASSERTeq(strcmp(D_RO(str3), D_RO(str4)), 0); } /* * do_strdup_alloc_empty_string -- duplicate string to internal container * associated with type number equal to range of unsigned long long int * and unsigned long long int - 1 */ static void do_strdup_alloc_empty_string(PMEMobjpool *pop) { TOID(char) str1 = do_alloc(pop, TEST_STR_1, TYPE_SIMPLE_ALLOC_1); TOID(wchar_t) wcs1 = do_wcs_alloc(pop, TEST_WCS_1, TYPE_SIMPLE_ALLOC_1); pmemobj_strdup(pop, &str1.oid, TEST_STR_EMPTY, TYPE_SIMPLE_ALLOC); pmemobj_wcsdup(pop, &wcs1.oid, TEST_WCS_EMPTY, TYPE_SIMPLE_ALLOC); UT_ASSERTeq(strcmp(D_RO(str1), TEST_STR_EMPTY), 0); UT_ASSERTeq(wcscmp(D_RO(wcs1), TEST_WCS_EMPTY), 0); } int main(int argc, char *argv[]) { START(argc, argv, "obj_strdup"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); do_strdup(pop); do_strdup_null(pop); do_strdup_alloc(pop); do_strdup_null_alloc(pop); do_strdup_uint64_range(pop); do_strdup_alloc_empty_string(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_strdup/TEST0.PS10000664000000000000000000000043514123364546016345 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_strdup/TEST0 -- unit test for pmemobj_strdup # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_strdup$Env:EXESUFFIX $DIR\testfile1 pass pmdk-1.11.1/src/test/obj_strdup/obj_strdup.vcxproj0000664000000000000000000000736414123364546020761 0ustar rootroot Debug x64 Release x64 {C2F94489-A483-4C44-B8A7-11A75F6AEC66} Win32Proj obj_strdup 10.0.17134.0 Application true v140 Application false v140 true Disabled CompileAsCpp MaxSpeed false CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_strdup/.gitignore0000664000000000000000000000001314123364546017141 0ustar rootrootobj_strdup pmdk-1.11.1/src/test/obj_strdup/obj_strdup.vcxproj.filters0000664000000000000000000000134014123364546022414 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {b7a01995-7cda-4819-ba93-6f1550111c24} Source Files Test Scripts pmdk-1.11.1/src/test/RUNTESTS.PS10000664000000000000000000002032614123364546014623 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # RUNTESTS.PS1 -- setup the environment and run each test # # # parameter handling # [CmdletBinding(PositionalBinding=$false)] Param( [alias("n")] [switch]$dryrun = $false, [alias("b")] [ValidateSet("all", "debug", "nondebug")] [string]$buildtype = "all", [alias("t")] [ValidateSet("check", "short", "medium", "long", "all")] [string]$testtype = "check", [alias("f")] [ValidateSet("pmem", "non-pmem", "any", "none", "all")] [string]$fstype = "all", [alias("o")] [ValidateScript({ if( $_ -match "^\d+[smhd]?$") { $true } else { throw "$_ is not valid timeout value." } })] [string]$time = "180s", [alias("s")] [string]$testfile = "all", [alias("i")] [ValidateScript({ if($_ -eq "all") { $true } elseif(Test-Path -Path $_ -pathType container) { $true } else { throw "Directory $_ doesn't exist." } })] [string]$testdir = "all", [alias("c")] [switch]$check_pool = $false, [alias("k")] [string]$skip_dir = "", [alias("j")] [uint32]$jobs = 1, [alias("h")] [switch]$help= $false ) if ($PSVersionTable.PSVersion.Major -lt 5) { throw $MyInvocation.MyCommand.Name + " require powershell version >= 5" } . .\RUNTESTLIB.PS1 if($help) { usage $MyInvocation.MyCommand.Name } Write-Verbose "Options: -v $(if ($dryrun) {"-n"})" Write-Verbose " build-type: $buildtype" Write-Verbose " test-type: $testtype" Write-Verbose " fs-type: $fstype" Write-Verbose " check-pool: $(if ($check_pool -eq "1") {"yes"} else {"no"})" $config = New-Object Config $config.setBuildtype($buildtype) $config.setFstype($fstype) $config.setTimeout($time) $config.setTestdir($testdir) $config.testtype = $testtype $config.check_pool = $check_pool $config.skip_dir = $skip_dir $config.testfile = $testfile $config.verbose = $VerbosePreference if ($config.testtype -eq "check") { Register-EngineEvent -SourceIdentifier "timeout-reset" -Action { $Global:stopwatch = [diagnostics.stopwatch]::StartNew() } | Out-Null $Global:stopwatch = [diagnostics.stopwatch]::StartNew() } else { # disable timeout $config.setTimeout(0) $Global:stopwatch = [diagnostics.stopwatch]::StartNew() $Global:stopwatch.Stop() } # script blocks - job's start functions $sb_ST = { param ([string]$dir, $config) # Config type is unknown here $VerbosePreference = $config.verbose Register-EngineEvent -SourceIdentifier "timeout-reset" -Forward # catch event and forward it to parent job cd $dir . .\RUNTESTLIB.PS1 $config.testdir | % { if ($config.skip_dir.split() -contains $_) { Write-Host "RUNTESTS: Skipping: $testName" return } cd $_ $_ | runtest -config $config cd .. } } $sb_MT = { param ([string]$dir, $config, [string]$test) # Config type is unknown here $VerbosePreference = $config.verbose Register-EngineEvent -SourceIdentifier "timeout-reset" -Forward # catch event and forward it to parent job cd $dir . .\RUNTESTLIB.PS1 if ($config.skip_dir.split() -contains $_) { Write-Host "RUNTESTS: Skipping: $testName" return } cd $test $test | runtest -config $config cd .. } # unique name for all jobs $name = [guid]::NewGuid().ToString() try { if ($jobs -gt 1) { $it = 0 $threads = 0 $tests = $config.testdir # start worker jobs 1..$jobs | % { if ($it -lt $tests.Length) { Start-Job -Name $name -Args $PSScriptRoot, $config, $tests[$it] -ScriptBlock $sb_MT | Out-Null $it++ $threads++ } } $fail = $false # control loop for receiving job outputs and starting new jobs while ($threads -ne 0) { if ($config.timeout.TotalSeconds -ne 0 -and $Global:stopwatch.Elapsed.TotalSeconds -ge $config.timeout.TotalSeconds) { Get-Job -name $name | Remove-Job -Force throw "RUNTESTS: stopping: TIMED OUT" } Get-Job -name $name | Receive-Job Get-Job -name $name | % { if ($_.State -eq "Running" -or $_.State -eq "NotStarted") { return } if ($_.State -eq "Failed") { $fail = $true } Receive-Job $_ Remove-Job $_ -Force $threads-- if ($fail -eq $false) { if ($it -lt $tests.Length) { Start-Job -Name $name -Args $PSScriptRoot, $config, $tests[$it] -ScriptBlock $sb_MT | Out-Null $it++ $threads++ } } } } if ($fail -eq $true) { throw "one of the tests failed" } } else { # if there is no timeout don't run tests in separate thread - useful for script debugging if ($config.timeout.TotalSeconds -eq 0) { & $sb_ST $PSScriptRoot $config } else { $job = Start-Job -Name $name -Args $PSScriptRoot, $config -ScriptBlock $sb_ST -Verbose $threads++ while ($Global:stopwatch.Elapsed.TotalSeconds -lt $config.timeout.TotalSeconds -and $(Get-Job).ChildJobs.Count -ne 0) { Receive-Job -Job $job if ($job.State -eq "Running" -or $job.State -eq "NotStarted") { sleep -Milliseconds 100 continue } if ($job.State -eq "Failed") { Remove-Job -job $job -Force | out-null $threads-- throw "one of the tests failed" } Receive-Job $job Remove-Job $job -Force $threads-- return } if ($Global:stopwatch.Elapsed.TotalSeconds -ge $config.timeout.TotalSeconds) { Receive-Job -Job $job throw "TIMED OUT" } } } } catch { # in case of fail test without timeout configured # we have to return to src/test dir if ($config.timeout.TotalSeconds -eq 0) { cd .. } Write-Error "RUNTESTS FAILED: $_" $status = 1 } finally { # cleanup jobs in case of exception or C-c if ($config.timeout.TotalSeconds -ne 0) { Get-Job -name "timeout-reset"| Remove-Job -Force } if ($threads -gt 0) { Get-Job -name $name | Remove-Job -Force } } Exit $status pmdk-1.11.1/src/test/out_err_win/0000775000000000000000000000000014123364546015340 5ustar rootrootpmdk-1.11.1/src/test/out_err_win/out_err_win.vcxproj.filters0000664000000000000000000000201514123364546022756 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {de41a380-e1fd-45b9-bca5-1c60b0a288f6} {dd367362-9e19-4a5d-bd31-01247ae35f9a} Source Files Test scripts Match Files Match Files pmdk-1.11.1/src/test/out_err_win/out_err_win.c0000664000000000000000000000222614123364546020042 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2014-2017, Intel Corporation */ /* * out_err_win.c -- unit test for error messages */ #define LOG_PREFIX "trace" #define LOG_LEVEL_VAR "TRACE_LOG_LEVEL" #define LOG_FILE_VAR "TRACE_LOG_FILE" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #include #include #include "unittest.h" #include "pmemcommon.h" int wmain(int argc, wchar_t *argv[]) { char buff[UT_MAX_ERR_MSG]; STARTW(argc, argv, "out_err_win"); /* Execute test */ common_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR, MAJOR_VERSION, MINOR_VERSION); errno = 0; ERR("ERR #%d", 1); UT_OUT("%S", out_get_errormsgW()); errno = 0; ERR("!ERR #%d", 2); UT_OUT("%S", out_get_errormsgW()); errno = EINVAL; ERR("!ERR #%d", 3); UT_OUT("%S", out_get_errormsgW()); errno = EBADF; ut_strerror(errno, buff, UT_MAX_ERR_MSG); out_err(__FILE__, 100, __func__, "ERR1: %s:%d", buff, 1234); UT_OUT("%S", out_get_errormsgW()); errno = EBADF; ut_strerror(errno, buff, UT_MAX_ERR_MSG); out_err(NULL, 0, NULL, "ERR2: %s:%d", buff, 1234); UT_OUT("%S", out_get_errormsgW()); /* Cleanup */ common_fini(); DONEW(NULL); } pmdk-1.11.1/src/test/out_err_win/traces0.log.match0000664000000000000000000000172614123364546020505 0ustar rootroot: <1> [out.c:$(N) out_init]$(W)pid $(N): program: $(nW) : <1> [out.c:$(N) out_init]$(W)trace version 1.0 : <1> [out.c:$(N) out_init]$(W)src version: $(nW) $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with support for Valgrind pmemcheck $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with support for Valgrind helgrind $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with support for Valgrind memcheck $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with support for Valgrind drd $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with support for shutdown state $(OPT): <1> [out.c:$(N) out_init]$(W)compiled with libndctl 63+ : <1> [out_err$(nW).c:$(N) $(nW)main]$(W)ERR #1 : <1> [out_err$(nW).c:$(N) $(nW)main]$(W)ERR #2: Success : <1> [out_err$(nW).c:$(N) $(nW)main]$(W)ERR #3: Invalid argument : <1> [out_err$(nW).c:$(N) $(nW)main]$(W)ERR1: Bad file descriptor:1234 ERR2: Bad file descriptor:1234 pmdk-1.11.1/src/test/out_err_win/out0.log.match0000664000000000000000000000032014123364546020020 0ustar rootrootout_err_win$(nW)TEST0: START: out_err_win$(nW) $(nW)out_err_win$(nW) ERR #1 ERR #2: Success ERR #3: Invalid argument ERR1: Bad file descriptor:1234 ERR2: Bad file descriptor:1234 out_err_win$(nW)TEST0: DONE pmdk-1.11.1/src/test/out_err_win/TEST0.PS10000664000000000000000000000062214123364546016524 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/out_err_win/TEST0 -- unit test for out_err() # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none require_build_type debug setup $Env:TRACE_LOG_LEVEL = 1 $Env:TRACE_LOG_FILE = ".\traces$Env:UNITTEST_NUM.log" expect_normal_exit $Env:EXE_DIR\out_err_win$Env:EXESUFFIX check pass pmdk-1.11.1/src/test/out_err_win/out_err_win.vcxproj0000664000000000000000000000671214123364546021317 0ustar rootroot Debug x64 Release x64 {A57D9365-172E-4782-ADC6-82A594E30943} Win32Proj out_err_win 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_mem/0000775000000000000000000000000014123364546014414 5ustar rootrootpmdk-1.11.1/src/test/obj_mem/TEST00000775000000000000000000000106114123364546015177 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_mem/TEST0 -- simple test for pmemobj_memcpy, pmemobj_memmove # and pmemobj_memset # . ../unittest/unittest.sh require_test_type medium # covered by TEST1 configure_valgrind memcheck force-disable setup create_poolset $DIR/poolset1 16M:$DIR/testfile1:z expect_normal_exit ./obj_mem$EXESUFFIX $DIR/poolset1 create_poolset $DIR/poolset2 16M:$DIR/testfile2:z r 16M:$DIR/testfile3:z expect_normal_exit ./obj_mem$EXESUFFIX $DIR/poolset2 pass pmdk-1.11.1/src/test/obj_mem/Makefile0000664000000000000000000000031414123364546016052 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/obj_mem/Makefile -- build obj_mem test # TARGET = obj_mem OBJS = obj_mem.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_mem/obj_mem.vcxproj.filters0000664000000000000000000000122414123364546021107 0ustar rootroot {345974e1-6ab8-48ee-bb89-c8351d31e02c} {70ce3522-b530-465b-af08-68b974cee5bc} Source Files Test Scripts pmdk-1.11.1/src/test/obj_mem/TEST0.PS10000664000000000000000000000077014123364546015604 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_mem/TEST0 -- test for pmemobj_memcpy, pmemobj_memmove # and pmemobj_memset # . ..\unittest\unittest.ps1 require_test_type medium setup create_poolset $DIR\poolset1 16M:$DIR\testfile1:z expect_normal_exit $Env:EXE_DIR\obj_mem$Env:EXESUFFIX $DIR/poolset1 create_poolset $DIR\poolset2 16M:$DIR\testfile2:z r 16M:$DIR\testfile3:z expect_normal_exit $Env:EXE_DIR\obj_mem$Env:EXESUFFIX $DIR/poolset2 pass pmdk-1.11.1/src/test/obj_mem/obj_mem.c0000664000000000000000000000315414123364546016173 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * obj_mem.c -- simple test for pmemobj_memcpy, pmemobj_memmove and * pmemobj_memset that verifies nothing blows up on pmemobj side. * Real consistency tests are for libpmem. */ #include "unittest.h" static unsigned Flags[] = { 0, PMEMOBJ_F_MEM_NODRAIN, PMEMOBJ_F_MEM_NONTEMPORAL, PMEMOBJ_F_MEM_TEMPORAL, PMEMOBJ_F_MEM_NONTEMPORAL | PMEMOBJ_F_MEM_TEMPORAL, PMEMOBJ_F_MEM_NONTEMPORAL | PMEMOBJ_F_MEM_NODRAIN, PMEMOBJ_F_MEM_WC, PMEMOBJ_F_MEM_WB, PMEMOBJ_F_MEM_NOFLUSH, /* all possible flags */ PMEMOBJ_F_MEM_NODRAIN | PMEMOBJ_F_MEM_NOFLUSH | PMEMOBJ_F_MEM_NONTEMPORAL | PMEMOBJ_F_MEM_TEMPORAL | PMEMOBJ_F_MEM_WC | PMEMOBJ_F_MEM_WB, }; int main(int argc, char *argv[]) { START(argc, argv, "obj_mem"); if (argc != 2) UT_FATAL("usage: %s [directory]", argv[0]); PMEMobjpool *pop = pmemobj_create(argv[1], "obj_mem", 0, S_IWUSR | S_IRUSR); if (!pop) UT_FATAL("!pmemobj_create"); struct root { char c[4096]; }; struct root *r = pmemobj_direct(pmemobj_root(pop, sizeof(struct root))); for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { unsigned f = Flags[i]; pmemobj_memset(pop, &r->c[0], 0x77, 2048, f); pmemobj_memset(pop, &r->c[2048], 0xff, 2048, f); pmemobj_memcpy(pop, &r->c[2048 + 7], &r->c[0], 100, f); pmemobj_memcpy(pop, &r->c[2048 + 1024], &r->c[0] + 17, 128, f); pmemobj_memmove(pop, &r->c[125], &r->c[150], 100, f); pmemobj_memmove(pop, &r->c[350], &r->c[325], 100, f); if (f & PMEMOBJ_F_MEM_NOFLUSH) pmemobj_persist(pop, r, sizeof(*r)); } pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_mem/.gitignore0000664000000000000000000000001014123364546016373 0ustar rootrootobj_mem pmdk-1.11.1/src/test/obj_mem/obj_mem.vcxproj0000664000000000000000000000751314123364546017447 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {B3AF8A19-5802-4A34-9157-27BBE4E53C0A} Win32Proj obj_mem 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_mem/TEST10000775000000000000000000000102614123364546015201 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_mem/TEST1 -- test for pmemobj_memcpy, pmemobj_memmove # and pmemobj_memset # . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-enable setup create_poolset $DIR/poolset1 16M:$DIR/testfile1:z expect_normal_exit ./obj_mem$EXESUFFIX $DIR/poolset1 create_poolset $DIR/poolset2 16M:$DIR/testfile2:z r 16M:$DIR/testfile3:z expect_normal_exit ./obj_mem$EXESUFFIX $DIR/poolset2 pass pmdk-1.11.1/src/test/obj_pool/0000775000000000000000000000000014123364546014607 5ustar rootrootpmdk-1.11.1/src/test/obj_pool/TEST31.PS10000664000000000000000000000103014123364546016051 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST31 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_fs_type any require_test_type medium setup # # TEST31 existing file, file size > min required size, layout is NULL # (valid pool header), reopen after failure # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile NULL 20 0640 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` f $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST20.PS10000664000000000000000000000362514123364546016063 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST20 -- unit test for pmemobj_open . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST20 non-existing file, layout is NULL # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST340000775000000000000000000000066414123364546015471 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST34 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup umask 0 require_free_space 33G # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 32768 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST7.PS10000664000000000000000000000405614123364546016007 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST7 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 17M 0K $DIR\testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST230000775000000000000000000000377314123364546015473 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST23 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile # # TEST23 existing file, file size >= min required size, layout is NULL # (empty pool header) # expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST330000775000000000000000000000205714123364546015466 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST33 -- unit test for pmemobj_open # with a poolset and bad block recovery files # . ../unittest/unittest.sh require_test_type medium setup POOLSET=$DIR/testset1 create_poolset $POOLSET 10M:$DIR/testfile0:z 10M:$DIR/testfile1:z 10M:$DIR/testfile2:z \ R 30M:$DIR/testfile3:z # # TEST33 existing file, file size >= min required size, # layout matches the value from pool header # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testset1 "test" 0 0640 # create recovery files - no bad blocks create_recovery_file $DIR/testset1_r0_p0_badblocks.txt create_recovery_file $DIR/testset1_r0_p1_badblocks.txt create_recovery_file $DIR/testset1_r0_p2_badblocks.txt create_recovery_file $DIR/testset1_r1_p0_badblocks.txt turn_on_checking_bad_blocks $DIR/testset1 # pmemobj_open() should fail, because the bad block recovery files exist expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testset1 "test" check pass pmdk-1.11.1/src/test/obj_pool/TEST220000775000000000000000000000077414123364546015470 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST22 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST22 existing file, file size < min required size, layout is NULL # (valid pool header) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile NULL 20 0640 truncate -s 1M $DIR/testfile expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out15.log.match0000664000000000000000000000033514123364546017363 0ustar rootrootobj_pool$(nW)TEST15: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 7 0640 $(nW)testfile: pmemobj_create: reservation pool size 7340032 smaller than 8388608: Invalid argument obj_pool$(nW)TEST15: DONE pmdk-1.11.1/src/test/obj_pool/TEST28.PS10000664000000000000000000000410714123364546016067 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST28 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST28 existing file, file size >= min required size # layout matches the value from pool header # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 20 0640 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile test$Env:SUFFIX check pass pmdk-1.11.1/src/test/obj_pool/TEST1.PS10000664000000000000000000000400614123364546015774 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST1 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST5.PS10000664000000000000000000000376414123364546016012 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST5 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST5 non-existing file, poolsize > 0 # path is invalid (directory not exist) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c \nul\testfile test$Env:SUFFIX 20 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out30.log.match0000664000000000000000000000023314123364546017355 0ustar rootrootobj_pool$(nW)TEST30: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testset test 0 0640 $(nW)testset: file size $(nW) mode 0666 obj_pool$(nW)TEST30: DONE pmdk-1.11.1/src/test/obj_pool/TEST160000775000000000000000000000067514123364546015473 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST16 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup # non-existing file, layout length == PMEMOBJ_MAX_LAYOUT, poolsize > 0 LAYOUT=$(printf 'x%.0s' {1..1023}) expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile $LAYOUT 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST22.PS10000664000000000000000000000410714123364546016061 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST22 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST22 existing file, file size < min required size, layout is NULL # (valid pool header) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile NULL 20 0640 truncate -s 1M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out24.log.match0000664000000000000000000000032014123364546017355 0ustar rootrootobj_pool$(nW)TEST24: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile EMPTY $(nW)testfile: pmemobj_open: wrong layout (""), pool created with layout "test": Invalid argument obj_pool$(nW)TEST24: DONE pmdk-1.11.1/src/test/obj_pool/TEST240000775000000000000000000000077714123364546015475 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST24 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST24 existing file, file size >= min required size, layout is "" # (layout doesn't match the value from pool header) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile EMPTY check pass pmdk-1.11.1/src/test/obj_pool/TEST9.PS10000664000000000000000000000372514123364546016013 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST9 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST9 non-existing file, poolsize < min required size # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 1 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST27.PS10000664000000000000000000000403114123364546016062 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST27 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST27 existing file, file size >= min required size, layout is NULL # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 20 0640 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out32.log.match0000664000000000000000000000041614123364546017362 0ustar rootrootobj_pool$(nW)TEST32: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile test$(nW) $(nW)testfile: pmemobj_open: error: a bad block recovery file exists, run 'pmempool sync --bad-blocks' utility to try to recover the pool: Invalid argument obj_pool$(nW)TEST32: DONE pmdk-1.11.1/src/test/obj_pool/out10.log.match0000664000000000000000000000031014123364546017347 0ustar rootrootobj_pool$(nW)TEST10: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 20 0640 $(nW)testfile: pmemobj_create: file $(nW)testfile already exists: File exists obj_pool$(nW)TEST10: DONE pmdk-1.11.1/src/test/obj_pool/out16.log.match0000664000000000000000000000024214123364546017361 0ustar rootrootobj_pool$(nW)TEST16: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile $(nW) 20 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool$(nW)TEST16: DONE pmdk-1.11.1/src/test/obj_pool/TEST170000775000000000000000000000106514123364546015466 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST17 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium require_command bc setup # non-existing file, poolsize == RANGE_OF_SIZE_T_AS_MB # Use 2^64-1 as an arbitrarily huge number (fixed size for match file) RANGE_OF_SIZE_T_AS_MB=$(echo "2^64/1024/1024-1" | bc) expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" \ $RANGE_OF_SIZE_T_AS_MB 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST25.PS10000664000000000000000000000450414123364546016065 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST25 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST25 existing file, file size >= min required size, layout is NULL # (no read permissions) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile NULL 20 0640 # remove read permissions & icacls $DIR\testfile /deny ${Env:USERNAME}:R >$null expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL # grant full permissions so test code can cleanup & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/obj_pool/TEST30000775000000000000000000000403414123364546015400 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST3 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile chmod 0640 $DIR/testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST10.PS10000664000000000000000000000442014123364546016054 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST10 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # XXX Doesn't change outcome whether we make it WO or not, # same goes for linux test & icacls $DIR\testfile /grant ${Env:USERNAME}:W >$null # # TEST10 existing file, file length >= min required size, poolsize > 0 # (no read permissions) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST90000775000000000000000000000062614123364546015411 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST9 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST9 non-existing file, poolsize < min required size # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 1 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/out23.log.match0000664000000000000000000000026614123364546017365 0ustar rootrootobj_pool$(nW)TEST23: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: invalid major version (0): Invalid argument obj_pool$(nW)TEST23: DONE pmdk-1.11.1/src/test/obj_pool/TEST120000775000000000000000000000065514123364546015465 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST12 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST12 non-existing file, poolsize >= min required size # layout is NULL # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile NULL 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST13.PS10000664000000000000000000000375414123364546016070 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST13 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST13 non-existing file, poolsize >= min required size # layout is empty string # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile EMPTY 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out26.log.match0000664000000000000000000000030514123364546017362 0ustar rootrootobj_pool$(nW)TEST26: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: open "$(nW)testfile": Permission denied: Permission denied obj_pool$(nW)TEST26: DONE pmdk-1.11.1/src/test/obj_pool/out21.log.match0000664000000000000000000000027614123364546017364 0ustar rootrootobj_pool$(nW)TEST21: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: size 1048576 smaller than 2097152: Invalid argument obj_pool$(nW)TEST21: DONE pmdk-1.11.1/src/test/obj_pool/TEST320000775000000000000000000000135714123364546015467 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST32 -- unit test for pmemobj_open # with a bad block recovery file # . ../unittest/unittest.sh require_test_type medium setup # # TEST32 existing file, file size >= min required size, # layout matches the value from pool header # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 # create a bad block recovery file create_recovery_file $DIR/testfile_r0_p0_badblocks.txt turn_on_checking_bad_blocks $DIR/testfile # pmemobj_open() should fail, because the bad block recovery file exists expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile "test" check pass pmdk-1.11.1/src/test/obj_pool/TEST130000775000000000000000000000066614123364546015470 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST13 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST13 non-existing file, poolsize >= min required size # layout is empty string # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile EMPTY 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST200000775000000000000000000000054114123364546015456 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST20 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST20 non-existing file, layout is NULL # expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST00000775000000000000000000000071514123364546015377 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST0 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit ./obj_pool$EXESUFFIX t $DIR/testfile "test" 20 0600 expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST250000775000000000000000000000101714123364546015462 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST25 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST25 existing file, file size >= min required size, layout is NULL # (no read permissions) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile NULL 20 0640 chmod -r $DIR/testfile expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/Makefile0000664000000000000000000000033214123364546016245 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/Makefile -- build obj_pool unit test # TARGET = obj_pool OBJS = obj_pool.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_pool/TEST3.PS10000664000000000000000000000400614123364546015776 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST3 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST3 existing file, file length >= min required size, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST14.PS10000664000000000000000000000432014123364546016057 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST14 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST14 non-existing file, poolsize >= min required size # layout string is too long # # LAYOUT=`dd if=/dev/urandom bs=1 count=768 2>/dev/null | base64 -w 0` # /dev/urandom is not implemented yet in windows # $ENV:LAYOUT = "dd if=/dev/urandom bs=1 count=768 2>/dev/null | base64 -w 0" $LAYOUT = "x" * 1025 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile $LAYOUT 20 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST2.PS10000664000000000000000000000370614123364546016003 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST2 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST50000775000000000000000000000066614123364546015411 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST5 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST5 non-existing file, poolsize > 0 # path is invalid (directory not exist) # expect_normal_exit ./obj_pool$EXESUFFIX c /NULL/testfile "test" 20 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/out7.log.match0000664000000000000000000000027314123364546017305 0ustar rootrootobj_pool$(nW)TEST7: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 0 0640 $(nW)testfile: pmemobj_create: Non-empty file detected: File exists obj_pool$(nW)TEST7: DONE pmdk-1.11.1/src/test/obj_pool/TEST15.PS10000664000000000000000000000075614123364546016071 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST15 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # non-existing file, poolsize == PMEMOBJ_MIN_POOL - 1 $PMEMOBJ_MIN_POOL = 8 $PMEMOBJ_MIN_POOL_BELOW = $PMEMOBJ_MIN_POOL-1 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX $PMEMOBJ_MIN_POOL_BELOW 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST6.PS10000664000000000000000000000424414123364546016005 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST6 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup touch $DIR\testfile # # TEST6 existing file, file length < min required size, poolsize == 0, # layout string is too long # /dev/urandom is not implemented yet in windows # $ENV:LAYOUT = "dd if=/dev/urandom bs=1 count=768 2>/dev/null | base64 -w 0" $LAYOUT = "x" * 1025 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile $LAYOUT 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/obj_pool.c0000664000000000000000000000553114123364546016562 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_pool.c -- unit test for pmemobj_create() and pmemobj_open() * Also tests pmemobj_(set/get)_user_data(). * * usage: obj_pool op path layout [poolsize mode] * * op can be: * c - create * o - open * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #include "../libpmemobj/obj.h" #define MB ((size_t)1 << 20) #define USER_DATA_V (void *) 123456789ULL static void pool_create(const char *path, const char *layout, size_t poolsize, unsigned mode) { PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode); if (pop == NULL) UT_OUT("!%s: pmemobj_create: %s", path, pmemobj_errormsg()); else { /* Test pmemobj_(get/set)_user data */ UT_ASSERTeq(NULL, pmemobj_get_user_data(pop)); pmemobj_set_user_data(pop, USER_DATA_V); UT_ASSERTeq(USER_DATA_V, pmemobj_get_user_data(pop)); os_stat_t stbuf; STAT(path, &stbuf); UT_OUT("%s: file size %zu mode 0%o", path, stbuf.st_size, stbuf.st_mode & 0777); pmemobj_close(pop); int result = pmemobj_check(path, layout); if (result < 0) UT_OUT("!%s: pmemobj_check", path); else if (result == 0) UT_OUT("%s: pmemobj_check: not consistent", path); } } static void pool_open(const char *path, const char *layout) { PMEMobjpool *pop = pmemobj_open(path, layout); if (pop == NULL) UT_OUT("!%s: pmemobj_open: %s", path, pmemobj_errormsg()); else { UT_OUT("%s: pmemobj_open: Success", path); UT_ASSERTeq(NULL, pmemobj_get_user_data(pop)); pmemobj_close(pop); } } static void test_fault_injection(const char *path, const char *layout, size_t poolsize, unsigned mode) { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "tx_params_new"); PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode); UT_ASSERTeq(pop, NULL); UT_ASSERTeq(errno, ENOMEM); } int main(int argc, char *argv[]) { START(argc, argv, "obj_pool"); if (argc < 4) UT_FATAL("usage: %s op path layout [poolsize mode]", argv[0]); char *layout = NULL; size_t poolsize; unsigned mode; if (strcmp(argv[3], "EMPTY") == 0) layout = ""; else if (strcmp(argv[3], "NULL") != 0) layout = argv[3]; switch (argv[1][0]) { case 'c': poolsize = strtoull(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); pool_create(argv[2], layout, poolsize, mode); break; case 'o': pool_open(argv[2], layout); break; case 'f': os_setenv("PMEMOBJ_CONF", "invalid-query", 1); pool_open(argv[2], layout); os_unsetenv("PMEMOBJ_CONF"); pool_open(argv[2], layout); break; case 't': poolsize = strtoull(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); test_fault_injection(argv[2], layout, poolsize, mode); break; default: UT_FATAL("unknown operation"); } DONE(NULL); } pmdk-1.11.1/src/test/obj_pool/TEST40000775000000000000000000000071714123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST4 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 touch $DIR/testfile chmod 0640 $DIR/testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/out34.log.match0000664000000000000000000000025414123364546017364 0ustar rootrootobj_pool$(nW)TEST34: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 32768 0600 $(nW)testfile: file size 34359738368 mode 0600 obj_pool$(nW)TEST34: DONE pmdk-1.11.1/src/test/obj_pool/TEST70000775000000000000000000000410214123364546015400 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST7 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_nonzeroed_file 8M 0K $DIR/testfile chmod 0640 $DIR/testfile # # TEST7 existing file, file length >= min required size, poolsize == 0 # (file contains garbage) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST23.PS10000664000000000000000000000376514123364546016073 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST23 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 20M $DIR\testfile # # TEST23 existing file, file size >= min required size, layout is NULL # (empty pool header) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out0.log.match0000664000000000000000000000024414123364546017274 0ustar rootrootobj_pool$(nW)TEST0: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 20 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_pool/TEST24.PS10000664000000000000000000000411014123364546016055 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST24 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST24 existing file, file size >= min required size, layout is "" # (layout doesn't match the value from pool header) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test 20 0640 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile EMPTY check pass pmdk-1.11.1/src/test/obj_pool/out33.log.match0000664000000000000000000000042314123364546017361 0ustar rootrootobj_pool$(nW)/TEST33: START: obj_pool$(nW) $(nW)/obj_pool$(nW) o $(nW)/testset1 test$(nW) $(nW)/testset1: pmemobj_open: error: a bad block recovery file exists, run 'pmempool sync --bad-blocks' utility to try to recover the pool: Invalid argument obj_pool$(nW)/TEST33: DONE pmdk-1.11.1/src/test/obj_pool/TEST210000775000000000000000000000373414123364546015466 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST21 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 1M $DIR/testfile # # TEST21 existing file, file size < min required size, layout in NULL # expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out25.log.match0000664000000000000000000000030514123364546017361 0ustar rootrootobj_pool$(nW)TEST25: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: open "$(nW)testfile": Permission denied: Permission denied obj_pool$(nW)TEST25: DONE pmdk-1.11.1/src/test/obj_pool/out9.log.match0000664000000000000000000000033314123364546017304 0ustar rootrootobj_pool$(nW)TEST9: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 1 0640 $(nW)testfile: pmemobj_create: reservation pool size 1048576 smaller than 8388608: Invalid argument obj_pool$(nW)TEST9: DONE pmdk-1.11.1/src/test/obj_pool/TEST30w.PS10000664000000000000000000000107714123364546016252 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # src/test/obj_pool/TEST30w -- create a pool with the smallest parts possible # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $MIN_PART = (2 * 1024 * 1024).toString() + "B" # 2MiB create_poolset $DIR\testset ${MIN_PART}:$DIR\testfile1:x ${MIN_PART}:$DIR\testfile2:x ` ${MIN_PART}:$DIR\testfile3:x ${MIN_PART}:$DIR\testfile4:x ${MIN_PART}:$DIR\testfile5:x expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX c $DIR\testset test 0 0600 check pass pmdk-1.11.1/src/test/obj_pool/TEST0.PS10000664000000000000000000000367514123364546016006 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST0 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX c $DIR\testfile test$Env:SUFFIX 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST17.PS10000664000000000000000000000100414123364546016056 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST17 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # non-existing file, poolsize == RANGE_OF_SIZE_T_AS_MB $RANGE_OF_SIZE_T=[UINT64]::MaxValue $RANGE_OF_SIZE_T_AS_MB=($RANGE_OF_SIZE_T/1024/1024)-1 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX $RANGE_OF_SIZE_T_AS_MB 0640 check_no_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out30w.log.match0000664000000000000000000000023514123364546017546 0ustar rootrootobj_pool$(nW)TEST30w: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testset test 0 0600 $(nW)testset: file size $(nW) mode 0600 obj_pool$(nW)TEST30w: DONE pmdk-1.11.1/src/test/obj_pool/out14.log.match0000664000000000000000000000026714123364546017366 0ustar rootrootobj_pool$(nW)TEST14: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile $(nW) 20 0640 $(nW)testfile: pmemobj_create: Layout too long: Invalid argument obj_pool$(nW)TEST14: DONE pmdk-1.11.1/src/test/obj_pool/TEST26.PS10000664000000000000000000000450614123364546016070 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST26 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup # # TEST26 existing file, file size >= min required size, layout is NULL # (no write permissions) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile NULL 20 0640 # remove write permissions & icacls $DIR\testfile /deny ${Env:USERNAME}:W >$null expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL # grant full permissions so test code can cleanup & icacls $DIR\testfile /grant ${Env:USERNAME}:F >$null check pass pmdk-1.11.1/src/test/obj_pool/out17.log.match0000664000000000000000000000034614123364546017367 0ustar rootrootobj_pool$(nW)TEST17: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 17592186044415 0640 $(nW)testfile: pmemobj_create: invalid size (18446744073708503040) for os_off_t: File too large obj_pool$(nW)TEST17: DONE pmdk-1.11.1/src/test/obj_pool/obj_pool.vcxproj.filters0000664000000000000000000001251314123364546021500 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 {b539ef93-f1f6-4c62-b624-1a07e6615e21} match Source Files Test Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Test Files Match Files Match Files Match Files Test Files Test Files Test Files pmdk-1.11.1/src/test/obj_pool/.gitignore0000664000000000000000000000001114123364546016567 0ustar rootrootobj_pool pmdk-1.11.1/src/test/obj_pool/TEST12.PS10000664000000000000000000000374314123364546016065 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST12 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST12 non-existing file, poolsize >= min required size # layout is NULL # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile NULL 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST35.PS10000664000000000000000000000407214123364546016066 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2021, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST35 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium require_short_path setup # override PMEMOBJ_CONF $Env:PMEMOBJ_CONF="fallocate.at_create=1;" create_holey_file 20M $DIR\testfile expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0600 check_files $DIR\testfile fsutil sparse queryFlag $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/README0000664000000000000000000000602014123364546015465 0ustar rootrootPersistent Memory Development Kit This is src/test/obj_pool/README. This directory contains a unit test for pmemobj_create() and pmemobj_open(). The program in obj_pool.c takes: operation, path, layout, poolsize, mode Operation can be: c - create o - open "poolsize and "mode" arguments are ignored if operation is "open". For example: ./obj_pool c /my/file "test_layout" 20 0640 This calls pmemobj_create() with the given arguments. Note that poolsize is given in megabytes. Test cases: - pmemobj_create: TEST0 (pass) non-existing file, poolsize >= min required size, layout != NULL TEST1 (pass) existing file, file length >= min required size, poolsize == 0, layout != NULL TEST2 (fail) non-existing file, poolsize == 0 TEST3 (fail) existing file, file length >= min required size, poolsize != 0, layout != NULL TEST4 (fail) existing file, file length < min required size, poolsize == 0, layout != NULL TEST5 (fail) non-existing file, poolsize >= min required size, layout != NULL path is invalid, directory does not exist TEST6 (fail) existing file, file length >= min required size, poolsize == 0, layout != NULL layout string is too long TEST7 (fail) existing file, file length >= min required size, poolsize == 0, layout != NULL file contains garbage TEST8 (pass) existing file, file length >= min required size, poolsize == 0, layout != NULL file contains garbage, except for header TEST9 (fail) non-existing file, poolsize < min required size, layout != NULL TEST10 (fail) existing file, file length >= min required size, poolsize == 0, layout != NULL no read permissions TEST11 (fail) existing file, file length >= min required size, poolsize == 0, layout != NULL no write permissions TEST12 (pass) non-existing file, poolsize >= min required size, layout == NULL TEST13 (pass) non-existing file, poolsize >= min required size, layout == "" TEST14 (fail) non-existing file, poolsize >= min required size, layout != NULL layout string is too long - pmemobj_open: TEST20 (fail) non-existing file, layout == NULL TEST21 (fail) existing file, file length < min required size, layout == NULL TEST22 (fail) existing file, file length < min required size, layout == NULL valid pool header TEST23 (fail) existing file, file length >= min required size, layout == NULL empty pool header TEST24 (fail) existing file, file length >= min required size, layout == "" layout doesn't match the value from pool header TEST25 (fail) existing file, file length >= min required size, layout == NULL no read permissions TEST26 (fail) existing file, file length >= min required size, layout == NULL no write permissions TEST27 (pass) existing file, file length >= min required size, layout == NULL TEST28 (pass) existing file, file length >= min required size, layout != NULL layout matches the value from pool header TEST29 (fail) existing poolset file, file length >= min required size, layout == NULL bad format of the poolset file - each case outputs: - error, if error happened - resulting file size, nblocks, mode, consistency check results pmdk-1.11.1/src/test/obj_pool/TEST21.PS10000664000000000000000000000372614123364546016066 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST21 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 1M $DIR\testfile # # TEST21 existing file, file size < min required size, layout in NULL # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o $DIR\testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/out20.log.match0000664000000000000000000000032514123364546017356 0ustar rootrootobj_pool$(nW)TEST20: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: open "$(nW)testfile": No such file or directory: No such file or directory obj_pool$(nW)TEST20: DONE pmdk-1.11.1/src/test/obj_pool/TEST150000775000000000000000000000074614123364546015471 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST15 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup # non-existing file, poolsize = PMEMOBJ_MIN_POOL - 1 PMEMOBJ_MIN_POOL=8 PMEMOBJ_MIN_POOL_BELOW=$((PMEMOBJ_MIN_POOL-1)) expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" \ $PMEMOBJ_MIN_POOL_BELOW 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/obj_pool.vcxproj0000664000000000000000000001302214123364546020025 0ustar rootroot Debug x64 Release x64 {3ECCB0F1-3ADF-486A-91C5-79DF0FC22F78} Win32Proj obj_pool 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_pool/TEST140000775000000000000000000000110014123364546015451 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST14 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST14 non-existing file, poolsize >= min required size # layout string is too long # LAYOUT=$(tr -cd '[:alnum:]' < /dev/urandom 2>/dev/null | head -c1024) [ $(echo $LAYOUT | wc -c) -ne 1025 ] && fatal "'tr' error" expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile $LAYOUT 20 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST60000775000000000000000000000116514123364546015405 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST6 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 touch $DIR/testfile chmod 0640 $DIR/testfile # # TEST6 existing file, file length < min required size, poolsize == 0, # layout string is too long # LAYOUT=$(tr -cd '[:alnum:]' < /dev/urandom 2>/dev/null | head -c1024) [ $(echo $LAYOUT | wc -c) -ne 1025 ] && fatal "'tr' error" expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile $LAYOUT 0 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST290000775000000000000000000000065214123364546015472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_pool/TEST29 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST29 existing poolset file, file size >= min required size, layout is NULL # bad format of the poolset file # expect_normal_exit ./obj_pool$EXESUFFIX o ./pool.set NULL check pass pmdk-1.11.1/src/test/obj_pool/out27.log.match0000664000000000000000000000022214123364546017361 0ustar rootrootobj_pool$(nW)TEST27: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: Success obj_pool$(nW)TEST27: DONE pmdk-1.11.1/src/test/obj_pool/TEST10000775000000000000000000000403414123364546015376 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST1 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 create_holey_file 20M $DIR/testfile chmod 0600 $DIR/testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST260000775000000000000000000000102014123364546015455 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST26 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 # # TEST26 existing file, file size >= min required size, layout is NULL # (no write permissions) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile NULL 20 0640 chmod -w $DIR/testfile expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST4.PS10000664000000000000000000000376514123364546016012 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST4 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup touch $DIR\testfile # # TEST4 existing file, file length < min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST300000775000000000000000000000405614123364546015464 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST30 -- create a pool with the smallest parts possible # . ../unittest/unittest.sh require_test_type medium setup umask 0 # create poolset file CMD="$DIR/testset" MIN_PART=$((2 * 1024 * 1024)) # 2MiB for i in {1..5}; do CMD="$CMD $MIN_PART:$DIR/testfile$i:x" done create_poolset $CMD expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testset "test" 0 0640 check pass pmdk-1.11.1/src/test/obj_pool/out11.log.match0000664000000000000000000000031014123364546017350 0ustar rootrootobj_pool$(nW)TEST11: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 20 0640 $(nW)testfile: pmemobj_create: file $(nW)testfile already exists: File exists obj_pool$(nW)TEST11: DONE pmdk-1.11.1/src/test/obj_pool/pool.set0000664000000000000000000000003414123364546016272 0ustar rootrootPMEMPOOLSET 100M ./pool.obj pmdk-1.11.1/src/test/obj_pool/out6.log.match0000664000000000000000000000026414123364546017304 0ustar rootrootobj_pool$(nW)TEST6: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile $(nW) 0 0640 $(nW)testfile: pmemobj_create: Layout too long: Invalid argument obj_pool$(nW)TEST6: DONE pmdk-1.11.1/src/test/obj_pool/TEST80000775000000000000000000000417114123364546015407 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST8 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 SIZE=$(obj_pool_desc_size) create_nonzeroed_file 8M "${SIZE}" $DIR/testfile chmod 0600 $DIR/testfile # # TEST8 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 0 0600 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/out13.log.match0000664000000000000000000000024214123364546017356 0ustar rootrootobj_pool$(nW)TEST13: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile EMPTY 20 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool$(nW)TEST13: DONE pmdk-1.11.1/src/test/obj_pool/TEST29.PS10000664000000000000000000000374114123364546016073 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST29 -- unit test for pmemobj_open # . ..\unittest\unittest.ps1 require_test_type medium setup # # TEST29 existing poolset file, file size >= min required size, layout is NULL # bad format of the poolset file # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` o .\pool.set NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST8.PS10000664000000000000000000000407714123364546016013 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST8 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 8M 8K $DIR\testfile # # TEST8 existing file, file length >= min required size, poolsize == 0 # (file contains garbage, except for header) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out22.log.match0000664000000000000000000000027614123364546017365 0ustar rootrootobj_pool$(nW)TEST22: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile NULL $(nW)testfile: pmemobj_open: size 1048576 smaller than 2097152: Invalid argument obj_pool$(nW)TEST22: DONE pmdk-1.11.1/src/test/obj_pool/out28.log.match0000664000000000000000000000022714123364546017367 0ustar rootrootobj_pool$(nW)TEST28: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)testfile test$(nW) $(nW)testfile: pmemobj_open: Success obj_pool$(nW)TEST28: DONE pmdk-1.11.1/src/test/obj_pool/out1.log.match0000664000000000000000000000024314123364546017274 0ustar rootrootobj_pool$(nW)TEST1: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 0 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_pool/TEST270000775000000000000000000000070514123364546015467 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST27 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST27 existing file, file size >= min required size, layout is NULL # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST100000775000000000000000000000412314123364546015455 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST10 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0240 $DIR/testfile # # TEST10 existing file, file length >= min required size, poolsize > 0 # (no read permissions) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST20000775000000000000000000000060714123364546015401 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST2 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST2 non-existing file, poolsize == 0 # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 0 0640 check_no_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/TEST310000775000000000000000000000101114123364546015451 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST31 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_fs_type any require_test_type medium setup umask 0 # # TEST31 existing file, file size > min required size, layout is NULL # (valid pool header), reopen after failure # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile NULL 20 0640 expect_normal_exit ./obj_pool$EXESUFFIX f $DIR/testfile NULL check pass pmdk-1.11.1/src/test/obj_pool/TEST11.PS10000664000000000000000000000442114123364546016056 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST11 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium # icacls does have problems with handling long paths in the correct way. require_short_path setup create_holey_file 20M $DIR\testfile # XXX Doesn't change outcome whether we make it RO or not, # same goes for linux test & icacls $DIR\testfile /grant ${Env:USERNAME}:R >$null # # TEST11 existing file, file length >= min required size, poolsize > 0 # (no write permissions) # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile test$Env:SUFFIX 20 0640 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out5.log.match0000664000000000000000000000034214123364546017300 0ustar rootrootobj_pool$(nW)TEST5: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 20 0640 $(nW)testfile: pmemobj_create: open "$(nW)testfile": No such file or directory: No such file or directory obj_pool$(nW)TEST5: DONE pmdk-1.11.1/src/test/obj_pool/out3.log.match0000664000000000000000000000030614123364546017276 0ustar rootrootobj_pool$(nW)TEST3: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 20 0640 $(nW)testfile: pmemobj_create: file $(nW)testfile already exists: File exists obj_pool$(nW)TEST3: DONE pmdk-1.11.1/src/test/obj_pool/TEST16.PS10000664000000000000000000000071014123364546016060 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST16 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type medium setup # non-existing file, layout length == PMEMOBJ_MAX_LAYOUT, poolsize > 0 $PMEMOBJ_MAX_LAYOUT = "x" * 1023 expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX ` c $DIR\testfile $PMEMOBJ_MAX_LAYOUT 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out31.log.match0000664000000000000000000000033414123364546017360 0ustar rootrootobj_pool$(nW)TEST31: START: obj_pool$(nW) $(nW)obj_pool$(nW) f $(nW)testfile NULL $(nW)testfile: pmemobj_open: pool initialization failed: Invalid argument $(nW)testfile: pmemobj_open: Success obj_pool$(nW)TEST31: DONE pmdk-1.11.1/src/test/obj_pool/out4.log.match0000664000000000000000000000035414123364546017302 0ustar rootrootobj_pool$(nW)TEST4: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 0 0640 $(nW)testfile: pmemobj_create: file is not a poolset file and its size (0) is smaller than 8388608: Invalid argument obj_pool$(nW)TEST4: DONE pmdk-1.11.1/src/test/obj_pool/TEST280000775000000000000000000000075214123364546015472 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool/TEST28 -- unit test for pmemobj_open # . ../unittest/unittest.sh require_test_type medium setup umask 0 # # TEST28 existing file, file size >= min required size # layout matches the value from pool header # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 expect_normal_exit ./obj_pool$EXESUFFIX o $DIR/testfile "test" check pass pmdk-1.11.1/src/test/obj_pool/out8.log.match0000664000000000000000000000024214123364546017302 0ustar rootrootobj_pool$(nW)TEST8: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 0 0600 $(nW)testfile: file size 8388608 mode 0600 obj_pool$(nW)TEST8: DONE pmdk-1.11.1/src/test/obj_pool/TEST34.PS10000664000000000000000000000063314123364546016064 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/obj_pool/TEST34 -- unit test for pmemobj_create # . ..\unittest\unittest.ps1 require_test_type long setup require_free_space 33G # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\obj_pool$Env:EXESUFFIX c $DIR\testfile test$Env:SUFFIX 32768 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/obj_pool/out2.log.match0000664000000000000000000000034114123364546017274 0ustar rootrootobj_pool$(nW)TEST2: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile test$(nW) 0 0640 $(nW)testfile: pmemobj_create: open "$(nW)testfile": No such file or directory: No such file or directory obj_pool$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_pool/out12.log.match0000664000000000000000000000024114123364546017354 0ustar rootrootobj_pool$(nW)TEST12: START: obj_pool$(nW) $(nW)obj_pool$(nW) c $(nW)testfile NULL 20 0600 $(nW)testfile: file size 20971520 mode 0600 obj_pool$(nW)TEST12: DONE pmdk-1.11.1/src/test/obj_pool/TEST110000775000000000000000000000412414123364546015457 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_pool/TEST11 -- unit test for pmemobj_create # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup umask 0 create_holey_file 20M $DIR/testfile chmod 0440 $DIR/testfile # # TEST11 existing file, file length >= min required size, poolsize > 0 # (no write permissions) # expect_normal_exit ./obj_pool$EXESUFFIX c $DIR/testfile "test" 20 0640 check_files $DIR/testfile check pass pmdk-1.11.1/src/test/obj_pool/out29.log.match0000664000000000000000000000032714123364546017371 0ustar rootrootobj_pool$(nW)TEST29: START: obj_pool$(nW) $(nW)obj_pool$(nW) o $(nW)pool.set NULL $(nW)pool.set: pmemobj_open: $(nW)pool.set [incorrect path (must be an absolute one):2]: Invalid argument obj_pool$(nW)TEST29: DONE pmdk-1.11.1/src/test/pmemobjcli/0000775000000000000000000000000014123364546015125 5ustar rootrootpmdk-1.11.1/src/test/pmemobjcli/TEST1.PS10000664000000000000000000000070214123364546016311 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmemobjcli/TEST1 -- test for pmemobjcli with transactions # . ..\unittest\unittest.ps1 require_test_type medium setup $POOL = "$DIR\testfile" $SCRIPT = "..\tools\pmemobjcli\pmemobjcli_example_tx.posc" $LOG = "out${Env:UNITTEST_NUM}.log" expect_normal_exit $PMEMPOOL create obj $POOL -s 16M expect_normal_exit $PMEMOBJCLI -s $SCRIPT $POOL > $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/TEST00000775000000000000000000000065614123364546015721 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmemobjcli/TEST0 -- test for pmemobjcli # . ../unittest/unittest.sh require_test_type medium setup POOL=$DIR/testfile SCRIPT=_example.posc LOG=out${UNITTEST_NUM}.log expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL -s 16M expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $PMEMOBJCLI$SCRIPT $POOL > $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/Makefile0000664000000000000000000000027514123364546016571 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/pmemobjcli/Makefile -- build pmemobjcli unittest # USE_PMEMOBJCLI=y include ../Makefile.inc pmdk-1.11.1/src/test/pmemobjcli/TEST2.PS10000664000000000000000000000071114123364546016312 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmemobjcli/TEST2 -- test for pmemobjcli -p option # . ..\unittest\unittest.ps1 require_test_type medium setup $PFX = "..\tools\pmemobjcli\pmemobjcli" $LOG = "out${Env:UNITTEST_NUM}.log" expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s ${PFX}_example.posc -p > $LOG echo "---" >> $LOG expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s ${PFX}_example_tx.posc -p >> $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/out0.log.match0000664000000000000000000000417314123364546017617 0ustar rootrootpmemobj_direct(r): off = 0x0 uuid = 0x0 ptr = $(nW) pmemobj_root(1024): off = $(nW) uuid = $(nW) pmemobj_direct(r): off = $(nW) uuid = $(nW) ptr = $(nW) pmemobj_root_size: size = 1024 pmemobj_alloc_usable_size(r): size = $(nW) pmemobj_type_num(r): type num = 0 pmemobj_alloc(r.0, 8192, 1): 0 pmemobj_zalloc(r.1, 256, 2): 0 pmemobj_zalloc(r.2, 128, 3): 0 pmemobj_zalloc(r.3, 128, 3): 0 pmemobj_realloc(r.0, 2, 3): 0 off = $(nW) uuid = $(nW) pmemobj_zrealloc(r.0, 8192, 4): 0 off = $(nW) uuid = $(nW) pmemobj_strdup(r.4, 0, 5): 0 pmemobj_direct(r.0): off = $(nW) uuid = $(nW) ptr = $(nW) pmemobj_direct(r.1): off = $(nW) uuid = $(nW) ptr = $(nW) pmemobj_type_num(r.0): type num = 4 pmemobj_type_num(r.1): type num = 2 pmemobj_alloc_usable_size(r.0): size = $(nW) pmemobj_alloc_usable_size(r.1): size = $(nW) pmemobj_first: off = $(nW) uuid = $(nW) pmemobj_next($(nW)): off = $(nW) uuid = $(nW) pmemobj_memset_persist($(nW), 255, 128): ptr = $(nW) pmemobj_memset_persist($(nW), 0, 128): ptr = $(nW) pmemobj_memcpy_persist($(nW), $(nW), 128): ptr = $(nW) pmemobj_persist($(nW), 96) pmemobj_flush($(nW), 96) pmemobj_drain pmemobj_pool_by_oid($(nW)): uuid = $(nW) pmemobj_pool_by_ptr($(nW)): uuid = $(nW) pmemobj_memset_persist($(nW), 0, 256): ptr = $(nW) pmemobj_memset_persist($(nW), 0, 256): ptr = $(nW) pmemobj_memset_persist($(nW), 0, 32): ptr = $(nW) pmemobj_list_insert_new(r.0, $(nW), 1, 64, 3): off = $(nW) uuid = $(nW) ptr = $(nW) pmemobj_list_insert_new(r.1, $(nW), 1, 64, 3): off = $(nW) uuid = $(nW) ptr = $(nW) pmemobj_list_insert($(nW), r.0, $(nW), 1): 0 pmemobj_list_insert($(nW), r.1, $(nW), 0): 0 pmemobj_list_move($(nW), r.0, r.1, $(nW), 0): 0 pmemobj_list_move($(nW), r.0, r.1, $(nW), 0): 0 pmemobj_list_remove($(nW), r.1, 0): off = $(nW) uuid = $(nW) pmemobj_list_remove($(nW), r.1, 0): off = $(nW) uuid = $(nW) pmemobj_list_remove($(nW), r.1, 1): off = $(nW) uuid = $(nW) pmemobj_list_remove($(nW), r.1, 1): off = $(nW) uuid = $(nW) pmemobj_free($(nW)): off = 0x0 uuid = 0x0 pmemobj_free($(nW)): off = 0x0 uuid = 0x0 pmemobj_free($(nW)): off = 0x0 uuid = 0x0 pmemobj_free($(nW)): off = 0x0 uuid = 0x0 pmemobj_direct(r.0): off = 0x0 uuid = 0x0 ptr = $(nW) pmdk-1.11.1/src/test/pmemobjcli/TEST0.PS10000664000000000000000000000065514123364546016317 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmemobjcli/TEST0 -- test for pmemobjcli # . ..\unittest\unittest.ps1 require_test_type medium setup $POOL = "$DIR\testfile" $SCRIPT = "..\tools\pmemobjcli\pmemobjcli_example.posc" $LOG = "out${Env:UNITTEST_NUM}.log" expect_normal_exit $PMEMPOOL create obj $POOL -s 16M expect_normal_exit $PMEMOBJCLI -s $SCRIPT $POOL > $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/.gitignore0000664000000000000000000000001314123364546017107 0ustar rootrootpmemobjcli pmdk-1.11.1/src/test/pmemobjcli/pmemobjcli.vcxproj.filters0000664000000000000000000000142214123364546022331 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Match Files Test Scripts Test Scripts pmdk-1.11.1/src/test/pmemobjcli/TEST10000775000000000000000000000070314123364546015713 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmemobjcli/TEST1 -- test for pmemobjcli with transactions # . ../unittest/unittest.sh require_test_type medium setup POOL=$DIR/testfile SCRIPT=_example_tx.posc LOG=out${UNITTEST_NUM}.log expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $POOL -s 16M expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s $PMEMOBJCLI$SCRIPT $POOL > $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/pmemobjcli.vcxproj0000664000000000000000000000754114123364546020672 0ustar rootroot Debug x64 Release x64 {D28F5FF6-8401-4E0D-94F9-3A1FD7ED64E3} pmemobjcli 10.0.17134.0 tools_pmemobjcli Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) {d2c30c7e-a7d3-487a-956e-418cecaffe8e} pmdk-1.11.1/src/test/pmemobjcli/out1.log.match0000664000000000000000000000141614123364546017615 0ustar rootrootpmemobj_root(256): off = $(nW) uuid = $(nW) pmemobj_zalloc(r.0, 8192, 1): 0 pmemobj_zalloc(r.1, 256, 2): 0 pmemobj_tx_begin(jmp): 0 pmemobj_tx_add_range(r, 0, 256): 0 pmemobj_tx_strdup(0, 5): off = $(nW) uuid = $(nW) pmemobj_tx_add_range_direct($(nW), 64, 128): 0 pmemobj_tx_add_range(r.1, 16, 16): 0 pmemobj_tx_zalloc(8192, 3): off = $(nW) uuid = $(nW) pmemobj_tx_zrealloc($(nW), 2048, 3): off = $(nW) uuid = $(nW) pmemobj_tx_free($(nW)): off = $(nW) uuid = $(nW) pmemobj_tx_stage: TX_STAGE_WORK pmemobj_tx_begin: 0 pmemobj_tx_commit pmemobj_tx_stage: TX_STAGE_ONCOMMIT pmemobj_tx_process pmemobj_tx_stage: TX_STAGE_FINALLY pmemobj_tx_end: 0 pmemobj_tx_stage: TX_STAGE_WORK pmemobj_tx_abort: -1 pmemobj_tx_stage: TX_STAGE_ONABORT pmemobj_tx_end: -1 pmemobj_tx_stage: TX_STAGE_NONE pmdk-1.11.1/src/test/pmemobjcli/TEST20000775000000000000000000000067114123364546015720 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmemobjcli/TEST2 -- test for pmemobjcli -p option # . ../unittest/unittest.sh require_test_type medium setup LOG=out${UNITTEST_NUM}.log expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s ${PMEMOBJCLI}_example.posc -p > $LOG echo "---" >> $LOG expect_normal_exit $PMEMOBJCLI$EXESUFFIX -s ${PMEMOBJCLI}_example_tx.posc -p >> $LOG check pass pmdk-1.11.1/src/test/pmemobjcli/out2.log.match0000664000000000000000000000140514123364546017614 0ustar rootrootpdr r pr 1024 pdr r prs paus r ptn r pa r.0 1 8192 pza r.1 2 256 pza r.2 3 128 pza r.3 3 128 pre r.0 3 2 pzre r.0 4 8192 psd r.4 0 5 pdr r.0 pdr r.1 ptn r.0 ptn r.1 paus r.0 paus r.1 pfi pn r.2 pmsp r.2 0 255 128 pmsp r.3 0 0 128 pmcp r.3 0 r.2 0 128 pp r.3 32 96 pfl r.2 32 96 pd ppbo r ppbp r.3 32 pmsp r.0 0 0 256 pmsp r.1 0 0 256 pmsp r.0 0 0 32 plin r.4 r.0 NULL 1 64 3 plin r.5 r.1 NULL 1 64 3 pli r.3 r.0 r.4 1 pli r.2 r.1 NULL 0 plm r.4 r.0 r.1 r.5 0 plm r.3 r.0 r.1 r.4 0 plr r.2 r.1 0 plr r.3 r.1 0 plr r.4 r.1 1 plr r.5 r.1 1 pf r.0 pf r.1 pf r.2 pf r.3 pdr r.0 --- pr 256 pza r.0 1 8192 pza r.1 2 256 ptb jmp ptar r 0 256 ptsd r.4 0 5 ptard r.0 64 128 ptar r.1 16 16 ptzal r.3 8192 3 ptzre r.3 2048 3 ptf r.4 pts ptb ptc pts ptp pts pte pts ptab -1 pts pte pts pmdk-1.11.1/src/test/pmem2_api/0000775000000000000000000000000014123364546014655 5ustar rootrootpmdk-1.11.1/src/test/pmem2_api/Makefile0000664000000000000000000000060614123364546016317 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem2_integration/Makefile -- build pmem2_integration test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest TARGET = pmem2_api OBJS = pmem2_api.o\ ut_pmem2_config.o\ ut_pmem2_map.o\ ut_pmem2_source.o\ ut_pmem2_utils.o\ ut_pmem2_setup_integration.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_api/pmem2_api.c0000664000000000000000000000413314123364546016673 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020, Intel Corporation */ /* * pmem2_api.c -- PMEM2_API_[START|END] unittests */ #include "unittest.h" #include "ut_pmem2.h" #include "ut_pmem2_setup_integration.h" /* * map_valid -- return valid mapped pmem2_map and validate mapped memory length */ static struct pmem2_map * map_valid(struct pmem2_config *cfg, struct pmem2_source *src, size_t size) { struct pmem2_map *map = NULL; pmem2_map_new(&map, cfg, src); UT_ASSERTeq(pmem2_map_get_size(map), size); return map; } /* * test_pmem2_api_logs -- map O_RDWR file and do pmem2_[cpy|set|move]_fns */ static int test_pmem2_api_logs(const struct test_case *tc, int argc, char *argv[]) { if (argc < 1) UT_FATAL( "usage: test_mem_move_cpy_set_with_map_private "); char *file = argv[0]; int fd = OPEN(file, O_RDWR); const char *word1 = "Persistent memory..."; const char *word2 = "Nonpersistent memory"; const char *word3 = "XXXXXXXXXXXXXXXXXXXX"; struct pmem2_config *cfg; struct pmem2_source *src; PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, PMEM2_GRANULARITY_PAGE); size_t size = 0; PMEM2_SOURCE_SIZE(src, &size); struct pmem2_map *map = map_valid(cfg, src, size); char *addr = pmem2_map_get_address(map); pmem2_memmove_fn memmove_fn = pmem2_get_memmove_fn(map); pmem2_memcpy_fn memcpy_fn = pmem2_get_memcpy_fn(map); pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); memcpy_fn(addr, word1, strlen(word1), 0); UT_ASSERTeq(strcmp(addr, word1), 0); memmove_fn(addr, word2, strlen(word2), 0); UT_ASSERTeq(strcmp(addr, word2), 0); memset_fn(addr, 'X', strlen(word3), 0); UT_ASSERTeq(strcmp(addr, word3), 0); /* cleanup after the test */ pmem2_map_delete(&map); pmem2_config_delete(&cfg); pmem2_source_delete(&src); CLOSE(fd); return 1; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_pmem2_api_logs), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char *argv[]) { START(argc, argv, "pmem2_api"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_api/TESTS.py0000775000000000000000000000472214123364546016141 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020-2021, Intel Corporation # import os import testframework as t import futils @t.require_valgrind_enabled('pmemcheck') class Pmem2ApiLogs(t.Test): test_type = t.Medium def run(self, ctx): filepath = ctx.create_holey_file(16 * t.MiB, 'testfile') ctx.env['PMREORDER_EMIT_LOG'] = self.PMREORDER_EMIT_LOG ctx.valgrind.add_opt('--log-stores=yes') ctx.exec('pmem2_api', self.test_case, filepath) log_name = 'pmemcheck{}.log'.format(self.testnum) pmemecheck_log = os.path.join(ctx.cwd, log_name) memmove_fn_begin_nums = futils.count( pmemecheck_log, 'pmem2_memmove.BEGIN') memmove_fn_end_nums = futils.count( pmemecheck_log, 'pmem2_memmove.END') memset_fn_begin_nums = futils.count( pmemecheck_log, 'pmem2_memset.BEGIN') memset_fn_end_nums = futils.count( pmemecheck_log, 'pmem2_memset.END') if (memmove_fn_begin_nums != self.expected_memmove_fn_nums or memmove_fn_end_nums != self.expected_memmove_fn_nums or memset_fn_begin_nums != self.expected_memset_fn_nums or memset_fn_end_nums != self.expected_memset_fn_nums): raise futils.Fail( 'Pattern: pmem2_memmove.BEGIN occurs {} times. Expected {}.\n' 'Pattern: pmem2_memmove.END occurs {} times. Expected {}.\n' 'Pattern: pmem2_memset.BEGIN occurs {} times. Expected {}.\n' 'Pattern: pmem2_memset.END occurs {} times. Expected {}.' .format(memmove_fn_begin_nums, self.expected_memmove_fn_nums, memmove_fn_end_nums, self.expected_memmove_fn_nums, memset_fn_begin_nums, self.expected_memset_fn_nums, memset_fn_end_nums, self.expected_memset_fn_nums) ) class TEST0(Pmem2ApiLogs): """ test the emission of library and function names to pmemcheck stores log """ test_case = "test_pmem2_api_logs" expected_memmove_fn_nums = 2 expected_memset_fn_nums = 1 PMREORDER_EMIT_LOG = '1' class TEST1(Pmem2ApiLogs): """ test the emission of library and function names to pmemcheck stores log with PMREORDER_EMIT_LOG set to '0'. Any names shouldn't be emitted. """ test_case = "test_pmem2_api_logs" expected_memmove_fn_nums = 0 expected_memset_fn_nums = 0 PMREORDER_EMIT_LOG = '0' pmdk-1.11.1/src/test/pmem2_api/.gitignore0000664000000000000000000000001214123364546016636 0ustar rootrootpmem2_api pmdk-1.11.1/src/test/obj_critnib/0000775000000000000000000000000014123364546015270 5ustar rootrootpmdk-1.11.1/src/test/obj_critnib/obj_critnib.vcxproj0000664000000000000000000000756414123364546021205 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {0CDCEB97-3270-4939-A290-EA2D3BE34B0C} Win32Proj obj_critnib 10.0.17134.0 Application true v140 Application false v140 true NotUsing Disabled $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) NotUsing MaxSpeed $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_critnib/Makefile0000664000000000000000000000044414123364546016732 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_critnib/Makefile -- build obj_critnib unit test # TARGET = obj_critnib OBJS = obj_critnib.o LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_critnib.c) pmdk-1.11.1/src/test/obj_critnib/TESTS.py0000775000000000000000000000043114123364546016545 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # import testframework as t from testframework import granularity as g @g.no_testdir() class TEST0(t.Test): test_type = t.Medium def run(self, ctx): ctx.exec('obj_critnib') pmdk-1.11.1/src/test/obj_critnib/.gitignore0000664000000000000000000000001414123364546017253 0ustar rootrootobj_critnib pmdk-1.11.1/src/test/obj_critnib/obj_critnib.c0000664000000000000000000001770714123364546017734 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_critnib.c -- unit test for critnib hash table */ #include #include "critnib.h" #include "unittest.h" #include "util.h" #include "../libpmemobj/obj.h" #define TEST_INSERTS 100 #define TEST_VAL(x) ((void *)((uintptr_t)(x))) static int Rcounter_malloc; static void * __wrap_malloc(size_t size) { switch (util_fetch_and_add32(&Rcounter_malloc, 1)) { case 1: /* internal out_err malloc */ default: return malloc(size); case 2: /* tab malloc */ case 0: /* critnib malloc */ return NULL; } } static void test_critnib_new_delete(void) { struct critnib *c = NULL; /* critnib malloc fail */ c = critnib_new(); UT_ASSERTeq(c, NULL); /* first insert malloc fail */ c = critnib_new(); UT_ASSERTeq(critnib_insert(c, 0, NULL), ENOMEM); critnib_delete(c); /* all ok */ c = critnib_new(); UT_ASSERTne(c, NULL); critnib_delete(c); } static void test_insert_get_remove(void) { struct critnib *c = critnib_new(); UT_ASSERTne(c, NULL); for (unsigned i = 0; i < TEST_INSERTS; ++i) UT_ASSERTeq(critnib_insert(c, i, TEST_VAL(i)), 0); for (unsigned i = 0; i < TEST_INSERTS; ++i) UT_ASSERTeq(critnib_get(c, i), TEST_VAL(i)); for (unsigned i = 0; i < TEST_INSERTS; ++i) UT_ASSERTeq(critnib_remove(c, i), TEST_VAL(i)); for (unsigned i = 0; i < TEST_INSERTS; ++i) UT_ASSERTeq(critnib_remove(c, i), NULL); for (unsigned i = 0; i < TEST_INSERTS; ++i) UT_ASSERTeq(critnib_get(c, i), NULL); critnib_delete(c); } static uint64_t rnd15() { return rand() & 0x7fff; /* Windows provides only 15 bits */ } static uint64_t rnd64() { return rnd15() | rnd15() << 15 | rnd15() << 30 | rnd15() << 45 | rnd15() << 60; } static void test_smoke() { struct critnib *c = critnib_new(); critnib_insert(c, 123, (void *)456); UT_ASSERTeq(critnib_get(c, 123), (void *)456); UT_ASSERTeq(critnib_get(c, 124), 0); critnib_delete(c); } static void test_key0() { struct critnib *c = critnib_new(); critnib_insert(c, 1, (void *)1); critnib_insert(c, 0, (void *)2); critnib_insert(c, 65536, (void *)3); UT_ASSERTeq(critnib_get(c, 1), (void *)1); UT_ASSERTeq(critnib_remove(c, 1), (void *)1); UT_ASSERTeq(critnib_get(c, 0), (void *)2); UT_ASSERTeq(critnib_remove(c, 0), (void *)2); UT_ASSERTeq(critnib_get(c, 65536), (void *)3); UT_ASSERTeq(critnib_remove(c, 65536), (void *)3); critnib_delete(c); } static void test_1to1000() { struct critnib *c = critnib_new(); for (uint64_t i = 0; i < 1000; i++) critnib_insert(c, i, (void *)i); for (uint64_t i = 0; i < 1000; i++) UT_ASSERTeq(critnib_get(c, i), (void *)i); critnib_delete(c); } static void test_insert_delete() { struct critnib *c = critnib_new(); for (uint64_t i = 0; i < 10000; i++) { UT_ASSERTeq(critnib_get(c, i), (void *)0); critnib_insert(c, i, (void *)i); UT_ASSERTeq(critnib_get(c, i), (void *)i); UT_ASSERTeq(critnib_remove(c, i), (void *)i); UT_ASSERTeq(critnib_get(c, i), (void *)0); } critnib_delete(c); } static void test_insert_bulk_delete() { struct critnib *c = critnib_new(); for (uint64_t i = 0; i < 10000; i++) { UT_ASSERTeq(critnib_get(c, i), (void *)0); critnib_insert(c, i, (void *)i); UT_ASSERTeq(critnib_get(c, i), (void *)i); } for (uint64_t i = 0; i < 10000; i++) { UT_ASSERTeq(critnib_get(c, i), (void *)i); UT_ASSERTeq(critnib_remove(c, i), (void *)i); UT_ASSERTeq(critnib_get(c, i), (void *)0); } critnib_delete(c); } static void test_ffffffff_and_friends() { static uint64_t vals[] = { 0, 0x7fffffff, 0x80000000, 0xffffffff, 0x7fffffffFFFFFFFF, 0x8000000000000000, 0xFfffffffFFFFFFFF, }; struct critnib *c = critnib_new(); for (int i = 0; i < ARRAY_SIZE(vals); i++) critnib_insert(c, vals[i], (void *)~vals[i]); for (int i = 0; i < ARRAY_SIZE(vals); i++) UT_ASSERTeq(critnib_get(c, vals[i]), (void *)~vals[i]); for (int i = 0; i < ARRAY_SIZE(vals); i++) UT_ASSERTeq(critnib_remove(c, vals[i]), (void *)~vals[i]); critnib_delete(c); } static void test_insert_delete_random() { struct critnib *c = critnib_new(); for (uint64_t i = 0; i < 10000; i++) { uint64_t v = rnd64(); critnib_insert(c, v, (void *)v); UT_ASSERTeq(critnib_get(c, v), (void *)v); UT_ASSERTeq(critnib_remove(c, v), (void *)v); UT_ASSERTeq(critnib_get(c, v), 0); } critnib_delete(c); } static void test_le_basic() { struct critnib *c = critnib_new(); #define INS(x) critnib_insert(c, (x), (void *)(x)) INS(1); INS(2); INS(3); INS(0); INS(4); INS(0xf); INS(0xe); INS(0x11); INS(0x12); INS(0x20); #define GET_SAME(x) UT_ASSERTeq(critnib_get(c, (x)), (void *)(x)) #define GET_NULL(x) UT_ASSERTeq(critnib_get(c, (x)), NULL) GET_NULL(122); GET_SAME(1); GET_SAME(2); GET_SAME(3); GET_SAME(4); GET_NULL(5); GET_SAME(0x11); GET_SAME(0x12); #define LE(x, y) UT_ASSERTeq(critnib_find_le(c, (x)), (void *)(y)) LE(1, 1); LE(2, 2); LE(5, 4); LE(6, 4); LE(0x11, 0x11); LE(0x15, 0x12); LE(0xfffffff, 0x20); #undef INS #undef GET_SAME #undef GET_NULL #undef LE critnib_delete(c); } /* * Spread the bits somehow -- more than a few (4 here) children per node * is unlikely to bring interested cases. This function leaves two bits * per nib, producing taller trees. */ static uint64_t expand_bits(int y) { uint64_t x = (uint64_t)y; return (x & 0xc000) << 14 | (x & 0x3000) << 12 | (x & 0x0c00) << 10 | (x & 0x0300) << 8 | (x & 0x00c0) << 6 | (x & 0x0030) << 4 | (x & 0x000c) << 2 | (x & 0x0003); } static void test_le_brute() { struct critnib *c = critnib_new(); char ws[65536] = { 0, }; for (uint32_t cnt = 0; cnt < 1024; cnt++) { int w = rand() & 0xffff; if (ws[w]) { critnib_remove(c, expand_bits(w)); ws[w] = 0; } else { critnib_insert(c, expand_bits(w), (void *)expand_bits(w)); ws[w] = 1; } for (uint32_t cnt2 = 0; cnt2 < 1024; cnt2++) { w = rand() & 0xffff; int v; for (v = w; v >= 0 && !ws[v]; v--) ; uint64_t res = (uint64_t)critnib_find_le(c, expand_bits(w)); uint64_t exp = (v >= 0) ? expand_bits(v) : 0; UT_ASSERTeq(res, exp); } } critnib_delete(c); } static void test_same_only() { struct critnib *c = critnib_new(); critnib_insert(c, 123, (void *)456); critnib_insert(c, 123, (void *)457); UT_ASSERTeq(critnib_get(c, 123), (void *)456); UT_ASSERTeq(critnib_get(c, 124), 0); critnib_delete(c); } static void test_same_two() { struct critnib *c = critnib_new(); critnib_insert(c, 122, (void *)111); critnib_insert(c, 123, (void *)456); critnib_insert(c, 123, (void *)457); UT_ASSERTeq(critnib_get(c, 122), (void *)111); UT_ASSERTeq(critnib_get(c, 123), (void *)456); UT_ASSERTeq(critnib_get(c, 124), 0); critnib_delete(c); } static void test_remove_nonexist() { struct critnib *c = critnib_new(); /* root */ UT_ASSERTeq(critnib_remove(c, 1), NULL); /* in a leaf node */ critnib_insert(c, 2, (void *)2); UT_ASSERTeq(critnib_remove(c, 1), NULL); /* in a non-leaf node */ critnib_insert(c, 3, (void *)3); UT_ASSERTeq(critnib_remove(c, 1), NULL); critnib_delete(c); } static void test_fault_injection() { if (!pmemobj_fault_injection_enabled()) return; struct critnib *c = critnib_new(); pmemobj_inject_fault_at(PMEM_MALLOC, 1, "alloc_node"); /* * The first critnib_insert() call should succeed * - it sets the critnib's root. */ int ret = critnib_insert(c, 1 /* any value */, NULL); UT_ASSERTeq(ret, 0); /* * The second critnib_insert() call should fail * in the alloc_node() function. */ ret = critnib_insert(c, 2 /* any value other than the previous one */, NULL); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); } int main(int argc, char *argv[]) { START(argc, argv, "obj_critnib"); set_func_malloc(__wrap_malloc); test_critnib_new_delete(); test_insert_get_remove(); test_fault_injection(); test_smoke(); test_key0(); test_1to1000(); test_insert_delete(); test_insert_bulk_delete(); test_ffffffff_and_friends(); test_insert_delete_random(); test_le_basic(); test_le_brute(); test_same_only(); test_same_two(); test_remove_nonexist(); DONE(NULL); } pmdk-1.11.1/src/test/obj_critnib/obj_critnib.vcxproj.filters0000664000000000000000000000155614123364546022647 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {ef0cac63-80b7-4779-b772-89df44b66ba3} ps1 Source Files Source Files Test Scripts pmdk-1.11.1/src/test/out_err_mt_win/0000775000000000000000000000000014123364546016040 5ustar rootrootpmdk-1.11.1/src/test/out_err_mt_win/out0.log.match0000664000000000000000000000344214123364546020530 0ustar rootrootout_err_mt_win$(nW)TEST0: START: out_err_mt_win$(nW) $(nW)out_err_mt$(nW) $(nW)testfile1 $(nW)testfile2 $(nW)testfile3 $(nW)testfile4 $(nW) start PMEM: PMEMOBJ: PMEMLOG: PMEMBLK: PMEMPOOL: version check PMEM: libpmem major version mismatch (need 10000, found 1) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmem_msync PMEM: msync: $(S) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemobj_alloc PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemlog_append PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemblk_set_error PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmempool_check_init PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: provided args_size is not supported out_err_mt_win$(nW)TEST0: DONE pmdk-1.11.1/src/test/out_err_mt_win/TEST0.PS10000664000000000000000000000366314123364546017234 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/out_err_mt_win/TEST0 -- unit test for error messages # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup expect_normal_exit $Env:EXE_DIR\out_err_mt_win$Env:EXESUFFIX ` $DIR\testfile1 $DIR\testfile2 $DIR\testfile3 $DIR\testfile4 $DIR check pass pmdk-1.11.1/src/test/out_err_mt_win/out_err_mt_win.vcxproj.filters0000664000000000000000000000200214123364546024152 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {1d395904-81fc-4e68-a335-f663b431dbf7} match {62ac7650-9f5d-4d5f-96ff-d652a437ea51} ps1 Source Files Test Scripts Match Files pmdk-1.11.1/src/test/out_err_mt_win/out_err_mt_win.vcxproj0000664000000000000000000000765014123364546022521 0ustar rootroot Debug x64 Release x64 {2B1A5104-A324-4D02-B5C7-D021FB8F880C} Win32Proj out_err_mt_win 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {cf9a0883-6334-44c7-ac29-349468c78e27} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/out_err_mt_win/out_err_mt_win.c0000664000000000000000000000740414123364546021245 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2020, Intel Corporation */ /* * out_err_mt_win.c -- unit test for error messages */ #include #include #include #include "unittest.h" #include "valgrind_internal.h" #include "util.h" #define NUM_THREADS 16 static void print_errors(const wchar_t *msg) { UT_OUT("%S", msg); UT_OUT("PMEM: %S", pmem_errormsgW()); UT_OUT("PMEMOBJ: %S", pmemobj_errormsgW()); UT_OUT("PMEMLOG: %S", pmemlog_errormsgW()); UT_OUT("PMEMBLK: %S", pmemblk_errormsgW()); UT_OUT("PMEMPOOL: %S", pmempool_errormsgW()); } static void check_errors(int ver) { int ret; int err_need; int err_found; ret = swscanf(pmem_errormsgW(), L"libpmem major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEM_MAJOR_VERSION); ret = swscanf(pmemobj_errormsgW(), L"libpmemobj major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMOBJ_MAJOR_VERSION); ret = swscanf(pmemlog_errormsgW(), L"libpmemlog major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMLOG_MAJOR_VERSION); ret = swscanf(pmemblk_errormsgW(), L"libpmemblk major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMBLK_MAJOR_VERSION); ret = swscanf(pmempool_errormsgW(), L"libpmempool major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMPOOL_MAJOR_VERSION); } static void * do_test(void *arg) { int ver = *(int *)arg; pmem_check_version(ver, 0); pmemobj_check_version(ver, 0); pmemlog_check_version(ver, 0); pmemblk_check_version(ver, 0); pmempool_check_version(ver, 0); check_errors(ver); return NULL; } static void run_mt_test(void *(*worker)(void *)) { os_thread_t thread[NUM_THREADS]; int ver[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; ++i) { ver[i] = 10000 + i; THREAD_CREATE(&thread[i], NULL, worker, &ver[i]); } for (int i = 0; i < NUM_THREADS; ++i) { THREAD_JOIN(&thread[i], NULL); } } int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "out_err_mt_win"); if (argc != 6) UT_FATAL("usage: %S file1 file2 file3 file4 dir", argv[0]); print_errors(L"start"); PMEMobjpool *pop = pmemobj_createW(argv[1], L"test", PMEMOBJ_MIN_POOL, 0666); PMEMlogpool *plp = pmemlog_createW(argv[2], PMEMLOG_MIN_POOL, 0666); PMEMblkpool *pbp = pmemblk_createW(argv[3], 128, PMEMBLK_MIN_POOL, 0666); util_init(); pmem_check_version(10000, 0); pmemobj_check_version(10001, 0); pmemlog_check_version(10002, 0); pmemblk_check_version(10003, 0); pmempool_check_version(10006, 0); print_errors(L"version check"); void *ptr = NULL; /* * We are testing library error reporting and we don't want this test * to fail under memcheck. */ VALGRIND_DO_DISABLE_ERROR_REPORTING; pmem_msync(ptr, 1); VALGRIND_DO_ENABLE_ERROR_REPORTING; print_errors(L"pmem_msync"); int ret; PMEMoid oid; ret = pmemobj_alloc(pop, &oid, 0, 0, NULL, NULL); UT_ASSERTeq(ret, -1); print_errors(L"pmemobj_alloc"); pmemlog_append(plp, NULL, PMEMLOG_MIN_POOL); print_errors(L"pmemlog_append"); size_t nblock = pmemblk_nblock(pbp); pmemblk_set_error(pbp, nblock + 1); print_errors(L"pmemblk_set_error"); run_mt_test(do_test); pmemobj_close(pop); pmemlog_close(plp); pmemblk_close(pbp); PMEMpoolcheck *ppc; struct pmempool_check_args args = {0, }; ppc = pmempool_check_init(&args, sizeof(args) / 2); UT_ASSERTeq(ppc, NULL); print_errors(L"pmempool_check_init"); DONEW(NULL); } pmdk-1.11.1/src/test/obj_tx_add_range/0000775000000000000000000000000014123364546016255 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_add_range/obj_tx_add_range.vcxproj0000664000000000000000000001036114123364546023144 0ustar rootroot Debug x64 Release x64 {F3E5650D-834E-45E6-90C7-3FC2AA954929} Win32Proj obj_tx_add_range 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) CompileAsCpp $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) 4200 CompileAsCpp $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) 4200 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_add_range/obj_tx_add_range.vcxproj.filters0000664000000000000000000000153014123364546024611 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {b94ffedf-6586-4a6f-9776-10034cce5db9} PS1 Source Files Test Scripts Test Scripts pmdk-1.11.1/src/test/obj_tx_add_range/obj_tx_add_range.c0000664000000000000000000006277714123364546021715 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_tx_add_range.c -- unit test for pmemobj_tx_add_range */ #include #include #include "tx.h" #include "unittest.h" #include "util.h" #include "valgrind_internal.h" #define LAYOUT_NAME "tx_add_range" #define OBJ_SIZE 1024 #define OVERLAP_SIZE 100 #define ROOT_TAB_SIZE\ (TX_DEFAULT_RANGE_CACHE_SIZE / sizeof(int)) #define REOPEN_COUNT 10 enum type_number { TYPE_OBJ, TYPE_OBJ_ABORT, TYPE_OBJ_WRONG_UUID, }; TOID_DECLARE(struct object, 0); TOID_DECLARE(struct overlap_object, 1); TOID_DECLARE_ROOT(struct root); struct root { int val; int tab[ROOT_TAB_SIZE]; }; struct object { size_t value; char data[OBJ_SIZE - sizeof(size_t)]; }; struct overlap_object { uint8_t data[OVERLAP_SIZE]; }; #define VALUE_OFF (offsetof(struct object, value)) #define VALUE_SIZE (sizeof(size_t)) #define DATA_OFF (offsetof(struct object, data)) #define DATA_SIZE (OBJ_SIZE - sizeof(size_t)) #define TEST_VALUE_1 1 #define TEST_VALUE_2 2 /* * do_tx_zalloc -- do tx allocation with specified type number */ static PMEMoid do_tx_zalloc(PMEMobjpool *pop, uint64_t type_num) { PMEMoid ret = OID_NULL; TX_BEGIN(pop) { ret = pmemobj_tx_zalloc(sizeof(struct object), type_num); } TX_END return ret; } /* * do_tx_alloc -- do tx allocation and initialize first num bytes */ static PMEMoid do_tx_alloc(PMEMobjpool *pop, uint64_t type_num, uint64_t init_num) { PMEMoid ret = OID_NULL; TX_BEGIN(pop) { ret = pmemobj_tx_alloc(sizeof(struct object), type_num); pmemobj_memset(pop, pmemobj_direct(ret), 0, init_num, 0); } TX_END return ret; } /* * do_tx_add_range_alloc_commit -- call pmemobj_add_range on object allocated * within the same transaction and commit the transaction */ static void do_tx_add_range_alloc_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range(obj.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj)->data[i], TEST_VALUE_2); } /* * do_tx_add_range_alloc_abort -- call pmemobj_add_range on object allocated * within the same transaction and abort the transaction */ static void do_tx_add_range_alloc_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range(obj.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_2, DATA_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_OBJ_ABORT)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_add_range_twice_commit -- call pmemobj_add_range one the same area * twice and commit the transaction */ static void do_tx_add_range_twice_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_2); } /* * do_tx_add_range_twice_abort -- call pmemobj_add_range one the same area * twice and abort the transaction */ static void do_tx_add_range_twice_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); UT_ASSERT(!TOID_IS_NULL(obj)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, 0); } /* * do_tx_add_range_abort_after_nested -- call pmemobj_tx_add_range and * commit the tx */ static void do_tx_add_range_abort_after_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj1.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj2.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, 0); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], 0); } /* * do_tx_add_range_abort_nested -- call pmemobj_tx_add_range and * commit the tx */ static void do_tx_add_range_abort_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj1.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj2.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, 0); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], 0); } /* * do_tx_add_range_abort_after_commit -- call pmemobj_tx_add_range with * non-zero data, commit first tx, and abort second tx * * This is the test for issue injected in commit: * 2ab13304664b353b82730f49b78fc67eea33b25b (ulog-invalidation). */ static void do_tx_add_range_abort_after_commit(PMEMobjpool *pop) { int ret; size_t i; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); /* 1. Set data to non-zero value. */ pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_1, DATA_SIZE); for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj)->data[i], TEST_VALUE_1); /* 2. Do the snapshot using non-zero value. */ TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); /* * You can modify data here, but it is not necessary * to reproduce abort/apply ulog issue. */ pmemobj_memset_persist(pop, D_RW(obj)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj)->data[i], TEST_VALUE_2); /* * 3. Do the second snapshot and then abort the transaction. */ for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj)->data[i], TEST_VALUE_2); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END /* 4. All data must be recovered after tx abort. */ UT_ASSERTeq(D_RO(obj)->value, 0); } /* * do_tx_add_range_commit_nested -- call pmemobj_tx_add_range and commit the tx */ static void do_tx_add_range_commit_nested(PMEMobjpool *pop) { int ret; TOID(struct object) obj1; TOID(struct object) obj2; TOID_ASSIGN(obj1, do_tx_zalloc(pop, TYPE_OBJ)); TOID_ASSIGN(obj2, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj1.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj1)->value = TEST_VALUE_1; TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj2.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); pmemobj_memset_persist(pop, D_RW(obj2)->data, TEST_VALUE_2, DATA_SIZE); } TX_ONABORT { UT_ASSERT(0); } TX_END } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj1)->value, TEST_VALUE_1); size_t i; for (i = 0; i < DATA_SIZE; i++) UT_ASSERTeq(D_RO(obj2)->data[i], TEST_VALUE_2); } /* * do_tx_add_range_abort -- call pmemobj_tx_add_range and abort the tx */ static void do_tx_add_range_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, 0); } /* * do_tx_add_huge_range_abort -- call pmemobj_tx_add_range on a huge range and * commit the tx */ static void do_tx_add_huge_range_abort(PMEMobjpool *pop) { int ret; size_t snapshot_s = TX_DEFAULT_RANGE_CACHE_THRESHOLD + 1; PMEMoid obj; pmemobj_zalloc(pop, &obj, snapshot_s, 0); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj, 0, snapshot_s); UT_ASSERTeq(ret, 0); memset(pmemobj_direct(obj), 0xc, snapshot_s); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(pmemobj_direct(obj), snapshot_s)); } /* * do_tx_add_range_commit -- call pmemobj_tx_add_range and commit the tx */ static void do_tx_add_range_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_flush_commit -- call pmemobj_tx_xadd_range with * POBJ_XADD_NO_FLUSH set and commit the tx */ static void do_tx_xadd_range_no_flush_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_FLUSH); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; /* let pmemcheck find we didn't flush it */ } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_snapshot_commit -- call pmemobj_tx_xadd_range with * POBJ_XADD_NO_SNAPSHOT flag set and commit the tx */ static void do_tx_xadd_range_no_snapshot_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_SNAPSHOT); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_twice_no_snapshot_abort -- call pmemobj_tx_add_range twice * - with POBJ_XADD_NO_SNAPSHOT flag set and without it - and abort the tx */ static void do_tx_xadd_range_twice_no_snapshot_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_SNAPSHOT); UT_ASSERTeq(ret, 0); /* Previously set flag on this range should NOT be overridden */ ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_snapshot_abort -- call pmemobj_tx_range with * POBJ_XADD_NO_SNAPSHOT flag, modify the value inside aborted transaction */ static void do_tx_xadd_range_no_snapshot_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); D_RW(obj)->value = TEST_VALUE_1; TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_NO_SNAPSHOT); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END /* * value added with NO_SNAPSHOT flag should NOT * be rolled back after abort */ UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_2); } /* * do_tx_xadd_range_no_snapshot_fields -- call pmemobj_tx_add_range * on selected fields and NO_SNAPSHOT flag set */ static void do_tx_xadd_range_no_snapshot_fields(PMEMobjpool *pop) { TOID(struct overlap_object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, 1)); char after_abort[OVERLAP_SIZE]; memcpy(after_abort, D_RO(obj)->data, OVERLAP_SIZE); TX_BEGIN(pop) { /* * changes of ranges with NO_SNAPSHOT flag set * should not be reverted after abort */ TX_XADD_FIELD(obj, data[1], POBJ_XADD_NO_SNAPSHOT); D_RW(obj)->data[1] = 1; after_abort[1] = 1; TX_ADD_FIELD(obj, data[2]); D_RW(obj)->data[2] = 2; TX_XADD_FIELD(obj, data[5], POBJ_XADD_NO_SNAPSHOT); D_RW(obj)->data[5] = 5; after_abort[5] = 5; TX_ADD_FIELD(obj, data[7]); D_RW(obj)->data[7] = 7; TX_XADD_FIELD(obj, data[8], POBJ_XADD_NO_SNAPSHOT); D_RW(obj)->data[8] = 8; after_abort[8] = 8; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(memcmp(D_RW(obj)->data, after_abort, OVERLAP_SIZE), 0); } /* * do_tx_xadd_range_no_uninit_check -- call pmemobj_tx_xadd_range for * initialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set and commit the * tx */ static void do_tx_xadd_range_no_uninit_check_commit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); } /* * do_tx_xadd_range_no_uninit_check -- call pmemobj_tx_xadd_range for * uninitialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set and commit * the tx */ static void do_tx_xadd_range_no_uninit_check_commit_uninit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, 0)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range(obj.oid, DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_xadd_range_no_uninit_check -- call pmemobj_tx_xadd_range for * partially uninitialized memory with POBJ_XADD_ASSUME_INITIALIZED flag set * only for uninitialized part and commit the tx */ static void do_tx_xadd_range_no_uninit_check_commit_part_uninit(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, VALUE_SIZE)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range(obj.oid, DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_add_range_no_uninit_check -- call pmemobj_tx_add_range for * partially uninitialized memory. */ static void do_tx_add_range_no_uninit_check_commit_no_flag(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, VALUE_SIZE)); TX_BEGIN(pop) { ret = pmemobj_tx_add_range(obj.oid, VALUE_OFF, VALUE_SIZE); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_add_range(obj.oid, DATA_OFF, DATA_SIZE); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERTeq(D_RO(obj)->data[256], TEST_VALUE_2); } /* * do_tx_xadd_range_no_uninit_check_abort -- call pmemobj_tx_range with * POBJ_XADD_ASSUME_INITIALIZED flag, modify the value inside aborted * transaction */ static void do_tx_xadd_range_no_uninit_check_abort(PMEMobjpool *pop) { int ret; TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_OBJ, 0)); TX_BEGIN(pop) { ret = pmemobj_tx_xadd_range(obj.oid, VALUE_OFF, VALUE_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); ret = pmemobj_tx_xadd_range(obj.oid, DATA_OFF, DATA_SIZE, POBJ_XADD_ASSUME_INITIALIZED); UT_ASSERTeq(ret, 0); D_RW(obj)->value = TEST_VALUE_1; D_RW(obj)->data[256] = TEST_VALUE_2; pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END } /* * do_tx_add_range_overlapping -- call pmemobj_tx_add_range with overlapping */ static void do_tx_add_range_overlapping(PMEMobjpool *pop) { TOID(struct overlap_object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, 1)); /* * -+-+-+-+- * +++++++++ */ TX_BEGIN(pop) { TX_ADD_FIELD(obj, data[1]); D_RW(obj)->data[1] = 1; TX_ADD_FIELD(obj, data[3]); D_RW(obj)->data[3] = 3; TX_ADD_FIELD(obj, data[5]); D_RW(obj)->data[5] = 5; TX_ADD_FIELD(obj, data[7]); D_RW(obj)->data[7] = 7; TX_ADD(obj); memset(D_RW(obj)->data, 0xFF, OVERLAP_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(D_RO(obj)->data, OVERLAP_SIZE)); /* * ++++----++++ * --++++++++-- */ TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, 4); memset(D_RW(obj)->data + 0, 1, 4); pmemobj_tx_add_range(obj.oid, 8, 4); memset(D_RW(obj)->data + 8, 2, 4); pmemobj_tx_add_range(obj.oid, 2, 8); memset(D_RW(obj)->data + 2, 3, 8); TX_ADD(obj); memset(D_RW(obj)->data, 0xFF, OVERLAP_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(D_RO(obj)->data, OVERLAP_SIZE)); /* * ++++----++++ * ----++++---- */ TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, 4); memset(D_RW(obj)->data + 0, 1, 4); pmemobj_tx_add_range(obj.oid, 8, 4); memset(D_RW(obj)->data + 8, 2, 4); pmemobj_tx_add_range(obj.oid, 4, 4); memset(D_RW(obj)->data + 4, 3, 4); TX_ADD(obj); memset(D_RW(obj)->data, 0xFF, OVERLAP_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(D_RO(obj)->data, OVERLAP_SIZE)); /* * ++++-++-++++ * --++++++++-- */ TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, 4); memset(D_RW(obj)->data + 0, 1, 4); pmemobj_tx_add_range(obj.oid, 5, 2); memset(D_RW(obj)->data + 5, 2, 2); pmemobj_tx_add_range(obj.oid, 8, 4); memset(D_RW(obj)->data + 8, 3, 4); pmemobj_tx_add_range(obj.oid, 2, 8); memset(D_RW(obj)->data + 2, 4, 8); TX_ADD(obj); memset(D_RW(obj)->data, 0xFF, OVERLAP_SIZE); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(D_RO(obj)->data, OVERLAP_SIZE)); /* * ++++ * ++++ */ TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, 4); memset(D_RW(obj)->data, 1, 4); pmemobj_tx_add_range(obj.oid, 0, 4); memset(D_RW(obj)->data, 2, 4); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERT(util_is_zeroed(D_RO(obj)->data, OVERLAP_SIZE)); } /* * do_tx_add_range_flag_merge_right -- call pmemobj_tx_add_range with * overlapping ranges, but different flags */ static void do_tx_add_range_flag_merge_right(PMEMobjpool *pop) { TOID(struct overlap_object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, 1)); /* * ++++-------- * --++++++++-- */ TX_BEGIN(pop) { pmemobj_tx_xadd_range(obj.oid, 0, 4, POBJ_XADD_NO_FLUSH); memset(D_RW(obj)->data, 1, 4); pmemobj_tx_add_range(obj.oid, 2, 8); memset(D_RW(obj)->data + 2, 3, 8); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_add_range_flag_merge_left -- call pmemobj_tx_add_range with * overlapping ranges, but different flags */ static void do_tx_add_range_flag_merge_left(PMEMobjpool *pop) { TOID(struct overlap_object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, 1)); /* * --------++++ * --++++++++-- */ TX_BEGIN(pop) { pmemobj_tx_xadd_range(obj.oid, 8, 4, POBJ_XADD_NO_FLUSH); memset(D_RW(obj)->data + 8, 2, 4); pmemobj_tx_add_range(obj.oid, 2, 8); memset(D_RW(obj)->data + 2, 3, 8); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_add_range_flag_merge_middle -- call pmemobj_tx_add_range with * three adjacent ranges, but different flags */ static void do_tx_add_range_flag_merge_middle(PMEMobjpool *pop) { TOID(struct overlap_object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, 1)); /* * ++++----++++ * ----++++---- */ TX_BEGIN(pop) { pmemobj_tx_xadd_range(obj.oid, 0, 4, POBJ_XADD_NO_FLUSH); memset(D_RW(obj)->data, 1, 4); pmemobj_tx_xadd_range(obj.oid, 8, 4, POBJ_XADD_NO_FLUSH); memset(D_RW(obj)->data + 8, 2, 4); pmemobj_tx_add_range(obj.oid, 4, 4); memset(D_RW(obj)->data + 4, 3, 4); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_add_range_reopen -- check for persistent memory leak in undo log set */ static void do_tx_add_range_reopen(char *path) { for (int i = 0; i < REOPEN_COUNT; i++) { PMEMobjpool *pop = pmemobj_open(path, LAYOUT_NAME); UT_ASSERTne(pop, NULL); TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(!TOID_IS_NULL(root)); UT_ASSERTeq(D_RO(root)->val, i); for (int j = 0; j < ROOT_TAB_SIZE; j++) UT_ASSERTeq(D_RO(root)->tab[j], i); TX_BEGIN(pop) { TX_SET(root, val, i + 1); TX_ADD_FIELD(root, tab); for (int j = 0; j < ROOT_TAB_SIZE; j++) D_RW(root)->tab[j] = i + 1; } TX_ONABORT { UT_ASSERT(0); } TX_END pmemobj_close(pop); } } static void do_tx_add_range_too_large(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, PMEMOBJ_MAX_ALLOC_SIZE + 1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTne(errno, 0); } static void do_tx_add_range_zero(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_zalloc(pop, TYPE_OBJ)); TX_BEGIN(pop) { pmemobj_tx_add_range(obj.oid, 0, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTne(errno, 0); } /* * do_tx_add_range_wrong_uuid -- call pmemobj_tx_xadd_range with * POBJ_TX_NO_ABORT flag and wrong uuid */ static void do_tx_add_range_wrong_uuid(PMEMobjpool *pop) { PMEMoid oid = do_tx_alloc(pop, TYPE_OBJ_WRONG_UUID, 0); oid.pool_uuid_lo = ~oid.pool_uuid_lo; TX_BEGIN(pop) { pmemobj_tx_xadd_range(oid, 0, 0, 0); }TX_ONCOMMIT { UT_ASSERT(0); } TX_END UT_ASSERTeq(errno, EINVAL); TX_BEGIN(pop) { pmemobj_tx_xadd_range(oid, 0, 0, POBJ_XADD_NO_ABORT); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(errno, EINVAL); TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_add_range(oid, 0, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(errno, EINVAL); TX_BEGIN(pop) { pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); pmemobj_tx_xadd_range(oid, 0, 0, 0); } TX_ONABORT { UT_ASSERT(0); } TX_END UT_ASSERTeq(errno, EINVAL); } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_add_range"); util_init(); if (argc != 3) UT_FATAL("usage: %s [file] [0|1]", argv[0]); int do_reopen = atoi(argv[2]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL * 2, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); if (do_reopen) { pmemobj_close(pop); do_tx_add_range_reopen(argv[1]); } else { do_tx_add_range_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_commit_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort_after_nested(pop); VALGRIND_WRITE_STATS; do_tx_add_range_abort_after_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_twice_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_twice_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_alloc_commit(pop); VALGRIND_WRITE_STATS; do_tx_add_range_alloc_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_overlapping(pop); VALGRIND_WRITE_STATS; do_tx_add_range_too_large(pop); VALGRIND_WRITE_STATS; do_tx_add_huge_range_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_zero(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_snapshot_commit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_snapshot_abort(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_twice_no_snapshot_abort(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_snapshot_fields(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit_uninit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_commit_part_uninit(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_uninit_check_abort(pop); VALGRIND_WRITE_STATS; do_tx_add_range_no_uninit_check_commit_no_flag(pop); VALGRIND_WRITE_STATS; do_tx_add_range_wrong_uuid(pop); VALGRIND_WRITE_STATS; do_tx_add_range_flag_merge_left(pop); VALGRIND_WRITE_STATS; do_tx_add_range_flag_merge_right(pop); VALGRIND_WRITE_STATS; do_tx_add_range_flag_merge_middle(pop); VALGRIND_WRITE_STATS; do_tx_xadd_range_no_flush_commit(pop); pmemobj_close(pop); } DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_add_range/TEST00000775000000000000000000000075614123364546017052 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range/TEST0 -- unit test for pmemobj_tx_add_range # . ../unittest/unittest.sh require_test_type medium # Pmemcheck is disabled here. The next test case (TEST1) will run the same test # under pmemcheck configure_valgrind pmemcheck force-disable configure_valgrind memcheck force-disable setup expect_normal_exit ./obj_tx_add_range$EXESUFFIX $DIR/testfile0 0 pass pmdk-1.11.1/src/test/obj_tx_add_range/Makefile0000664000000000000000000000047414123364546017722 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range/Makefile -- build obj_tx_add_range unit test # TOP = ../../.. TARGET = obj_tx_add_range OBJS = obj_tx_add_range.o LIBPMEMCOMMON=y LIBPMEMOBJ=y include ../Makefile.inc INCS += -I$(TOP)/src/libpmemobj/ pmdk-1.11.1/src/test/obj_tx_add_range/TEST2.PS10000664000000000000000000000360314123364546017445 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_add_range/TEST2 -- unit test for pmemobj_tx_add_range # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type pmem setup expect_normal_exit $ENV:EXE_DIR\obj_tx_add_range$Env:EXESUFFIX $DIR\testfile2 1 pass pmdk-1.11.1/src/test/obj_tx_add_range/TESTS.py0000775000000000000000000000223614123364546017537 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation """unit tests for pmemobj_tx_add_range and pmemobj_tx_xadd_range""" from os import path import testframework as t @t.require_valgrind_disabled('memcheck', 'pmemcheck') class TEST0(t.Test): test_type = t.Medium def run(self, ctx): testfile = path.join(ctx.testdir, 'testfile0') ctx.exec('obj_tx_add_range', testfile, '0') @t.require_valgrind_enabled('pmemcheck') class TEST1(t.Test): test_type = t.Medium def run(self, ctx): ctx.valgrind.add_opt('--mult-stores=no') testfile = path.join(ctx.testdir, 'testfile1') ctx.exec('obj_tx_add_range', testfile, '0') @t.require_valgrind_disabled('memcheck') class TEST2(t.Test): test_type = t.Medium def run(self, ctx): testfile = path.join(ctx.testdir, 'testfile2') ctx.exec('obj_tx_add_range', testfile, '1') @t.require_valgrind_enabled('memcheck') @t.require_build('debug') class TEST3(t.Test): test_type = t.Medium def run(self, ctx): testfile = path.join(ctx.testdir, 'testfile3') ctx.exec('obj_tx_add_range', testfile, '0') pmdk-1.11.1/src/test/obj_tx_add_range/TEST0.PS10000664000000000000000000000355614123364546017452 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_add_range/TEST0 -- unit test for pmemobj_tx_add_range # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $ENV:EXE_DIR\obj_tx_add_range$Env:EXESUFFIX $DIR\testfile0 0 pass pmdk-1.11.1/src/test/obj_tx_add_range/pmemcheck1.log.match0000664000000000000000000000570114123364546022073 0ustar rootroot==$(*)== pmemcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/obj_tx_add_range$(*) ==$(*)== Parent PID: $(*) ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== Number of stores not made persistent: 0 ==$(*)== ERROR SUMMARY: 0 errors ==$(*)== ==$(*)== ==$(*)== Number of stores not made persistent: 1 ==$(*)== Stores not made persistent properly: ==$(*)== [0] at 0x$(*): do_tx_xadd_range_no_flush_commit (obj_tx_add_range.c:$(*)) ==$(*)== by 0x$(*): main (obj_tx_add_range.c:$(*)) ==$(*)== Address: 0x$(*) size: 8 state: DIRTY ==$(*)== Total memory not made persistent: 8 ==$(*)== ERROR SUMMARY: 1 errors pmdk-1.11.1/src/test/obj_tx_add_range/.gitignore0000664000000000000000000000002114123364546020236 0ustar rootrootobj_tx_add_range pmdk-1.11.1/src/test/obj_tx_add_range/config.sh0000664000000000000000000000043114123364546020054 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # # obj_tx_add_range/config.sh -- test configuration # # Extend timeout for this test, as it may take a few minutes # when run on a non-pmem file system. CONF_GLOBAL_TIMEOUT='10m' pmdk-1.11.1/src/test/obj_tx_add_range/TEST10000775000000000000000000000071414123364546017045 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range/TEST1 -- unit test for pmemobj_tx_add_range # with valgrind pmemcheck tool # . ../unittest/unittest.sh require_test_type medium require_fs_type pmem non-pmem configure_valgrind pmemcheck force-enable export VALGRIND_OPTS="--mult-stores=no" setup expect_normal_exit ./obj_tx_add_range$EXESUFFIX $DIR/testfile1 0 check pass pmdk-1.11.1/src/test/obj_tx_add_range/TEST20000775000000000000000000000056614123364546017053 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_add_range/TEST2 -- unit test for pmemobj_tx_add_range # . ../unittest/unittest.sh require_test_type medium configure_valgrind memcheck force-disable require_fs_type pmem setup expect_normal_exit ./obj_tx_add_range$EXESUFFIX $DIR/testfile2 1 pass pmdk-1.11.1/src/test/obj_tx_add_range/memcheck3.log.match0000664000000000000000000000376314123364546021723 0ustar rootroot==$(*)== Memcheck$(*) ==$(*)== Copyright$(*) ==$(*)== Using Valgrind-$(*) ==$(*)== Command: $(*)/obj_tx_add_range$(*) ==$(*)== Parent PID: $(*) ==$(*)== **$(*)** Snapshotting uninitialized data in range <0x$(*),0x$(*)> () ==$(*)== Uninitialised byte(s) found during client check request ==$(*)== at $(*): vg_verify_initialized ($(*)) ==$(*)== by $(*): pmemobj_tx_add_snapshot ($(*)) ==$(*)== by $(*): pmemobj_tx_add_common ($(*)) ==$(*)== by $(*): pmemobj_tx_add_range ($(*)) ==$(*)== by $(*): do_tx_add_range_no_uninit_check_commit_no_flag ($(*)obj_tx_add_range$(*)) ==$(*)== by $(*): main ($(*)obj_tx_add_range$(*)) ==$(*)== Address $(*) is 8 bytes inside a block of size $(*) client-defined ==$(*)== at $(*): alloc_prep_block ($(*)) ==$(*)== by $(*): palloc_reservation_create ($(*)) ==$(*)== by $(*): palloc_reserve ($(*)) ==$(*)== by $(*): tx_alloc_common ($(*)) ==$(*)== by $(*): pmemobj_tx_alloc ($(*)) ==$(*)== by $(*): do_tx_alloc ($(*)) ==$(*)== by $(*): do_tx_add_range_no_uninit_check_commit_no_flag ($(*)obj_tx_add_range$(*)) ==$(*)== by $(*): main ($(*)obj_tx_add_range$(*)) ==$(*)== ==$(*)== ==$(*)== HEAP SUMMARY: ==$(*)== in use at exit: $(*) bytes in $(*) blocks ==$(*)== total heap usage: $(*) allocs, $(*) frees, $(*) bytes allocated ==$(*)== $(OPT)==$(*)== All heap blocks were freed -- no leaks are possible $(OPX)==$(*)== LEAK SUMMARY: $(OPT)==$(*)== definitely lost: 0 bytes in 0 blocks $(OPT)==$(*)== indirectly lost: 0 bytes in 0 blocks $(OPT)==$(*)== possibly lost: 0 bytes in 0 blocks $(OPT)==$(*)== still reachable: 0 bytes in 0 blocks $(OPT)==$(*)== suppressed: $(*) bytes in $(*) blocks ==$(*)== $(OPT)==$(*)== For counts of detected and suppressed errors, rerun with: -v ==$(*)== Use --track-origins=yes to see where uninitialised values come from $(OPT)==$(*)== For lists of detected and suppressed errors, rerun with: -s ==$(*)== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: $(*) from $(*)) pmdk-1.11.1/src/test/pmempool_rm/0000775000000000000000000000000014123364546015332 5ustar rootrootpmdk-1.11.1/src/test/pmempool_rm/TEST7.PS10000664000000000000000000000152014123364546016523 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_rm/TEST7.PS1 -- test for pmempool rm in interactive mode # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" remove_files $LOG # Create poolset with replica create_poolset $DIR\pool.set 32M:$DIR\pool.part1:z 32M:$DIR\pool.part2:z ` R 32M:$DIR\rep.part1:z 32M:$DIR\rep.part2:z # Check if pool set file exists check_files ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 # Try to remove all files in interactive mode echo @" Y n n y N "@ | &$PMEMPOOL rm -il $DIR\pool.set 2>&1 | out-file -width 1024 -literalpath $LOG check_no_files ` $DIR\pool.part1 ` $DIR\rep.part2 check_files ` $DIR\pool.set ` $DIR\pool.part2 ` $DIR\rep.part1 pass pmdk-1.11.1/src/test/pmempool_rm/TEST1.PS10000664000000000000000000000347314123364546016526 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_rm/TEST1w.PS1 -- test for pmempool rm # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" remove_files $LOG # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL create -m400 log $DIR\pool.log expect_normal_exit $PMEMPOOL create -m400 blk 512 $DIR\pool.blk expect_normal_exit $PMEMPOOL create -m400 obj $DIR\pool.obj # Create poolset with replica create_poolset $DIR\pool.set 32M:$DIR\pool.part1:z 32M:$DIR\pool.part2:z ` R 32M:$DIR\rep.part1:z 32M:$DIR\rep.part2:z # Create pmemobj pools from the poolset expect_normal_exit $PMEMPOOL create -m400 obj $DIR\pool.set set_file_mode IsReadOnly $true $DIR\pool.set $DIR\pool.part1 $DIR\pool.part2 $DIR\rep.part1 $DIR\rep.part2 # Check if all pools and poolset exist check_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 @" n n n y y y y n "@ | &$PMEMPOOL rm -sv ` $DIR\pool.log $DIR\pool.blk $DIR\pool.obj $DIR\pool.set >> $LOG check_exit_code check_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set ` check_no_files ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 expect_normal_exit $PMEMPOOL create -m400 obj $DIR\pool.set check_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 expect_normal_exit $PMEMPOOL rm -flv ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set >> $LOG check_no_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 check pass pmdk-1.11.1/src/test/pmempool_rm/log5.log.match0000775000000000000000000000030614123364546020000 0ustar rootrooterror: cannot remove file '$(nW)pool2': No such file or directory error: cannot remove file '$(nW)pool3': No such file or directory error: removing '$(nW)pool.set' failed: No such file or directory pmdk-1.11.1/src/test/pmempool_rm/TEST30000775000000000000000000000045614123364546016127 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # # pmempool_rm/TEST3 -- test for pmempool rm # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 setup expect_normal_exit $PMEMPOOL$EXESUFFIX rm -f $DEVICE_DAX_PATH pass pmdk-1.11.1/src/test/pmempool_rm/TEST10.PS10000664000000000000000000000252214123364546016600 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_rm/TEST10.PS1 -- test for pmempool rm in interactive mode # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL create log $DIR\pool.log expect_normal_exit $PMEMPOOL create blk 512 $DIR\pool.blk expect_normal_exit $PMEMPOOL create obj $DIR\pool.obj # Create poolset create_poolset $DIR\pool.set 32M:$DIR\pool.part1:z 32M:$DIR\pool.part2:z # Create pmemobj pool from the poolset expect_normal_exit $PMEMPOOL create obj $DIR\pool.set # Check if files exist check_files ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj set_file_mode IsReadOnly $true ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj # Try to remove all files in interactive mode echo @" n N Y N y "@ | &$PMEMPOOL rm ` $DIR\pool.set ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` > $LOG check_no_files ` $DIR\pool.log ` $DIR\pool.obj check_files ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 echo @" n y "@ | &$PMEMPOOL rm $DIR\pool.set >> $LOG check_no_files $DIR\part2 check_files ` $DIR\pool.part1 ` $DIR\pool.set pass pmdk-1.11.1/src/test/pmempool_rm/TEST90000775000000000000000000000103214123364546016124 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_rm/TEST9 -- test for pmempool rm # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup RESVSIZE=$((4 * 1024 * 1024 * 1024)) # 4GiB create_poolset $DIR/testset1\ $RESVSIZE:$DIR/testdir11:d\ O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX create obj --layout pmempool$SUFFIX\ $DIR/testset1 expect_normal_exit $PMEMPOOL$EXESUFFIX rm -af $DIR/testset1 check_no_files $DIR/testset1 pass pmdk-1.11.1/src/test/pmempool_rm/TEST120000775000000000000000000000155314123364546016206 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # pmempool_rm/TEST12 -- test for pmempool rm - verify removing of # a write-protected part file by answering with invalid response # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_no_superuser setup LOG=out$UNITTEST_NUM.log # Create poolset with replica create_poolset $DIR/pool.set 32M:$DIR/pool.part1:z 32M:$DIR/pool.part2:z\ R 32M:$DIR/rep.part1:z 32M:$DIR/rep.part2:z chmod 0400 $DIR/pool.set $DIR/pool.part1 $DIR/pool.part2 $DIR/rep.part1 $DIR/rep.part2 # Check if all pools and poolset exist check_files\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 expect_normal_exit $PMEMPOOL$EXESUFFIX rm -il $DIR/pool.part1 >> $LOG 2>&1 <> $LOG # Check if all pool files don't exist check_no_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 # Pool set file must exist check_file $DIR/pool.set # Create pmemobj pools from the poolset expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set # Remove all pool files and poolset expect_normal_exit $PMEMPOOL$EXESUFFIX rm -v $DIR/pool.set >> $LOG # Check if all pool files don't exist check_no_files\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 # Check if poolset file exists check_file $DIR/pool.set check pass pmdk-1.11.1/src/test/pmempool_rm/Makefile0000664000000000000000000000025414123364546016773 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/pmempool_rm/Makefile -- build pmempool rm unittest # include ../Makefile.inc pmdk-1.11.1/src/test/pmempool_rm/TEST2.PS10000664000000000000000000000234614123364546016525 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_rm/TEST2.PS1 -- test for pmempool rm # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any require_short_path setup $LOG="out$Env:UNITTEST_NUM.log" remove_files $LOG # Create poolset with replica create_poolset $DIR\pool.set 32M:$DIR\pool.part1:x 32M:$DIR\pool.part2:x ` R 32M:$DIR\rep.part1 32M:$DIR\rep.part2 # Check if pool set file exists check_files ` $DIR\pool.set # Check if all pools don't exist check_no_files ` $DIR\pool.obj ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 # Try to remove files without force flag # all commands are called through cmd shell to avoid powershell stderror parsing expect_abnormal_exit cmd /c $PMEMPOOL rm -v $DIR\pool.obj 2`>`&1 | out-file -literalpath $LOG expect_abnormal_exit cmd /c $PMEMPOOL rm -sv $DIR\pool.set 2`>`&1 | out-file -append -literalpath $LOG # Try to remove files with force flag expect_normal_exit cmd /c $PMEMPOOL rm -flv ` $DIR\pool.obj ` $DIR\pool.set 2`>`&1 | out-file -append -literalpath $LOG check_no_files ` $DIR\pool.set ` $DIR\pool.obj ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 check pass pmdk-1.11.1/src/test/pmempool_rm/TEST50000775000000000000000000000164514123364546016132 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # # pmempool_rm/TEST5 -- test for pmempool rm # . ../unittest/unittest.sh require_test_type medium setup create_poolset $DIR/pool.set\ 8M:$DIR/pool1:x\ 8M:$DIR/pool2:x\ 8M:$DIR/pool3:x\ 8M:$DIR/pool4:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.1 expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.2 check_files $DIR/pool.set $DIR/pool1 $DIR/pool2 $DIR/pool3 $DIR/pool4\ $DIR/pool.1 $DIR/pool.2 expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool2 $DIR/pool3 check_no_file $DIR/pool2 $DIR/pool3 expect_abnormal_exit $PMEMPOOL$EXESUFFIX rm -a\ $DIR/pool.1 $DIR/pool.set $DIR/pool.2 2>log$UNITTEST_NUM.log check_no_files $DIR/pool1 $DIR/pool2 $DIR/pool3 $DIR/pool4\ $DIR/pool.1 $DIR/pool.2 check_file $DIR/pool.set check pass pmdk-1.11.1/src/test/pmempool_rm/TEST40000775000000000000000000000057614123364546016133 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # # pmempool_rm/TEST4 -- test for pmempool rm # . ../unittest/unittest.sh require_test_type medium require_dax_devices 1 setup create_poolset $DIR/testset1 AUTO:$DEVICE_DAX_PATH expect_normal_exit $PMEMPOOL$EXESUFFIX rm -af $DIR/testset1 check_no_files $DIR/testset1 pass pmdk-1.11.1/src/test/pmempool_rm/TEST70000775000000000000000000000151614123364546016131 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2017-2018, Intel Corporation # # # pmempool_rm/TEST7 -- test for pmempool rm in interactive mode # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG # Create poolset with replica create_poolset $DIR/pool.set 32M:$DIR/pool.part1:z 32M:$DIR/pool.part2:z\ R 32M:$DIR/rep.part1:z 32M:$DIR/rep.part2:z # Check if pool set file exists check_files\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 # Try to remove all files in interactive mode expect_normal_exit $PMEMPOOL$EXESUFFIX rm -il $DIR/pool.set >> $LOG 2>&1 < {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Test Scripts Test Scripts Match Files Match Files Test Scripts Match Files Test Scripts pmdk-1.11.1/src/test/pmempool_rm/out0.log.match0000664000000000000000000000042414123364546020017 0ustar rootrootremoved '$(nW)pool.log' removed '$(nW)pool.blk' removed '$(nW)pool.obj' removed '$(nW)pool.part1' removed '$(nW)pool.part2' removed '$(nW)rep.part1' removed '$(nW)rep.part2' removed '$(nW)pool.part1' removed '$(nW)pool.part2' removed '$(nW)rep.part1' removed '$(nW)rep.part2' pmdk-1.11.1/src/test/pmempool_rm/TEST0.PS10000664000000000000000000000322614123364546016521 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # pmempool_rm/TEST0 -- test for pmempool rm # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" remove_files $LOG # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL create log $DIR\pool.log expect_normal_exit $PMEMPOOL create blk 512 $DIR\pool.blk expect_normal_exit $PMEMPOOL create obj $DIR\pool.obj # Create poolset with replica create_poolset $DIR\pool.set 32M:$DIR\pool.part1:z 32M:$DIR\pool.part2:z ` R 32M:$DIR\rep.part1 32M:$DIR\rep.part2 # Create pmemobj pools from the poolset expect_normal_exit $PMEMPOOL create obj $DIR\pool.set # Check if all pools and poolset exist check_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 # Remove all pool files without the poolset expect_normal_exit $PMEMPOOL rm -sv ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.set >> $LOG # Check if all pool files don't exist check_no_files ` $DIR\pool.log ` $DIR\pool.blk ` $DIR\pool.obj ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 # Pool set file must exist check_file $DIR\pool.set # Create pmemobj pools from the poolset expect_normal_exit $PMEMPOOL create obj $DIR\pool.set # Remove all pool files and poolset expect_normal_exit $PMEMPOOL rm -v $DIR\pool.set >> $LOG # Check if all pool files don't exist check_no_files ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 # Check if poolset file exists check_file $DIR\pool.set check pass pmdk-1.11.1/src/test/pmempool_rm/TEST12.PS10000664000000000000000000000160314123364546016601 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # pmempool_rm/TEST12.PS1 -- test for pmempool rm - verify removing of # a write-protected part file by answering with invalid response # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup $LOG="out$Env:UNITTEST_NUM.log" # Create poolset with replica create_poolset $DIR\pool.set 32M:$DIR\pool.part1:z 32M:$DIR\pool.part2:z ` R 32M:$DIR\rep.part1:z 32M:$DIR\rep.part2:z set_file_mode IsReadOnly $true $DIR\pool.set $DIR\pool.part1 $DIR\pool.part2 $DIR\rep.part1 $DIR\rep.part2 # Check if all pools and poolset exist check_files ` $DIR\pool.set ` $DIR\pool.part1 ` $DIR\pool.part2 ` $DIR\rep.part1 ` $DIR\rep.part2 echo @" x x \x03 "@ | &$PMEMPOOL rm -il $DIR\pool.part1 2>&1 | out-file -width 1024 -literalpath $LOG check_exit_code check_files ` $DIR\pool.part1 check pass pmdk-1.11.1/src/test/pmempool_rm/README0000664000000000000000000000021014123364546016203 0ustar rootrootPersistent Memory Development Kit This is src/test/pmempool_rm/README. This directory contains a unit test for 'pmempool rm' command. pmdk-1.11.1/src/test/pmempool_rm/TEST60000775000000000000000000000104414123364546016124 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # # pmempool_rm/TEST6 -- test for pmempool rm # # Same as TEST4, but run on a pool set that spans two Device DAX devices # with 4K alignment. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 4096 4096 setup create_poolset $DIR/testset1 AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} expect_normal_exit $PMEMPOOL$EXESUFFIX rm -af $DIR/testset1 check_no_files $DIR/testset1 pass pmdk-1.11.1/src/test/pmempool_rm/TEST10000775000000000000000000000354614123364546016130 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2014-2018, Intel Corporation # # # pmempool_rm/TEST1 -- test for pmempool rm # . ../unittest/unittest.sh require_test_type medium require_no_superuser setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL$EXESUFFIX create -m400 log $DIR/pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create -m440 blk 512 $DIR/pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create -m444 obj $DIR/pool.obj # Create poolset with replica create_poolset $DIR/pool.set 32M:$DIR/pool.part1:z 32M:$DIR/pool.part2:z\ R 32M:$DIR/rep.part1:z 32M:$DIR/rep.part2:z # Create pmemobj pools from the poolset expect_normal_exit $PMEMPOOL$EXESUFFIX create -m444 obj $DIR/pool.set chmod 444 $DIR/pool.set $DIR/pool.part1 $DIR/pool.part2 $DIR/rep.part1 $DIR/rep.part2 # Check if all pools and poolset exist check_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 expect_normal_exit $PMEMPOOL$EXESUFFIX rm -sv\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set >> $LOG 2>&1 << EOF n n n y y y y n EOF check_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ check_no_files\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 expect_normal_exit $PMEMPOOL$EXESUFFIX create -m444 obj $DIR/pool.set check_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 expect_normal_exit $PMEMPOOL$EXESUFFIX rm -fvl\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set >> $LOG check_no_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 check pass pmdk-1.11.1/src/test/pmempool_rm/pmempool_rm.vcxproj0000664000000000000000000000751714123364546021307 0ustar rootroot Debug x64 Release x64 {7dc3b3dd-73ed-4602-9af3-8d7053620dea} {99F7F00F-1DE5-45EA-992B-64BA282FAC76} pmempool_rm 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/pmempool_rm/TEST80000775000000000000000000000110014123364546016117 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2018, Intel Corporation # # # pmempool_rm/TEST8 -- test for pmempool rm # # Same as TEST4, but run on a pool set that spans two Device DAX devices # with 2M alignment. # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_dax_device_alignments 2097152 2097152 # 2MiB setup create_poolset $DIR/testset1 AUTO:${DEVICE_DAX_PATH[0]} AUTO:${DEVICE_DAX_PATH[1]} \ O SINGLEHDR expect_normal_exit $PMEMPOOL$EXESUFFIX rm -af $DIR/testset1 check_no_files $DIR/testset1 pass pmdk-1.11.1/src/test/pmempool_rm/out1.log.match0000664000000000000000000000125414123364546020022 0ustar rootrootremove write-protected file '$(nW)pool.log' ? [Y/n] n remove write-protected file '$(nW)pool.blk' ? [Y/n] n remove write-protected file '$(nW)pool.obj' ? [Y/n] n remove write-protected file '$(nW)pool.part1' ? [Y/n] y removed '$(nW)pool.part1' remove write-protected file '$(nW)pool.part2' ? [Y/n] y removed '$(nW)pool.part2' remove write-protected file '$(nW)rep.part1' ? [Y/n] y removed '$(nW)rep.part1' remove write-protected file '$(nW)rep.part2' ? [Y/n] y removed '$(nW)rep.part2' removed '$(nW)pool.log' removed '$(nW)pool.blk' removed '$(nW)pool.obj' removed '$(nW)pool.part1' removed '$(nW)pool.part2' removed '$(nW)rep.part1' removed '$(nW)rep.part2' removed '$(nW)pool.set' pmdk-1.11.1/src/test/pmempool_rm/TEST100000775000000000000000000000312414123364546016200 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # # pmempool_rm/TEST10 -- test for pmempool rm in interactive mode # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_no_superuser setup LOG=out$UNITTEST_NUM.log # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL$EXESUFFIX create log $DIR/pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create blk 512 $DIR/pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.obj # Create poolset create_poolset $DIR/pool.set 32M:$DIR/pool.part1:z 32M:$DIR/pool.part2:z # Create pmemobj pool from the poolset expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set check_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2 chmod 400\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2 echo Y | expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.log > $LOG echo n | expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.blk >> $LOG echo y | expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.obj >> $LOG echo N | expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.part1 >> $LOG echo n | expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.part2 >> $LOG check_files\ $DIR/pool.blk\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2 check_no_files\ $DIR/pool.log\ $DIR/pool.obj expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool.set >> $LOG <> $LOG 2>&1 expect_abnormal_exit $PMEMPOOL$EXESUFFIX rm -sv $DIR/pool.set >> $LOG 2>&1 # Try to remove files with force flag expect_normal_exit $PMEMPOOL$EXESUFFIX rm -lfv\ $DIR/pool.obj\ $DIR/pool.set >> $LOG 2>&1 check_no_files\ $DIR/pool.set\ $DIR/pool.obj\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 check pass pmdk-1.11.1/src/test/pmempool_rm/out2.log.match0000664000000000000000000000065514123364546020027 0ustar rootrooterror: cannot remove '$(*)pool.obj': No such file or directory error: cannot remove file '$(*)pool.part1': No such file or directory error: cannot remove file '$(*)pool.part2': No such file or directory error: cannot remove file '$(*)rep.part1': No such file or directory error: cannot remove file '$(*)rep.part2': No such file or directory error: removing '$(*)pool.set' failed: No such file or directory removed '$(*)pool.set' pmdk-1.11.1/src/test/pmempool_rm/TEST110000775000000000000000000000306214123364546016202 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # # pmempool_rm/TEST11 -- test for pmempool rm using 'yes','no' responses # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup LOG=out${UNITTEST_NUM}.log rm -f $LOG && touch $LOG # Create pmemlog, pmemblk and pmemobj pools expect_normal_exit $PMEMPOOL$EXESUFFIX create -m400 log $DIR/pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create -m440 blk 512 $DIR/pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create -m444 obj $DIR/pool.obj # Create poolset with replica create_poolset $DIR/pool.set 32M:$DIR/pool.part1:z 32M:$DIR/pool.part2:z\ R 32M:$DIR/rep.part1:z 32M:$DIR/rep.part2:z # Check if pools exists check_files\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set\ $DIR/pool.part1\ $DIR/pool.part2\ $DIR/rep.part1\ $DIR/rep.part2 # Try to remove all files in interactive mode expect_normal_exit $PMEMPOOL$EXESUFFIX rm -il\ $DIR/pool.log\ $DIR/pool.blk\ $DIR/pool.obj\ $DIR/pool.set >> $LOG 2>&1 <> $LOG 2>&1 < Debug x64 Release x64 {FD726AA3-D4FA-4597-B435-08CC7752888E} Win32Proj util_vecq 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/util_vecq/TEST00000775000000000000000000000045314123364546015566 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/util_vecq/TEST0 -- unit test for vecq implementation # . ../unittest/unittest.sh require_test_type short require_fs_type none setup expect_normal_exit ./util_vecq$EXESUFFIX pass pmdk-1.11.1/src/test/util_vecq/Makefile0000664000000000000000000000033414123364546016437 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018, Intel Corporation # # src/test/util_vecq/Makefile -- build util_vecq unit test # TARGET = util_vecq OBJS = util_vecq.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/util_vecq/util_vecq.c0000664000000000000000000000227714123364546017146 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018, Intel Corporation */ /* * util_vecq.c -- unit test for vecq implementation */ #include "unittest.h" #include "vecq.h" struct test { int foo; int bar; }; static void vecq_test() { VECQ(testvec, struct test) v; VECQ_INIT(&v); struct test t = {5, 10}; struct test t2 = {10, 15}; int ret; ret = VECQ_ENQUEUE(&v, t); UT_ASSERTeq(ret, 0); ret = VECQ_ENQUEUE(&v, t2); UT_ASSERTeq(ret, 0); struct test res = VECQ_FRONT(&v); UT_ASSERTeq(res.bar, t.bar); size_t s = VECQ_SIZE(&v); UT_ASSERTeq(s, 2); size_t c = VECQ_CAPACITY(&v); UT_ASSERTeq(c, 64); res = VECQ_DEQUEUE(&v); UT_ASSERTeq(res.bar, t.bar); res = VECQ_DEQUEUE(&v); UT_ASSERTeq(res.bar, t2.bar); VECQ_DELETE(&v); } static void vecq_test_grow() { VECQ(testvec, int) v; VECQ_INIT(&v); for (int j = 0; j < 100; ++j) { int n = j * 100; for (int i = 1; i < n; ++i) { int ret = VECQ_ENQUEUE(&v, i); UT_ASSERTeq(ret, 0); } for (int i = 1; i < n; ++i) { int res = VECQ_DEQUEUE(&v); UT_ASSERTeq(res, i); } } VECQ_DELETE(&v); } int main(int argc, char *argv[]) { START(argc, argv, "util_vecq"); vecq_test(); vecq_test_grow(); DONE(NULL); } pmdk-1.11.1/src/test/util_vecq/TEST0.PS10000664000000000000000000000044714123364546016170 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation # # src/test/util_vecq/TEST0 -- unit test for vecq implementation # . ..\unittest\unittest.ps1 require_test_type short require_fs_type none setup expect_normal_exit $Env:EXE_DIR\util_vecq$Env:EXESUFFIX pass pmdk-1.11.1/src/test/util_vecq/.gitignore0000664000000000000000000000001214123364546016760 0ustar rootrootutil_vecq pmdk-1.11.1/src/test/util_vecq/util_vecq.vcxproj.filters0000664000000000000000000000134014123364546022054 0ustar rootroot {5FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {db0140fc-b255-4ef9-a417-11f1a13525ba} Source Files Test Scripts pmdk-1.11.1/src/test/helgrind-cxgb4.supp0000664000000000000000000000027014123364546016515 0ustar rootroot{ Helgrind:Misc ... fun:pthread_spin_lock fun:c4iw_flush_qps fun:c4iw_poll_cq fun:ibv_poll_cq fun:fi_ibv_poll_cq ... } pmdk-1.11.1/src/test/remote_basic/0000775000000000000000000000000014123364546015440 5ustar rootrootpmdk-1.11.1/src/test/remote_basic/node_0_out0.log.match0000664000000000000000000000023414123364546021350 0ustar rootrootremote_basic/TEST0: START: remote_basic ./remote_basic$(nW) $(nW)test-file File '$(nW)test-file' exists An example of OUT message remote_basic/TEST0: DONE pmdk-1.11.1/src/test/remote_basic/TEST00000775000000000000000000000160714123364546016231 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_basic/TEST0 -- unit test for remote tests support # . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a local test file for this unit test TEST_FILE_REMOTE="test-file" TEST_FILE_LOCAL="$DIR/$TEST_FILE_REMOTE" touch $TEST_FILE_LOCAL # list of required files that should be copied to the remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $TEST_FILE_LOCAL # remove the local test file rm -f $TEST_FILE_LOCAL # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node 0 ./remote_basic$EXESUFFIX ${NODE_DIR[0]}/$TEST_FILE_REMOTE check pass pmdk-1.11.1/src/test/remote_basic/Makefile0000664000000000000000000000040614123364546017100 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # src/test/remote_basic/Makefile -- build remote_basic unit test # SCP_TO_REMOTE_NODES = y TARGET = remote_basic OBJS = remote_basic.o LIBPMEMCOMMON=y include ../Makefile.inc pmdk-1.11.1/src/test/remote_basic/node_0_trace0.log.match0000664000000000000000000000055714123364546021647 0ustar rootroot{$(nW)remote_basic.c:$(nW) main} remote_basic/TEST0: START: remote_basic ./remote_basic$(nW) $(nW)test-file {$(nW)remote_basic.c:$(nW) main} File '$(nW)test-file' exists {$(nW)remote_basic.c:$(nW) main} An example of OUT message {$(nW)remote_basic.c:$(nW) main} remote_basic/TEST0: An example of ERR message {$(nW)remote_basic.c:$(nW) main} remote_basic/TEST0: DONE pmdk-1.11.1/src/test/remote_basic/node_0_out1.log.match0000664000000000000000000000023414123364546021351 0ustar rootrootremote_basic/TEST1: START: remote_basic ./remote_basic$(nW) $(nW)test-file File '$(nW)test-file' exists An example of OUT message remote_basic/TEST1: DONE pmdk-1.11.1/src/test/remote_basic/node_0_err1.log.match0000664000000000000000000000011714123364546021332 0ustar rootroot{$(nW)remote_basic.c:$(nW) main} remote_basic/TEST1: An example of ERR message pmdk-1.11.1/src/test/remote_basic/.gitignore0000664000000000000000000000001514123364546017424 0ustar rootrootremote_basic pmdk-1.11.1/src/test/remote_basic/README0000664000000000000000000000106114123364546016316 0ustar rootrootPersistent Memory Development Kit This is src/test/remote_basic/README. This directory contains a very basic unit test for remote tests support. The program in remote_basic.c takes a file name as an argument and checks if the given file exists. Next it prints two exemplary messages: the first one is printed to stdout and the second one to stderr. The unit tests copy a test file from the local host to the remote node and check if it exists using: - run_on_node() function in case of TEST0 - run_on_node_background() and wait_on_node() in case of TEST1 pmdk-1.11.1/src/test/remote_basic/remote_basic.c0000664000000000000000000000127214123364546020242 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * remote_basic.c -- unit test for remote tests support * * usage: remote_basic */ #include "file.h" #include "unittest.h" int main(int argc, char *argv[]) { START(argc, argv, "remote_basic"); if (argc != 2) UT_FATAL("usage: %s ", argv[0]); const char *file = argv[1]; int exists = util_file_exists(file); if (exists < 0) UT_FATAL("!util_file_exists"); if (!exists) UT_FATAL("File '%s' does not exist", file); else UT_OUT("File '%s' exists", file); UT_OUT("An example of OUT message"); UT_ERR("An example of ERR message"); DONE(NULL); } pmdk-1.11.1/src/test/remote_basic/TEST10000775000000000000000000000216714123364546016234 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/remote_basic/TEST1 -- unit test for remote tests support # . ../unittest/unittest.sh require_test_type medium setup # how much remote nodes are required require_nodes 1 # create a local test file for this unit test TEST_FILE_REMOTE="test-file" TEST_FILE_LOCAL="$DIR/$TEST_FILE_REMOTE" touch $TEST_FILE_LOCAL # list of required files that should be copied to the remote nodes copy_files_to_node 0 ${NODE_DIR[0]} $TEST_FILE_LOCAL # remove the local test file rm -f $TEST_FILE_LOCAL # PID file name for remote test run in background PID_FILE="pid-file-$$.txt" # register the list of PID files to be cleaned in case of an error clean_remote_node 0 $PID_FILE # # Run commands on remote nodes # (run_on_node or run_on_node_background can be used here). # # LD_LIBRARY_PATH for the n-th remote node can be provided # in the array NODE_LD_LIBRARY_PATH[n]. # expect_normal_exit run_on_node_background 0 $PID_FILE ./remote_basic$EXESUFFIX ${NODE_DIR[0]}$TEST_FILE_REMOTE expect_normal_exit wait_on_node 0 $PID_FILE check pass pmdk-1.11.1/src/test/remote_basic/node_0_trace1.log.match0000664000000000000000000000055714123364546021650 0ustar rootroot{$(nW)remote_basic.c:$(nW) main} remote_basic/TEST1: START: remote_basic ./remote_basic$(nW) $(nW)test-file {$(nW)remote_basic.c:$(nW) main} File '$(nW)test-file' exists {$(nW)remote_basic.c:$(nW) main} An example of OUT message {$(nW)remote_basic.c:$(nW) main} remote_basic/TEST1: An example of ERR message {$(nW)remote_basic.c:$(nW) main} remote_basic/TEST1: DONE pmdk-1.11.1/src/test/remote_basic/node_0_err0.log.match0000664000000000000000000000011714123364546021331 0ustar rootroot{$(nW)remote_basic.c:$(nW) main} remote_basic/TEST0: An example of ERR message pmdk-1.11.1/src/test/ex_linkedlist/0000775000000000000000000000000014123364546015642 5ustar rootrootpmdk-1.11.1/src/test/ex_linkedlist/ex_linkedlist.vcxproj.filters0000664000000000000000000000226214123364546023566 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} {27a90a51-98cd-4cdb-868a-0026952b4dbc} {3961c5e9-a720-4fa0-8269-e506cd1edfe2} Source Files Match Files Test Scripts Header Files pmdk-1.11.1/src/test/ex_linkedlist/ex_linkedlist.vcxproj0000664000000000000000000000775114123364546022127 0ustar rootroot Debug x64 Release x64 {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {B440BB05-37A8-42EA-98D3-D83EB113E497} ex_linkedlist 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\examples\libpmemobj\linkedlist;%(AdditionalIncludeDirectories) CompileAsCpp $(SolutionDir)\examples\libpmemobj\linkedlist;%(AdditionalIncludeDirectories) CompileAsCpp pmdk-1.11.1/src/test/ex_linkedlist/TEST00000775000000000000000000000052414123364546016430 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/ex_linkedlist/TEST0 -- unit test for linkedlist example # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup expect_normal_exit ./ex_linkedlist$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/ex_linkedlist/Makefile0000664000000000000000000000043414123364546017303 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/ex_linkedlist/Makefile -- build ex_linkedlist unittest # TARGET = ex_linkedlist OBJS = ex_linkedlist.o LIBPMEMOBJ=y include ../Makefile.inc INCS += -I../../examples/libpmemobj/linkedlist pmdk-1.11.1/src/test/ex_linkedlist/out0.log.match0000664000000000000000000000365614123364546020341 0ustar rootrootex_linkedlist$(nW)TEST0: START: ex_linkedlist $(nW)ex_linkedlist$(*) $(nW) after init start after init end after insert[head|tail] start 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 after insert[head|tail] end after insert_after1 start 9 8 7 6 5 4 3 2 1 0 666 0 1 2 3 4 5 6 7 8 9 after insert_after1 end after insert_before1 start 9 8 7 6 5 4 3 2 1 0 888 666 0 1 2 3 4 5 6 7 8 9 after insert_before1 end after insert_before2 start 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 after insert_before2 end after insert_before3 start 111 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 after insert_before3 end after insert_after2 start 111 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 222 after insert_after2 end after move_element_tail start 111 9 8 7 6 5 4 3 2 1 0 888 666 0 1 2 3 4 5 6 7 8 9 222 555 after move_element_tail end after move_element_head start 666 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 555 after move_element_head end after remove1 start 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 555 after remove1 end after remove2 start 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 after remove2 end after remove3 start 111 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 222 after remove3 end after init start after init end after insert_head start 9 8 7 6 5 4 3 2 1 0 after insert_head end after insert_after1 start 9 111 8 7 6 5 4 3 2 1 0 after insert_after1 end after insert_after2 start 9 111 8 222 7 6 5 4 3 2 1 0 after insert_after2 end after remove_free1 start 9 111 8 222 6 5 4 3 2 1 0 after remove_free1 end after remove_head start 111 8 222 6 5 4 3 2 1 0 after remove_head end after insert_after3 start 111 8 222 6 5 4 3 2 1 0 333 after insert_after3 end after insert_after4 start 111 8 222 6 5 4 3 2 1 0 333 123 after insert_after4 end after remove_free2 start 111 8 222 6 5 4 3 2 1 0 333 after remove_free2 end Outcome for tail queue is correct! Outcome for singly linked list is correct! ex_linkedlist$(nW)TEST0: DONE pmdk-1.11.1/src/test/ex_linkedlist/TEST0.PS10000664000000000000000000000054314123364546017030 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/ex_linkedlist/TEST0 -- unit test for linkedlist example # . ..\unittest\unittest.ps1 require_test_type medium require_build_type debug nondebug require_no_unicode setup expect_normal_exit $Env:EXE_DIR\ex_linkedlist$Env:EXESUFFIX $DIR\testfile check pass pmdk-1.11.1/src/test/ex_linkedlist/.gitignore0000664000000000000000000000001614123364546017627 0ustar rootrootex_linkedlist pmdk-1.11.1/src/test/ex_linkedlist/README0000664000000000000000000000033114123364546016517 0ustar rootrootPersistent Memory Development Kit This is src/test/ex_linkedlist/README. This directory contains unit tests for libpmemobj example. The unit tests utilize example from src/examples/libpmemobj/linkedlist directory. pmdk-1.11.1/src/test/ex_linkedlist/TEST10000775000000000000000000000123214123364546016426 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/ex_linkedlist/TEST1 -- unit test for linkedlist example # # Do not enable "--mult-stores" flag. # When this flag is on test reports overwritten store errors # due to loop which repeatedly add an element to the list which results # in multiply stores to the same field. This is not en error considering # the transactional nature of the test. . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug configure_valgrind pmemcheck force-enable setup expect_normal_exit ./ex_linkedlist$EXESUFFIX $DIR/testfile check pass pmdk-1.11.1/src/test/ex_linkedlist/ex_linkedlist.c0000664000000000000000000001540714123364546020653 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2017, Intel Corporation */ /* * ex_linkedlist.c - test of linkedlist example */ #include #include #include #include #include "pmemobj_list.h" #include "unittest.h" #define ELEMENT_NO 10 #define PRINT_RES(res, struct_name) do {\ if ((res) == 0) {\ UT_OUT("Outcome for " #struct_name " is correct!");\ } else {\ UT_ERR("Outcome for " #struct_name\ " does not match expected result!!!");\ }\ } while (0) POBJ_LAYOUT_BEGIN(list); POBJ_LAYOUT_ROOT(list, struct base); POBJ_LAYOUT_TOID(list, struct tqueuehead); POBJ_LAYOUT_TOID(list, struct slisthead); POBJ_LAYOUT_TOID(list, struct tqnode); POBJ_LAYOUT_TOID(list, struct snode); POBJ_LAYOUT_END(list); POBJ_TAILQ_HEAD(tqueuehead, struct tqnode); struct tqnode { int data; POBJ_TAILQ_ENTRY(struct tqnode) tnd; }; POBJ_SLIST_HEAD(slisthead, struct snode); struct snode { int data; POBJ_SLIST_ENTRY(struct snode) snd; }; struct base { struct tqueuehead tqueue; struct slisthead slist; }; static const int expectedResTQ[] = { 111, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 222 }; static const int expectedResSL[] = { 111, 8, 222, 6, 5, 4, 3, 2, 1, 0, 333 }; /* * dump_tq -- dumps list on standard output */ static void dump_tq(struct tqueuehead *head, const char *str) { TOID(struct tqnode) var; UT_OUT("%s start", str); POBJ_TAILQ_FOREACH(var, head, tnd) UT_OUT("%d", D_RW(var)->data); UT_OUT("%s end", str); } /* * init_tqueue -- initialize tail queue */ static void init_tqueue(PMEMobjpool *pop, struct tqueuehead *head) { if (!POBJ_TAILQ_EMPTY(head)) return; TOID(struct tqnode) node; TOID(struct tqnode) middleNode; TOID(struct tqnode) node888; TOID(struct tqnode) tempNode; int i = 0; TX_BEGIN(pop) { POBJ_TAILQ_INIT(head); dump_tq(head, "after init"); for (i = 0; i < ELEMENT_NO; ++i) { node = TX_NEW(struct tqnode); D_RW(node)->data = i; if (0 == i) { middleNode = node; } POBJ_TAILQ_INSERT_HEAD(head, node, tnd); node = TX_NEW(struct tqnode); D_RW(node)->data = i; POBJ_TAILQ_INSERT_TAIL(head, node, tnd); } dump_tq(head, "after insert[head|tail]"); node = TX_NEW(struct tqnode); D_RW(node)->data = 666; POBJ_TAILQ_INSERT_AFTER(middleNode, node, tnd); dump_tq(head, "after insert_after1"); middleNode = POBJ_TAILQ_NEXT(middleNode, tnd); node = TX_NEW(struct tqnode); D_RW(node)->data = 888; node888 = node; POBJ_TAILQ_INSERT_BEFORE(middleNode, node, tnd); dump_tq(head, "after insert_before1"); node = TX_NEW(struct tqnode); D_RW(node)->data = 555; POBJ_TAILQ_INSERT_BEFORE(middleNode, node, tnd); dump_tq(head, "after insert_before2"); node = TX_NEW(struct tqnode); D_RW(node)->data = 111; tempNode = POBJ_TAILQ_FIRST(head); POBJ_TAILQ_INSERT_BEFORE(tempNode, node, tnd); dump_tq(head, "after insert_before3"); node = TX_NEW(struct tqnode); D_RW(node)->data = 222; tempNode = POBJ_TAILQ_LAST(head); POBJ_TAILQ_INSERT_AFTER(tempNode, node, tnd); dump_tq(head, "after insert_after2"); tempNode = middleNode; middleNode = POBJ_TAILQ_PREV(tempNode, tnd); POBJ_TAILQ_MOVE_ELEMENT_TAIL(head, middleNode, tnd); dump_tq(head, "after move_element_tail"); POBJ_TAILQ_MOVE_ELEMENT_HEAD(head, tempNode, tnd); dump_tq(head, "after move_element_head"); tempNode = POBJ_TAILQ_FIRST(head); POBJ_TAILQ_REMOVE(head, tempNode, tnd); dump_tq(head, "after remove1"); tempNode = POBJ_TAILQ_LAST(head); POBJ_TAILQ_REMOVE(head, tempNode, tnd); dump_tq(head, "after remove2"); POBJ_TAILQ_REMOVE(head, node888, tnd); dump_tq(head, "after remove3"); } TX_ONABORT { abort(); } TX_END } /* * dump_sl -- dumps list on standard output */ static void dump_sl(struct slisthead *head, const char *str) { TOID(struct snode) var; UT_OUT("%s start", str); POBJ_SLIST_FOREACH(var, head, snd) UT_OUT("%d", D_RW(var)->data); UT_OUT("%s end", str); } /* * init_slist -- initialize SLIST */ static void init_slist(PMEMobjpool *pop, struct slisthead *head) { if (!POBJ_SLIST_EMPTY(head)) return; TOID(struct snode) node; TOID(struct snode) tempNode; int i = 0; TX_BEGIN(pop) { POBJ_SLIST_INIT(head); dump_sl(head, "after init"); for (i = 0; i < ELEMENT_NO; ++i) { node = TX_NEW(struct snode); D_RW(node)->data = i; POBJ_SLIST_INSERT_HEAD(head, node, snd); } dump_sl(head, "after insert_head"); tempNode = POBJ_SLIST_FIRST(head); node = TX_NEW(struct snode); D_RW(node)->data = 111; POBJ_SLIST_INSERT_AFTER(tempNode, node, snd); dump_sl(head, "after insert_after1"); tempNode = POBJ_SLIST_NEXT(node, snd); node = TX_NEW(struct snode); D_RW(node)->data = 222; POBJ_SLIST_INSERT_AFTER(tempNode, node, snd); dump_sl(head, "after insert_after2"); tempNode = POBJ_SLIST_NEXT(node, snd); POBJ_SLIST_REMOVE_FREE(head, tempNode, snd); dump_sl(head, "after remove_free1"); POBJ_SLIST_REMOVE_HEAD(head, snd); dump_sl(head, "after remove_head"); TOID(struct snode) element = POBJ_SLIST_FIRST(head); while (!TOID_IS_NULL(D_RO(element)->snd.pe_next)) { element = D_RO(element)->snd.pe_next; } node = TX_NEW(struct snode); D_RW(node)->data = 333; POBJ_SLIST_INSERT_AFTER(element, node, snd); dump_sl(head, "after insert_after3"); element = node; node = TX_NEW(struct snode); D_RW(node)->data = 123; POBJ_SLIST_INSERT_AFTER(element, node, snd); dump_sl(head, "after insert_after4"); tempNode = POBJ_SLIST_NEXT(node, snd); POBJ_SLIST_REMOVE_FREE(head, node, snd); dump_sl(head, "after remove_free2"); } TX_ONABORT { abort(); } TX_END } int main(int argc, char *argv[]) { unsigned res = 0; PMEMobjpool *pop; const char *path; START(argc, argv, "ex_linkedlist"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(list) != 4); if (argc != 2) { UT_FATAL("usage: %s file-name", argv[0]); } path = argv[1]; if (os_access(path, F_OK) != 0) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(list), PMEMOBJ_MIN_POOL, 0666)) == NULL) { UT_FATAL("!pmemobj_create: %s", path); } } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(list))) == NULL) { UT_FATAL("!pmemobj_open: %s", path); } } TOID(struct base) base = POBJ_ROOT(pop, struct base); struct tqueuehead *tqhead = &D_RW(base)->tqueue; struct slisthead *slhead = &D_RW(base)->slist; init_tqueue(pop, tqhead); init_slist(pop, slhead); int i = 0; TOID(struct tqnode) tqelement; POBJ_TAILQ_FOREACH(tqelement, tqhead, tnd) { if (D_RO(tqelement)->data != expectedResTQ[i]) { res = 1; break; } i++; } PRINT_RES(res, tail queue); i = 0; res = 0; TOID(struct snode) slelement; POBJ_SLIST_FOREACH(slelement, slhead, snd) { if (D_RO(slelement)->data != expectedResSL[i]) { res = 1; break; } i++; } PRINT_RES(res, singly linked list); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/ex_linkedlist/out1.log.match0000664000000000000000000000365614123364546020342 0ustar rootrootex_linkedlist$(nW)TEST1: START: ex_linkedlist $(nW)ex_linkedlist$(*) $(nW) after init start after init end after insert[head|tail] start 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 after insert[head|tail] end after insert_after1 start 9 8 7 6 5 4 3 2 1 0 666 0 1 2 3 4 5 6 7 8 9 after insert_after1 end after insert_before1 start 9 8 7 6 5 4 3 2 1 0 888 666 0 1 2 3 4 5 6 7 8 9 after insert_before1 end after insert_before2 start 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 after insert_before2 end after insert_before3 start 111 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 after insert_before3 end after insert_after2 start 111 9 8 7 6 5 4 3 2 1 0 888 555 666 0 1 2 3 4 5 6 7 8 9 222 after insert_after2 end after move_element_tail start 111 9 8 7 6 5 4 3 2 1 0 888 666 0 1 2 3 4 5 6 7 8 9 222 555 after move_element_tail end after move_element_head start 666 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 555 after move_element_head end after remove1 start 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 555 after remove1 end after remove2 start 111 9 8 7 6 5 4 3 2 1 0 888 0 1 2 3 4 5 6 7 8 9 222 after remove2 end after remove3 start 111 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 222 after remove3 end after init start after init end after insert_head start 9 8 7 6 5 4 3 2 1 0 after insert_head end after insert_after1 start 9 111 8 7 6 5 4 3 2 1 0 after insert_after1 end after insert_after2 start 9 111 8 222 7 6 5 4 3 2 1 0 after insert_after2 end after remove_free1 start 9 111 8 222 6 5 4 3 2 1 0 after remove_free1 end after remove_head start 111 8 222 6 5 4 3 2 1 0 after remove_head end after insert_after3 start 111 8 222 6 5 4 3 2 1 0 333 after insert_after3 end after insert_after4 start 111 8 222 6 5 4 3 2 1 0 333 123 after insert_after4 end after remove_free2 start 111 8 222 6 5 4 3 2 1 0 333 after remove_free2 end Outcome for tail queue is correct! Outcome for singly linked list is correct! ex_linkedlist$(nW)TEST1: DONE pmdk-1.11.1/src/test/libpmempool_rm/0000775000000000000000000000000014123364546016021 5ustar rootrootpmdk-1.11.1/src/test/libpmempool_rm/TEST1.PS10000664000000000000000000000454314123364546017214 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST0 -- test pmempool_rm with pool set files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR\pool1p1r.set 32M:$DIR\pool1p1.obj:x create_poolset $DIR\pool3p2r.set 32M:$DIR\pool2p1.obj:x ` 32M:$DIR\pool2p2.obj:x 32M:$DIR\pool2p3.obj:x ` R 32M:$DIR\pool3p1.obj:x 32M:$DIR\pool3p2.obj:x 32M:$DIR\pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool3p2r.set check_files $DIR\pool1p1r.set $DIR\pool1p1.obj ` $DIR\pool3p2r.set $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # this should remove all the pool files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\pool1p1r.set $DIR\pool3p2r.set # check if all pool files are removed check_no_files $DIR\pool1p1.obj $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # poolset files should exist check_files $DIR\pool1p1r.set $DIR\pool3p2r.set create_poolset $DIR\pool1p1r.set 32M:$DIR\pool1p1.obj:x create_poolset $DIR\pool3p2r.set 32M:$DIR\pool2p1.obj:x ` 32M:$DIR\pool2p2.obj:x 32M:$DIR\pool2p3.obj:x ` R 32M:$DIR\pool3p1.obj:x 32M:$DIR\pool3p2.obj:x 32M:$DIR\pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool3p2r.set check_files $DIR\pool1p1r.set $DIR\pool1p1.obj ` $DIR\pool3p2r.set $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj # this should remove all the pool files and pool sets expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -l $DIR\pool1p1r.set $DIR\pool3p2r.set # check if all pool files are removed check_no_files $DIR\pool1p1.obj $DIR\pool2p1.obj ` $DIR\pool2p2.obj $DIR\pool2p3.obj ` $DIR\pool3p1.obj $DIR\pool3p2.obj $DIR\pool3p3.obj ` $DIR\pool1p1r.set $DIR\pool3p2r.set # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\pool1p1r.set $DIR\pool3p2r.set # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -f $DIR\pool1p1r.set $DIR\pool3p2r.set check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST30000775000000000000000000000100414123364546016604 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST3 -- test for pmempool_rm with directories # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append mkdir $DIR/dir.1 mkdir $DIR/dir.2 mkdir $DIR/dir.2/dir.3 expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/dir.1 $DIR/dir.2 $DIR/dir.2/dir.3 expect_normal_exit ./libpmempool_rm$EXESUFFIX -f $DIR/dir.1 $DIR/dir.2 $DIR/dir.2/dir.3 check pass pmdk-1.11.1/src/test/libpmempool_rm/Makefile.inc0000664000000000000000000000043214123364546020230 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2017, Intel Corporation # # src/test/libpmempool_rm/Makefile.inc -- build libpmempool_rm test # include ../Makefile.inc ../libpmempool_rm/libpmempool_rm: $(MAKE) -C ../libpmempool_rm all all: ../libpmempool_rm/libpmempool_rm pmdk-1.11.1/src/test/libpmempool_rm/TEST00000775000000000000000000000177414123364546016617 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST0 -- test for pmempool_rm with single-file pools # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append expect_normal_exit $PMEMPOOL$EXESUFFIX create blk 512 $DIR/pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create log $DIR/pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.obj check_files $DIR/pool.blk $DIR/pool.log $DIR/pool.obj # this should remove all the pool files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool.blk $DIR/pool.log $DIR/pool.obj # check if all pool files are removed check_no_files $DIR/pool.blk $DIR/pool.log $DIR/pool.obj # this should report errors for all files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool.blk $DIR/pool.log $DIR/pool.obj # this should ignore all errors expect_normal_exit ./libpmempool_rm$EXESUFFIX -f $DIR/pool.blk $DIR/pool.log $DIR/pool.obj check pass pmdk-1.11.1/src/test/libpmempool_rm/Makefile0000664000000000000000000000037414123364546017465 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/libpmempool_rm/Makefile -- build libpmempool rm tests # TARGET = libpmempool_rm OBJS = libpmempool_rm.o LIBPMEMOBJ=y LIBPMEMPOOL=y include ../Makefile.inc pmdk-1.11.1/src/test/libpmempool_rm/TEST3.PS10000664000000000000000000000105414123364546017210 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST3 -- test pmempool_rm with directories # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append mkdir $DIR\dir.1 | out-null mkdir $DIR\dir.2 | out-null mkdir $DIR\dir.2\dir.3 | out-null expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\dir.1 $DIR\dir.2 $DIR\dir.2\dir.3 expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -f $DIR\dir.1 $DIR\dir.2 $DIR\dir.2\dir.3 check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST2.PS10000664000000000000000000000211414123364546017205 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST2 -- test pmempool_rm with non-pool files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append [System.IO.File]::WriteAllText("$DIR\file.1", "TEST"); [System.IO.File]::WriteAllText("$DIR\file.2", "TEST`n"); [System.IO.File]::WriteAllText("$DIR\file.3", ""); [System.IO.File]::WriteAllText("$DIR\file.4", "NOTAPMEMPOOLSET`n"); check_files $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should remove all the files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # check if all pool files are removed check_no_files $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -f $DIR\file.1 $DIR\file.2 $DIR\file.3 $DIR\file.4 check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST50000775000000000000000000000106014123364546016610 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # # libpmempool_rm/TEST5 -- test for pmempool_rm with limited permissions # . ../unittest/unittest.sh require_test_type medium require_fs_type any require_no_superuser setup enable_log_append create_poolset $DIR/pool.set1 32M:$DIR/pool.obj1:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set1 check_files $DIR/pool.set1 $DIR/pool.obj1 chmod -r $DIR/pool.set1 expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool.set1 check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST40000775000000000000000000000136414123364546016616 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST4 -- test for pmempool_rm with opened files # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR/pool.set 32M:$DIR/pool.obj.1:x 32M:$DIR/pool.obj.2:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.obj expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set check_files $DIR/pool.obj $DIR/pool.set $DIR/pool.obj.1 expect_normal_exit ./libpmempool_rm$EXESUFFIX -o $DIR/pool.obj check_files $DIR/pool.obj expect_normal_exit ./libpmempool_rm$EXESUFFIX -o $DIR/pool.set check_files $DIR/pool.set $DIR/pool.obj.1 $DIR/pool.obj.2 check pass pmdk-1.11.1/src/test/libpmempool_rm/out0.log.match0000664000000000000000000000100114123364546020476 0ustar rootrootlibpmempool_rm/TEST0: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) libpmempool_rm/TEST0: DONE libpmempool_rm/TEST0: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) $(nW)pool.blk: removing file failed: No such file or directory $(nW)pool.log: removing file failed: No such file or directory $(nW)pool.obj: removing file failed: No such file or directory libpmempool_rm/TEST0: DONE libpmempool_rm/TEST0: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -f $(*) libpmempool_rm/TEST0: DONE pmdk-1.11.1/src/test/libpmempool_rm/TEST0.PS10000664000000000000000000000202214123364546017201 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST0 -- test pmempool_rm with single-file pools # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append expect_normal_exit $PMEMPOOL$EXESUFFIX create blk 512 $DIR\pool.blk expect_normal_exit $PMEMPOOL$EXESUFFIX create log $DIR\pool.log expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.obj check_files $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should remove all the pool files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # check if all pool files are removed check_no_files $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should report errors for all files expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX $DIR\pool.blk $DIR\pool.log $DIR\pool.obj # this should ignore all errors expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -f $DIR\pool.blk $DIR\pool.log $DIR\pool.obj check pass pmdk-1.11.1/src/test/libpmempool_rm/libpmempool_rm.c0000664000000000000000000000231414123364546021202 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * libpmempool_rm -- a unittest for pmempool_rm. * */ #include #include #include #include #include #include "unittest.h" #define FATAL_USAGE(n) UT_FATAL("usage: %s [-f -l -r -o] path..", (n)) static PMEMobjpool *Pop; int main(int argc, char *argv[]) { START(argc, argv, "libpmempool_rm"); if (argc < 2) FATAL_USAGE(argv[0]); unsigned flags = 0; char *optstr = "flro"; int do_open = 0; int opt; while ((opt = getopt(argc, argv, optstr)) != -1) { switch (opt) { case 'f': flags |= PMEMPOOL_RM_FORCE; break; case 'r': flags |= PMEMPOOL_RM_POOLSET_REMOTE; break; case 'l': flags |= PMEMPOOL_RM_POOLSET_LOCAL; break; case 'o': do_open = 1; break; default: FATAL_USAGE(argv[0]); } } for (int i = optind; i < argc; i++) { const char *path = argv[i]; if (do_open) { Pop = pmemobj_open(path, NULL); UT_ASSERTne(Pop, NULL); } int ret = pmempool_rm(path, flags); if (ret) { UT_OUT("!%s: %s", path, pmempool_errormsg()); } if (do_open) { UT_ASSERTne(Pop, NULL); pmemobj_close(Pop); } } DONE(NULL); } pmdk-1.11.1/src/test/libpmempool_rm/.gitignore0000664000000000000000000000001714123364546020007 0ustar rootrootlibpmempool_rm pmdk-1.11.1/src/test/libpmempool_rm/libpmempool_rm.vcxproj0000664000000000000000000001104614123364546022455 0ustar rootroot Debug x64 Release x64 {5F2B687A-1B42-439C-AEEC-135DD22FB851} Win32Proj libpmempool_rm 10.0.17134.0 Application true v140 Application false v140 true false $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) true $(SolutionDir)\windows\getopt;%(AdditionalIncludeDirectories) {1baa1617-93ae-4196-8a1a-bd492fb18aef} {cf9a0883-6334-44c7-ac29-349468c78e27} {9e9e3d25-2139-4a5d-9200-18148ddead45} {9186eac4-2f34-4f17-b940-6585d7869bcd} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/libpmempool_rm/README0000664000000000000000000000021114123364546016673 0ustar rootrootPersistent Memory Development Kit This is src/test/libpmempool_rm/README. This directory contains unit tests for pmempool_rm function. pmdk-1.11.1/src/test/libpmempool_rm/libpmempool_rm.vcxproj.filters0000664000000000000000000000314014123364546024120 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {0d34316a-f8ec-4b25-ae70-41c75318bc7f} {55ac52b5-5cc6-44e4-87b2-8d243a23ff71} Source Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files Match Files Match Files Match Files Match Files pmdk-1.11.1/src/test/libpmempool_rm/TEST60000775000000000000000000000132514123364546016615 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST6 -- test for pmempool_rm # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR/pool.set\ 8M:$DIR/pool1:x\ 8M:$DIR/pool2:x\ 8M:$DIR/pool3:x\ 8M:$DIR/pool4:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool.set check_files $DIR/pool.set $DIR/pool1 $DIR/pool2 $DIR/pool3 $DIR/pool4 expect_normal_exit $PMEMPOOL$EXESUFFIX rm $DIR/pool3 $DIR/pool2 check_no_file $DIR/pool2 $DIR/pool3 expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool.set check_no_files $DIR/pool1 $DIR/pool2 $DIR/pool3 $DIR/pool4 check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST10000775000000000000000000000445714123364546016621 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST1 -- test for pmempool_rm with pool set files # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR/pool1p1r.set 32M:$DIR/pool1p1.obj:x create_poolset $DIR/pool3p2r.set 32M:$DIR/pool2p1.obj:x\ 32M:$DIR/pool2p2.obj:x 32M:$DIR/pool2p3.obj:x\ R 32M:$DIR/pool3p1.obj:x 32M:$DIR/pool3p2.obj:x 32M:$DIR/pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool3p2r.set check_files $DIR/pool1p1r.set $DIR/pool1p1.obj\ $DIR/pool3p2r.set $DIR/pool2p1.obj\ $DIR/pool2p2.obj $DIR/pool2p3.obj\ $DIR/pool3p1.obj $DIR/pool3p2.obj $DIR/pool3p3.obj # this should remove all the pool files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool1p1r.set $DIR/pool3p2r.set # check if all pool files are removed check_no_files $DIR/pool1p1.obj $DIR/pool2p1.obj\ $DIR/pool2p2.obj $DIR/pool2p3.obj\ $DIR/pool3p1.obj $DIR/pool3p2.obj $DIR/pool3p3.obj # poolset files should exist check_files $DIR/pool1p1r.set $DIR/pool3p2r.set create_poolset $DIR/pool1p1r.set 32M:$DIR/pool1p1.obj:x create_poolset $DIR/pool3p2r.set 32M:$DIR/pool2p1.obj:x\ 32M:$DIR/pool2p2.obj:x 32M:$DIR/pool2p3.obj:x\ R 32M:$DIR/pool3p1.obj:x 32M:$DIR/pool3p2.obj:x 32M:$DIR/pool3p3.obj:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool1p1r.set expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR/pool3p2r.set check_files $DIR/pool1p1r.set $DIR/pool1p1.obj\ $DIR/pool3p2r.set $DIR/pool2p1.obj\ $DIR/pool2p2.obj $DIR/pool2p3.obj\ $DIR/pool3p1.obj $DIR/pool3p2.obj $DIR/pool3p3.obj # this should remove all the pool files and pool sets expect_normal_exit ./libpmempool_rm$EXESUFFIX -l $DIR/pool1p1r.set $DIR/pool3p2r.set # check if all pool files are removed check_no_files $DIR/pool1p1.obj $DIR/pool2p1.obj\ $DIR/pool2p2.obj $DIR/pool2p3.obj\ $DIR/pool3p1.obj $DIR/pool3p2.obj $DIR/pool3p3.obj\ $DIR/pool1p1r.set $DIR/pool3p2r.set # this should report errors for all files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/pool1p1r.set $DIR/pool3p2r.set # this should ignore all errors expect_normal_exit ./libpmempool_rm$EXESUFFIX -f $DIR/pool1p1r.set $DIR/pool3p2r.set check pass pmdk-1.11.1/src/test/libpmempool_rm/TEST4.PS10000664000000000000000000000137314123364546017215 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST4 -- test pmempool_rm with opened files # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup enable_log_append create_poolset $DIR\pool.set 32M:$DIR\pool.obj.1:x 32M:$DIR\pool.obj.2:x expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.obj expect_normal_exit $PMEMPOOL$EXESUFFIX create obj $DIR\pool.set check_files $DIR\pool.obj $DIR\pool.set $DIR\pool.obj.1 expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -o $DIR\pool.obj check_files $DIR\pool.obj expect_normal_exit $Env:EXE_DIR\libpmempool_rm$Env:EXESUFFIX -o $DIR\pool.set check_files $DIR\pool.set $DIR\pool.obj.1 $DIR\pool.obj.2 check pass pmdk-1.11.1/src/test/libpmempool_rm/out6.log.match0000775000000000000000000000026714123364546020524 0ustar rootrootlibpmempool_rm/TEST6: START: libpmempool_rm ./libpmempool_rm$(nW) $(nW)pool.set $(nW)pool.set: $(nW)pool3: removing file failed: No such file or directory libpmempool_rm/TEST6: DONE pmdk-1.11.1/src/test/libpmempool_rm/out1.log.match0000664000000000000000000000106714123364546020513 0ustar rootrootlibpmempool_rm/TEST1: START: libpmempool_rm$(nW) $(nW)ibpmempool_rm$(nW) $(*) libpmempool_rm/TEST1: DONE libpmempool_rm/TEST1: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -l $(*) libpmempool_rm/TEST1: DONE libpmempool_rm/TEST1: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) $(nW)pool1p1r.set: removing file failed: No such file or directory $(nW)pool3p2r.set: removing file failed: No such file or directory libpmempool_rm/TEST1: DONE libpmempool_rm/TEST1: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -f $(*) libpmempool_rm/TEST1: DONE pmdk-1.11.1/src/test/libpmempool_rm/TEST20000775000000000000000000000166714123364546016622 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2018, Intel Corporation # # # libpmempool_rm/TEST2 -- test for pmempool_rm with non-pool files # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup enable_log_append echo -n TEST > $DIR/file.1 echo TEST > $DIR/file.2 touch $DIR/file.3 echo NOTAPMEMPOOLSET > $DIR/file.4 check_files $DIR/file.1 $DIR/file.2 $DIR/file.3 $DIR/file.4 # this should remove all the files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/file.1 $DIR/file.2 $DIR/file.3 $DIR/file.4 # check if all pool files are removed check_no_files $DIR/file.1 $DIR/file.2 $DIR/file.3 $DIR/file.4 # this should report errors for all files expect_normal_exit ./libpmempool_rm$EXESUFFIX $DIR/file.1 $DIR/file.2 $DIR/file.3 $DIR/file.4 # this should ignore all errors expect_normal_exit ./libpmempool_rm$EXESUFFIX -f $DIR/file.1 $DIR/file.2 $DIR/file.3 $DIR/file.4 check pass pmdk-1.11.1/src/test/libpmempool_rm/out5.log.match0000664000000000000000000000023214123364546020510 0ustar rootrootlibpmempool_rm/TEST5: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) $(nW): removing file failed: Permission denied libpmempool_rm/TEST5: DONE pmdk-1.11.1/src/test/libpmempool_rm/out3.log.match0000664000000000000000000000074114123364546020513 0ustar rootrootlibpmempool_rm/TEST3: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory libpmempool_rm/TEST3: DONE libpmempool_rm/TEST3: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -f $(*) $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory $(nW): removing file failed: Is a directory libpmempool_rm/TEST3: DONE pmdk-1.11.1/src/test/libpmempool_rm/out4.log.match0000664000000000000000000000044714123364546020517 0ustar rootrootlibpmempool_rm/TEST4: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -o $(*) $(nW): removing file failed: $(*) libpmempool_rm/TEST4: DONE libpmempool_rm/TEST4: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -o $(*) $(nW): $(nW): removing file failed: $(*) libpmempool_rm/TEST4: DONE pmdk-1.11.1/src/test/libpmempool_rm/out2.log.match0000664000000000000000000000104014123364546020503 0ustar rootrootlibpmempool_rm/TEST2: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) libpmempool_rm/TEST2: DONE libpmempool_rm/TEST2: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) $(*) $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory $(nW): removing file failed: No such file or directory libpmempool_rm/TEST2: DONE libpmempool_rm/TEST2: START: libpmempool_rm$(nW) $(nW)libpmempool_rm$(nW) -f $(*) libpmempool_rm/TEST2: DONE pmdk-1.11.1/src/test/ex_libpmemlog/0000775000000000000000000000000014123364546015627 5ustar rootrootpmdk-1.11.1/src/test/ex_libpmemlog/ex_libpmemlog.vcxproj.filters0000664000000000000000000000121614123364546023536 0ustar rootroot {b7d9fc2e-949d-4e29-840a-977c514a3ace} {69c8e99a-d0b9-4288-a418-1b2674e8fa5d} Match Files Test Scripts pmdk-1.11.1/src/test/ex_libpmemlog/TEST00000775000000000000000000000472014123364546016417 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/ex_libpmemlog/TEST0 -- unit test for libpmemlog examples # . ../unittest/unittest.sh require_test_type medium require_build_type debug nondebug setup EX_PATH=../../examples/libpmemlog/logfile create_holey_file 32M $DIR/testfile1 expect_normal_exit $EX_PATH/addlog $DIR/testfile1 "Hello World! foo bar" > out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/printlog $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/addlog $DIR/testfile1 "PMEMLOG" >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/printlog -t $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/addlog $DIR/testfile1 "PMDK" >> out$UNITTEST_NUM.log 2>&1 expect_normal_exit $EX_PATH/printlog -t $DIR/testfile1 >> out$UNITTEST_NUM.log 2>&1 check_pool $DIR/testfile1 check pass pmdk-1.11.1/src/test/ex_libpmemlog/Makefile0000664000000000000000000000046014123364546017267 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2016, Intel Corporation # # src/test/ex_libpmemlog/Makefile -- build ex_libpmemlog unittest # all: $(EXAMPLES) $(MAKE) -C $(EX_LIBPMEMLOG) include ../Makefile.inc EXAMPLES=$(EX_LIBPMEMLOG)/logfile/addlog \ $(EX_LIBPMEMLOG)/logfile/printlog pmdk-1.11.1/src/test/ex_libpmemlog/out0.log.match0000664000000000000000000000043714123364546020320 0ustar rootrootEntry from pid: $(N) Created: $(*) Contents: Hello World! foo bar Entry from pid: $(N) Created: $(*) Contents: Hello World! foo bar Entry from pid: $(N) Created: $(*) Contents: PMEMLOG Entry from pid: $(N) Created: $(*) Contents: PMDK pmdk-1.11.1/src/test/ex_libpmemlog/ex_libpmemlog.vcxproj0000664000000000000000000000752714123364546022102 0ustar rootroot Debug x64 Release x64 {a7ca7975-cedb-48e6-9aeb-1209dcbd07f2} {c3cee34c-29e0-4a22-b258-3fbaf662aa19} {D8317F1D-7A70-4A39-977A-EAB05A04A87B} ex_libpmemlog 10.0.17134.0 Application true v140 Application false v140 Level3 Disabled true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) Level3 MaxSpeed true true true NTDDI_VERSION=NTDDI_WIN10_RS1;_MBCS;%(PreprocessorDefinitions) pmdk-1.11.1/src/test/ex_libpmemlog/TEST0.PS10000664000000000000000000000507214123364546017017 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/ex_libpmemlog/TEST0 -- unit test for libpmemlog examples # . ..\unittest\unittest.PS1 require_test_type medium require_build_type debug nondebug require_no_unicode setup create_holey_file 32M $DIR\testfile1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_addlog $DIR\testfile1 "Hello" "World!" "foo" "bar" > out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_printlog $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_addlog $DIR\testfile1 "PMEMLOG" >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_printlog -t $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_addlog $DIR\testfile1 "PMDK" >> out$Env:UNITTEST_NUM.log 2>&1 expect_normal_exit $Env:EXAMPLES_DIR\ex_pmemlog_printlog -t $DIR\testfile1 >> out$Env:UNITTEST_NUM.log 2>&1 check_pool $DIR\testfile1 check pass pmdk-1.11.1/src/test/ex_libpmemlog/README0000664000000000000000000000032114123364546016503 0ustar rootrootPersistent Memory Development Kit This is src/test/ex_libpmemlog/README. This directory contains unit tests for libpmemlog examples. The unit tests utilizes examples from src/examples/libpmemlog directory. pmdk-1.11.1/src/test/obj_realloc/0000775000000000000000000000000014123364546015257 5ustar rootrootpmdk-1.11.1/src/test/obj_realloc/obj_realloc.vcxproj.filters0000664000000000000000000000711214123364546022617 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {9cef02dc-bf93-4bcc-88fd-82b274dbbf71} ps1 {5ed3a714-4184-4abe-92cb-ce881168ad0c} match Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts Match Files pmdk-1.11.1/src/test/obj_realloc/obj_realloc.vcxproj0000664000000000000000000002524514123364546021157 0ustar rootroot Debug x64 Release x64 {91E19AEB-7B75-43E0-B8B4-D2BB60D839EA} Win32Proj obj_realloc 10.0.17134.0 Application true v140 Application false v140 true Disabled false 4200 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) CompileAsCpp MaxSpeed 4200 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) CompileAsCpp CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_realloc/TEST00000775000000000000000000000072514123364546016050 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_realloc/TEST0 -- unit test for pmemobj_realloc and # pmemobj_zrealloc # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup expect_normal_exit $PMEMPOOL$EXESUFFIX\ create obj --layout realloc --size=512M $DIR/testfile1 export PMEM_IS_PMEM_FORCE=1 expect_normal_exit ./obj_realloc$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_realloc/Makefile0000664000000000000000000000036314123364546016721 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_realloc/Makefile -- build obj_realloc unit test # TARGET = obj_realloc OBJS = obj_realloc.o LIBPMEMOBJ=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/obj_realloc/obj_realloc.c0000664000000000000000000001715414123364546017706 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_realloc.c -- unit test for pmemobj_realloc and pmemobj_zrealloc */ #include #include #include "unittest.h" #include "heap.h" #include "alloc_class.h" #include "obj.h" #include "util.h" #define MAX_ALLOC_MUL 8 #define MAX_ALLOC_CLASS 5 POBJ_LAYOUT_BEGIN(realloc); POBJ_LAYOUT_ROOT(realloc, struct root); POBJ_LAYOUT_TOID(realloc, struct object); POBJ_LAYOUT_END(realloc); struct object { size_t value; char data[]; }; struct root { TOID(struct object) obj; char data[CHUNKSIZE - sizeof(TOID(struct object))]; }; static struct alloc_class_collection *alloc_classes; /* * test_alloc -- test allocation using realloc */ static void test_alloc(PMEMobjpool *pop, size_t size) { TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); int ret = pmemobj_realloc(pop, &D_RW(root)->obj.oid, size, TOID_TYPE_NUM(struct object)); UT_ASSERTeq(ret, 0); UT_ASSERT(!TOID_IS_NULL(D_RO(root)->obj)); UT_ASSERT(pmemobj_alloc_usable_size(D_RO(root)->obj.oid) >= size); } /* * test_free -- test free using realloc */ static void test_free(PMEMobjpool *pop) { TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(!TOID_IS_NULL(D_RO(root)->obj)); int ret = pmemobj_realloc(pop, &D_RW(root)->obj.oid, 0, TOID_TYPE_NUM(struct object)); UT_ASSERTeq(ret, 0); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); } /* * test_huge_size -- test zrealloc with size greater than pool size */ static void test_huge_size(PMEMobjpool *pop) { TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); int ret; ret = pmemobj_zrealloc(pop, &D_RW(root)->obj.oid, PMEMOBJ_MAX_ALLOC_SIZE, TOID_TYPE_NUM(struct object)); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); ret = pmemobj_zrealloc(pop, &D_RW(root)->obj.oid, UINTMAX_MAX, TOID_TYPE_NUM(struct object)); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); ret = pmemobj_zrealloc(pop, &D_RW(root)->obj.oid, UINTMAX_MAX - 1, TOID_TYPE_NUM(struct object)); UT_ASSERTne(ret, 0); UT_ASSERTeq(errno, ENOMEM); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); } /* test zrealloc passing PMEMoid that points to OID_NULL value */ static void test_null_oid(PMEMobjpool *pop) { TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); int ret = pmemobj_zrealloc(pop, &D_RW(root)->obj.oid, 1024, TOID_TYPE_NUM(struct object)); UT_ASSERTeq(ret, 0); UT_ASSERT(!TOID_IS_NULL(D_RO(root)->obj)); pmemobj_free(&D_RW(root)->obj.oid); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); } static int check_integrity = 1; /* * fill_buffer -- fill buffer with random data and return its checksum */ static uint16_t fill_buffer(unsigned char *buf, size_t size) { for (size_t i = 0; i < size; ++i) buf[i] = rand() % 255; pmem_persist(buf, size); return ut_checksum(buf, size); } /* * test_realloc -- test single reallocation */ static void test_realloc(PMEMobjpool *pop, size_t size_from, size_t size_to, uint64_t type_from, uint64_t type_to, int zrealloc) { TOID(struct root) root = POBJ_ROOT(pop, struct root); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); int ret; if (zrealloc) ret = pmemobj_zalloc(pop, &D_RW(root)->obj.oid, size_from, type_from); else ret = pmemobj_alloc(pop, &D_RW(root)->obj.oid, size_from, type_from, NULL, NULL); UT_ASSERTeq(ret, 0); UT_ASSERT(!TOID_IS_NULL(D_RO(root)->obj)); size_t usable_size_from = pmemobj_alloc_usable_size(D_RO(root)->obj.oid); UT_ASSERT(usable_size_from >= size_from); size_t check_size; uint16_t checksum; if (zrealloc) { UT_ASSERT(util_is_zeroed(D_RO(D_RO(root)->obj), size_from)); } else if (check_integrity) { check_size = size_to >= usable_size_from ? usable_size_from : size_to; checksum = fill_buffer((unsigned char *)D_RW(D_RW(root)->obj), check_size); } if (zrealloc) { ret = pmemobj_zrealloc(pop, &D_RW(root)->obj.oid, size_to, type_to); } else { ret = pmemobj_realloc(pop, &D_RW(root)->obj.oid, size_to, type_to); } UT_ASSERTeq(ret, 0); UT_ASSERT(!TOID_IS_NULL(D_RO(root)->obj)); size_t usable_size_to = pmemobj_alloc_usable_size(D_RO(root)->obj.oid); UT_ASSERT(usable_size_to >= size_to); if (size_to < size_from) { UT_ASSERT(usable_size_to <= usable_size_from); } if (zrealloc) { UT_ASSERT(util_is_zeroed(D_RO(D_RO(root)->obj), size_to)); } else if (check_integrity) { uint16_t checksum2 = ut_checksum( (uint8_t *)D_RW(D_RW(root)->obj), check_size); if (checksum2 != checksum) UT_ASSERTinfo(0, "memory corruption"); } pmemobj_free(&D_RW(root)->obj.oid); UT_ASSERT(TOID_IS_NULL(D_RO(root)->obj)); } /* * test_realloc_sizes -- test reallocations from/to specified sizes */ static void test_realloc_sizes(PMEMobjpool *pop, uint64_t type_from, uint64_t type_to, int zrealloc, unsigned size_diff) { for (uint8_t i = 0; i < MAX_ALLOCATION_CLASSES; ++i) { struct alloc_class *c = alloc_class_by_id(alloc_classes, i); if (c == NULL) continue; size_t header_size = header_type_to_size[c->header_type]; size_t size_from = c->unit_size - header_size - size_diff; for (unsigned j = 2; j <= MAX_ALLOC_MUL; j++) { size_t inc_size_to = c->unit_size * j - header_size; test_realloc(pop, size_from, inc_size_to, type_from, type_to, zrealloc); size_t dec_size_to = c->unit_size / j; if (dec_size_to <= header_size) dec_size_to = header_size; else dec_size_to -= header_size; test_realloc(pop, size_from, dec_size_to, type_from, type_to, zrealloc); for (int k = 0; k < MAX_ALLOC_CLASS; k++) { struct alloc_class *ck = alloc_class_by_id( alloc_classes, k); if (c == NULL) continue; size_t header_sizek = header_type_to_size[c->header_type]; size_t prev_size = ck->unit_size - header_sizek; test_realloc(pop, size_from, prev_size, type_from, type_to, zrealloc); } } } } int main(int argc, char *argv[]) { START(argc, argv, "obj_realloc"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(realloc) != 1); if (argc < 2) UT_FATAL("usage: %s file [check_integrity]", argv[0]); PMEMobjpool *pop = pmemobj_open(argv[1], POBJ_LAYOUT_NAME(realloc)); if (!pop) UT_FATAL("!pmemobj_open"); if (argc >= 3) check_integrity = atoi(argv[2]); alloc_classes = alloc_class_collection_new(); /* test huge size alloc */ test_huge_size(pop); /* test alloc and free */ test_alloc(pop, 16); test_free(pop); /* test zrealloc passing PMEMoid that points to OID_NULL value */ test_null_oid(pop); /* test realloc without changing type number */ test_realloc_sizes(pop, 0, 0, 0, 0); /* test realloc with changing type number */ test_realloc_sizes(pop, 0, 1, 0, 0); /* test zrealloc without changing type number... */ test_realloc_sizes(pop, 0, 0, 1, 8); test_realloc_sizes(pop, 0, 0, 1, 0); /* test zrealloc with changing type number... */ test_realloc_sizes(pop, 0, 1, 1, 8); test_realloc_sizes(pop, 0, 1, 1, 0); /* test realloc with type number equal to range of long long int */ test_realloc_sizes(pop, 0, UINT64_MAX, 0, 0); test_realloc_sizes(pop, 0, UINT64_MAX - 1, 0, 0); /* test zrealloc with type number equal to range of long long int */ test_realloc_sizes(pop, 0, UINT64_MAX, 1, 0); test_realloc_sizes(pop, 0, (UINT64_MAX - 1), 1, 0); alloc_class_collection_delete(alloc_classes); pmemobj_close(pop); DONE(NULL); } #ifdef _MSC_VER extern "C" { /* * Since libpmemobj is linked statically, * we need to invoke its ctor/dtor. */ MSVC_CONSTR(libpmemobj_init) MSVC_DESTR(libpmemobj_fini) } #endif pmdk-1.11.1/src/test/obj_realloc/out0.log.match0000664000000000000000000000014214123364546017741 0ustar rootrootobj_realloc$(nW)TEST0: START: obj_realloc $(nW)obj_realloc$(nW) $(*) obj_realloc$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_realloc/TEST0.PS10000664000000000000000000000406614123364546016451 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_realloc/TEST0 -- unit test for pmemobj_realloc and # pmemobj_zrealloc # . ..\unittest\unittest.ps1 require_test_type long require_fs_type any setup rm $DIR\testfile1 -Force -ErrorAction SilentlyContinue expect_normal_exit $PMEMPOOL create obj --layout realloc --size=512M $DIR\testfile1 $Env:PMEM_IS_PMEM_FORCE=1 expect_normal_exit $Env:EXE_DIR\obj_realloc$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_realloc/.gitignore0000664000000000000000000000001414123364546017242 0ustar rootrootobj_realloc pmdk-1.11.1/src/test/obj_realloc/TEST10000775000000000000000000000147614123364546016055 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_realloc/TEST1 -- unit test for pmemobj_realloc and # pmemobj_zrealloc # . ../unittest/unittest.sh require_test_type long # XXX reduce the number of reallocs performed under pmemcheck so that the # execution time is reasonable and within the time limit (5 minutes) on both # pmem and non-pmem fs types. require_fs_type non-pmem configure_valgrind pmemcheck force-enable setup expect_normal_exit $PMEMPOOL$EXESUFFIX\ create obj --layout realloc --size=512M $DIR/testfile1 # last parameter disables integrity tests, because they are veeeeeery slow # under pmemcheck (19 minutes vs 7 seconds) # XXX enable after pmemcheck optimization expect_normal_exit ./obj_realloc$EXESUFFIX $DIR/testfile1 0 check pass pmdk-1.11.1/src/test/obj_realloc/out1.log.match0000664000000000000000000000014214123364546017742 0ustar rootrootobj_realloc$(nW)TEST1: START: obj_realloc $(nW)obj_realloc$(nW) $(*) obj_realloc$(nW)TEST1: DONE pmdk-1.11.1/src/test/obj_memblock/0000775000000000000000000000000014123364546015427 5ustar rootrootpmdk-1.11.1/src/test/obj_memblock/mocks_windows.h0000664000000000000000000000120214123364546020461 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2016-2020, Intel Corporation */ /* * mocks_windows.h -- redefinitions of memops functions * * This file is Windows-specific. * * This file should be included (i.e. using Forced Include) by libpmemobj * files, when compiled for the purpose of obj_memblock test. * It would replace default implementation with mocked functions defined * in obj_memblock.c. * * These defines could be also passed as preprocessor definitions. */ #ifndef WRAP_REAL #define operation_add_typed_entry __wrap_operation_add_typed_entry #define operation_add_entry __wrap_operation_add_entry #endif pmdk-1.11.1/src/test/obj_memblock/obj_memblock.c0000664000000000000000000001231014123364546020213 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * obj_memblock.c -- unit test for memblock interface */ #include "memblock.h" #include "memops.h" #include "obj.h" #include "unittest.h" #include "heap.h" #define NCHUNKS 10 static PMEMobjpool *pop; FUNC_MOCK(operation_add_typed_entry, int, struct operation_context *ctx, void *ptr, uint64_t value, ulog_operation_type type, enum operation_log_type en_type) FUNC_MOCK_RUN_DEFAULT { uint64_t *pval = ptr; switch (type) { case ULOG_OPERATION_SET: *pval = value; break; case ULOG_OPERATION_AND: *pval &= value; break; case ULOG_OPERATION_OR: *pval |= value; break; default: UT_ASSERT(0); } return 0; } FUNC_MOCK_END FUNC_MOCK(operation_add_entry, int, struct operation_context *ctx, void *ptr, uint64_t value, ulog_operation_type type) FUNC_MOCK_RUN_DEFAULT { /* just call the mock above - the entry type doesn't matter */ return operation_add_typed_entry(ctx, ptr, value, type, LOG_TRANSIENT); } FUNC_MOCK_END static void test_detect(void) { struct memory_block mhuge_used = { .chunk_id = 0, 0, 0, 0 }; struct memory_block mhuge_free = { .chunk_id = 1, 0, 0, 0 }; struct memory_block mrun = { .chunk_id = 2, 0, 0, 0 }; struct heap_layout *layout = pop->heap.layout; layout->zone0.chunk_headers[0].size_idx = 1; layout->zone0.chunk_headers[0].type = CHUNK_TYPE_USED; layout->zone0.chunk_headers[1].size_idx = 1; layout->zone0.chunk_headers[1].type = CHUNK_TYPE_FREE; layout->zone0.chunk_headers[2].size_idx = 1; layout->zone0.chunk_headers[2].type = CHUNK_TYPE_RUN; memblock_rebuild_state(&pop->heap, &mhuge_used); memblock_rebuild_state(&pop->heap, &mhuge_free); memblock_rebuild_state(&pop->heap, &mrun); UT_ASSERTeq(mhuge_used.type, MEMORY_BLOCK_HUGE); UT_ASSERTeq(mhuge_free.type, MEMORY_BLOCK_HUGE); UT_ASSERTeq(mrun.type, MEMORY_BLOCK_RUN); } static void test_block_size(void) { struct memory_block mhuge = { .chunk_id = 0, 0, 0, 0 }; struct memory_block mrun = { .chunk_id = 1, 0, 0, 0 }; struct palloc_heap *heap = &pop->heap; struct heap_layout *layout = heap->layout; layout->zone0.chunk_headers[0].size_idx = 1; layout->zone0.chunk_headers[0].type = CHUNK_TYPE_USED; layout->zone0.chunk_headers[1].size_idx = 1; layout->zone0.chunk_headers[1].type = CHUNK_TYPE_RUN; struct chunk_run *run = (struct chunk_run *) &layout->zone0.chunks[1]; run->hdr.block_size = 1234; memblock_rebuild_state(&pop->heap, &mhuge); memblock_rebuild_state(&pop->heap, &mrun); UT_ASSERTne(mhuge.m_ops, NULL); UT_ASSERTne(mrun.m_ops, NULL); UT_ASSERTeq(mhuge.m_ops->block_size(&mhuge), CHUNKSIZE); UT_ASSERTeq(mrun.m_ops->block_size(&mrun), 1234); } static void test_prep_hdr(void) { struct memory_block mhuge_used = { .chunk_id = 0, 0, .size_idx = 1, 0 }; struct memory_block mhuge_free = { .chunk_id = 1, 0, .size_idx = 1, 0 }; struct memory_block mrun_used = { .chunk_id = 2, 0, .size_idx = 4, .block_off = 0 }; struct memory_block mrun_free = { .chunk_id = 2, 0, .size_idx = 4, .block_off = 4 }; struct memory_block mrun_large_used = { .chunk_id = 2, 0, .size_idx = 64, .block_off = 64 }; struct memory_block mrun_large_free = { .chunk_id = 2, 0, .size_idx = 64, .block_off = 128 }; struct palloc_heap *heap = &pop->heap; struct heap_layout *layout = heap->layout; layout->zone0.chunk_headers[0].size_idx = 1; layout->zone0.chunk_headers[0].type = CHUNK_TYPE_USED; layout->zone0.chunk_headers[1].size_idx = 1; layout->zone0.chunk_headers[1].type = CHUNK_TYPE_FREE; layout->zone0.chunk_headers[2].size_idx = 1; layout->zone0.chunk_headers[2].type = CHUNK_TYPE_RUN; struct chunk_run *run = (struct chunk_run *)&layout->zone0.chunks[2]; run->hdr.block_size = 128; uint64_t *bitmap = (uint64_t *)run->content; bitmap[0] = 0b1111; bitmap[1] = ~0ULL; bitmap[2] = 0ULL; memblock_rebuild_state(heap, &mhuge_used); memblock_rebuild_state(heap, &mhuge_free); memblock_rebuild_state(heap, &mrun_used); memblock_rebuild_state(heap, &mrun_free); memblock_rebuild_state(heap, &mrun_large_used); memblock_rebuild_state(heap, &mrun_large_free); UT_ASSERTne(mhuge_used.m_ops, NULL); mhuge_used.m_ops->prep_hdr(&mhuge_used, MEMBLOCK_FREE, NULL); UT_ASSERTeq(layout->zone0.chunk_headers[0].type, CHUNK_TYPE_FREE); mhuge_free.m_ops->prep_hdr(&mhuge_free, MEMBLOCK_ALLOCATED, NULL); UT_ASSERTeq(layout->zone0.chunk_headers[1].type, CHUNK_TYPE_USED); mrun_used.m_ops->prep_hdr(&mrun_used, MEMBLOCK_FREE, NULL); UT_ASSERTeq(bitmap[0], 0ULL); mrun_free.m_ops->prep_hdr(&mrun_free, MEMBLOCK_ALLOCATED, NULL); UT_ASSERTeq(bitmap[0], 0b11110000); mrun_large_used.m_ops->prep_hdr(&mrun_large_used, MEMBLOCK_FREE, NULL); UT_ASSERTeq(bitmap[1], 0ULL); mrun_large_free.m_ops->prep_hdr(&mrun_large_free, MEMBLOCK_ALLOCATED, NULL); UT_ASSERTeq(bitmap[2], ~0ULL); } static int fake_persist(void *base, const void *addr, size_t size, unsigned flags) { return 0; } int main(int argc, char *argv[]) { START(argc, argv, "obj_memblock"); PMEMobjpool pool; pop = &pool; pop->heap.layout = ZALLOC(sizeof(struct heap_layout) + NCHUNKS * sizeof(struct chunk)); pop->heap.p_ops.persist = fake_persist; test_detect(); test_block_size(); test_prep_hdr(); FREE(pop->heap.layout); DONE(NULL); } pmdk-1.11.1/src/test/obj_memblock/TEST00000775000000000000000000000046014123364546016214 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_memblock/TEST0 -- unit test for memblock interface # . ../unittest/unittest.sh require_test_type medium require_fs_type none setup expect_normal_exit ./obj_memblock$EXESUFFIX pass pmdk-1.11.1/src/test/obj_memblock/Makefile0000664000000000000000000000044514123364546017072 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_memblock/Makefile -- build memblock unit test # TARGET = obj_memblock OBJS = obj_memblock.o LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_memblock.c) pmdk-1.11.1/src/test/obj_memblock/TEST0.PS10000664000000000000000000000045414123364546016616 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_memblock/TEST0 -- unit test for memblock interface # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type none setup expect_normal_exit $Env:EXE_DIR\obj_memblock$Env:EXESUFFIX pass pmdk-1.11.1/src/test/obj_memblock/.gitignore0000664000000000000000000000001514123364546017413 0ustar rootrootobj_memblock pmdk-1.11.1/src/test/obj_memblock/obj_memblock.vcxproj.filters0000664000000000000000000000674414123364546023151 0ustar rootroot Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files {76119d1b-52a7-4d56-b6da-4bb08337cf2d} {ef338777-a9d3-4316-bc27-c5fe76c475cf} {27ffeb04-ab4d-4407-af86-fae8a2c0387b} Test Scripts Header Files pmdk-1.11.1/src/test/obj_memblock/obj_memblock.vcxproj0000664000000000000000000001311614123364546021471 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} _CONSOLE;%(PreprocessorDefinitions);WRAP_REAL NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL {0388E945-A655-41A7-AF27-8981CEE0E49A} Win32Proj obj_memblock 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) pmdk-1.11.1/src/test/pmem2_memset/0000775000000000000000000000000014123364546015376 5ustar rootrootpmdk-1.11.1/src/test/pmem2_memset/pmem2_memset.c0000664000000000000000000000346614123364546020145 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2020-2021, Intel Corporation */ /* * pmem_memset.c -- unit test for doing a memset * * usage: pmem_memset file offset length */ #include "unittest.h" #include "file.h" #include "ut_pmem2.h" #include "memset_common.h" static void do_memset_variants(int fd, char *dest, const char *file_name, size_t dest_off, size_t bytes, persist_fn p, memset_fn fn) { for (int i = 0; i < ARRAY_SIZE(Flags); ++i) { do_memset(fd, dest, file_name, dest_off, bytes, fn, Flags[i], p, NULL, NULL, NULL); if (Flags[i] & PMEMOBJ_F_MEM_NOFLUSH) p(dest, bytes); } } int main(int argc, char *argv[]) { int fd; char *dest; struct pmem2_config *cfg; struct pmem2_source *src; struct pmem2_map *map; if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); const char *thr = os_getenv("PMEM_MOVNT_THRESHOLD"); const char *avx = os_getenv("PMEM_AVX"); const char *avx512f = os_getenv("PMEM_AVX512F"); START(argc, argv, "pmem2_memset %s %s %s %savx %savx512f", argv[2], argv[3], thr ? thr : "default", avx ? "" : "!", avx512f ? "" : "!"); fd = OPEN(argv[1], O_RDWR); PMEM2_CONFIG_NEW(&cfg); PMEM2_SOURCE_FROM_FD(&src, fd); PMEM2_CONFIG_SET_GRANULARITY(cfg, PMEM2_GRANULARITY_PAGE); int ret = pmem2_map_new(&map, cfg, src); UT_PMEM2_EXPECT_RETURN(ret, 0); PMEM2_CONFIG_DELETE(&cfg); dest = pmem2_map_get_address(map); if (dest == NULL) UT_FATAL("!could not map file: %s", argv[1]); size_t dest_off = strtoul(argv[2], NULL, 0); size_t bytes = strtoul(argv[3], NULL, 0); pmem2_persist_fn persist = pmem2_get_persist_fn(map); pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); do_memset_variants(fd, dest, argv[1], dest_off, bytes, persist, memset_fn); ret = pmem2_map_delete(&map); UT_ASSERTeq(ret, 0); CLOSE(fd); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_memset/Makefile0000664000000000000000000000057514123364546017045 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # # src/test/pmem2_memset/Makefile -- build pmem2_memset test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_memset OBJS += pmem2_memset.o\ memset_common.o\ ut_pmem2_utils.o\ ut_pmem2_config.o\ ut_pmem2_source.o LIBPMEM2=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_memset/TESTS.py0000775000000000000000000000300714123364546016655 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2020, Intel Corporation # from collections import namedtuple import testframework as t TC = namedtuple('TC', ['offset', 'length']) class Pmem2Memset(t.Test): test_type = t.Short filesize = 4 * t.MiB envs0 = () envs1 = () test_cases = ( TC(offset=0, length=8), TC(offset=13, length=4096) ) def run(self, ctx): for env in self.envs0: ctx.env[env] = '0' for env in self.envs1: ctx.env[env] = '1' if ctx.wc_workaround() == 'on': ctx.env['PMEM_WC_WORKAROUND'] = '1' elif ctx.wc_workaround() == 'off': ctx.env['PMEM_WC_WORKAROUND'] = '0' for tc in self.test_cases: filepath = ctx.create_holey_file(self.filesize, 'testfile',) ctx.exec('pmem2_memset', filepath, tc.offset, tc.length) @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST0(Pmem2Memset): pass @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST1(Pmem2Memset): envs0 = ("PMEM_AVX512F",) @t.require_architectures('x86_64') @t.add_params('wc_workaround', ['on', 'off', 'default']) class TEST2(Pmem2Memset): envs0 = ("PMEM_AVX512F", "PMEM_AVX",) @t.add_params('wc_workaround', ['default']) class TEST3(Pmem2Memset): envs1 = ("PMEM_NO_MOVNT",) @t.add_params('wc_workaround', ['default']) class TEST4(Pmem2Memset): envs1 = ("PMEM_NO_MOVNT", "PMEM_NO_GENERIC_MEMCPY") pmdk-1.11.1/src/test/pmem2_memset/.gitignore0000664000000000000000000000001514123364546017362 0ustar rootrootpmem2_memset pmdk-1.11.1/src/test/pmem2_memset/pmem2_memset.vcxproj.filters0000664000000000000000000000264314123364546023061 0ustar rootroot {4200f836-ad76-482e-9962-43243397298a} {efd29bfb-c8ff-4cee-989b-4edf4e3af894} {23a70f8d-0265-4412-a8f0-b4b1a8bc8c73} Test Scripts Source Files Source Files Source Files Source Files Source Files Header files Header files pmdk-1.11.1/src/test/pmem2_memset/pmem2_memset.vcxproj0000664000000000000000000000755614123364546021422 0ustar rootroot Debug x64 Release x64 {f596c36c-5c96-4f08-b420-8908af500954} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {6770917C-5B8E-49F1-9297-163FAB76DAFB} Win32Proj pmem2_memset 10.0.17134.0 Application true v140 Application false v140 $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/pmem2_memset/memset_common.h0000664000000000000000000000144014123364546020410 0ustar rootroot/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright 2020-2021, Intel Corporation */ /* * memset_common.h -- header file for common memset utilities */ #ifndef MEMSET_COMMON_H #define MEMSET_COMMON_H 1 #include "unittest.h" #include "file.h" extern unsigned Flags[10]; typedef void *(*memset_fn)(void *pmemdest, int c, size_t len, unsigned flags); typedef void *(*set_memset_fn)(struct pmemset *set, void *pmemdest, int c, size_t len, unsigned flags); typedef void (*persist_fn)(const void *ptr, size_t len); typedef int (*set_persist_fn)(struct pmemset *set, void *ptr, size_t len); void do_memset(int fd, char *dest, const char *file_name, size_t dest_off, size_t bytes, memset_fn fn, unsigned flags, persist_fn p, set_persist_fn sp, set_memset_fn sm, struct pmemset *set); #endif pmdk-1.11.1/src/test/pmem2_memset/memset_common.c0000664000000000000000000000520014123364546020401 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2021, Intel Corporation */ /* * memset_common.c -- common part for tests doing a persistent memset */ #include "unittest.h" #include "memset_common.h" /* * do_persist - performs selected persist function */ static void do_persist(struct pmemset *set, set_persist_fn sp, persist_fn p, char *ptr, size_t len) { if (set) sp(set, ptr, len); else p(ptr, len); } /* * do_memset_s - performs selected memcpy function */ static void * do_memset_s(struct pmemset *set, set_memset_fn sm, memset_fn m, char *ptr, int c, size_t len, unsigned flags) { if (set) return sm(set, ptr, c, len, flags); else return m(ptr, c, len, flags); } /* * do_memset - worker function for memset */ void do_memset(int fd, char *dest, const char *file_name, size_t dest_off, size_t bytes, memset_fn fn, unsigned flags, persist_fn persist, set_persist_fn sp, set_memset_fn sm, struct pmemset *set) { char *buf = MALLOC(bytes); char *dest1; char *ret; memset(dest, 0, bytes); do_persist(set, sp, persist, dest, bytes); dest1 = MALLOC(bytes); memset(dest1, 0, bytes); /* * This is used to verify that the value of what a non persistent * memset matches the outcome of the persistent memset. The * persistent memset will match the file but may not be the * correct or expected value. */ memset(dest1 + dest_off, 0x5A, bytes / 4); memset(dest1 + dest_off + (bytes / 4), 0x46, bytes / 4); /* Test the corner cases */ ret = do_memset_s(set, sm, fn, dest + dest_off, 0x5A, 0, flags); UT_ASSERTeq(ret, dest + dest_off); UT_ASSERTeq(*(char *)(dest + dest_off), 0); /* * Do the actual memset with persistence. */ ret = do_memset_s(set, sm, fn, dest + dest_off, 0x5A, bytes / 4, flags); UT_ASSERTeq(ret, dest + dest_off); ret = do_memset_s(set, sm, fn, dest + dest_off + (bytes / 4), 0x46, bytes / 4, flags); UT_ASSERTeq(ret, dest + dest_off + (bytes / 4)); if (memcmp(dest, dest1, bytes / 2)) UT_FATAL("%s: first %zu bytes do not match", file_name, bytes / 2); LSEEK(fd, 0, SEEK_SET); if (READ(fd, buf, bytes / 2) == bytes / 2) { if (memcmp(buf, dest, bytes / 2)) UT_FATAL("%s: first %zu bytes do not match", file_name, bytes / 2); } FREE(dest1); FREE(buf); } unsigned Flags[] = { 0, PMEM_F_MEM_NODRAIN, PMEM_F_MEM_NONTEMPORAL, PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL, PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_NODRAIN, PMEM_F_MEM_WC, PMEM_F_MEM_WB, PMEM_F_MEM_NOFLUSH, /* all possible flags */ PMEM_F_MEM_NODRAIN | PMEM_F_MEM_NOFLUSH | PMEM_F_MEM_NONTEMPORAL | PMEM_F_MEM_TEMPORAL | PMEM_F_MEM_WC | PMEM_F_MEM_WB, }; pmdk-1.11.1/src/test/out_err_mt/0000775000000000000000000000000014123364546015163 5ustar rootrootpmdk-1.11.1/src/test/out_err_mt/out_err_mt.vcxproj0000664000000000000000000000764014123364546020766 0ustar rootroot Debug x64 Release x64 {063037B2-CA35-4520-811C-19D9C4ED891E} Win32Proj out_err_mt 10.0.17134.0 Application true v140 Application false v140 {492baa3d-0d5d-478e-9765-500463ae69aa} {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {0b1818eb-bdc8-4865-964f-db8bf05cfd86} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {cf9a0883-6334-44c7-ac29-349468c78e27} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/out_err_mt/out_err_mt.c0000664000000000000000000000740014123364546017507 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * out_err_mt.c -- unit test for error messages */ #include #include #include #include "unittest.h" #include "valgrind_internal.h" #include "util.h" #define NUM_THREADS 16 static void print_errors(const char *msg) { UT_OUT("%s", msg); UT_OUT("PMEM: %s", pmem_errormsg()); UT_OUT("PMEMOBJ: %s", pmemobj_errormsg()); UT_OUT("PMEMLOG: %s", pmemlog_errormsg()); UT_OUT("PMEMBLK: %s", pmemblk_errormsg()); UT_OUT("PMEMPOOL: %s", pmempool_errormsg()); } static void check_errors(unsigned ver) { int ret; int err_need; int err_found; ret = sscanf(pmem_errormsg(), "libpmem major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEM_MAJOR_VERSION); ret = sscanf(pmemobj_errormsg(), "libpmemobj major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMOBJ_MAJOR_VERSION); ret = sscanf(pmemlog_errormsg(), "libpmemlog major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMLOG_MAJOR_VERSION); ret = sscanf(pmemblk_errormsg(), "libpmemblk major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMBLK_MAJOR_VERSION); ret = sscanf(pmempool_errormsg(), "libpmempool major version mismatch (need %d, found %d)", &err_need, &err_found); UT_ASSERTeq(ret, 2); UT_ASSERTeq(err_need, ver); UT_ASSERTeq(err_found, PMEMPOOL_MAJOR_VERSION); } static void * do_test(void *arg) { unsigned ver = *(unsigned *)arg; pmem_check_version(ver, 0); pmemobj_check_version(ver, 0); pmemlog_check_version(ver, 0); pmemblk_check_version(ver, 0); pmempool_check_version(ver, 0); check_errors(ver); return NULL; } static void run_mt_test(void *(*worker)(void *)) { os_thread_t thread[NUM_THREADS]; unsigned ver[NUM_THREADS]; for (unsigned i = 0; i < NUM_THREADS; ++i) { ver[i] = 10000 + i; THREAD_CREATE(&thread[i], NULL, worker, &ver[i]); } for (unsigned i = 0; i < NUM_THREADS; ++i) { THREAD_JOIN(&thread[i], NULL); } } int main(int argc, char *argv[]) { START(argc, argv, "out_err_mt"); if (argc != 6) UT_FATAL("usage: %s file1 file2 file3 file4 dir", argv[0]); print_errors("start"); PMEMobjpool *pop = pmemobj_create(argv[1], "test", PMEMOBJ_MIN_POOL, 0666); PMEMlogpool *plp = pmemlog_create(argv[2], PMEMLOG_MIN_POOL, 0666); PMEMblkpool *pbp = pmemblk_create(argv[3], 128, PMEMBLK_MIN_POOL, 0666); util_init(); pmem_check_version(10000, 0); pmemobj_check_version(10001, 0); pmemlog_check_version(10002, 0); pmemblk_check_version(10003, 0); pmempool_check_version(10006, 0); print_errors("version check"); void *ptr = NULL; /* * We are testing library error reporting and we don't want this test * to fail under memcheck. */ VALGRIND_DO_DISABLE_ERROR_REPORTING; pmem_msync(ptr, 1); VALGRIND_DO_ENABLE_ERROR_REPORTING; print_errors("pmem_msync"); int ret; PMEMoid oid; ret = pmemobj_alloc(pop, &oid, 0, 0, NULL, NULL); UT_ASSERTeq(ret, -1); print_errors("pmemobj_alloc"); pmemlog_append(plp, NULL, PMEMLOG_MIN_POOL); print_errors("pmemlog_append"); size_t nblock = pmemblk_nblock(pbp); pmemblk_set_error(pbp, (long long)nblock + 1); print_errors("pmemblk_set_error"); run_mt_test(do_test); pmemobj_close(pop); pmemlog_close(plp); pmemblk_close(pbp); PMEMpoolcheck *ppc; struct pmempool_check_args args = {NULL, }; ppc = pmempool_check_init(&args, sizeof(args) / 2); UT_ASSERTeq(ppc, NULL); print_errors("pmempool_check_init"); DONE(NULL); } pmdk-1.11.1/src/test/out_err_mt/TEST00000775000000000000000000000060614123364546015752 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # # src/test/out_err_mt/TEST0 -- unit test for error messages # . ../unittest/unittest.sh require_test_type medium require_fs_type any disable_eatmydata setup expect_normal_exit ./out_err_mt$EXESUFFIX \ $DIR/testfile1 $DIR/testfile2 $DIR/testfile3 $DIR/testfile4 $DIR check pass pmdk-1.11.1/src/test/out_err_mt/Makefile0000664000000000000000000000045414123364546016626 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/out_err_mt/Makefile -- build unit test for error messages # TARGET = out_err_mt OBJS = out_err_mt.o LIBPMEMCOMMON=y LIBPMEM=y LIBPMEMLOG=y LIBPMEMBLK=y LIBPMEMOBJ=y LIBPMEMPOOL=y include ../Makefile.inc pmdk-1.11.1/src/test/out_err_mt/out0.log.match0000664000000000000000000000343114123364546017651 0ustar rootrootout_err_mt$(nW)TEST0: START: out_err_mt$(nW) $(nW)out_err_mt$(nW) $(nW)testfile1 $(nW)testfile2 $(nW)testfile3 $(nW)testfile4 $(nW) start PMEM: PMEMOBJ: PMEMLOG: PMEMBLK: PMEMPOOL: version check PMEM: libpmem major version mismatch (need 10000, found $(N)) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmem_msync PMEM: msync: $(S) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemobj_alloc PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemlog_append PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemblk_set_error PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmempool_check_init PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: provided args_size is not supported out_err_mt$(nW)TEST0: DONE pmdk-1.11.1/src/test/out_err_mt/TEST0.PS10000664000000000000000000000365314123364546016356 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/out_err_mt/TEST0 -- unit test for error messages # . ..\unittest\unittest.ps1 require_test_type medium require_fs_type any setup expect_normal_exit $Env:EXE_DIR\out_err_mt$Env:EXESUFFIX ` $DIR\testfile1 $DIR\testfile2 $DIR\testfile3 $DIR\testfile4 $DIR check pass pmdk-1.11.1/src/test/out_err_mt/.gitignore0000664000000000000000000000001314123364546017145 0ustar rootrootout_err_mt pmdk-1.11.1/src/test/out_err_mt/TEST10000775000000000000000000000125114123364546015750 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # # src/test/out_err_mt/TEST1 -- unit test for error messages # . ../unittest/unittest.sh require_test_type medium require_fs_type any disable_eatmydata require_valgrind 3.7 configure_valgrind drd force-enable setup unset PMEM_LOG_LEVEL unset PMEMLOG_LOG_LEVEL unset PMEMBLK_LOG_LEVEL unset PMEMOBJ_LOG_LEVEL unset PMEMPOOL_LOG_LEVEL unset PMEM_LOG_FILE unset PMEMLOG_LOG_FILE unset PMEMBLK_LOG_FILE unset PMEMOBJ_LOG_FILE unset PMEMPOOL_LOG_FILE expect_normal_exit ./out_err_mt$EXESUFFIX $DIR/testfile1\ $DIR/testfile2 $DIR/testfile3 $DIR/testfile4 $DIR check pass pmdk-1.11.1/src/test/out_err_mt/out_err_mt.vcxproj.filters0000664000000000000000000000177614123364546022441 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {1d395904-81fc-4e68-a335-f663b431dbf7} match {62ac7650-9f5d-4d5f-96ff-d652a437ea51} ps1 Source Files Match Files Test Scripts pmdk-1.11.1/src/test/out_err_mt/out1.log.match0000664000000000000000000000343114123364546017652 0ustar rootrootout_err_mt$(nW)TEST1: START: out_err_mt$(nW) $(nW)out_err_mt$(nW) $(nW)testfile1 $(nW)testfile2 $(nW)testfile3 $(nW)testfile4 $(nW) start PMEM: PMEMOBJ: PMEMLOG: PMEMBLK: PMEMPOOL: version check PMEM: libpmem major version mismatch (need 10000, found $(N)) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmem_msync PMEM: msync: $(S) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemobj_alloc PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemlog_append PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemblk_set_error PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmempool_check_init PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: provided args_size is not supported out_err_mt$(nW)TEST1: DONE pmdk-1.11.1/src/test/out_err_mt/TEST20000775000000000000000000000117614123364546015757 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2020, Intel Corporation # # # src/test/out_err_mt/TEST2 -- unit test for error messages # . ../unittest/unittest.sh require_test_type medium require_fs_type any disable_eatmydata require_valgrind 3.7 configure_valgrind helgrind force-enable setup unset PMEM_LOG_LEVEL unset PMEMLOG_LOG_LEVEL unset PMEMBLK_LOG_LEVEL unset PMEMOBJ_LOG_LEVEL unset PMEM_LOG_FILE unset PMEMLOG_LOG_FILE unset PMEMBLK_LOG_FILE unset PMEMOBJ_LOG_FILE expect_normal_exit ./out_err_mt$EXESUFFIX $DIR/testfile1 $DIR/testfile2\ $DIR/testfile3 $DIR/testfile4 $DIR check pass pmdk-1.11.1/src/test/out_err_mt/out2.log.match0000664000000000000000000000343114123364546017653 0ustar rootrootout_err_mt$(nW)TEST2: START: out_err_mt$(nW) $(nW)out_err_mt$(nW) $(nW)testfile1 $(nW)testfile2 $(nW)testfile3 $(nW)testfile4 $(nW) start PMEM: PMEMOBJ: PMEMLOG: PMEMBLK: PMEMPOOL: version check PMEM: libpmem major version mismatch (need 10000, found $(N)) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmem_msync PMEM: msync: $(S) PMEMOBJ: libpmemobj major version mismatch (need 10001, found $(N)) PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemobj_alloc PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: libpmemlog major version mismatch (need 10002, found $(N)) PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemlog_append PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: libpmemblk major version mismatch (need 10003, found $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmemblk_set_error PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: libpmempool major version mismatch (need 10006, found $(N)) pmempool_check_init PMEM: msync: $(S) PMEMOBJ: allocation with size 0 PMEMLOG: pmemlog_append: No space left on device PMEMBLK: lba out of range (nlba $(N)) PMEMPOOL: provided args_size is not supported out_err_mt$(nW)TEST2: DONE pmdk-1.11.1/src/test/obj_pool_lookup/0000775000000000000000000000000014123364546016200 5ustar rootrootpmdk-1.11.1/src/test/obj_pool_lookup/obj_pool_lookup.vcxproj0000664000000000000000000000761314123364546023020 0ustar rootroot Debug x64 Release x64 {4850F425-9128-4E91-973C-5AE7BD97395B} Win32Proj obj_pool_lookup 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {5580d11c-fda6-4cf2-a0e8-1c2d3fbc11f1} pmdk-1.11.1/src/test/obj_pool_lookup/TEST00000775000000000000000000000046714123364546016774 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool_lookup/TEST0 -- unit test for pmemobj_pool # . ../unittest/unittest.sh require_test_type medium require_fs_type any setup expect_normal_exit ./obj_pool_lookup$EXESUFFIX $DIR 9 pass pmdk-1.11.1/src/test/obj_pool_lookup/obj_pool_lookup.c0000664000000000000000000000677014123364546021552 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ /* * obj_pool_lookup.c -- unit test for pmemobj_pool and pmemobj_pool_of */ #include "unittest.h" #define MAX_PATH_LEN 255 #define LAYOUT_NAME "pool_lookup" #define ALLOC_SIZE 100 static void define_path(char *str, size_t size, const char *dir, unsigned i) { int ret = snprintf(str, size, "%s"OS_DIR_SEP_STR"testfile%d", dir, i); if (ret < 0 || ret >= size) UT_FATAL("snprintf: %d", ret); } int main(int argc, char *argv[]) { START(argc, argv, "obj_pool_lookup"); if (argc != 3) UT_FATAL("usage: %s [directory] [# of pools]", argv[0]); unsigned npools = ATOU(argv[2]); const char *dir = argv[1]; int r; /* check before pool creation */ PMEMoid some_oid = {2, 3}; UT_ASSERTeq(pmemobj_pool_by_ptr(&some_oid), NULL); UT_ASSERTeq(pmemobj_pool_by_oid(some_oid), NULL); PMEMobjpool **pops = MALLOC(npools * sizeof(PMEMobjpool *)); void **guard_after = MALLOC(npools * sizeof(void *)); size_t length = strlen(dir) + MAX_PATH_LEN; char *path = MALLOC(length); for (unsigned i = 0; i < npools; ++i) { define_path(path, length, dir, i); pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); /* * Reserve a page after the pool for address checks, if it * doesn't map precisely at that address - it's OK. */ guard_after[i] = MMAP((char *)pops[i] + PMEMOBJ_MIN_POOL, Ut_pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); UT_ASSERTne(guard_after[i], NULL); if (pops[i] == NULL) UT_FATAL("!pmemobj_create"); } PMEMoid *oids = MALLOC(npools * sizeof(PMEMoid)); for (unsigned i = 0; i < npools; ++i) { r = pmemobj_alloc(pops[i], &oids[i], ALLOC_SIZE, 1, NULL, NULL); UT_ASSERTeq(r, 0); } PMEMoid invalid = {123, 321}; UT_ASSERTeq(pmemobj_pool_by_oid(OID_NULL), NULL); UT_ASSERTeq(pmemobj_pool_by_oid(invalid), NULL); for (unsigned i = 0; i < npools; ++i) { UT_ASSERTeq(pmemobj_pool_by_oid(oids[i]), pops[i]); } UT_ASSERTeq(pmemobj_pool_by_ptr(NULL), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr((void *)0xCBA), NULL); void *valid_ptr = MALLOC(ALLOC_SIZE); UT_ASSERTeq(pmemobj_pool_by_ptr(valid_ptr), NULL); FREE(valid_ptr); for (unsigned i = 0; i < npools; ++i) { void *before_pool = (char *)pops[i] - 1; void *after_pool = (char *)pops[i] + PMEMOBJ_MIN_POOL + 1; void *start_pool = (char *)pops[i]; void *end_pool = (char *)pops[i] + PMEMOBJ_MIN_POOL - 1; void *edge = (char *)pops[i] + PMEMOBJ_MIN_POOL; void *middle = (char *)pops[i] + (PMEMOBJ_MIN_POOL / 2); void *in_oid = (char *)pmemobj_direct(oids[i]) + (ALLOC_SIZE / 2); UT_ASSERTeq(pmemobj_pool_by_ptr(before_pool), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(after_pool), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(start_pool), pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(end_pool), pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(edge), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(middle), pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), pops[i]); pmemobj_close(pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(middle), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), NULL); MUNMAP(guard_after[i], Ut_pagesize); } for (unsigned i = 0; i < npools; ++i) { UT_ASSERTeq(pmemobj_pool_by_oid(oids[i]), NULL); define_path(path, length, dir, i); pops[i] = pmemobj_open(path, LAYOUT_NAME); UT_ASSERTne(pops[i], NULL); UT_ASSERTeq(pmemobj_pool_by_oid(oids[i]), pops[i]); pmemobj_close(pops[i]); } FREE(path); FREE(pops); FREE(guard_after); FREE(oids); DONE(NULL); } pmdk-1.11.1/src/test/obj_pool_lookup/Makefile0000664000000000000000000000036714123364546017646 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool_lookup/Makefile -- build obj_pool_lookup unit test # TARGET = obj_pool_lookup OBJS = obj_pool_lookup.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_pool_lookup/TEST0.PS10000664000000000000000000000054114123364546017364 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_pool_lookup/TEST0 -- unit test for pmemobj_pool # . ..\unittest\unittest.ps1 require_test_type medium # doesn't make sense to run in local directory require_fs_type any setup expect_normal_exit $Env:EXE_DIR\obj_pool_lookup$Env:EXESUFFIX $DIR 9 pass pmdk-1.11.1/src/test/obj_pool_lookup/.gitignore0000664000000000000000000000002014123364546020160 0ustar rootrootobj_pool_lookup pmdk-1.11.1/src/test/obj_pool_lookup/obj_pool_lookup.vcxproj.filters0000664000000000000000000000134514123364546024463 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {fcfbf748-7cf6-4f89-b297-f8e2faed1399} Source Files Test Scripts pmdk-1.11.1/src/test/obj_tx_realloc/0000775000000000000000000000000014123364546015772 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_realloc/obj_tx_realloc.vcxproj0000664000000000000000000001003314123364546022372 0ustar rootroot Debug x64 Release x64 {9AE2DAF9-10C4-4EC3-AE52-AD5EE9C77C55} Win32Proj obj_tx_realloc 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled CompileAsCpp CompileAsCpp {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_tx_realloc/TEST00000775000000000000000000000367614123364546016573 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_realloc/TEST0 -- unit test for pmemobj_tx_realloc # . ../unittest/unittest.sh require_test_type medium setup SIZE=$(obj_pool_desc_size) create_nonzeroed_file 8M ${SIZE} $DIR/testfile1 expect_normal_exit ./obj_tx_realloc$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_realloc/Makefile0000664000000000000000000000040214123364546017426 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_tx_realloc/Makefile -- build obj_tx_realloc unit test # TARGET = obj_tx_realloc OBJS = obj_tx_realloc.o LIBPMEMCOMMON=y LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_realloc/out0.log.match0000664000000000000000000000017014123364546020455 0ustar rootrootobj_tx_realloc$(nW)TEST0: START: obj_tx_realloc $(nW)obj_tx_realloc$(nW) $(nW)testfile1 obj_tx_realloc$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_realloc/TEST0.PS10000664000000000000000000000363114123364546017161 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src\test\obj_tx_realloc\TEST0 -- unit test for pmemobj_tx_realloc # . ..\unittest\unittest.ps1 require_test_type medium setup create_nonzeroed_file 8M 8K $DIR\testfile1 expect_normal_exit $ENV:EXE_DIR\obj_tx_realloc$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_tx_realloc/obj_tx_realloc.vcxproj.filters0000664000000000000000000000200214123364546024036 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {c6db624a-34a6-4e84-9ca2-819ec5bd668e} match {6edeaaa2-46bb-43cc-be55-9245d44aeb9a} ps1 Source Files Match Files Test Scripts pmdk-1.11.1/src/test/obj_tx_realloc/.gitignore0000664000000000000000000000001714123364546017760 0ustar rootrootobj_tx_realloc pmdk-1.11.1/src/test/obj_tx_realloc/obj_tx_realloc.c0000664000000000000000000003111214123364546021122 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * obj_tx_realloc.c -- unit test for pmemobj_tx_realloc and pmemobj_tx_zrealloc */ #include #include #include "unittest.h" #include "util.h" #define LAYOUT_NAME "tx_realloc" #define TEST_VALUE_1 1 #define OBJ_SIZE 1024 enum type_number { TYPE_NO_TX, TYPE_COMMIT, TYPE_ABORT, TYPE_TYPE, TYPE_COMMIT_ZERO, TYPE_COMMIT_ZERO_MACRO, TYPE_ABORT_ZERO, TYPE_ABORT_ZERO_MACRO, TYPE_COMMIT_ALLOC, TYPE_ABORT_ALLOC, TYPE_ABORT_HUGE, TYPE_ABORT_ZERO_HUGE, TYPE_ABORT_ZERO_HUGE_MACRO, TYPE_FREE, }; struct object { size_t value; char data[OBJ_SIZE - sizeof(size_t)]; }; TOID_DECLARE(struct object, 0); struct object_macro { size_t value; char data[OBJ_SIZE - sizeof(size_t)]; }; TOID_DECLARE(struct object_macro, TYPE_COMMIT_ZERO_MACRO); /* * do_tx_alloc -- do tx allocation with specified type number */ static PMEMoid do_tx_alloc(PMEMobjpool *pop, unsigned type_num, size_t value) { TOID(struct object) obj; TOID_ASSIGN(obj, OID_NULL); TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_alloc( sizeof(struct object), type_num)); if (!TOID_IS_NULL(obj)) { D_RW(obj)->value = value; } } TX_ONABORT { UT_ASSERT(0); } TX_END return obj.oid; } /* * do_tx_realloc_commit -- reallocate an object and commit the transaction */ static void do_tx_realloc_commit(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_COMMIT, TEST_VALUE_1)); size_t new_size = 2 * pmemobj_alloc_usable_size(obj.oid); TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, new_size, TYPE_COMMIT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_abort -- reallocate an object and commit the transaction */ static void do_tx_realloc_abort(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT, TEST_VALUE_1)); size_t new_size = 2 * pmemobj_alloc_usable_size(obj.oid); TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, new_size, TYPE_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_huge -- reallocate an object to a huge size to trigger tx abort */ static void do_tx_realloc_huge(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_HUGE, TEST_VALUE_1)); size_t new_size = PMEMOBJ_MAX_ALLOC_SIZE + 1; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, new_size, TYPE_ABORT_HUGE)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_HUGE)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_zrealloc_commit_macro -- reallocate an object, zero it and commit * the transaction using macro */ static void do_tx_zrealloc_commit_macro(PMEMobjpool *pop) { TOID(struct object_macro) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_COMMIT_ZERO_MACRO, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { obj = TX_ZREALLOC(obj, new_size); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_ZERO_MACRO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_zrealloc_commit -- reallocate an object, zero it and commit * the transaction */ static void do_tx_zrealloc_commit(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_COMMIT_ZERO, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zrealloc(obj.oid, new_size, TYPE_COMMIT_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_abort_macro -- reallocate an object, zero it and commit the * transaction using macro */ static void do_tx_zrealloc_abort_macro(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_ZERO_MACRO, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { obj = TX_ZREALLOC(obj, new_size); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_ZERO_MACRO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_abort -- reallocate an object and commit the transaction */ static void do_tx_zrealloc_abort(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_ZERO, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zrealloc(obj.oid, new_size, TYPE_ABORT_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); void *new_ptr = (void *)((uintptr_t)D_RW(obj) + old_size); UT_ASSERT(util_is_zeroed(new_ptr, new_size - old_size)); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_ZERO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_huge_macro -- reallocate an object to a huge size to trigger * tx abort and zero it using macro */ static void do_tx_zrealloc_huge_macro(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_ZERO_HUGE_MACRO, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { obj = TX_ZREALLOC(obj, PMEMOBJ_MAX_ALLOC_SIZE + 1); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_ZERO_HUGE_MACRO)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_huge -- reallocate an object to a huge size to trigger tx abort */ static void do_tx_zrealloc_huge(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_ZERO_HUGE, TEST_VALUE_1)); size_t old_size = pmemobj_alloc_usable_size(obj.oid); size_t new_size = 2 * old_size; TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_zrealloc(obj.oid, PMEMOBJ_MAX_ALLOC_SIZE + 1, TYPE_ABORT_ZERO_HUGE)); UT_ASSERT(0); /* should not get to this point */ } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_ZERO_HUGE)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) < new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_alloc_commit -- reallocate an allocated object * and commit the transaction */ static void do_tx_realloc_alloc_commit(PMEMobjpool *pop) { TOID(struct object) obj; size_t new_size = 0; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_COMMIT_ALLOC, TEST_VALUE_1)); UT_ASSERT(!TOID_IS_NULL(obj)); new_size = 2 * pmemobj_alloc_usable_size(obj.oid); TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, new_size, TYPE_COMMIT_ALLOC)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_COMMIT_ALLOC)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERTeq(D_RO(obj)->value, TEST_VALUE_1); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); TOID_ASSIGN(obj, POBJ_NEXT_TYPE_NUM(obj.oid)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_realloc_alloc_abort -- reallocate an allocated object * and commit the transaction */ static void do_tx_realloc_alloc_abort(PMEMobjpool *pop) { TOID(struct object) obj; size_t new_size = 0; TX_BEGIN(pop) { TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_ABORT_ALLOC, TEST_VALUE_1)); UT_ASSERT(!TOID_IS_NULL(obj)); new_size = 2 * pmemobj_alloc_usable_size(obj.oid); TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, new_size, TYPE_ABORT_ALLOC)); UT_ASSERT(!TOID_IS_NULL(obj)); UT_ASSERT(pmemobj_alloc_usable_size(obj.oid) >= new_size); pmemobj_tx_abort(-1); } TX_ONCOMMIT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_ABORT_ALLOC)); UT_ASSERT(TOID_IS_NULL(obj)); } /* * do_tx_root_realloc -- retrieve root inside of transaction */ static void do_tx_root_realloc(PMEMobjpool *pop) { TX_BEGIN(pop) { PMEMoid root = pmemobj_root(pop, sizeof(struct object)); UT_ASSERT(!OID_IS_NULL(root)); UT_ASSERT(util_is_zeroed(pmemobj_direct(root), sizeof(struct object))); UT_ASSERTeq(sizeof(struct object), pmemobj_root_size(pop)); root = pmemobj_root(pop, 2 * sizeof(struct object)); UT_ASSERT(!OID_IS_NULL(root)); UT_ASSERT(util_is_zeroed(pmemobj_direct(root), 2 * sizeof(struct object))); UT_ASSERTeq(2 * sizeof(struct object), pmemobj_root_size(pop)); } TX_ONABORT { UT_ASSERT(0); } TX_END } /* * do_tx_realloc_free -- reallocate an allocated object * and commit the transaction */ static void do_tx_realloc_free(PMEMobjpool *pop) { TOID(struct object) obj; TOID_ASSIGN(obj, do_tx_alloc(pop, TYPE_FREE, TEST_VALUE_1)); TX_BEGIN(pop) { TOID_ASSIGN(obj, pmemobj_tx_realloc(obj.oid, 0, TYPE_COMMIT)); } TX_ONABORT { UT_ASSERT(0); } TX_END TOID_ASSIGN(obj, POBJ_FIRST_TYPE_NUM(pop, TYPE_FREE)); UT_ASSERT(TOID_IS_NULL(obj)); } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_realloc"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); do_tx_root_realloc(pop); do_tx_realloc_commit(pop); do_tx_realloc_abort(pop); do_tx_realloc_huge(pop); do_tx_zrealloc_commit(pop); do_tx_zrealloc_commit_macro(pop); do_tx_zrealloc_abort(pop); do_tx_zrealloc_abort_macro(pop); do_tx_zrealloc_huge(pop); do_tx_zrealloc_huge_macro(pop); do_tx_realloc_alloc_commit(pop); do_tx_realloc_alloc_abort(pop); do_tx_realloc_free(pop); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_realloc/TEST10000775000000000000000000000375014123364546016565 0ustar rootroot#!/usr/bin/env bash # # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # src/test/obj_tx_realloc/TEST1 -- unit test for pmemobj_tx_realloc # . ../unittest/unittest.sh require_test_type medium configure_valgrind pmemcheck force-enable setup SIZE=$(obj_pool_desc_size) create_nonzeroed_file 8M ${SIZE} $DIR/testfile1 expect_normal_exit ./obj_tx_realloc$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_realloc/out1.log.match0000664000000000000000000000017014123364546020456 0ustar rootrootobj_tx_realloc$(nW)TEST1: START: obj_tx_realloc $(nW)obj_tx_realloc$(nW) $(nW)testfile1 obj_tx_realloc$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem2_source_size/0000775000000000000000000000000014123364546016436 5ustar rootrootpmdk-1.11.1/src/test/pmem2_source_size/pmem2_source_size.c0000664000000000000000000000623214123364546022237 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019-2020, Intel Corporation */ /* * pmem2_source_size.c -- pmem2_source_size unittests */ #include #include "fault_injection.h" #include "unittest.h" #include "ut_pmem2.h" #include "ut_fh.h" #include "config.h" #include "out.h" typedef void (*test_fun)(const char *path, os_off_t size); /* * test_normal_file - tests normal file (common) */ static void test_normal_file(const char *path, os_off_t expected_size, enum file_handle_type type) { struct FHandle *fh = UT_FH_OPEN(type, path, FH_RDWR); struct pmem2_source *src; PMEM2_SOURCE_FROM_FH(&src, fh); size_t size; int ret = pmem2_source_size(src, &size); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(size, expected_size); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); } /* * test_normal_file_fd - tests normal file using a file descriptor */ static int test_normal_file_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_normal_file_fd "); char *path = argv[0]; os_off_t expected_size = ATOLL(argv[1]); test_normal_file(path, expected_size, FH_FD); return 2; } /* * test_normal_file_handle - tests normal file using a HANDLE */ static int test_normal_file_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_normal_file_handle" " "); char *path = argv[0]; os_off_t expected_size = ATOLL(argv[1]); test_normal_file(path, expected_size, FH_HANDLE); return 2; } /* * test_tmpfile - tests temporary file */ static void test_tmpfile(const char *dir, os_off_t requested_size, enum file_handle_type type) { struct FHandle *fh = UT_FH_OPEN(type, dir, FH_RDWR | FH_TMPFILE); UT_FH_TRUNCATE(fh, requested_size); struct pmem2_source *src; PMEM2_SOURCE_FROM_FH(&src, fh); size_t size = SIZE_MAX; int ret = pmem2_source_size(src, &size); UT_PMEM2_EXPECT_RETURN(ret, 0); UT_ASSERTeq(size, requested_size); PMEM2_SOURCE_DELETE(&src); UT_FH_CLOSE(fh); } /* * test_tmpfile_fd - tests temporary file using file descriptor interface */ static int test_tmpfile_fd(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_tmpfile_fd "); char *dir = argv[0]; os_off_t requested_size = ATOLL(argv[1]); test_tmpfile(dir, requested_size, FH_FD); return 2; } /* * test_tmpfile_handle - tests temporary file using file handle interface */ static int test_tmpfile_handle(const struct test_case *tc, int argc, char *argv[]) { if (argc < 2) UT_FATAL("usage: test_tmpfile_handle "); char *dir = argv[0]; os_off_t requested_size = ATOLL(argv[1]); test_tmpfile(dir, requested_size, FH_HANDLE); return 2; } /* * test_cases -- available test cases */ static struct test_case test_cases[] = { TEST_CASE(test_normal_file_fd), TEST_CASE(test_normal_file_handle), TEST_CASE(test_tmpfile_fd), TEST_CASE(test_tmpfile_handle), }; #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) int main(int argc, char **argv) { START(argc, argv, "pmem2_source_size"); TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); DONE(NULL); } pmdk-1.11.1/src/test/pmem2_source_size/pmem2_source_size.vcxproj0000664000000000000000000001127514123364546023513 0ustar rootroot Debug x64 Release x64 {DE068BE1-A8E9-48A2-B216-92A7CE5EA4CF} pmem2_source_size 10.0.17134.0 Application true v140 MultiByte Application false v140 true MultiByte Level3 Disabled true PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) Level3 MaxSpeed true true true $(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories) true true {492baa3d-0d5d-478e-9765-500463ae69aa} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/pmem2_source_size/Makefile0000664000000000000000000000066414123364546020104 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # # src/test/pmem2_source_size/Makefile -- build pmem2_source_size unit test # TOP = ../../.. vpath %.c $(TOP)/src/test/unittest vpath %.c $(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2 TARGET = pmem2_source_size OBJS += pmem2_source_size.o\ ut_pmem2_config.o\ ut_pmem2_source.o\ ut_pmem2_utils.o LIBPMEM2=internal-debug include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_source_size/TESTS.py0000775000000000000000000000271514123364546017722 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # import testframework as t class NormalFile(t.Test): test_type = t.Short def run(self, ctx): filepath = ctx.create_holey_file(self.size, 'testfile') ctx.exec('pmem2_source_size', self.test_case, filepath, self.size) class TEST0(NormalFile): test_case = 'test_normal_file_fd' size = 0 @t.windows_only class TEST1(NormalFile): test_case = 'test_normal_file_handle' size = 0 class TEST2(NormalFile): test_case = 'test_normal_file_fd' size = 16 * t.MiB @t.windows_only class TEST3(NormalFile): test_case = 'test_normal_file_handle' size = 16 * t.MiB # On Windows fd interface doesn't support temporary files # FreeBSD doesn't support O_TMPFILE @t.linux_only class TEST4(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem2_source_size', 'test_tmpfile_fd', ctx.testdir, 16 * t.MiB) # XXX doesn't work # @t.windows_only # class TEST5(t.Test): # test_type = t.Short # # def run(self, ctx): # ctx.exec('pmem2_source_size', 'tmp_file_handle', # ctx.testdir, str(16 * t.MiB)) @t.windows_exclude @t.require_devdax(t.DevDax('devdax1')) class TEST6(t.Test): test_type = t.Short def run(self, ctx): dd = ctx.devdaxes.devdax1 ctx.exec('pmem2_source_size', 'test_normal_file_fd', dd.path, dd.size) pmdk-1.11.1/src/test/pmem2_source_size/pmem2_source_size.vcxproj.filters0000664000000000000000000000371214123364546025157 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files pmdk-1.11.1/src/test/pmem2_source_size/.gitignore0000664000000000000000000000002214123364546020420 0ustar rootrootpmem2_source_size pmdk-1.11.1/src/test/obj_tx_callbacks/0000775000000000000000000000000014123364546016270 5ustar rootrootpmdk-1.11.1/src/test/obj_tx_callbacks/obj_tx_callbacks.c0000664000000000000000000001144414123364546021724 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2019, Intel Corporation */ /* * obj_tx_callbacks.c -- unit test for transaction stage callbacks */ #include "unittest.h" #define LAYOUT_NAME "tx_callback" POBJ_LAYOUT_BEGIN(tx_callback); POBJ_LAYOUT_ROOT(tx_callback, struct pmem_root); POBJ_LAYOUT_TOID(tx_callback, struct pmem_obj); POBJ_LAYOUT_END(tx_callback); struct runtime_info { int something; }; struct pmem_obj { struct runtime_info *rt; int pmem_info; }; struct pmem_root { TOID(struct pmem_obj) obj; }; struct free_info { void *to_free; }; static int freed = 0; static const char *desc[] = { "TX_STAGE_NONE", "TX_STAGE_WORK", "TX_STAGE_ONCOMMIT", "TX_STAGE_ONABORT", "TX_STAGE_FINALLY", "WTF?" }; static void free_onabort(PMEMobjpool *pop, enum pobj_tx_stage stage, void *arg) { UT_OUT("cb stage: %s", desc[stage]); if (stage == TX_STAGE_ONABORT) { struct free_info *f = (struct free_info *)arg; UT_OUT("rt_onabort: free"); free(f->to_free); freed++; } } static void allocate_pmem(struct free_info *f, TOID(struct pmem_root) root, int val) { TOID(struct pmem_obj) obj = TX_NEW(struct pmem_obj); D_RW(obj)->pmem_info = val; D_RW(obj)->rt = (struct runtime_info *)malloc(sizeof(struct runtime_info)); f->to_free = D_RW(obj)->rt; D_RW(obj)->rt->something = val; TX_ADD_FIELD(root, obj); D_RW(root)->obj = obj; } static void do_something_fishy(TOID(struct pmem_root) root) { TX_ADD_FIELD(root, obj); D_RW(root)->obj = TX_ALLOC(struct pmem_obj, 1 << 30); } static void free_oncommit(PMEMobjpool *pop, enum pobj_tx_stage stage, void *arg) { UT_OUT("cb stage: %s", desc[stage]); if (stage == TX_STAGE_ONCOMMIT) { struct free_info *f = (struct free_info *)arg; UT_OUT("rt_oncommit: free"); free(f->to_free); freed++; } } static void free_pmem(struct free_info *f, TOID(struct pmem_root) root) { TOID(struct pmem_obj) obj = D_RW(root)->obj; f->to_free = D_RW(obj)->rt; TX_FREE(obj); TX_SET(root, obj, TOID_NULL(struct pmem_obj)); } static void log_stages(PMEMobjpool *pop, enum pobj_tx_stage stage, void *arg) { UT_OUT("cb stage: %s", desc[stage]); } static void test(PMEMobjpool *pop, TOID(struct pmem_root) root) { struct free_info *volatile f = (struct free_info *)ZALLOC(sizeof(*f)); TX_BEGIN_CB(pop, free_onabort, f) { allocate_pmem(f, root, 7); do_something_fishy(root); UT_ASSERT(0); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { UT_OUT("on abort 1"); } TX_FINALLY { UT_OUT("finally 1"); } TX_END UT_OUT("end of tx 1\n"); memset(f, 0, sizeof(*f)); UT_ASSERTeq(freed, 1); freed = 0; TX_BEGIN_CB(pop, free_onabort, f) { allocate_pmem(f, root, 7); } TX_ONCOMMIT { UT_OUT("on commit 2"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("finally 2"); } TX_END UT_OUT("end of tx 2\n"); memset(f, 0, sizeof(*f)); UT_ASSERTeq(freed, 0); TX_BEGIN_CB(pop, free_oncommit, f) { free_pmem(f, root); do_something_fishy(root); UT_ASSERT(0); } TX_ONCOMMIT { UT_ASSERT(0); } TX_ONABORT { UT_OUT("on abort 3"); } TX_FINALLY { UT_OUT("finally 3"); } TX_END UT_OUT("end of tx 3\n"); memset(f, 0, sizeof(*f)); UT_ASSERTeq(freed, 0); TX_BEGIN_CB(pop, free_oncommit, f) { free_pmem(f, root); } TX_ONCOMMIT { UT_OUT("on commit 4"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("finally 4"); } TX_END UT_OUT("end of tx 4\n"); memset(f, 0, sizeof(*f)); UT_ASSERTeq(freed, 1); freed = 0; TX_BEGIN_CB(pop, log_stages, NULL) { TX_BEGIN(pop) { UT_OUT("inner tx work 5"); } TX_ONCOMMIT { UT_OUT("inner tx on commit 5"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("inner tx finally 5"); } TX_END } TX_ONCOMMIT { UT_OUT("on commit 5"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("finally 5"); } TX_END UT_OUT("end of tx 5\n"); TX_BEGIN(pop) { TX_BEGIN_CB(pop, log_stages, NULL) { UT_OUT("inner tx work 6"); } TX_ONCOMMIT { UT_OUT("inner tx on commit 6"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("inner tx finally 6"); } TX_END } TX_ONCOMMIT { UT_OUT("on commit 6"); } TX_ONABORT { UT_ASSERT(0); } TX_FINALLY { UT_OUT("finally 6"); } TX_END UT_OUT("end of tx 6\n"); UT_OUT("start of tx 7"); if (pmemobj_tx_begin(pop, NULL, TX_PARAM_CB, log_stages, NULL, TX_PARAM_NONE)) UT_FATAL("!pmemobj_tx_begin"); UT_OUT("work"); pmemobj_tx_commit(); UT_OUT("on commit"); if (pmemobj_tx_end()) UT_FATAL("!pmemobj_tx_end"); UT_OUT("end of tx 7\n"); FREE(f); } int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_callbacks"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (!pop) UT_FATAL("!pmemobj_create"); TOID(struct pmem_root) root = POBJ_ROOT(pop, struct pmem_root); test(pop, root); pmemobj_close(pop); DONE(NULL); } pmdk-1.11.1/src/test/obj_tx_callbacks/TEST00000775000000000000000000000050214123364546017052 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_callbacks/TEST0 -- unit test for transaction stage callbacks # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_tx_callbacks$EXESUFFIX $DIR/testfile1 check pass pmdk-1.11.1/src/test/obj_tx_callbacks/Makefile0000664000000000000000000000037214123364546017732 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_callbacks/Makefile -- build obj_tx_callbacks unit test # TARGET = obj_tx_callbacks OBJS = obj_tx_callbacks.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_tx_callbacks/out0.log.match0000664000000000000000000000225414123364546020760 0ustar rootrootobj_tx_callbacks$(nW)TEST0: START: obj_tx_callbacks $(nW)obj_tx_callbacks$(nW) $(nW)testfile1 cb stage: TX_STAGE_ONABORT rt_onabort: free on abort 1 cb stage: TX_STAGE_FINALLY finally 1 cb stage: TX_STAGE_NONE end of tx 1 cb stage: TX_STAGE_WORK cb stage: TX_STAGE_ONCOMMIT on commit 2 cb stage: TX_STAGE_FINALLY finally 2 cb stage: TX_STAGE_NONE end of tx 2 cb stage: TX_STAGE_ONABORT on abort 3 cb stage: TX_STAGE_FINALLY finally 3 cb stage: TX_STAGE_NONE end of tx 3 cb stage: TX_STAGE_WORK cb stage: TX_STAGE_ONCOMMIT rt_oncommit: free on commit 4 cb stage: TX_STAGE_FINALLY finally 4 cb stage: TX_STAGE_NONE end of tx 4 inner tx work 5 inner tx on commit 5 inner tx finally 5 cb stage: TX_STAGE_WORK cb stage: TX_STAGE_ONCOMMIT on commit 5 cb stage: TX_STAGE_FINALLY finally 5 cb stage: TX_STAGE_NONE end of tx 5 inner tx work 6 inner tx on commit 6 inner tx finally 6 cb stage: TX_STAGE_WORK cb stage: TX_STAGE_ONCOMMIT on commit 6 cb stage: TX_STAGE_FINALLY finally 6 cb stage: TX_STAGE_NONE end of tx 6 start of tx 7 work cb stage: TX_STAGE_WORK cb stage: TX_STAGE_ONCOMMIT on commit cb stage: TX_STAGE_FINALLY cb stage: TX_STAGE_NONE end of tx 7 obj_tx_callbacks$(nW)TEST0: DONE pmdk-1.11.1/src/test/obj_tx_callbacks/obj_tx_callbacks.vcxproj.filters0000664000000000000000000000156314123364546024645 0ustar rootroot {8d33c409-5e43-4520-9323-670f4ba5e6a6} {3f330111-6e5c-4f55-85a1-70be1bf2f951} {c35d1775-c11b-48f7-8daf-cd01903a11a5} Match Files Test Scripts Source Files pmdk-1.11.1/src/test/obj_tx_callbacks/TEST0.PS10000664000000000000000000000047614123364546017463 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_tx_callbacks/TEST0 -- unit test for transaction stage callbacks # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $ENV:EXE_DIR\obj_tx_callbacks$Env:EXESUFFIX $DIR\testfile1 check pass pmdk-1.11.1/src/test/obj_tx_callbacks/.gitignore0000664000000000000000000000002114123364546020251 0ustar rootrootobj_tx_callbacks pmdk-1.11.1/src/test/obj_tx_callbacks/obj_tx_callbacks.vcxproj0000664000000000000000000000760314123364546023177 0ustar rootroot Debug x64 Release x64 {0529575C-F6E8-44FD-BB82-82A29948D0F2} Win32Proj obj_tx_callbacks 10.0.17134.0 Application true v140 Application false v140 true NotSet $(SolutionDir)\common;$(SolutionDir)\test\unittest;$(SolutionDir)\windows\include;$(SolutionDir)\include;$(SolutionDir)\libpmemobj;$(IncludePath) Disabled CompileAsCpp CompileAsCpp {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/ex_librpmem_manpage/0000775000000000000000000000000014123364546016777 5ustar rootrootpmdk-1.11.1/src/test/ex_librpmem_manpage/TEST00000775000000000000000000000122514123364546017564 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ex_librpmem_manpage/TEST0 -- manpage example unittest # . ../unittest/unittest.sh require_test_type short require_nodes 2 require_node_libfabric 0 $RPMEM_PROVIDER require_node_libfabric 1 $RPMEM_PROVIDER setup init_rpmem_on_node 1 0 POOLSET=pool.set TEST_FILE_REMOTE="testfile_remote" create_poolset $DIR/$POOLSET \ 32M:${NODE_DIR[0]}/$TEST_FILE_REMOTE:x copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$POOLSET rm_files_from_node 0 ${NODE_DIR[0]}$TEST_FILE_REMOTE expect_normal_exit run_on_node 1 ./manpage ${NODE_ADDR[0]} $POOLSET check pass pmdk-1.11.1/src/test/ex_librpmem_manpage/Makefile0000664000000000000000000000051514123364546020440 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/ex_librpmem_manpage/Makefile -- build manpage librpmem example # unittest # include ../../common.inc ifeq ($(BUILD_RPMEM), y) SCP_TO_REMOTE_NODES = y SCP_TARGET = manpage SCP_SRC_DIR = ../../examples/librpmem endif include ../Makefile.inc pmdk-1.11.1/src/test/ex_librpmem_manpage/config.sh0000664000000000000000000000062414123364546020602 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # # ex_librpmem_manpage/config.sh -- test configuration # # Filesystem-DAX cannot be used for RDMA # since it is missing support in Linux kernel CONF_GLOBAL_FS_TYPE=non-pmem CONF_GLOBAL_BUILD_TYPE="debug nondebug" CONF_GLOBAL_TEST_TYPE=short CONF_GLOBAL_RPMEM_PROVIDER=all CONF_GLOBAL_RPMEM_PMETHOD=all pmdk-1.11.1/src/test/rpmem_proto/0000775000000000000000000000000014123364546015347 5ustar rootrootpmdk-1.11.1/src/test/rpmem_proto/rpmem_proto.c0000664000000000000000000001314514123364546020062 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2016-2018, Intel Corporation */ /* * rpmem_proto.c -- unit test for rpmem_proto header * * The purpose of this test is to make sure the structures which describe * rpmem protocol messages does not have any padding. */ #include "unittest.h" #include "librpmem.h" #include "rpmem_proto.h" int main(int argc, char *argv[]) { START(argc, argv, "rpmem_proto"); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_hdr, type); ASSERT_ALIGNED_FIELD(struct rpmem_msg_hdr, size); ASSERT_ALIGNED_CHECK(struct rpmem_msg_hdr); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_hdr_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_hdr_resp, status); ASSERT_ALIGNED_FIELD(struct rpmem_msg_hdr_resp, type); ASSERT_ALIGNED_FIELD(struct rpmem_msg_hdr_resp, size); ASSERT_ALIGNED_CHECK(struct rpmem_msg_hdr_resp); ASSERT_ALIGNED_BEGIN(struct rpmem_pool_attr); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, signature); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, major); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, compat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, incompat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, ro_compat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, poolset_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, next_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, prev_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr, user_flags); ASSERT_ALIGNED_CHECK(struct rpmem_pool_attr); ASSERT_ALIGNED_BEGIN(struct rpmem_pool_attr_packed); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, signature); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, major); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, compat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, incompat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, ro_compat_features); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, poolset_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, next_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, prev_uuid); ASSERT_ALIGNED_FIELD(struct rpmem_pool_attr_packed, user_flags); ASSERT_ALIGNED_CHECK(struct rpmem_pool_attr_packed); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_ibc_attr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_ibc_attr, port); ASSERT_ALIGNED_FIELD(struct rpmem_msg_ibc_attr, persist_method); ASSERT_ALIGNED_FIELD(struct rpmem_msg_ibc_attr, rkey); ASSERT_ALIGNED_FIELD(struct rpmem_msg_ibc_attr, raddr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_ibc_attr, nlanes); ASSERT_ALIGNED_CHECK(struct rpmem_msg_ibc_attr); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_common); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, major); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, minor); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, pool_size); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, nlanes); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, provider); ASSERT_ALIGNED_FIELD(struct rpmem_msg_common, buff_size); ASSERT_ALIGNED_CHECK(struct rpmem_msg_common); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_pool_desc); ASSERT_ALIGNED_FIELD(struct rpmem_msg_pool_desc, size); ASSERT_ALIGNED_CHECK(struct rpmem_msg_pool_desc); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_create); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create, c); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create, pool_attr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create, pool_desc); ASSERT_ALIGNED_CHECK(struct rpmem_msg_create); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_create_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create_resp, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_create_resp, ibc); ASSERT_ALIGNED_CHECK(struct rpmem_msg_create_resp); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_open); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open, c); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open, pool_desc); ASSERT_ALIGNED_CHECK(struct rpmem_msg_open); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_open_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open_resp, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open_resp, ibc); ASSERT_ALIGNED_FIELD(struct rpmem_msg_open_resp, pool_attr); ASSERT_ALIGNED_CHECK(struct rpmem_msg_open_resp); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_close); ASSERT_ALIGNED_FIELD(struct rpmem_msg_close, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_close, flags); ASSERT_ALIGNED_CHECK(struct rpmem_msg_close); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_close_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_close_resp, hdr); ASSERT_ALIGNED_CHECK(struct rpmem_msg_close_resp); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_persist); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist, flags); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist, lane); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist, addr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist, size); ASSERT_ALIGNED_CHECK(struct rpmem_msg_persist); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_persist_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist_resp, flags); ASSERT_ALIGNED_FIELD(struct rpmem_msg_persist_resp, lane); ASSERT_ALIGNED_CHECK(struct rpmem_msg_persist_resp); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_set_attr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_set_attr, hdr); ASSERT_ALIGNED_FIELD(struct rpmem_msg_set_attr, pool_attr); ASSERT_ALIGNED_CHECK(struct rpmem_msg_set_attr); ASSERT_ALIGNED_BEGIN(struct rpmem_msg_set_attr_resp); ASSERT_ALIGNED_FIELD(struct rpmem_msg_set_attr_resp, hdr); ASSERT_ALIGNED_CHECK(struct rpmem_msg_set_attr_resp); DONE(NULL); } pmdk-1.11.1/src/test/rpmem_proto/TEST00000775000000000000000000000050014123364546016127 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/rpmem_obc/TEST0 -- unit test for rpmem_proto.h # . ../unittest/unittest.sh require_test_type medium require_build_type debug require_fs_type none setup expect_normal_exit ./rpmem_proto$EXESUFFIX pass pmdk-1.11.1/src/test/rpmem_proto/Makefile0000664000000000000000000000043314123364546017007 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016, Intel Corporation # # src/test/rpmem_proto/Makefile -- build rpmem_proto test # TARGET = rpmem_proto OBJS = rpmem_proto.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n include ../Makefile.inc INCS += -I../../rpmem_common pmdk-1.11.1/src/test/rpmem_proto/.gitignore0000664000000000000000000000001414123364546017332 0ustar rootrootrpmem_proto pmdk-1.11.1/src/test/obj_memcheck/0000775000000000000000000000000014123364546015412 5ustar rootrootpmdk-1.11.1/src/test/obj_memcheck/memcheck0.log.match0000664000000000000000000001531014123364546021044 0ustar rootroot==$(N)== Memcheck, a memory error detector ==$(N)== Copyright $(*) ==$(N)== Using $(*) ==$(N)== Command: $(*) ==$(N)== Parent PID: $(N) ==$(N)== ==$(N)== Conditional jump or move depends on uninitialised value(s) ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) ==$(N)== Address 0x$(X) is $(N) bytes inside a block of size $(N) free'd $(OPT)==$(N)== $(S) 0x$(X): ${palloc_heap_action_on_process|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_exec_actions|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_free|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_free $(*) ==$(N)== by 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== $(S) 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_alloc_construct|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_alloc $(*) $(OPT)==$(N)== $(S) 0x$(X): test_everything $(*) $(OPT)==$(N)== $(S) 0x$(X): main $(*) ==$(N)== ==$(N)== Unaddressable byte(s) found during client check request ==$(N)== at 0x$(X): pmem_msync $(*) $(OPT)==$(N)== by 0x$(X): ${obj_msync_nofail|???} $(*) $(OPT)==$(N)== by 0x$(X): ${obj_norep_persist|???} $(*) $(OPT)==$(N)== by 0x$(X): UnknownInlinedFun $(*) $(OPT)==$(N)== by 0x$(X): ${pmemops_xpersist|???} $(*) $(OPT)==$(N)== by 0x$(X): UnknownInlinedFun $(*) $(OPT)==$(N)== by 0x$(X): ${pmemops_persist|???} $(*) $(OPT)==$(N)== by 0x$(X): pmemobj_persist $(*) ==$(N)== by 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) ==$(N)== Address 0x$(X) is 0 bytes inside a block of size $(N) free'd $(OPT)==$(N)== $(S) 0x$(X): ${palloc_heap_action_on_process|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_exec_actions|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_free|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_free $(*) ==$(N)== by 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== $(S) 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_alloc_construct|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_alloc $(*) $(OPT)==$(N)== $(S) 0x$(X): test_everything $(*) $(OPT)==$(N)== $(S) 0x$(X): main $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Address 0x$(X) is not stack'd, malloc'd or (recently) free'd $(OPT)==$(N)== Address 0x$(X) is in a rw- mapped file $(nW) segment ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Address 0x$(X) is not stack'd, malloc'd or (recently) free'd $(OPT)==$(N)== Address 0x$(X) is in a rw- mapped file $(nW) segment ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) ==$(N)== Address 0x$(X) is $(N) bytes inside a block of size $(N) free'd $(OPT)==$(N)== $(S) 0x$(X): ${palloc_heap_action_on_process|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_exec_actions|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_free|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_free $(*) ==$(N)== by 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== $(S) 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_realloc_common|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_realloc $(*) $(OPT)==$(N)== $(S) 0x$(X): test_everything $(*) $(OPT)==$(N)== $(S) 0x$(X): main $(*) ==$(N)== ==$(N)== Invalid write of size 4 ==$(N)== at 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) ==$(N)== Address 0x$(X) is $(N) bytes inside a block of size $(N) free'd $(OPT)==$(N)== $(S) 0x$(X): ${palloc_heap_action_on_process|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_exec_actions|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_free|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_free $(*) ==$(N)== by 0x$(X): test_everything ($(*)obj_memcheck$(*)) ==$(N)== by 0x$(X): main ($(*)obj_memcheck$(*)) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== $(S) 0x$(X): ${alloc_prep_block|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_reservation_create|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${palloc_operation|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): ${obj_realloc_common|???} $(*) $(OPT)==$(N)== $(S) 0x$(X): pmemobj_realloc $(*) $(OPT)==$(N)== $(S) 0x$(X): test_everything $(*) $(OPT)==$(N)== $(S) 0x$(X): main $(*) $(OPT)==$(N)== $(OPT)==$(N)== Invalid write of size $(N) $(OPT)==$(N)== at 0x$(X): test_memcheck_bug2 $(*) $(OPT)==$(N)== by 0x$(X): main $(*) $(OPT)==$(N)== Address 0x$(X) is $(N) bytes after a block of size $(N) free'd $(OPT)==$(N)== at 0x$(X): test_memcheck_bug2 $(*) $(OPT)==$(N)== by 0x$(X): main $(*) $(OPT)==$(N)== Block was alloc'd at $(OPT)==$(N)== at 0x$(X): test_memcheck_bug2 $(*) $(OPT)==$(N)== by 0x$(X): main $(*) ==$(N)== ==$(N)== ==$(N)== HEAP SUMMARY: ==$(N)== in use at exit: $(NC) bytes in $(N) blocks ==$(N)== total heap usage: $(NC) allocs, $(NC) frees, $(NC) bytes allocated ==$(N)== $(OPT)==$(N)== All heap blocks were freed -- no leaks are possible $(OPX)==$(N)== LEAK SUMMARY: $(OPT)==$(N)== definitely lost: 0 bytes in 0 blocks $(OPT)==$(N)== indirectly lost: 0 bytes in 0 blocks $(OPT)==$(N)== possibly lost: 0 bytes in 0 blocks $(OPT)==$(N)== still reachable: 0 bytes in 0 blocks $(OPT)==$(N)== suppressed: $(NC) bytes in $(N) blocks ==$(N)== ==$(N)== Use --track-origins=yes to see where uninitialised values come from ==$(N)== ERROR SUMMARY: 10 errors from 8 contexts (suppressed: $(N) from $(N)) pmdk-1.11.1/src/test/obj_memcheck/TEST00000775000000000000000000000164714123364546016207 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_memcheck/TEST0 -- unit test for obj_memcheck # . ../unittest/unittest.sh require_test_type medium require_fs_type non-pmem # Valgrind merges errors which have the same last 4 stack frames. With non-debug # builds the depth of the stack trace depends on how much compiler optimized it. # So always use debug build to take a compiler out of the picture and get # deterministic stack traces. require_build_type debug require_valgrind 3.10 configure_valgrind memcheck force-enable setup export PMEMOBJ_VG_CHECK_UNDEF=1 export VALIDATE_VALGRIND_LOG=0 export VALGRIND_OPTS="$VALGRIND_OPTS --show-reachable=yes" if ! eval $TRACE valgrind ./obj_memcheck$EXESUFFIX m 2>/dev/null; then echo "$UNITTEST_NAME: SKIP valgrind with bug" exit 0 fi expect_normal_exit ./obj_memcheck$EXESUFFIX t $DIR/testfile check pass pmdk-1.11.1/src/test/obj_memcheck/Makefile0000664000000000000000000000035314123364546017053 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_memcheck/Makefile -- build obj_memcheck unit test # TARGET = obj_memcheck OBJS = obj_memcheck.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_memcheck/obj_memcheck.c0000664000000000000000000000700714123364546020170 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2018, Intel Corporation */ #include "unittest.h" #include "valgrind_internal.h" /* * Layout definition */ POBJ_LAYOUT_BEGIN(mc); POBJ_LAYOUT_ROOT(mc, struct root); POBJ_LAYOUT_TOID(mc, struct struct1); POBJ_LAYOUT_END(mc); struct struct1 { int fld; int dyn[]; }; struct root { TOID(struct struct1) s1; TOID(struct struct1) s2; }; static void test_memcheck_bug(void) { #if VG_MEMCHECK_ENABLED volatile char tmp[100]; VALGRIND_CREATE_MEMPOOL(tmp, 0, 0); VALGRIND_MEMPOOL_ALLOC(tmp, tmp + 8, 16); VALGRIND_MEMPOOL_FREE(tmp, tmp + 8); VALGRIND_MEMPOOL_ALLOC(tmp, tmp + 8, 16); VALGRIND_MAKE_MEM_NOACCESS(tmp, 8); tmp[7] = 0x66; #endif } static void test_memcheck_bug2(void) { #if VG_MEMCHECK_ENABLED volatile char tmp[1000]; VALGRIND_CREATE_MEMPOOL(tmp, 0, 0); VALGRIND_MEMPOOL_ALLOC(tmp, tmp + 128, 128); VALGRIND_MEMPOOL_FREE(tmp, tmp + 128); VALGRIND_MEMPOOL_ALLOC(tmp, tmp + 256, 128); VALGRIND_MEMPOOL_FREE(tmp, tmp + 256); /* * This should produce warning: * Address ... is 0 bytes inside a block of size 128 bytes freed. * instead, it produces a warning: * Address ... is 0 bytes after a block of size 128 freed */ int *data = (int *)(tmp + 256); *data = 0x66; #endif } static void test_everything(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(mc), PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); struct root *rt = D_RW(POBJ_ROOT(pop, struct root)); POBJ_ALLOC(pop, &rt->s1, struct struct1, sizeof(struct struct1), NULL, NULL); struct struct1 *s1 = D_RW(rt->s1); struct struct1 *s2; POBJ_ALLOC(pop, &rt->s2, struct struct1, sizeof(struct struct1), NULL, NULL); s2 = D_RW(rt->s2); POBJ_FREE(&rt->s2); /* read of uninitialized variable */ if (s1->fld) UT_OUT("%d", 1); /* write to freed object */ s2->fld = 7; pmemobj_persist(pop, s2, sizeof(*s2)); POBJ_ALLOC(pop, &rt->s2, struct struct1, sizeof(struct struct1), NULL, NULL); s2 = D_RW(rt->s2); memset(s2, 0, pmemobj_alloc_usable_size(rt->s2.oid)); s2->fld = 12; /* ok */ /* invalid write */ s2->dyn[100000] = 9; /* invalid write */ s2->dyn[1000] = 9; pmemobj_persist(pop, s2, sizeof(struct struct1)); POBJ_REALLOC(pop, &rt->s2, struct struct1, sizeof(struct struct1) + 100 * sizeof(int)); s2 = D_RW(rt->s2); s2->dyn[0] = 9; /* ok */ pmemobj_persist(pop, s2, sizeof(struct struct1) + 100 * sizeof(int)); POBJ_FREE(&rt->s2); /* invalid write to REALLOCated and FREEd object */ s2->dyn[0] = 9; pmemobj_persist(pop, s2, sizeof(struct struct1) + 100 * sizeof(int)); POBJ_ALLOC(pop, &rt->s2, struct struct1, sizeof(struct struct1), NULL, NULL); POBJ_REALLOC(pop, &rt->s2, struct struct1, sizeof(struct struct1) + 30 * sizeof(int)); s2 = D_RW(rt->s2); s2->dyn[0] = 0; s2->dyn[29] = 29; pmemobj_persist(pop, s2, sizeof(struct struct1) + 30 * sizeof(int)); POBJ_FREE(&rt->s2); s2->dyn[0] = 9; pmemobj_persist(pop, s2, sizeof(struct struct1) + 30 * sizeof(int)); pmemobj_close(pop); } static void usage(const char *a) { UT_FATAL("usage: %s [m|t] file-name", a); } int main(int argc, char *argv[]) { START(argc, argv, "obj_memcheck"); /* root doesn't count */ UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(mc) != 1); if (argc < 2) usage(argv[0]); if (strcmp(argv[1], "m") == 0) test_memcheck_bug(); else if (strcmp(argv[1], "t") == 0) { if (argc < 3) usage(argv[0]); test_everything(argv[2]); } else usage(argv[0]); test_memcheck_bug2(); DONE(NULL); } pmdk-1.11.1/src/test/obj_memcheck/.gitignore0000664000000000000000000000001514123364546017376 0ustar rootrootobj_memcheck pmdk-1.11.1/src/test/.gitignore0000664000000000000000000000100114123364546014764 0ustar rootroot# testconfig.sh or testconfig.ps1 should not be checked into git. # It describes the configuration of the local machine where the local copy # of the source tree is being tested. testconfig.sh testconfig.ps1 testconfig.py # ignore files generated during test runs (left around for analysis) *.log testfile* # ignore static binaries generated for testing *.static-debug *.static-nondebug libs.tar *.synced .sync-dir # ignore lock files *.lock # ignore python modules cache __pycache__/ /envconfig.sh /envconfig.py pmdk-1.11.1/src/test/pmem_map_file_trunc/0000775000000000000000000000000014123364546017011 5ustar rootrootpmdk-1.11.1/src/test/pmem_map_file_trunc/pmem_map_file_trunc.vcxproj0000664000000000000000000000655514123364546024446 0ustar rootroot Debug x64 Release x64 {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {34DB4951-DA08-45F1-938D-B08E5FF5AB46} Win32Proj pmem_map_file_trunc 10.0.17134.0 Application true v140 Application false v140 pmdk-1.11.1/src/test/pmem_map_file_trunc/Makefile0000664000000000000000000000040014123364546020443 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem_map_file_trunc/Makefile -- build pmem_map_file() truncation test # TARGET = pmem_map_file_trunc OBJS = pmem_map_file_trunc.o LIBPMEM=y include ../Makefile.inc pmdk-1.11.1/src/test/pmem_map_file_trunc/TESTS.py0000775000000000000000000000047414123364546020275 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation import testframework as t import os @t.require_build(['debug', 'release']) class TEST0(t.Test): test_type = t.Short def run(self, ctx): ctx.exec('pmem_map_file_trunc', os.path.join(ctx.testdir, 'testfile')) pmdk-1.11.1/src/test/pmem_map_file_trunc/.gitignore0000664000000000000000000000002414123364546020775 0ustar rootrootpmem_map_file_trunc pmdk-1.11.1/src/test/pmem_map_file_trunc/pmem_map_file_trunc.c0000664000000000000000000000242614123364546023166 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * pmem_map_file_trunc.c -- test for mapping specially crafted files, * which used to confuse Windows libc to truncate it by 1 byte * * See https://github.com/pmem/pmdk/pull/3728 for full description. * * usage: pmem_map_file_trunc file */ #include "unittest.h" #define EXPECTED_SIZE (4 * 1024) /* * so called "Ctrl-Z" or EOF character * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen */ #define FILL_CHAR 0x1a int main(int argc, char *argv[]) { START(argc, argv, "pmem_map_file_trunc"); if (argc < 2) UT_FATAL("not enough args"); size_t mapped; int ispmem; char *p; os_stat_t st; p = pmem_map_file(argv[1], EXPECTED_SIZE, PMEM_FILE_CREATE, 0644, &mapped, &ispmem); UT_ASSERT(p); UT_ASSERTeq(mapped, EXPECTED_SIZE); p[EXPECTED_SIZE - 1] = FILL_CHAR; pmem_persist(&p[EXPECTED_SIZE - 1], 1); pmem_unmap(p, EXPECTED_SIZE); STAT(argv[1], &st); UT_ASSERTeq(st.st_size, EXPECTED_SIZE); p = pmem_map_file(argv[1], 0, 0, 0644, &mapped, &ispmem); UT_ASSERT(p); UT_ASSERTeq(mapped, EXPECTED_SIZE); UT_ASSERTeq(p[EXPECTED_SIZE - 1], FILL_CHAR); pmem_unmap(p, EXPECTED_SIZE); STAT(argv[1], &st); UT_ASSERTeq(st.st_size, EXPECTED_SIZE); DONE(NULL); } pmdk-1.11.1/src/test/pmem_map_file_trunc/pmem_map_file_trunc.vcxproj.filters0000664000000000000000000000127514123364546026107 0ustar rootroot {189d0bf0-2f10-40d2-9a97-1c627dede493} {c775678f-276b-4eef-a23a-1e2e5e70e6f2} Test Scripts Source Files pmdk-1.11.1/src/test/obj_ctl_alloc_class/0000775000000000000000000000000014123364546016757 5ustar rootrootpmdk-1.11.1/src/test/obj_ctl_alloc_class/obj_ctl_alloc_class.c0000664000000000000000000001726114123364546023105 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2017-2018, Intel Corporation */ /* * obj_ctl_alloc_class.c -- tests for the ctl entry points: heap.alloc_class */ #include #include "unittest.h" #define LAYOUT "obj_ctl_alloc_class" static void basic(const char *path) { PMEMobjpool *pop; if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL * 20, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); int ret; PMEMoid oid; size_t usable_size; struct pobj_alloc_class_desc alloc_class_128; alloc_class_128.header_type = POBJ_HEADER_NONE; alloc_class_128.unit_size = 128; alloc_class_128.units_per_block = 1000; alloc_class_128.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.128.desc", &alloc_class_128); UT_ASSERTeq(ret, 0); struct pobj_alloc_class_desc alloc_class_129; alloc_class_129.header_type = POBJ_HEADER_COMPACT; alloc_class_129.unit_size = 1024; alloc_class_129.units_per_block = 1000; alloc_class_129.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.129.desc", &alloc_class_129); UT_ASSERTeq(ret, 0); struct pobj_alloc_class_desc alloc_class_128_r; ret = pmemobj_ctl_get(pop, "heap.alloc_class.128.desc", &alloc_class_128_r); UT_ASSERTeq(ret, 0); UT_ASSERTeq(alloc_class_128.header_type, alloc_class_128_r.header_type); UT_ASSERTeq(alloc_class_128.unit_size, alloc_class_128_r.unit_size); UT_ASSERT(alloc_class_128.units_per_block <= alloc_class_128_r.units_per_block); /* * One unit from alloc class 128 - 128 bytes unit size, minimal headers. */ ret = pmemobj_xalloc(pop, &oid, 128, 0, POBJ_CLASS_ID(128), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, 128); pmemobj_free(&oid); /* * Reserve as above. */ struct pobj_action act; oid = pmemobj_xreserve(pop, &act, 128, 0, POBJ_CLASS_ID(128)); UT_ASSERT(!OID_IS_NULL(oid)); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, 128); pmemobj_cancel(pop, &act, 1); /* * One unit from alloc class 128 - 128 bytes unit size, minimal headers, * but request size 1 byte. */ ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(128), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, 128); pmemobj_free(&oid); /* * Two units from alloc class 129 - * 1024 bytes unit size, compact headers. */ ret = pmemobj_xalloc(pop, &oid, 1024 + 1, 0, POBJ_CLASS_ID(129), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, (1024 * 2) - 16); /* 2 units minus hdr */ pmemobj_free(&oid); /* * 64 units from alloc class 129 * - 1024 bytes unit size, compact headers. */ ret = pmemobj_xalloc(pop, &oid, (1024 * 64) - 16, 0, POBJ_CLASS_ID(129), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, (1024 * 64) - 16); pmemobj_free(&oid); /* * 65 units from alloc class 129 - * 1024 bytes unit size, compact headers. * Should fail, as it would require two bitmap modifications. */ ret = pmemobj_xalloc(pop, &oid, 1024 * 64 + 1, 0, POBJ_CLASS_ID(129), NULL, NULL); UT_ASSERTeq(ret, -1); /* * Nonexistent alloc class. */ ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(130), NULL, NULL); UT_ASSERTeq(ret, -1); struct pobj_alloc_class_desc alloc_class_new; alloc_class_new.header_type = POBJ_HEADER_NONE; alloc_class_new.unit_size = 777; alloc_class_new.units_per_block = 200; alloc_class_new.class_id = 0; alloc_class_new.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_new); UT_ASSERTeq(ret, 0); struct pobj_alloc_class_desc alloc_class_fail; alloc_class_fail.header_type = POBJ_HEADER_NONE; alloc_class_fail.unit_size = 777; alloc_class_fail.units_per_block = 200; alloc_class_fail.class_id = 0; alloc_class_fail.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_fail); UT_ASSERTeq(ret, -1); ret = pmemobj_ctl_set(pop, "heap.alloc_class.200.desc", &alloc_class_fail); UT_ASSERTeq(ret, -1); ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(alloc_class_new.class_id), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, 777); struct pobj_alloc_class_desc alloc_class_new_huge; alloc_class_new_huge.header_type = POBJ_HEADER_NONE; alloc_class_new_huge.unit_size = (2 << 23); alloc_class_new_huge.units_per_block = 1; alloc_class_new_huge.class_id = 0; alloc_class_new_huge.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_new_huge); UT_ASSERTeq(ret, 0); ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(alloc_class_new_huge.class_id), NULL, NULL); UT_ASSERTeq(ret, 0); usable_size = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(usable_size, (2 << 23)); struct pobj_alloc_class_desc alloc_class_new_max; alloc_class_new_max.header_type = POBJ_HEADER_COMPACT; alloc_class_new_max.unit_size = PMEMOBJ_MAX_ALLOC_SIZE; alloc_class_new_max.units_per_block = 1024; alloc_class_new_max.class_id = 0; alloc_class_new_max.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_new_max); UT_ASSERTeq(ret, 0); ret = pmemobj_xalloc(pop, &oid, 1, 0, POBJ_CLASS_ID(alloc_class_new_max.class_id), NULL, NULL); UT_ASSERTne(ret, 0); struct pobj_alloc_class_desc alloc_class_new_loop; alloc_class_new_loop.header_type = POBJ_HEADER_COMPACT; alloc_class_new_loop.unit_size = 16384; alloc_class_new_loop.units_per_block = 63; alloc_class_new_loop.class_id = 0; alloc_class_new_loop.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_new_loop); UT_ASSERTeq(ret, 0); size_t s = (63 * 16384) - 16; ret = pmemobj_xalloc(pop, &oid, s + 1, 0, POBJ_CLASS_ID(alloc_class_new_loop.class_id), NULL, NULL); UT_ASSERTne(ret, 0); struct pobj_alloc_class_desc alloc_class_tiny; alloc_class_tiny.header_type = POBJ_HEADER_NONE; alloc_class_tiny.unit_size = 7; alloc_class_tiny.units_per_block = 1; alloc_class_tiny.class_id = 0; alloc_class_tiny.alignment = 0; ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_tiny); UT_ASSERTeq(ret, 0); UT_ASSERT(alloc_class_tiny.units_per_block > 1); for (int i = 0; i < 1000; ++i) { ret = pmemobj_xalloc(pop, &oid, 7, 0, POBJ_CLASS_ID(alloc_class_tiny.class_id), NULL, NULL); UT_ASSERTeq(ret, 0); } pmemobj_close(pop); } static void many(const char *path) { PMEMobjpool *pop; if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); unsigned nunits = UINT16_MAX + 1; struct pobj_alloc_class_desc alloc_class_tiny; alloc_class_tiny.header_type = POBJ_HEADER_NONE; alloc_class_tiny.unit_size = 8; alloc_class_tiny.units_per_block = nunits; alloc_class_tiny.class_id = 0; alloc_class_tiny.alignment = 0; int ret = pmemobj_ctl_set(pop, "heap.alloc_class.new.desc", &alloc_class_tiny); UT_ASSERTeq(ret, 0); PMEMoid oid; uint64_t *counterp = NULL; for (size_t i = 0; i < nunits; ++i) { pmemobj_xalloc(pop, &oid, 8, 0, POBJ_CLASS_ID(alloc_class_tiny.class_id), NULL, NULL); counterp = pmemobj_direct(oid); (*counterp)++; /* * This works only because this is a fresh pool in a new file * and so the counter must be initially zero. * This might have to be fixed if that ever changes. */ UT_ASSERTeq(*counterp, 1); } pmemobj_close(pop); } int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_alloc_class"); if (argc != 3) UT_FATAL("usage: %s file-name b|m", argv[0]); const char *path = argv[1]; if (argv[2][0] == 'b') basic(path); else if (argv[2][0] == 'm') many(path); DONE(NULL); } pmdk-1.11.1/src/test/obj_ctl_alloc_class/obj_ctl_alloc_class.vcxproj.filters0000664000000000000000000000141014123364546026012 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {43b16ba6-eb2f-4083-9f90-76ecc299c720} ps1 Source Files Test Files pmdk-1.11.1/src/test/obj_ctl_alloc_class/TEST00000775000000000000000000000042714123364546017547 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation . ../unittest/unittest.sh require_test_type short require_fs_type any require_build_type debug setup expect_normal_exit ./obj_ctl_alloc_class$EXESUFFIX $DIR/testfile b pass pmdk-1.11.1/src/test/obj_ctl_alloc_class/Makefile0000664000000000000000000000040114123364546020412 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2016-2019, Intel Corporation # # src/test/obj_ctl_alloc_class/Makefile -- build obj_ctl_alloc_class test # TARGET = obj_ctl_alloc_class OBJS = obj_ctl_alloc_class.o LIBPMEMOBJ=y include ../Makefile.inc pmdk-1.11.1/src/test/obj_ctl_alloc_class/TEST0.PS10000664000000000000000000000042514123364546020144 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2018-2019, Intel Corporation . ..\unittest\unittest.ps1 require_test_type short require_fs_type any require_build_type debug setup expect_normal_exit ` $Env:EXE_DIR\obj_ctl_alloc_class$Env:EXESUFFIX $DIR\testfile b pass pmdk-1.11.1/src/test/obj_ctl_alloc_class/.gitignore0000664000000000000000000000002414123364546020743 0ustar rootrootobj_ctl_alloc_class pmdk-1.11.1/src/test/obj_ctl_alloc_class/obj_ctl_alloc_class.vcxproj0000664000000000000000000000707614123364546024361 0ustar rootroot Debug x64 Release x64 {E07C9A5F-B2E4-44FB-AA87-FBC885AC955D} Win32Proj obj_ctl_alloc_class 10.0.17134.0 Application true v140 Application false v140 true Disabled MaxSpeed {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} pmdk-1.11.1/src/test/obj_heap/0000775000000000000000000000000014123364546014553 5ustar rootrootpmdk-1.11.1/src/test/obj_heap/obj_heap.vcxproj0000664000000000000000000001113514123364546017740 0ustar rootroot Debug x64 Release x64 {492baa3d-0d5d-478e-9765-500463ae69aa} {1baa1617-93ae-4196-8a1a-bd492fb18aef} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {85D4076B-896B-4EBB-8F3A-8B44C24CD452} Win32Proj obj_heap 10.0.17134.0 Application true v140 Application false v140 NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) NotUsing $(SolutionDir)\libpmemobj;%(AdditionalIncludeDirectories) pmdk-1.11.1/src/test/obj_heap/TEST00000775000000000000000000000042514123364546015341 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_heap/TEST0 -- unit test for obj_heap interface # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_heap$EXESUFFIX t pass pmdk-1.11.1/src/test/obj_heap/Makefile0000664000000000000000000000042114123364546016210 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_heap/Makefile -- build heap unit test # TARGET = obj_heap OBJS = obj_heap.o LIBPMEMOBJ=internal-debug include ../Makefile.inc LDFLAGS += $(call extract_funcs, obj_heap.c) pmdk-1.11.1/src/test/obj_heap/TEST0.PS10000664000000000000000000000042114123364546015734 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/obj_heap/TEST0 -- unit test for obj_heap interface # . ..\unittest\unittest.ps1 require_test_type medium setup expect_normal_exit $Env:EXE_DIR\obj_heap$Env:EXESUFFIX t pass pmdk-1.11.1/src/test/obj_heap/obj_heap.c0000664000000000000000000004102514123364546016470 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2020, Intel Corporation */ /* * obj_heap.c -- unit test for heap * * operations are: 't', 'b', 'r', 'c', 'h', 'a', 'n', 's' * t: do test_heap, test_recycler * b: do fault_injection in function container_new_ravl * r: do fault_injection in function recycler_new * c: do fault_injection in function container_new_seglists * h: do fault_injection in function heap_boot * a: do fault_injection in function alloc_class_new * n: do fault_injection in function alloc_class_collection_new * s: do fault_injection in function stats_new */ #include "libpmemobj.h" #include "palloc.h" #include "heap.h" #include "recycler.h" #include "obj.h" #include "unittest.h" #include "util.h" #include "container_ravl.h" #include "container_seglists.h" #include "container.h" #include "alloc_class.h" #include "valgrind_internal.h" #include "set.h" #define MOCK_POOL_SIZE PMEMOBJ_MIN_POOL #define MAX_BLOCKS 3 struct mock_pop { PMEMobjpool p; void *heap; }; static int obj_heap_persist(void *ctx, const void *ptr, size_t sz, unsigned flags) { UT_ASSERTeq(pmem_msync(ptr, sz), 0); return 0; } static int obj_heap_flush(void *ctx, const void *ptr, size_t sz, unsigned flags) { UT_ASSERTeq(pmem_msync(ptr, sz), 0); return 0; } static void obj_heap_drain(void *ctx) { } static void * obj_heap_memset(void *ctx, void *ptr, int c, size_t sz, unsigned flags) { memset(ptr, c, sz); UT_ASSERTeq(pmem_msync(ptr, sz), 0); return ptr; } static void init_run_with_score(struct heap_layout *l, uint32_t chunk_id, int score) { l->zone0.chunk_headers[chunk_id].size_idx = 1; l->zone0.chunk_headers[chunk_id].type = CHUNK_TYPE_RUN; l->zone0.chunk_headers[chunk_id].flags = 0; struct chunk_run *run = (struct chunk_run *) &l->zone0.chunks[chunk_id]; VALGRIND_DO_MAKE_MEM_UNDEFINED(run, sizeof(*run)); run->hdr.alignment = 0; run->hdr.block_size = 1024; memset(run->content, 0xFF, RUN_DEFAULT_BITMAP_SIZE); UT_ASSERTeq(score % 64, 0); score /= 64; uint64_t *bitmap = (uint64_t *)run->content; for (; score >= 0; --score) { bitmap[score] = 0; } } static void init_run_with_max_block(struct heap_layout *l, uint32_t chunk_id) { l->zone0.chunk_headers[chunk_id].size_idx = 1; l->zone0.chunk_headers[chunk_id].type = CHUNK_TYPE_RUN; l->zone0.chunk_headers[chunk_id].flags = 0; struct chunk_run *run = (struct chunk_run *) &l->zone0.chunks[chunk_id]; VALGRIND_DO_MAKE_MEM_UNDEFINED(run, sizeof(*run)); uint64_t *bitmap = (uint64_t *)run->content; run->hdr.block_size = 1024; run->hdr.alignment = 0; memset(bitmap, 0xFF, RUN_DEFAULT_BITMAP_SIZE); /* the biggest block is 10 bits */ bitmap[3] = 0b1000001110111000111111110000111111000000000011111111110000000011; } static void test_container(struct block_container *bc, struct palloc_heap *heap) { UT_ASSERTne(bc, NULL); struct memory_block a = {1, 0, 1, 4}; struct memory_block b = {1, 0, 2, 8}; struct memory_block c = {1, 0, 3, 16}; struct memory_block d = {1, 0, 5, 32}; init_run_with_score(heap->layout, 1, 128); memblock_rebuild_state(heap, &a); memblock_rebuild_state(heap, &b); memblock_rebuild_state(heap, &c); memblock_rebuild_state(heap, &d); int ret; ret = bc->c_ops->insert(bc, &a); UT_ASSERTeq(ret, 0); ret = bc->c_ops->insert(bc, &b); UT_ASSERTeq(ret, 0); ret = bc->c_ops->insert(bc, &c); UT_ASSERTeq(ret, 0); ret = bc->c_ops->insert(bc, &d); UT_ASSERTeq(ret, 0); struct memory_block invalid_ret = {0, 0, 6, 0}; ret = bc->c_ops->get_rm_bestfit(bc, &invalid_ret); UT_ASSERTeq(ret, ENOMEM); struct memory_block b_ret = {0, 0, 2, 0}; ret = bc->c_ops->get_rm_bestfit(bc, &b_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(b_ret.chunk_id, b.chunk_id); struct memory_block a_ret = {0, 0, 1, 0}; ret = bc->c_ops->get_rm_bestfit(bc, &a_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(a_ret.chunk_id, a.chunk_id); struct memory_block c_ret = {0, 0, 3, 0}; ret = bc->c_ops->get_rm_bestfit(bc, &c_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(c_ret.chunk_id, c.chunk_id); struct memory_block d_ret = {0, 0, 4, 0}; /* less one than target */ ret = bc->c_ops->get_rm_bestfit(bc, &d_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(d_ret.chunk_id, d.chunk_id); ret = bc->c_ops->get_rm_bestfit(bc, &c_ret); UT_ASSERTeq(ret, ENOMEM); ret = bc->c_ops->insert(bc, &a); UT_ASSERTeq(ret, 0); ret = bc->c_ops->insert(bc, &b); UT_ASSERTeq(ret, 0); ret = bc->c_ops->insert(bc, &c); UT_ASSERTeq(ret, 0); bc->c_ops->rm_all(bc); ret = bc->c_ops->is_empty(bc); UT_ASSERTeq(ret, 1); ret = bc->c_ops->get_rm_bestfit(bc, &c_ret); UT_ASSERTeq(ret, ENOMEM); bc->c_ops->destroy(bc); } static void do_fault_injection_new_ravl() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "container_new_ravl"); struct block_container *bc = container_new_ravl(NULL); UT_ASSERTeq(bc, NULL); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_new_seglists() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "container_new_seglists"); struct block_container *bc = container_new_seglists(NULL); UT_ASSERTeq(bc, NULL); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_heap_boot() { if (!pmemobj_fault_injection_enabled()) return; struct mock_pop *mpop = MMAP_ANON_ALIGNED(MOCK_POOL_SIZE, Ut_mmap_align); PMEMobjpool *pop = &mpop->p; pop->p_ops.persist = obj_heap_persist; uint64_t heap_size = MOCK_POOL_SIZE - sizeof(PMEMobjpool); struct pmem_ops *p_ops = &pop->p_ops; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "heap_boot"); int r = heap_boot(NULL, NULL, heap_size, &pop->heap_size, NULL, p_ops, NULL, NULL); UT_ASSERTne(r, 0); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_recycler() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "recycler_new"); size_t active_arenas = 1; struct recycler *r = recycler_new(NULL, 0, &active_arenas); UT_ASSERTeq(r, NULL); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_class_new(int i) { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, i, "alloc_class_new"); struct alloc_class_collection *c = alloc_class_collection_new(); UT_ASSERTeq(c, NULL); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_class_collection_new() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "alloc_class_collection_new"); struct alloc_class_collection *c = alloc_class_collection_new(); UT_ASSERTeq(c, NULL); UT_ASSERTeq(errno, ENOMEM); } static void do_fault_injection_stats() { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "stats_new"); struct stats *s = stats_new(NULL); UT_ASSERTeq(s, NULL); UT_ASSERTeq(errno, ENOMEM); } static void test_heap(void) { struct mock_pop *mpop = MMAP_ANON_ALIGNED(MOCK_POOL_SIZE, Ut_mmap_align); PMEMobjpool *pop = &mpop->p; memset(pop, 0, MOCK_POOL_SIZE); pop->heap_offset = (uint64_t)((uint64_t)&mpop->heap - (uint64_t)mpop); pop->p_ops.persist = obj_heap_persist; pop->p_ops.flush = obj_heap_flush; pop->p_ops.drain = obj_heap_drain; pop->p_ops.memset = obj_heap_memset; pop->p_ops.base = pop; pop->set = MALLOC(sizeof(*(pop->set))); pop->set->options = 0; pop->set->directory_based = 0; struct stats *s = stats_new(pop); UT_ASSERTne(s, NULL); void *heap_start = (char *)pop + pop->heap_offset; uint64_t heap_size = MOCK_POOL_SIZE - sizeof(PMEMobjpool); struct palloc_heap *heap = &pop->heap; struct pmem_ops *p_ops = &pop->p_ops; UT_ASSERT(heap_check(heap_start, heap_size) != 0); UT_ASSERT(heap_init(heap_start, heap_size, &pop->heap_size, p_ops) == 0); UT_ASSERT(heap_boot(heap, heap_start, heap_size, &pop->heap_size, pop, p_ops, s, pop->set) == 0); UT_ASSERT(heap_buckets_init(heap) == 0); UT_ASSERT(pop->heap.rt != NULL); test_container((struct block_container *)container_new_ravl(heap), heap); test_container((struct block_container *)container_new_seglists(heap), heap); struct alloc_class *c_small = heap_get_best_class(heap, 1); struct alloc_class *c_big = heap_get_best_class(heap, 2048); UT_ASSERT(c_small->unit_size < c_big->unit_size); /* new small buckets should be empty */ UT_ASSERT(c_big->type == CLASS_RUN); struct memory_block blocks[MAX_BLOCKS] = { {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0} }; struct bucket *b_def = heap_bucket_acquire(heap, DEFAULT_ALLOC_CLASS_ID, HEAP_ARENA_PER_THREAD); for (int i = 0; i < MAX_BLOCKS; ++i) { heap_get_bestfit_block(heap, b_def, &blocks[i]); UT_ASSERT(blocks[i].block_off == 0); } heap_bucket_release(heap, b_def); struct memory_block old_run = {0, 0, 1, 0}; struct memory_block new_run = {0, 0, 0, 0}; struct alloc_class *c_run = heap_get_best_class(heap, 1024); struct bucket *b_run = heap_bucket_acquire(heap, c_run->id, HEAP_ARENA_PER_THREAD); /* * Allocate blocks from a run until one run is exhausted. */ UT_ASSERTne(heap_get_bestfit_block(heap, b_run, &old_run), ENOMEM); do { new_run.chunk_id = 0; new_run.block_off = 0; new_run.size_idx = 1; UT_ASSERTne(heap_get_bestfit_block(heap, b_run, &new_run), ENOMEM); UT_ASSERTne(new_run.size_idx, 0); } while (old_run.block_off != new_run.block_off); heap_bucket_release(heap, b_run); stats_delete(pop, s); UT_ASSERT(heap_check(heap_start, heap_size) == 0); heap_cleanup(heap); UT_ASSERT(heap->rt == NULL); FREE(pop->set); MUNMAP_ANON_ALIGNED(mpop, MOCK_POOL_SIZE); } /* * test_heap_with_size -- tests scenarios with not-nicely aligned sizes */ static void test_heap_with_size() { /* * To trigger bug with incorrect metadata alignment we need to * use a size that uses exactly the size used in bugged zone size * calculations. */ size_t size = PMEMOBJ_MIN_POOL + sizeof(struct zone_header) + sizeof(struct chunk_header) * MAX_CHUNK + sizeof(PMEMobjpool); struct mock_pop *mpop = MMAP_ANON_ALIGNED(size, Ut_mmap_align); PMEMobjpool *pop = &mpop->p; memset(pop, 0, size); pop->heap_offset = (uint64_t)((uint64_t)&mpop->heap - (uint64_t)mpop); pop->p_ops.persist = obj_heap_persist; pop->p_ops.flush = obj_heap_flush; pop->p_ops.drain = obj_heap_drain; pop->p_ops.memset = obj_heap_memset; pop->p_ops.base = pop; pop->set = MALLOC(sizeof(*(pop->set))); pop->set->options = 0; pop->set->directory_based = 0; void *heap_start = (char *)pop + pop->heap_offset; uint64_t heap_size = size - sizeof(PMEMobjpool); struct palloc_heap *heap = &pop->heap; struct pmem_ops *p_ops = &pop->p_ops; UT_ASSERT(heap_check(heap_start, heap_size) != 0); UT_ASSERT(heap_init(heap_start, heap_size, &pop->heap_size, p_ops) == 0); UT_ASSERT(heap_boot(heap, heap_start, heap_size, &pop->heap_size, pop, p_ops, NULL, pop->set) == 0); UT_ASSERT(heap_buckets_init(heap) == 0); UT_ASSERT(pop->heap.rt != NULL); struct bucket *b_def = heap_bucket_acquire(heap, DEFAULT_ALLOC_CLASS_ID, HEAP_ARENA_PER_THREAD); struct memory_block mb; mb.size_idx = 1; while (heap_get_bestfit_block(heap, b_def, &mb) == 0) ; /* mb should now be the last chunk in the heap */ char *ptr = mb.m_ops->get_real_data(&mb); size_t s = mb.m_ops->get_real_size(&mb); /* last chunk should be within the heap and accessible */ UT_ASSERT((size_t)ptr + s <= (size_t)mpop + size); VALGRIND_DO_MAKE_MEM_DEFINED(ptr, s); memset(ptr, 0xc, s); heap_bucket_release(heap, b_def); UT_ASSERT(heap_check(heap_start, heap_size) == 0); heap_cleanup(heap); UT_ASSERT(heap->rt == NULL); FREE(pop->set); MUNMAP_ANON_ALIGNED(mpop, size); } static void test_recycler(void) { struct mock_pop *mpop = MMAP_ANON_ALIGNED(MOCK_POOL_SIZE, Ut_mmap_align); PMEMobjpool *pop = &mpop->p; memset(pop, 0, MOCK_POOL_SIZE); pop->heap_offset = (uint64_t)((uint64_t)&mpop->heap - (uint64_t)mpop); pop->p_ops.persist = obj_heap_persist; pop->p_ops.flush = obj_heap_flush; pop->p_ops.drain = obj_heap_drain; pop->p_ops.memset = obj_heap_memset; pop->p_ops.base = pop; pop->set = MALLOC(sizeof(*(pop->set))); pop->set->options = 0; pop->set->directory_based = 0; void *heap_start = (char *)pop + pop->heap_offset; uint64_t heap_size = MOCK_POOL_SIZE - sizeof(PMEMobjpool); struct palloc_heap *heap = &pop->heap; struct pmem_ops *p_ops = &pop->p_ops; struct stats *s = stats_new(pop); UT_ASSERTne(s, NULL); UT_ASSERT(heap_check(heap_start, heap_size) != 0); UT_ASSERT(heap_init(heap_start, heap_size, &pop->heap_size, p_ops) == 0); UT_ASSERT(heap_boot(heap, heap_start, heap_size, &pop->heap_size, pop, p_ops, s, pop->set) == 0); UT_ASSERT(heap_buckets_init(heap) == 0); UT_ASSERT(pop->heap.rt != NULL); /* trigger heap bucket populate */ struct memory_block m = MEMORY_BLOCK_NONE; m.size_idx = 1; struct bucket *b = heap_bucket_acquire(heap, DEFAULT_ALLOC_CLASS_ID, HEAP_ARENA_PER_THREAD); UT_ASSERT(heap_get_bestfit_block(heap, b, &m) == 0); heap_bucket_release(heap, b); int ret; size_t active_arenas = 1; struct recycler *r = recycler_new(&pop->heap, 10000 /* never recalc */, &active_arenas); UT_ASSERTne(r, NULL); init_run_with_score(pop->heap.layout, 0, 64); init_run_with_score(pop->heap.layout, 1, 128); init_run_with_score(pop->heap.layout, 15, 0); struct memory_block mrun = {0, 0, 1, 0}; struct memory_block mrun2 = {1, 0, 1, 0}; memblock_rebuild_state(&pop->heap, &mrun); memblock_rebuild_state(&pop->heap, &mrun2); ret = recycler_put(r, &mrun, recycler_element_new(&pop->heap, &mrun)); UT_ASSERTeq(ret, 0); ret = recycler_put(r, &mrun2, recycler_element_new(&pop->heap, &mrun2)); UT_ASSERTeq(ret, 0); struct memory_block mrun_ret = MEMORY_BLOCK_NONE; mrun_ret.size_idx = 1; struct memory_block mrun2_ret = MEMORY_BLOCK_NONE; mrun2_ret.size_idx = 1; ret = recycler_get(r, &mrun_ret); UT_ASSERTeq(ret, 0); ret = recycler_get(r, &mrun2_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(mrun2.chunk_id, mrun2_ret.chunk_id); UT_ASSERTeq(mrun.chunk_id, mrun_ret.chunk_id); init_run_with_score(pop->heap.layout, 7, 64); init_run_with_score(pop->heap.layout, 2, 128); init_run_with_score(pop->heap.layout, 5, 192); init_run_with_score(pop->heap.layout, 10, 256); mrun.chunk_id = 7; mrun2.chunk_id = 2; struct memory_block mrun3 = {5, 0, 1, 0}; struct memory_block mrun4 = {10, 0, 1, 0}; memblock_rebuild_state(&pop->heap, &mrun3); memblock_rebuild_state(&pop->heap, &mrun4); mrun_ret.size_idx = 1; mrun2_ret.size_idx = 1; struct memory_block mrun3_ret = MEMORY_BLOCK_NONE; mrun3_ret.size_idx = 1; struct memory_block mrun4_ret = MEMORY_BLOCK_NONE; mrun4_ret.size_idx = 1; ret = recycler_put(r, &mrun, recycler_element_new(&pop->heap, &mrun)); UT_ASSERTeq(ret, 0); ret = recycler_put(r, &mrun2, recycler_element_new(&pop->heap, &mrun2)); UT_ASSERTeq(ret, 0); ret = recycler_put(r, &mrun3, recycler_element_new(&pop->heap, &mrun3)); UT_ASSERTeq(ret, 0); ret = recycler_put(r, &mrun4, recycler_element_new(&pop->heap, &mrun4)); UT_ASSERTeq(ret, 0); ret = recycler_get(r, &mrun_ret); UT_ASSERTeq(ret, 0); ret = recycler_get(r, &mrun2_ret); UT_ASSERTeq(ret, 0); ret = recycler_get(r, &mrun3_ret); UT_ASSERTeq(ret, 0); ret = recycler_get(r, &mrun4_ret); UT_ASSERTeq(ret, 0); UT_ASSERTeq(mrun.chunk_id, mrun_ret.chunk_id); UT_ASSERTeq(mrun2.chunk_id, mrun2_ret.chunk_id); UT_ASSERTeq(mrun3.chunk_id, mrun3_ret.chunk_id); UT_ASSERTeq(mrun4.chunk_id, mrun4_ret.chunk_id); init_run_with_max_block(pop->heap.layout, 1); struct memory_block mrun5 = {1, 0, 1, 0}; memblock_rebuild_state(&pop->heap, &mrun5); ret = recycler_put(r, &mrun5, recycler_element_new(&pop->heap, &mrun5)); UT_ASSERTeq(ret, 0); struct memory_block mrun5_ret = MEMORY_BLOCK_NONE; mrun5_ret.size_idx = 11; ret = recycler_get(r, &mrun5_ret); UT_ASSERTeq(ret, ENOMEM); mrun5_ret = MEMORY_BLOCK_NONE; mrun5_ret.size_idx = 10; ret = recycler_get(r, &mrun5_ret); UT_ASSERTeq(ret, 0); recycler_delete(r); stats_delete(pop, s); heap_cleanup(heap); UT_ASSERT(heap->rt == NULL); FREE(pop->set); MUNMAP_ANON_ALIGNED(mpop, MOCK_POOL_SIZE); } int main(int argc, char *argv[]) { START(argc, argv, "obj_heap"); if (argc < 2) UT_FATAL("usage: %s path ", argv[0]); switch (argv[1][0]) { case 't': test_heap(); test_heap_with_size(); test_recycler(); break; case 'b': do_fault_injection_new_ravl(); break; case 'r': do_fault_injection_recycler(); break; case 'c': do_fault_injection_new_seglists(); break; case 'h': do_fault_injection_heap_boot(); break; case 'a': /* first call alloc_class_new */ do_fault_injection_class_new(1); /* second call alloc_class_new */ do_fault_injection_class_new(2); break; case 'n': do_fault_injection_class_collection_new(); break; case 's': do_fault_injection_stats(); break; default: UT_FATAL("unknown operation"); } DONE(NULL); } pmdk-1.11.1/src/test/obj_heap/.gitignore0000664000000000000000000000001114123364546016533 0ustar rootrootobj_heap pmdk-1.11.1/src/test/obj_heap/obj_heap.vcxproj.filters0000664000000000000000000000414314123364546021410 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {9b6e9354-5309-4cf2-9323-28313bdf729a} ps1 Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Test Scripts pmdk-1.11.1/src/test/obj_heap/TEST10000775000000000000000000000101514123364546015336 0ustar rootroot#!/usr/bin/env bash # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/obj_heap/TEST1 -- unit test for inject fault malloc # . ../unittest/unittest.sh require_test_type medium setup expect_normal_exit ./obj_heap$EXESUFFIX b expect_normal_exit ./obj_heap$EXESUFFIX r expect_normal_exit ./obj_heap$EXESUFFIX c expect_normal_exit ./obj_heap$EXESUFFIX h expect_normal_exit ./obj_heap$EXESUFFIX a expect_normal_exit ./obj_heap$EXESUFFIX n expect_normal_exit ./obj_heap$EXESUFFIX s pass pmdk-1.11.1/src/test/blk_pool_win/0000775000000000000000000000000014123364546015462 5ustar rootrootpmdk-1.11.1/src/test/blk_pool_win/TEST1.PS10000664000000000000000000000400014123364546016641 0ustar rootroot# # SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # Copyright (c) 2016, Microsoft Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # src/test/blk_pool_win/TEST1 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup create_holey_file 40M $DIR\testfile # # TEST1 existing file, file length >= min required size, poolsize == 0 # expect_normal_exit $Env:EXE_DIR\blk_pool_win$Env:EXESUFFIX ` c $DIR\testfile 4096 0 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool_win/blk_pool_win.vcxproj0000664000000000000000000000706114123364546021561 0ustar rootroot Debug x64 Release x64 {f7c6c6b6-4142-4c82-8699-4a9d8183181b} {9e9e3d25-2139-4a5d-9200-18148ddead45} {ce3f2dfb-8470-4802-ad37-21caf6cb2681} {80AF1B7D-B8CE-4AF0-AE3B-1DABED1B57E7} Win32Proj blk_pool_win 10.0.17134.0 Application true v140 Application false v140 true pmdk-1.11.1/src/test/blk_pool_win/blk_pool_win.c0000664000000000000000000000372614123364546020314 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2015-2019, Intel Corporation */ /* * blk_pool_win.c -- unit test for pmemblk_create() and pmemblk_open() * * usage: blk_pool_win op path bsize [poolsize mode] * * op can be: * c - create * o - open * * "poolsize" and "mode" arguments are ignored for "open" */ #include "unittest.h" #define MB ((size_t)1 << 20) static void pool_create(const wchar_t *path, size_t bsize, size_t poolsize, unsigned mode) { char *upath = ut_toUTF8(path); UT_ASSERTne(upath, NULL); PMEMblkpool *pbp = pmemblk_createW(path, bsize, poolsize, mode); if (pbp == NULL) UT_OUT("!%s: pmemblk_create", upath); else { os_stat_t stbuf; STATW(path, &stbuf); UT_OUT("%s: file size %zu usable blocks %zu mode 0%o", upath, stbuf.st_size, pmemblk_nblock(pbp), stbuf.st_mode & 0777); pmemblk_close(pbp); int result = pmemblk_checkW(path, bsize); if (result < 0) UT_OUT("!%s: pmemblk_check", upath); else if (result == 0) UT_OUT("%s: pmemblk_check: not consistent", upath); else UT_ASSERTeq(pmemblk_checkW(path, bsize * 2), -1); free(upath); } } static void pool_open(const wchar_t *path, size_t bsize) { char *upath = ut_toUTF8(path); UT_ASSERTne(upath, NULL); PMEMblkpool *pbp = pmemblk_openW(path, bsize); if (pbp == NULL) UT_OUT("!%s: pmemblk_open", upath); else { UT_OUT("%s: pmemblk_open: Success", upath); pmemblk_close(pbp); } free(upath); } int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "blk_pool_win"); if (argc < 4) UT_FATAL("usage: %s op path bsize [poolsize mode]", ut_toUTF8(argv[0])); size_t bsize = wcstoul(argv[3], NULL, 0); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = wcstoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = wcstoul(argv[5], NULL, 8); pool_create(argv[2], bsize, poolsize, mode); break; case 'o': pool_open(argv[2], bsize); break; default: UT_FATAL("unknown operation"); } DONEW(NULL); } pmdk-1.11.1/src/test/blk_pool_win/out0.log.match0000664000000000000000000000030214123364546020142 0ustar rootrootblk_pool_win$(nW)TEST0: START: blk_pool_win$(nW) $(nW)blk_pool_win$(nW) c $(nW)testfile 4096 20 0600 $(nW)testfile: file size 20971520 usable blocks 4850 mode 0600 blk_pool_win$(nW)TEST0: DONE pmdk-1.11.1/src/test/blk_pool_win/TEST0.PS10000664000000000000000000000125014123364546016644 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2015-2019, Intel Corporation # # src/test/blk_pool_win/TEST0 -- unit test for pmemblk_create # . ..\unittest\unittest.ps1 require_test_type medium setup # Note: linux test reset default permissions and assures the library # creates a file using the permissions given. The Windows test just # checks that the permissions match. Note that the library's use # of the Windows CRT file functions (_chmod, _stat, etc) limit # permissions to R/W or RO # # TEST0 non-existing file, poolsize > 0 # expect_normal_exit $Env:EXE_DIR\blk_pool_win$Env:EXESUFFIX ` c $DIR\testfile 4096 20 0600 check_files $DIR\testfile check pass pmdk-1.11.1/src/test/blk_pool_win/blk_pool_win.vcxproj.filters0000664000000000000000000000202214123364546023220 0ustar rootroot {d4cd54d2-000e-4b7a-92c7-f4809d6cbd79} {df50a25f-1d05-4a29-9212-591165353458} {e44944fb-07d3-4369-8297-1897b6d3a631} Source Files Test Scripts Test Scripts Match Files Match Files pmdk-1.11.1/src/test/blk_pool_win/blk_pool_win.filters0000664000000000000000000001271314123364546021536 0ustar rootroot {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {05f2a8a8-59fc-4969-8e86-6ee33c321153} match {881544fe-d25d-4cf8-8468-86eeb68ab91e} ps1 Source Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Match Files Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Test Scripts Match Files pmdk-1.11.1/src/test/blk_pool_win/out1.log.match0000664000000000000000000000030114123364546020142 0ustar rootrootblk_pool_win$(nW)TEST1: START: blk_pool_win$(nW) $(nW)blk_pool_win$(nW) c $(nW)testfile 4096 0 0600 $(nW)testfile: file size 41943040 usable blocks 9965 mode 0600 blk_pool_win$(nW)TEST1: DONE pmdk-1.11.1/src/test/pmem2_granularity_detection/0000775000000000000000000000000014123364546020503 5ustar rootrootpmdk-1.11.1/src/test/pmem2_granularity_detection/Makefile0000664000000000000000000000027014123364546022142 0ustar rootroot# SPDX-License-Identifier: BSD-3-Clause # Copyright 2019, Intel Corporation # # src/test/pmem2_granularity_detection/Makefile -- granularity detection test # include ../Makefile.inc pmdk-1.11.1/src/test/pmem2_granularity_detection/TESTS.py0000775000000000000000000000332014123364546021760 0ustar rootroot#!../env.py # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019-2020, Intel Corporation # import testframework as t from testframework import granularity as g import futils as f @g.require_granularity(g.ANY) class PMEM2_CONFIG(t.BaseTest): test_type = t.Short class TEST0(PMEM2_CONFIG): """test granularity detection with PMEM2_FORCE_GRANULARITY set to page""" def run(self, ctx): ctx.env['PMEM2_FORCE_GRANULARITY'] = "page" ctx.exec(f.get_test_tool_path(ctx.build, "gran_detecto"), '-p', ctx.testdir) class TEST1(PMEM2_CONFIG): """test granularity detection with PMEM2_FORCE_GRANULARITY set to cache_line""" def run(self, ctx): ctx.env['PMEM2_FORCE_GRANULARITY'] = "cache_line" ctx.exec(f.get_test_tool_path(ctx.build, "gran_detecto"), '-c', ctx.testdir) class TEST2(PMEM2_CONFIG): """test granularity detection with PMEM2_FORCE_GRANULARITY set to byte""" def run(self, ctx): ctx.env['PMEM2_FORCE_GRANULARITY'] = "byte" ctx.exec(f.get_test_tool_path(ctx.build, "gran_detecto"), '-b', ctx.testdir) class TEST3(PMEM2_CONFIG): """test granularity detection with PMEM2_FORCE_GRANULARITY set to CaCHe_Line""" def run(self, ctx): ctx.env['PMEM2_FORCE_GRANULARITY'] = "CaCHe_Line" ctx.exec(f.get_test_tool_path(ctx.build, "gran_detecto"), '-c', ctx.testdir) class TEST4(PMEM2_CONFIG): """test granularity detection with PMEM2_FORCE_GRANULARITY set to CACHELINE""" def run(self, ctx): ctx.env['PMEM2_FORCE_GRANULARITY'] = "CACHELINE" ctx.exec(f.get_test_tool_path(ctx.build, "gran_detecto"), '-c', ctx.testdir) pmdk-1.11.1/src/test/pmem_has_auto_flush_win/0000775000000000000000000000000014123364546017703 5ustar rootrootpmdk-1.11.1/src/test/pmem_has_auto_flush_win/pmem_has_auto_flush_win.vcxproj0000664000000000000000000001304614123364546026223 0ustar rootroot Debug x64 Release x64 {DEA3CD0A-8781-4ABE-9A7D-00B91132FED0} Win32Proj pmem_has_auto_flush_win 10.0.17134.0 pmem_has_auto_flush_win Application true v140 Application false v140 $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) $(SolutionDir)\libpmem2;$(SolutionDir)\libpmem;%(AdditionalIncludeDirectories) mocks_windows.h;%(ForcedIncludeFiles) SSE2_AVAILABLE=0;AVX_AVAILABLE=0;AVX512F_AVAILABLE=0;%(PreprocessorDefinitions) {ce3f2dfb-8470-4802-ad37-21caf6cb2681} _DEBUG;_CONSOLE;%(PreprocessorDefinitions);WRAP_REAL %(PreprocessorDefinitions);WRAP_REAL pmdk-1.11.1/src/test/pmem_has_auto_flush_win/pmem_has_auto_flush_win.c0000664000000000000000000000243114123364546024746 0ustar rootroot// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018-2019, Intel Corporation */ /* * pmem_has_auto_flush_win.c -- unit test for pmem_has_auto_flush_win() * * usage: pmem_has_auto_flush_win