[PATCH 0/2] nvmet: add namespace-level debugfs for reservation state

Guixin Liu kanie at linux.alibaba.com
Mon Jul 6 03:28:18 PDT 2026



在 2026/7/6 15:59, Daniel Wagner 写道:
> On Mon, Jul 06, 2026 at 11:10:41AM +0800, Guixin Liu wrote:
>>>>> Example output with two registered hosts and an active holder:
>>>>>
>>>>>     $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
>>>>>     enable : 1
>>>>>     generation : 2
>>>>>     notify_mask : 0x0
>>>>>     rtype : write_exclusive
>>>>>     holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>>     registrants:
>>>>>       hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>>       hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
>>>> I expect blktests will make use of this interface eventually. The parser
>>>> for this wont be dead simple, sure doable but not simple. If you see a
>>>> way to make a bit simpler I wouldn't mind.
>>> How about this:
>>>
>>> 1. One holer, multi registrants:
>>>    enable=1
>>>    generation=2
>>>    notify_mask=0x0
>>>    rtype=write_exclusive
>>>    holder=11111111-1111-1111-1111-111111111111,0x1111
>>>    reg=11111111-1111-1111-1111-111111111111,0x1111
>>>    reg=22222222-2222-2222-2222-222222222222,0x2222
>>>
>>> 2. No holder, multi registrants:
>>>    enable=1
>>>    generation=1
>>>    notify_mask=0x0
>>>    rtype=none
>>>    holder=none
>>>    reg=11111111-1111-1111-1111-111111111111,0x1111
>>>    reg=22222222-2222-2222-2222-222222222222,0x2222
>>>
>>> 3. No registrant:
>>>    enable=1
>>>    generation=0
>>>    notify_mask=0x0
>>>    rtype=none
>>>    holder=none
>>>
>>> 4. Reservation not enabled:
>>>    enable=0
>>>
>>> Otherwise, the notify_mask can be stringization:
>>>
>>>    notify_mask=reg_preempted,resv_released,resv_preempted
> Sorry, missed your previous post. This looks easier to parser (*), but I
> think it's up to Shiinchiro to make the call.
>
> Thanks,
> Daniel
>
> (*) I asked a LLM to generate one and it looks straight forward.
>
> #!/bin/bash
>
> # Clean plaintext data with email/quote formatting completely removed
> DATA=$(cat << 'EOF'
>    19   enable=1
>    20   generation=2
>    21   notify_mask=0x0
>    22   rtype=write_exclusive
>    23   holder=11111111-1111-1111-1111-111111111111,0x1111
>    24   reg=11111111-1111-1111-1111-111111111111,0x1111
>    25   reg=22222222-2222-2222-2222-222222222222,0x2222
>    26
>    27 2. No holder, multi registrants:
>    28   enable=1
>    29   generation=1
>    30   notify_mask=0x0
>    31   rtype=none
>    32   holder=none
>    33   reg=11111111-1111-1111-1111-111111111111,0x1111
>    34   reg=22222222-2222-2222-2222-222222222222,0x2222
>    35
>    36 3. No registrant:
>    37   enable=1
>    38   generation=0
>    39   notify_mask=0x0
>    40   rtype=none
>    41   holder=none
>    42
>    43 4. Reservation not enabled:
>    44   enable=0
> EOF
> )
>
> # Declare an associative array to store parsed data
> declare -A INI_DATA
>
> # Tracks the active section namespace
> current_section="1. Default"
>
> # Read line-by-line
> while IFS= read -r raw_line; do
>      # Strip leading line numbers (e.g., "  19 ") and trim surrounding spaces
>      line=$(echo "$raw_line" | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]+//; s/^[[:space:]]+//; s/[[:space:]]+$//')
>
>      # Skip empty lines
>      [[ -z "$line" ]] && continue
>
>      # Check if the line is a section header (e.g., "2. No holder, multi registrants:")
>      if [[ "$line" =~ ^[0-9]+\. ]]; then
>          current_section="$line"
>          continue
>      fi
>
>      # Parse Key=Value configurations
>      if [[ "$line" == *"="* ]]; then
>          key="${line%%=*}"
>          val="${line#*=}"
>          
>          # Build a compound key: "SectionName|||KeyName"
>          map_key="${current_section}|||${key}"
>
>          # If key already exists in this section, append value using a pipe '|' delimiter
>          if [[ -n "${INI_DATA[$map_key]}" ]]; then
>              INI_DATA[$map_key]+="|$val"
>          else
>              INI_DATA[$map_key]="$val"
>          fi
>      fi
> done <<< "$DATA"
>
> # --- Demonstrate Accessing the Generated Arrays ---
> echo "=== PARSED DATA STRUCTURE ==="
>
> for compound_key in "${!INI_DATA[@]}"; do
>      section="${compound_key%%|||*}"
>      key="${compound_key##*|||}"
>      raw_value="${INI_DATA[$compound_key]}"
>
>      echo "[$section]"
>      
>      # If the value contains our delimiter '|', turn it into a real Bash array
>      if [[ "$raw_value" == *"|"* ]]; then
>          IFS='|' read -r -a val_array <<< "$raw_value"
>          echo "  Key '$key' is an ARRAY (${#val_array[@]} elements):"
>          for i in "${!val_array[@]}"; do
>              echo "    -> index [$i]: ${val_array[$i]}"
>          done
>      else
>          echo "  Key '$key' is a STRING:"
>          echo "    -> value: $raw_value"
>      fi
>      echo "----------------------------------------"
> done
>
>
> === PARSED DATA STRUCTURE ===
> [3. No registrant:]
>    Key 'rtype' is a STRING:
>      -> value: none
> ----------------------------------------
> [3. No registrant:]
>    Key 'generation' is a STRING:
>      -> value: 0
> ----------------------------------------
> [1. Default]
>    Key 'generation' is a STRING:
>      -> value: 2
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'holder' is a STRING:
>      -> value: none
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'reg' is an ARRAY (2 elements):
>      -> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
>      -> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'enable' is a STRING:
>      -> value: 1
> ----------------------------------------
> [1. Default]
>    Key 'enable' is a STRING:
>      -> value: 1
> ----------------------------------------
> [1. Default]
>    Key 'notify_mask' is a STRING:
>      -> value: 0x0
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'generation' is a STRING:
>      -> value: 1
> ----------------------------------------
> [3. No registrant:]
>    Key 'notify_mask' is a STRING:
>      -> value: 0x0
> ----------------------------------------
> [1. Default]
>    Key 'holder' is a STRING:
>      -> value: 11111111-1111-1111-1111-111111111111,0x1111
> ----------------------------------------
> [3. No registrant:]
>    Key 'holder' is a STRING:
>      -> value: none
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'rtype' is a STRING:
>      -> value: none
> ----------------------------------------
> [3. No registrant:]
>    Key 'enable' is a STRING:
>      -> value: 1
> ----------------------------------------
> [4. Reservation not enabled:]
>    Key 'enable' is a STRING:
>      -> value: 0
> ----------------------------------------
> [1. Default]
>    Key 'rtype' is a STRING:
>      -> value: write_exclusive
> ----------------------------------------
> [2. No holder, multi registrants:]
>    Key 'notify_mask' is a STRING:
>      -> value: 0x0
> ----------------------------------------
> [1. Default]
>    Key 'reg' is an ARRAY (2 elements):
>      -> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
>      -> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
> ----------------------------------------
OK, this seems feasible.

Hi Shin'ichiro:
     Does this work for you?

Best Regards,
Guixin Liu




More information about the Linux-nvme mailing list