pax_global_header00006660000000000000000000000064146316705560014527gustar00rootroot0000000000000052 comment=2c9651e42c777201766e8935107831b10b185ee3 azure-nvme-utils-0.2.0/000077500000000000000000000000001463167055600147555ustar00rootroot00000000000000azure-nvme-utils-0.2.0/.github/000077500000000000000000000000001463167055600163155ustar00rootroot00000000000000azure-nvme-utils-0.2.0/.github/workflows/000077500000000000000000000000001463167055600203525ustar00rootroot00000000000000azure-nvme-utils-0.2.0/.github/workflows/debs.yml000066400000000000000000000024131463167055600220120ustar00rootroot00000000000000name: Debian Packaging CI on: [push, pull_request] jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-20.04, ubuntu-22.04] defaults: run: shell: bash steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ github.event.sha }} fetch-depth: 0 fetch-tags: true - name: Get tags from upstream, if needed if: github.repository != 'Azure/azure-nvme-utils' run: | git remote add upstream https://github.com/Azure/azure-nvme-utils.git git fetch upstream --tags - name: Setup run: | sudo apt update sudo apt install gcc pandoc cmake devscripts debhelper -y - name: Build debs run: | DEBEMAIL="Azure NVMe Utils CI " ./scripts/build-deb.sh - name: Lintian check run: | lintian out/*.deb - name: Install debs run: | sudo dpkg -i out/*.deb - name: Verify installation run: | set -x dpkg -L azure-nvme-utils test -f /usr/share/man/man1/azure-nvme-id.1.gz test -f /usr/sbin/azure-nvme-id test -f /lib/udev/rules.d/80-azure-nvme.rules azure-nvme-id --version azure-nvme-utils-0.2.0/.github/workflows/main.yml000066400000000000000000000036421463167055600220260ustar00rootroot00000000000000name: Main CI on: [push, pull_request] jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-20.04, ubuntu-22.04] defaults: run: shell: bash steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ github.event.sha }} fetch-depth: 0 fetch-tags: true - name: Get tags from upstream, if needed if: github.repository != 'Azure/azure-nvme-utils' run: | git remote add upstream https://github.com/Azure/azure-nvme-utils.git git fetch upstream --tags - name: Setup run: | sudo apt update sudo apt install gcc pandoc cmake -y - name: Build & install project with cmake run: | cmake -B build -S . make -C build sudo make -C build install - name: Verify installation run: | test -f /usr/local/sbin/azure-nvme-id test -f /usr/local/share/man/man1/azure-nvme-id.1 test -f /usr/local/lib/udev/rules.d/80-azure-nvme.rules azure-nvme-id --version - name: Verify manpages are not generated by default run: | rm -rf build cmake -B build -S . make -C build if grep -c "Pandoc" build/doc/azure-nvme-id.1; then echo "manpage unexpectedly generated by pandoc"; exit 1; fi - name: Verify manpages are not generated with -DGENERATE_MANPAGES=0 run: | rm -rf build cmake -DGENERATE_MANPAGES=0 -B build -S . make -C build if grep -c "Pandoc" build/doc/azure-nvme-id.1; then echo "manpage unexpectedly generated by pandoc"; exit 1; fi - name: Verify manpages are generated with -DGENERATE_MANPAGES=1 run: | rm -rf build cmake -DGENERATE_MANPAGES=1 -B build -S . make -C build if ! grep -c "Pandoc" build/doc/azure-nvme-id.1; then echo "manpage not generated by pandoc"; exit 1; fi azure-nvme-utils-0.2.0/.gitignore000066400000000000000000000014561463167055600167530ustar00rootroot00000000000000# Prerequisites *.d # Object files *.o *.ko *.obj *.elf # Linker output *.ilk *.map *.exp # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb # Kernel Module Compile Results *.mod* *.cmd .tmp_versions/ modules.order Module.symvers Mkfile.old dkms.conf # CMake CMakeLists.txt.user CMakeCache.txt CMakeFiles CMakeScripts CPackConfig.cmake CPackSourceConfig.cmake DartConfiguration.tcl Testing Makefile cmake_install.cmake install_manifest.txt compile_commands.json CTestTestfile.cmake _deps # VS Code .vscode # Compiled artifacts azure-nvme-id obj-* /build/ /debian/ /doc/azure-nvme-id.1 /src/version.h /udev/80-azure-nvme.rules /out/ azure-nvme-utils-0.2.0/CMakeLists.txt000066400000000000000000000027771463167055600175320ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0.0) project(azure-nvme-utils VERSION 0.1.0 LANGUAGES C) if(NOT DEFINED VERSION) execute_process( COMMAND git describe --tags --always --dirty WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() include(cmake/cppcheck.cmake) include(cmake/clangformat.cmake) include(cmake/doc.cmake) include(CTest) enable_testing() add_compile_options(-Wextra -Wall $<$:-Werror> -std=gnu11 -D_GNU_SOURCE=1) add_executable(azure-nvme-id src/main.c) set(AZURE_NVME_ID_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/sbin") set(UDEV_RULES_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d" CACHE PATH "udev rules.d installation directory") option(AZURE_LUN_CALCULATION_BY_NSID_ENABLED "Enable fallback \"LUN\" calculation via NSID" ON) if(AZURE_LUN_CALCULATION_BY_NSID_ENABLED) set(AZURE_LUN_CALCULATION_BY_NSID_ENABLED 1) else() set(AZURE_LUN_CALCULATION_BY_NSID_ENABLED 0) endif() configure_file( "${PROJECT_SOURCE_DIR}/udev/80-azure-nvme.rules.in" "${PROJECT_BINARY_DIR}/udev/80-azure-nvme.rules" @ONLY ) configure_file( "${CMAKE_SOURCE_DIR}/src/version.h.in" "${CMAKE_SOURCE_DIR}/src/version.h" @ONLY ) install(TARGETS azure-nvme-id DESTINATION ${AZURE_NVME_ID_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/udev/80-azure-nvme.rules DESTINATION ${UDEV_RULES_INSTALL_DIR}) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) azure-nvme-utils-0.2.0/CODE_OF_CONDUCT.md000066400000000000000000000006741463167055600175630ustar00rootroot00000000000000# Microsoft Open Source Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). Resources: - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns azure-nvme-utils-0.2.0/LICENSE000066400000000000000000000021651463167055600157660ustar00rootroot00000000000000 MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE azure-nvme-utils-0.2.0/README.md000066400000000000000000000047301463167055600162400ustar00rootroot00000000000000# Project This project includes a utility to help identify Azure NVMe devices. ## Quick Start To build: ``` cmake . make ``` To install /usr/local/bin/azure-nvme-id and /usr/local/lib/udev/rules.d/80-azure-nvme.rules: ``` sudo make install ``` To run: ``` sudo azure-nvme-id ``` To run in udev mode: ``` DEVNAME=/dev/nvme0n1 azure-nvme-id --udev ``` ### Enabling LUN Calculation by Namespace Identifier (Default) The "LUN" configured by the user for data disks can be computed by the namespace identifier for "MSFT NVMe Accelerator v1.0" controllers. This is currently enabled by default to support cases where there is no identification information available in the vendor-specific field of Identify Namespace data structure. It can be explicitly enabled by passing AZURE_LUN_CALCULATION_BY_NSID_ENABLED=1 to cmake: ``` cmake -DAZURE_LUN_CALCULATION_BY_NSID_ENABLED=1 . ``` ## Disabling LUN Calculation by Namespace Identifier Pass AZURE_LUN_CALCULATION_BY_NSID_ENABLED=0 to cmake: ``` cmake -DAZURE_LUN_CALCULATION_BY_NSID_ENABLED=0 . ``` ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. azure-nvme-utils-0.2.0/SECURITY.md000066400000000000000000000051401463167055600165460ustar00rootroot00000000000000 ## Security Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin). If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below. ## Reporting Security Issues **Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report). If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) * Full paths of source file(s) related to the manifestation of the issue * The location of the affected source code (tag/branch/commit or direct URL) * Any special configuration required to reproduce the issue * Step-by-step instructions to reproduce the issue * Proof-of-concept or exploit code (if possible) * Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs. ## Preferred Languages We prefer all communications to be in English. ## Policy Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd). azure-nvme-utils-0.2.0/SUPPORT.md000066400000000000000000000023341463167055600164550ustar00rootroot00000000000000# TODO: The maintainer of this repo has not yet edited this file **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project? - **No CSS support:** Fill out this template with information about how to file issues and get help. - **Yes CSS support:** Fill out an intake form at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). CSS will work with/help you to determine next steps. - **Not sure?** Fill out an intake as though the answer were "Yes". CSS will help you decide. *Then remove this first heading from this SUPPORT.MD file before publishing your repo.* # Support ## How to file issues and get help This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue. For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER CHANNEL. WHERE WILL YOU HELP PEOPLE?**. ## Microsoft Support Policy Support for this **PROJECT or PRODUCT** is limited to the resources listed above. azure-nvme-utils-0.2.0/cmake/000077500000000000000000000000001463167055600160355ustar00rootroot00000000000000azure-nvme-utils-0.2.0/cmake/clangformat.cmake000066400000000000000000000002501463167055600213310ustar00rootroot00000000000000file(GLOB_RECURSE ALL_SOURCE_FILES *.c *.h) add_custom_target( clangformat COMMAND /usr/bin/clang-format -style=Microsoft -i ${ALL_SOURCE_FILES} ) azure-nvme-utils-0.2.0/cmake/cppcheck.cmake000066400000000000000000000003161463167055600206170ustar00rootroot00000000000000file(GLOB_RECURSE ALL_SOURCE_FILES *.c *.h) add_custom_target( cppcheck COMMAND /usr/bin/cppcheck --enable=all --suppress=missingIncludeSystem ${ALL_SOURCE_FILES} ) azure-nvme-utils-0.2.0/cmake/doc.cmake000066400000000000000000000024551463167055600176120ustar00rootroot00000000000000string(TIMESTAMP TODAY "%B %d, %Y") option(GENERATE_MANPAGES "Generate manpages with pandoc" OFF) if(GENERATE_MANPAGES) find_program(PANDOC_EXECUTABLE pandoc) if(NOT PANDOC_EXECUTABLE) message(WARNING "Pandoc not found, will not generate manpages") return() endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doc/azure-nvme-id.1 COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/doc COMMAND ${PANDOC_EXECUTABLE} ${CMAKE_SOURCE_DIR}/doc/azure-nvme-id.md --standalone --from markdown --to man --variable footer="azure-nvme-id ${VERSION}" --variable date="${TODAY}" -o ${CMAKE_CURRENT_BINARY_DIR}/doc/azure-nvme-id.1 DEPENDS ${CMAKE_SOURCE_DIR}/doc/azure-nvme-id.md COMMENT "Generating manpage for azure-nvme-id" ) else() configure_file( "${CMAKE_SOURCE_DIR}/doc/azure-nvme-id.1" "${CMAKE_CURRENT_BINARY_DIR}/doc/azure-nvme-id.1" @ONLY ) endif() add_custom_target( doc ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/azure-nvme-id.1 ) set(MANPAGES_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/man") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/doc/azure-nvme-id.1 DESTINATION ${MANPAGES_INSTALL_DIR}/man1) azure-nvme-utils-0.2.0/doc/000077500000000000000000000000001463167055600155225ustar00rootroot00000000000000azure-nvme-utils-0.2.0/doc/azure-nvme-id.1000066400000000000000000000026171463167055600202750ustar00rootroot00000000000000.TH "azure\-nvme\-id" "1" "@TODAY@" "azure-nvme-id\ @VERSION@" "User Manual" .SH NAME azure\-nvme\-id \- Identify Azure NVMe devices. .SH SYNOPSIS \f[B]azure\-nvme\-id\f[R] [\-\-debug] [\-\-help | \-\-version | \-\-udev] .SH DESCRIPTION \f[B]azure\-nvme\-id\f[R] is a utility to identify Azure NVMe devices. .PP It performs an Identify Namespace command on the NVMe namespaces, parsing metadata available in the vendor\-specific (vs) field which contains various identification details with a comma\-separated, key=value format. .SH OPTIONS .TP \f[CR]\-\-help\f[R] Show usage information and exit. .TP \f[CR]\-\-version\f[R] Show version information and exit. .TP \f[CR]\-\-udev\f[R] Run in udev mode, printing a set of \f[CR]=\f[R] variables consumed by udev rules. Requires DEVNAME to be set in environment. .SH EXAMPLES Identify NVMe namespaces: .IP .EX $ sudo azure\-nvme\-id /dev/nvme0n1: /dev/nvme1n1: type=local,index=1,name=nvme\-110G\-1 .EE .PP Parse device identifiers for udev consumption: .IP .EX $ sudo env DEVNAME=/dev/nvme1n1 azure\-nvme\-id \-\-udev AZURE_NVME_VS=type=local,index=1,name=nvme\-110G\-1 AZURE_NVME_TYPE=local AZURE_NVME_INDEX=1 AZURE_NVME_NAME=nvme\-110G\-1 .EE .PP Check \f[CR]azure\-nvme\-id\f[R] version: .IP .EX $ azure\-nvme\-id \-\-version azure\-nvme\-id 0.1.2 .EE .SH SEE ALSO Source and documentation available at: \c .UR https://github.com/Azure/azure-nvme-utils .UE \c azure-nvme-utils-0.2.0/doc/azure-nvme-id.md000066400000000000000000000025041463167055600205300ustar00rootroot00000000000000--- title: azure-nvme-id section: 1 header: User Manual footer: azure-nvme-id __VERSION__ date: __DATE__ --- # NAME azure-nvme-id - Identify Azure NVMe devices. # SYNOPSIS **azure-nvme-id** [\-\-debug] [\-\-help | \-\-version | \-\-udev] # DESCRIPTION **azure-nvme-id** is a utility to identify Azure NVMe devices. It performs an Identify Namespace command on the NVMe namespaces, parsing metadata available in the vendor-specific (vs) field which contains various identification details with a comma-separated, key=value format. # OPTIONS `--help` : Show usage information and exit. `--version` : Show version information and exit. `--udev` : Run in udev mode, printing a set of `=` variables consumed by udev rules. Requires DEVNAME to be set in environment. # EXAMPLES Identify NVMe namespaces: ```bash $ sudo azure-nvme-id /dev/nvme0n1: /dev/nvme1n1: type=local,index=1,name=nvme-110G-1 ``` Parse device identifiers for udev consumption: ```bash $ sudo env DEVNAME=/dev/nvme1n1 azure-nvme-id --udev AZURE_NVME_VS=type=local,index=1,name=nvme-110G-1 AZURE_NVME_TYPE=local AZURE_NVME_INDEX=1 AZURE_NVME_NAME=nvme-110G-1 ``` Check `azure-nvme-id` version: ```bash $ azure-nvme-id --version azure-nvme-id 0.1.2 ``` # SEE ALSO Source and documentation available at: azure-nvme-utils-0.2.0/packaging/000077500000000000000000000000001463167055600167015ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/azurelinux000077700000000000000000000000001463167055600224642mariner/ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/debian/000077500000000000000000000000001463167055600201235ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/debian/control000066400000000000000000000010771463167055600215330ustar00rootroot00000000000000Source: azure-nvme-utils Section: utils Priority: optional Maintainer: Chris Patterson Build-Depends: cmake, pandoc, debhelper-compat (= 12) Standards-Version: 4.5.0 Homepage: https://github.com/Azure/azure-nvme-utils Rules-Requires-Root: no Package: azure-nvme-utils Architecture: any Multi-Arch: foreign Depends: ${misc:Depends}, ${shlibs:Depends} Description: Utilities to assist managing NVMe devices on Azure This package provides azure-nvme-id for NVMe device identification and udev rules to provide symlinks using available identifiers. azure-nvme-utils-0.2.0/packaging/debian/copyright000066400000000000000000000025001463167055600220530ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: azure-nvme-utils Upstream-Contact: https://github.com/Azure/azure-nvme-utils/issues Source: https://github.com/Azure/azure-nvme-utils Files: * Copyright: 2024 Microsoft Corporation License: Expat License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE azure-nvme-utils-0.2.0/packaging/debian/rules000077500000000000000000000003161463167055600212030ustar00rootroot00000000000000#!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -Werror -Wextra export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed %: dh $@ azure-nvme-utils-0.2.0/packaging/debian/source/000077500000000000000000000000001463167055600214235ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/debian/source/format000066400000000000000000000000151463167055600226320ustar00rootroot000000000000003.0 (native) azure-nvme-utils-0.2.0/packaging/debian/source/lintian-overrides000066400000000000000000000001141463167055600250000ustar00rootroot00000000000000source: no-nmu-in-changelog source: source-nmu-has-incorrect-version-number azure-nvme-utils-0.2.0/packaging/fedora/000077500000000000000000000000001463167055600201415ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/fedora/azure-nvme-utils.spec000066400000000000000000000011731463167055600242460ustar00rootroot00000000000000Name: azure-nvme-utils Version: %{__git_version} Release: %{__git_release}%{?dist} Summary: Utility and udev rules to help identify Azure NVMe devices License: MIT URL: https://github.com/Azure/%{name} Source0: %{name}_dev.tgz BuildRequires: cmake BuildRequires: gcc %description Utility and udev rules to help identify Azure NVMe devices. %prep %autosetup %build %cmake -DVERSION="%{version}-%{release}" %cmake_build %install %cmake_install %check %ctest %files %{_exec_prefix}/lib/udev/rules.d/80-azure-nvme.rules %{_sbindir}/azure-nvme-id %changelog %autochangelog azure-nvme-utils-0.2.0/packaging/mariner/000077500000000000000000000000001463167055600203365ustar00rootroot00000000000000azure-nvme-utils-0.2.0/packaging/mariner/azure-nvme-utils.spec000066400000000000000000000012641463167055600244440ustar00rootroot00000000000000Name: azure-nvme-utils Version: %{__git_version} Release: %{__git_release}%{?dist} Summary: Utility and udev rules to help identify Azure NVMe devices License: MIT URL: https://github.com/Azure/%{name} Source0: azure-nvme-utils_dev.tgz BuildRequires: binutils BuildRequires: cmake BuildRequires: gcc BuildRequires: glibc-devel BuildRequires: kernel-headers %description Utility and udev rules to help identify Azure NVMe devices. %prep %autosetup %build %cmake -DVERSION="%{version}-%{release}" %cmake_build %install %cmake_install %check %ctest %files %{_libdir}/udev/rules.d/80-azure-nvme.rules %{_sbindir}/azure-nvme-id azure-nvme-utils-0.2.0/packaging/rhel000077700000000000000000000000001463167055600210132fedora/ustar00rootroot00000000000000azure-nvme-utils-0.2.0/scripts/000077500000000000000000000000001463167055600164445ustar00rootroot00000000000000azure-nvme-utils-0.2.0/scripts/build-deb.sh000077500000000000000000000016161463167055600206360ustar00rootroot00000000000000#!/bin/bash set -eux -o pipefail project_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" git_version="$(git describe --tags --always --dirty)" git_ref="$(echo "${git_version}" | sed 's/.*-g//' | sed 's/-dirty/DIRTY/')" deb_version="$(echo "${git_version}" | sed 's/^v//' | sed 's/-.*//')+git${git_ref}" output_dir="${project_dir}/out" echo "project root: $project_dir" echo "project version: $git_version" cd "$project_dir" mkdir -p debian rsync -a packaging/debian/. debian/. rm -f debian/changelog if [[ -z ${DEBEMAIL:-} ]]; then git_user="$(git config user.name)" git_email="$(git config user.email)" export DEBEMAIL="${git_user} <${git_email}>" fi dch --create -v "${deb_version}" --package "azure-nvme-utils" "development build: ${git_version}" debuild --no-tgz-check mkdir -p "${output_dir}" rm -f "${output_dir}"/*.deb mv ../azure-nvme-utils*"${deb_version}"* "${output_dir}"/ azure-nvme-utils-0.2.0/scripts/build-rpm.sh000077500000000000000000000023701463167055600207000ustar00rootroot00000000000000#!/bin/bash # shellcheck disable=SC1091 set -eu -o pipefail source /etc/os-release distro="$ID" project_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" version="$(git describe --tags | cut -f 1 -d "-" | sed 's/^v//')" release="dev_$(git describe --tags --dirty --always | sed 's/^v//g' | sed 's/-/_/g')" output_dir="${project_dir}/out" echo "project root: ${project_dir}" echo "build version: ${version}" echo "build release: ${release}" set -x # Create rpmbuild directory layout. build_dir="$(mktemp -d)" mkdir -p "${build_dir}"/{BUILD,RPMS,SOURCES,SPECS,SRPMS} # Create source tarball. output_source="${build_dir}/SOURCES/azure-nvme-utils_dev.tgz" cd "$project_dir" git archive --verbose --format=tar.gz --prefix="azure-nvme-utils-${version}/" HEAD --output "${output_source}" # Create spec file from template. cd "${project_dir}/packaging/${distro}" # Install dependencies. sudo dnf builddep -y --spec azure-nvme-utils.spec # Build RPM. rpmbuild -ba --define "__git_version ${version}" --define "__git_release ${release}" --define "_topdir ${build_dir}" azure-nvme-utils.spec # Copy RPM to output directory. mkdir -p "${output_dir}" rm -f "${output_dir}"/*.rpm cp -v "${build_dir}"/RPMS/*/"azure-nvme-utils-${version}-${release}".*.rpm "${output_dir}" azure-nvme-utils-0.2.0/src/000077500000000000000000000000001463167055600155445ustar00rootroot00000000000000azure-nvme-utils-0.2.0/src/main.c000066400000000000000000000255551463167055600166500ustar00rootroot00000000000000/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See LICENSE in the project root for license information. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nvme.h" #include "version.h" #define MAX_PATH 4096 #define MICROSOFT_NVME_VENDOR_ID 0x1414 #define SYS_CLASS_NVME_PATH "/sys/class/nvme" struct nvme_controller { char name[256]; char dev_path[MAX_PATH]; char sys_path[MAX_PATH]; char model[MAX_PATH]; }; static bool debug = false; static bool udev_mode = false; #define DEBUG_PRINTF(fmt, ...) \ do \ { \ if (debug == true) \ { \ fprintf(stderr, "DEBUG: " fmt, ##__VA_ARGS__); \ } \ } while (0) /** * Given the path to a namespace, determine the namespace id. */ int get_namespace_id_for_path(const char *namespace_path) { unsigned int ctrl, nsid; if (sscanf(namespace_path, "/dev/nvme%un%u", &ctrl, &nsid) != 2) { return -1; } return nsid; } /** * Dump environment variables. */ void debug_environment_variables() { int i = 0; DEBUG_PRINTF("Environment Variables:\n"); while (environ[i]) { DEBUG_PRINTF("%s\n", environ[i]); i++; } } /** * Read file contents as a null-terminated string. * * For sysfs entries, etc. where the file contents are not null-terminated and * we know the contents are just a simple string (e.g. sysfs attributes). */ char *read_file_as_string(const char *path) { DEBUG_PRINTF("reading %s...\n", path); FILE *file = fopen(path, "r"); if (file == NULL) { fprintf(stderr, "failed to fopen %s: %m\n", path); return NULL; } // Determine the file size if (fseek(file, 0, SEEK_END) < 0) { fprintf(stderr, "failed to fseek on %s: %m\n", path); fclose(file); return NULL; } long length = ftell(file); if (length < 0) { fprintf(stderr, "failed to ftell on %s: %m\n", path); fclose(file); return NULL; } if (fseek(file, 0, SEEK_SET) < 0) { fprintf(stderr, "failed to fseek on %s: %m\n", path); fclose(file); return NULL; } // Allocate size of file plus one byte for null. char *contents = malloc(length + 1); if (contents == NULL) { fprintf(stderr, "failed to malloc for %s: %m\n", path); fclose(file); return NULL; } // Read file contents. size_t bytes_read = fread(contents, 1, length, file); if ((long)bytes_read < length) { DEBUG_PRINTF("short read on %s, contents probably changed", path); } fclose(file); // Null-terminate the string. contents[bytes_read] = '\0'; DEBUG_PRINTF("%s => %s\n", path, contents); return contents; } /** * Check if NVMe vendor in sysfs matches Microsoft's vendor ID. */ int is_microsoft_nvme_device(const char *device_name) { char vendor_id_path[MAX_PATH]; snprintf(vendor_id_path, sizeof(vendor_id_path), "%s/%s/device/vendor", SYS_CLASS_NVME_PATH, device_name); char *vendor_id_string = read_file_as_string(vendor_id_path); if (vendor_id_string == NULL) { return false; } long int vendor_id = strtol(vendor_id_string, NULL, 16); free(vendor_id_string); return vendor_id == MICROSOFT_NVME_VENDOR_ID; } /** * Query the NVMe namespace for the vendor specific data. * * For Azure devices, the vendor-specific data is current exposed as a string. * It will include the type of device and various properties in the format: * key1=value1,key2=value2,...\0. * * Anything beyond the terminating null-byte is currently undefined and * consequently ignored. */ char *query_namespace_vs(const char *namespace_path) { int nsid = get_namespace_id_for_path(namespace_path); if (nsid < 0) { fprintf(stderr, "failed to parse namespace id: %s\n", namespace_path); return NULL; } int fd = open(namespace_path, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open %s: %m\n", namespace_path); return NULL; } DEBUG_PRINTF("Opened device: %s with namespace id: %d...\n", namespace_path, nsid); struct nvme_id_ns *ns = NULL; if (posix_memalign((void **)&ns, sysconf(_SC_PAGESIZE), sizeof(struct nvme_id_ns)) != 0) { fprintf(stderr, "failed posix_memalign for %s: %m\n", namespace_path); close(fd); return NULL; } struct nvme_admin_cmd cmd = { .opcode = 0x06, // Identify command .nsid = nsid, .addr = (unsigned long)ns, .data_len = sizeof(ns), }; if (ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd) < 0) { fprintf(stderr, "failed NVME_IOCTL_ADMIN_CMD ioctl for %s: %m\n", namespace_path); free(ns); close(fd); return NULL; } char *vs = strndup((const char *)ns->vs, sizeof(ns->vs)); free(ns); close(fd); return vs; } /** * Callback for scandir() to filter for NVMe namespaces. */ int is_nvme_namespace(const struct dirent *entry) { unsigned int ctrl, nsid; char p; // Check for NVME controller name format: nvmen return sscanf(entry->d_name, "nvme%un%u%c", &ctrl, &nsid, &p) == 2; } /** * Enumerate namespaces for a controller. */ int enumerate_namespaces_for_controller(struct nvme_controller *ctrl) { struct dirent **namelist; int n = scandir(ctrl->sys_path, &namelist, is_nvme_namespace, alphasort); if (n < 0) { fprintf(stderr, "failed scandir for %s: %m\n", ctrl->sys_path); return 1; } DEBUG_PRINTF("found %d namespace(s) for controller=%s:\n", n, ctrl->name); for (int i = 0; i < n; i++) { char namespace_path[MAX_PATH]; snprintf(namespace_path, sizeof(namespace_path), "/dev/%s", namelist[i]->d_name); char *vs = query_namespace_vs(namespace_path); if (vs != NULL) { printf("%s: %s\n", namespace_path, vs); free(vs); } free(namelist[i]); } free(namelist); return 0; } /** * Callback for scandir() to filter for Microsoft Azure NVMe controllers. */ int is_azure_nvme_controller(const struct dirent *entry) { unsigned int ctrl; char p; // Check for NVME controller name format: nvme if (sscanf(entry->d_name, "nvme%u%c", &ctrl, &p) != 1) { return false; } return is_microsoft_nvme_device(entry->d_name); } /** * Enumerate Microsoft Azure NVMe controllers. */ int enumerate_azure_nvme_controllers() { struct dirent **namelist; int n = scandir(SYS_CLASS_NVME_PATH, &namelist, is_azure_nvme_controller, alphasort); if (n < 0) { fprintf(stderr, "no NVMe devices found in %s\n", SYS_CLASS_NVME_PATH); return 1; } DEBUG_PRINTF("found %d controllers\n", n); for (int i = 0; i < n; i++) { struct nvme_controller ctrl; strncpy(ctrl.name, namelist[i]->d_name, sizeof(ctrl.name)); snprintf(ctrl.dev_path, sizeof(ctrl.dev_path), "/dev/%s", ctrl.name); snprintf(ctrl.sys_path, sizeof(ctrl.sys_path), "%s/%s", SYS_CLASS_NVME_PATH, ctrl.name); enumerate_namespaces_for_controller(&ctrl); free(namelist[i]); } free(namelist); return 0; } /** * Print a udev key-value pair for environment variable. */ void print_udev_key_value(const char *key, const char *value) { printf("AZURE_NVME_"); while (*key) { putchar(toupper((unsigned char)*key)); key++; } printf("=%s\n", value); } /** * Print udev environment variables for all vs properties. * * Example parsing for vs: * type=local,index=2,name=nvme-600G-2 * * Environment variables printed include: * AZURE_NVME_TYPE=local * AZURE_NVME_INDEX=2 * AZURE_NVME_NAME=nvme-600G-2 */ int parse_vs_for_udev_import(char *vs) { char *vs_copy = strdup(vs); char *outer_saveptr = NULL; char *inner_saveptr = NULL; char *pair = strtok_r(vs_copy, ",", &outer_saveptr); while (pair != NULL) { char *key = strtok_r(pair, "=", &inner_saveptr); char *value = strtok_r(NULL, "=", &inner_saveptr); if (key == NULL || value == NULL) { fprintf(stderr, "failed to parse key-value pair: %s\n", pair); free(vs_copy); return 1; } print_udev_key_value(key, value); pair = strtok_r(NULL, ",", &outer_saveptr); } free(vs_copy); return 0; } /** * Execute udev mode, printing out environment variables for import. * * AZURE_NVME_VS: * AZURE_NVME_TYPE: * AZURE_NVME_INDEX: * AZURE_NVME_NAME: * etc... */ int execute_udev_import(void) { const char *dev_name = getenv("DEVNAME"); if (dev_name == NULL) { fprintf(stderr, "environment variable 'DEVNAME' not set\n"); return 1; } char *vs = query_namespace_vs(dev_name); if (vs == NULL) { fprintf(stderr, "failed to query namespace vendor-specific data: %s\n", dev_name); return 1; } printf("AZURE_NVME_VS=%s\n", vs); parse_vs_for_udev_import(vs); free(vs); return 0; } int main(int argc, const char **argv) { for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--debug") == 0) { debug = true; continue; } if (strcmp(argv[i], "--udev") == 0) { udev_mode = true; continue; } if (strcmp(argv[i], "--version") == 0) { printf("azure-nvme-id %s\n", VERSION); return 0; } if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { printf("Usage: %s [--debug] [--udev|--help|--version]\n", argv[0]); return 0; } } if (debug) { debug_environment_variables(); } if (udev_mode) { return execute_udev_import(); } return enumerate_azure_nvme_controllers(); } azure-nvme-utils-0.2.0/src/nvme.h000066400000000000000000000016571463167055600166730ustar00rootroot00000000000000/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See LICENSE in the project root for license information. */ #include struct nvme_lbaf { __le16 ms; __u8 ds; __u8 rp; }; struct nvme_id_ns { __le64 nsze; __le64 ncap; __le64 nuse; __u8 nsfeat; __u8 nlbaf; __u8 flbas; __u8 mc; __u8 dpc; __u8 dps; __u8 nmic; __u8 rescap; __u8 fpi; __u8 dlfeat; __le16 nawun; __le16 nawupf; __le16 nacwu; __le16 nabsn; __le16 nabo; __le16 nabspf; __le16 noiob; __u8 nvmcap[16]; __le16 npwg; __le16 npwa; __le16 npdg; __le16 npda; __le16 nows; __u8 rsvd74[18]; __le32 anagrpid; __u8 rsvd96[3]; __u8 nsattr; __le16 nvmsetid; __le16 endgid; __u8 nguid[16]; __u8 eui64[8]; struct nvme_lbaf lbaf[16]; __u8 rsvd192[192]; __u8 vs[3712]; }; azure-nvme-utils-0.2.0/src/version.h.in000066400000000000000000000003701463167055600200070ustar00rootroot00000000000000/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See LICENSE in the project root for license information. */ #ifndef VERSION_H #define VERSION_H #define VERSION "@VERSION@" #endif // VERSION_H azure-nvme-utils-0.2.0/udev/000077500000000000000000000000001463167055600157205ustar00rootroot00000000000000azure-nvme-utils-0.2.0/udev/80-azure-nvme.rules.in000066400000000000000000000046751463167055600217330ustar00rootroot00000000000000ACTION!="add|change", GOTO="azure_nvme_end" SUBSYSTEM!="block", GOTO="azure_nvme_end" KERNEL!="nvme*", GOTO="azure_nvme_end" ATTRS{nsid}!="?*", GOTO="azure_nvme_end" ENV{ID_MODEL}=="Microsoft NVMe Direct Disk", GOTO="azure_nvme_direct_v1_start" ENV{ID_MODEL}=="Microsoft NVMe Direct Disk v2", GOTO="azure_nvme_direct_v2_start" ENV{ID_MODEL}=="MSFT NVMe Accelerator v1.0", GOTO="azure_nvme_remote_start" GOTO="azure_nvme_end" LABEL="azure_nvme_direct_v1_start" LABEL="azure_nvme_direct_v2_start" ATTRS{nsid}=="?*", ENV{AZURE_NVME_TYPE}="local" GOTO="azure_nvme_start" LABEL="azure_nvme_remote_start" ATTRS{nsid}=="?*", ENV{AZURE_LUN_CALCULATION_BY_NSID_ENABLED}="@AZURE_LUN_CALCULATION_BY_NSID_ENABLED@" ENV{AZURE_LUN_CALCULATION_BY_NSID_ENABLED}=="1", ATTRS{nsid}=="1", ENV{AZURE_NVME_TYPE}="os", GOTO="azure_nvme_start" ENV{AZURE_LUN_CALCULATION_BY_NSID_ENABLED}=="1", ATTRS{nsid}=="?*", ENV{AZURE_NVME_TYPE}="data" ENV{AZURE_LUN_CALCULATION_BY_NSID_ENABLED}=="1", ENV{AZURE_NVME_TYPE}=="data", ATTRS{nsid}=="?*", PROGRAM="/bin/sh -ec 'echo $$((%s{nsid}-2))'", ENV{AZURE_NVME_LUN}="$result" GOTO="azure_nvme_start" LABEL="azure_nvme_start" ATTRS{nsid}=="?*", IMPORT{program}="@AZURE_NVME_ID_INSTALL_DIR@/azure-nvme-id --udev" # systemd v254 ships an updated 60-persistent-storage.rules that would allow # these to be deduplicated using $env{.PART_SUFFIX} ENV{DEVTYPE}=="disk", ENV{AZURE_NVME_TYPE}=="os", SYMLINK+="disk/azure/os" ENV{DEVTYPE}=="disk", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_INDEX}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-index/$env{AZURE_NVME_INDEX}" ENV{DEVTYPE}=="disk", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_LUN}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-lun/$env{AZURE_NVME_LUN}" ENV{DEVTYPE}=="disk", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_NAME}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-name/$env{AZURE_NVME_NAME}" ENV{DEVTYPE}=="partition", ENV{AZURE_NVME_TYPE}=="os", SYMLINK+="disk/azure/os-part%n" ENV{DEVTYPE}=="partition", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_INDEX}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-index/$env{AZURE_NVME_INDEX}-part%n" ENV{DEVTYPE}=="partition", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_LUN}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-lun/$env{AZURE_NVME_LUN}-part%n" ENV{DEVTYPE}=="partition", ENV{AZURE_NVME_TYPE}=="?*", ENV{AZURE_NVME_NAME}=="?*", SYMLINK+="disk/azure/$env{AZURE_NVME_TYPE}/by-name/$env{AZURE_NVME_NAME}-part%n" LABEL="azure_nvme_end"