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

Daniel Wagner <[email protected]>
Newsgroups org.infradead.lists.linux-nvme
Message-ID <[email protected]>
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
----------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.