Skip to content

Commit 4562d80

Browse files
committed
mkdumprd: basic support for btrfs subvol
The kdump scripts previously could not correctly handle cases where the dump target was located on a btrfs subvolume. The logic for finding the mount point did not account for the way subvolumes are represented, leading to failures in identifying the target device and checking for available space. This patch introduces support for btrfs subvolumes by: 1. Adding a new helper function `get_btrfs_subvol_from_mntopt` to extract the subvolume name from mount options. 2. Modifying `get_mntpoint_from_target` to accept a subvolume name. When a subvolume is provided, it correctly identifies the mount point by looking for the source entry that includes the subvolume name (e.g., `/dev/sda1[/subvol]`). 3. Updating various functions in `mkdumprd`, `kdump-lib.sh`, and the dracut module setup scripts to detect if the target is on a btrfs filesystem, parse the subvolume, and pass it to the relevant functions for mount point resolution and free space checks. This ensures that kdump can now be reliably configured with a dump target located on a btrfs subvolume. Signed-off-by: Lichen Liu <[email protected]>
1 parent e44958c commit 4562d80

File tree

4 files changed

+48
-22
lines changed

4 files changed

+48
-22
lines changed

dracut/99kdumpbase/module-setup.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -683,16 +683,21 @@ kdump_install_pre_post_conf() {
683683
}
684684

685685
default_dump_target_install_conf() {
686-
local _target _fstype
686+
local _target _fstype _subvol _options
687687
local _mntpoint _save_path
688688

689689
is_user_configured_dump_target && return
690690

691691
_save_path=$(get_bind_mount_source "$(get_save_path)")
692692
_target=$(get_target_from_path "$_save_path")
693-
_mntpoint=$(get_mntpoint_from_target "$_target")
694-
693+
_options=$(get_mount_info OPTIONS target "$_save_path" -f)
695694
_fstype=$(get_fs_type_from_target "$_target")
695+
if [[ $_fstype == btrfs ]]; then
696+
_subvol=$(get_btrfs_subvol_from_mntopt "$_options")
697+
fi
698+
699+
_mntpoint=$(get_mntpoint_from_target "$_target" "$_subvol")
700+
696701
if is_fs_type_nfs "$_fstype"; then
697702
kdump_collect_netif_usage "$_target"
698703
_fstype="nfs"

kdump-lib-initramfs.sh

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,29 @@ get_fs_type_from_target()
110110

111111
get_mntpoint_from_target()
112112
{
113-
# get the first TARGET when SOURCE doesn't end with ].
114-
# In most cases, a SOURCE ends with ] when fsroot or subvol exists.
115-
_mntpoint=$(get_mount_info TARGET,SOURCE source "$1" | grep -v "\]$" | awk 'NR==1 { print $1 }')
116-
113+
_subvol="$2"
114+
if [ -z "$_subvol" ]; then
115+
# get the first TARGET when SOURCE doesn't end with ].
116+
# In most cases, a SOURCE ends with ] when fsroot or subvol exists.
117+
_mntpoint=$(get_mount_info TARGET,SOURCE source "$1" | grep -v "\]$" | awk 'NR==1 { print $1 }')
118+
else
119+
# btrfs with subvol
120+
_mntpoint=$(get_mount_info TARGET,SOURCE source "$1" | grep "\[$_subvol\]$" | awk 'NR==1 { print $1 }')
121+
fi
117122
# fallback to the old way when _mntpoint is empty.
118123
[ -n "$_mntpoint" ] || _mntpoint=$(get_mount_info TARGET source "$1" -f)
119124
echo "$_mntpoint"
120125
}
121126

127+
get_btrfs_subvol_from_mntopt()
128+
{
129+
_subvol=${1#*subvol=}
130+
# mount option may not contain subvol
131+
[ "$1" != "$_subvol" ] || return 0
132+
_subvol=${_subvol%%,*}
133+
echo "$_subvol"
134+
}
135+
122136
is_ssh_dump_target()
123137
{
124138
kdump_get_conf_val ssh | grep -q @

kdump-lib.sh

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ get_kdump_targets()
177177
# part is the bind mounted directory which quotes by bracket "[]".
178178
get_bind_mount_source()
179179
{
180-
local _mnt _path _src _opt _fstype
180+
local _mnt _path _src _opt _fstype _subvol
181181
local _fsroot _src_nofsroot
182182

183183
_mnt=$(df "$1" | tail -1 | awk '{print $NF}')
@@ -200,15 +200,13 @@ get_bind_mount_source()
200200

201201
_fsroot=${_src#"${_src_nofsroot}"[}
202202
_fsroot=${_fsroot%]}
203-
_mnt=$(get_mntpoint_from_target "$_src_nofsroot")
204-
205203
# for btrfs, _fsroot will also contain the subvol value as well, strip it
206204
if [[ $_fstype == btrfs ]]; then
207-
local _subvol
208-
_subvol=${_opt#*subvol=}
209-
_subvol=${_subvol%,*}
205+
_subvol=$(get_btrfs_subvol_from_mntopt "$_opt")
210206
_fsroot=${_fsroot#"$_subvol"}
211207
fi
208+
_mnt=$(get_mntpoint_from_target "$_src_nofsroot" "$_subvol")
209+
212210
echo "$_mnt$_fsroot$_path"
213211
}
214212

@@ -219,11 +217,12 @@ get_mntopt_from_target()
219217

220218
# Get the path where the target will be mounted in kdump kernel
221219
# $1: kdump target device
220+
# $2: btrfs subvol
222221
get_kdump_mntpoint_from_target()
223222
{
224223
local _mntpoint
225224

226-
_mntpoint=$(get_mntpoint_from_target "$1")
225+
_mntpoint=$(get_mntpoint_from_target "$1" "$2")
227226
# mount under /sysroot if dump to root disk or mount under
228227
# mount under /kdumproot if dump target is not mounted in first kernel
229228
# mount under /kdumproot/$_mntpoint in other cases in 2nd kernel.

mkdumprd

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,13 @@ to_mount()
7676
{
7777
local _target=$1 _fstype=$2 _options=$3 _sed_cmd _new_mntpoint _pdev
7878

79-
_new_mntpoint=$(get_kdump_mntpoint_from_target "$_target")
8079
_fstype="${_fstype:-$(get_fs_type_from_target "$_target")}"
8180
_options="${_options:-$(get_mntopt_from_target "$_target")}"
8281
_options="${_options:-defaults}"
82+
if [[ $_fstype == btrfs ]]; then
83+
_subvol=$(get_btrfs_subvol_from_mntopt "$_options")
84+
fi
85+
_new_mntpoint=$(get_kdump_mntpoint_from_target "$_target" "$_subvol")
8386

8487
if [[ $_fstype == "nfs"* ]]; then
8588
_pdev=$_target
@@ -146,7 +149,7 @@ mkdir_save_path_ssh()
146149
#$1=dump target
147150
get_fs_size()
148151
{
149-
df --output=avail "$(get_mntpoint_from_target "$1")/$SAVE_PATH" | tail -1
152+
df --output=avail "$(get_mntpoint_from_target "$1" "$2")/$SAVE_PATH" | tail -1
150153
}
151154

152155
#Function: get_raw_size
@@ -159,6 +162,7 @@ get_raw_size()
159162
#Function: check_size
160163
#$1: dump type string ('raw', 'fs', 'ssh')
161164
#$2: dump target
165+
#$3: btrfs subvol
162166
check_size()
163167
{
164168
local avail memtotal
@@ -172,7 +176,7 @@ check_size()
172176
avail=$(get_ssh_size "$2")
173177
;;
174178
fs)
175-
avail=$(get_fs_size "$2")
179+
avail=$(get_fs_size "$2" "$3")
176180
;;
177181
*)
178182
return
@@ -302,20 +306,24 @@ add_mount()
302306
#handle the case user does not specify the dump target explicitly
303307
handle_default_dump_target()
304308
{
305-
local _target
306-
local _mntpoint
309+
local _target _mntpoint _fstype _subvol _options
307310

308311
is_user_configured_dump_target && return
309312

310313
check_save_path_fs "$SAVE_PATH"
311314

312315
_save_path=$(get_bind_mount_source "$SAVE_PATH")
316+
_options=$(get_mount_info OPTIONS target "$_save_path" -f)
313317
_target=$(get_target_from_path "$_save_path")
314-
_mntpoint=$(get_mntpoint_from_target "$_target")
318+
_fstype=$(get_fs_type_from_target "$_target")
319+
if [[ $_fstype == btrfs ]]; then
320+
_subvol=$(get_btrfs_subvol_from_mntopt "$_options")
321+
fi
315322

323+
_mntpoint=$(get_mntpoint_from_target "$_target" "$_subvol")
316324
SAVE_PATH=${_save_path##"$_mntpoint"}
317-
add_mount "$_target"
318-
check_size fs "$_target"
325+
add_mount "$_target" "$_fstype" "$_options"
326+
check_size fs "$_target" "$_subvol"
319327
}
320328

321329
# firstly get right SSH_KEY_LOCATION

0 commit comments

Comments
 (0)