Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-108623

Anaconda installation with kickstart over NFS results in wrong path(double filename)

Linking RHIVOS CVEs to...Migration: Automation ...Sync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • rhel-8.10
    • dracut
    • No
    • Moderate
    • rhel-bootloader
    • 5
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • Unspecified
    • Unspecified
    • Unspecified
    • x86_64
    • None

      What were you trying to do that didn't work?

      Installing RHEL with kickstart hosted over NFS

      What is the impact of this issue to you?

      Installation fails for the customer due to wrong path. 

      ~~~

      [ 1917.653079] dracut-initqueue[7949]: cp: cannot stat '/run/nfs_mnt0/tfdm.ks/tfdm.ks': Not a directory
      [ 1917.653197] dracut-initqueue[875]: //lib/url-lib.sh@152(nfs_fetch_url): return 1
      [ 1917.653271] dracut-initqueue[875]: //lib/dracut/hooks/initqueue/fetch-ks-eno1.sh@16(source): warn 'anaconda: failed to fetch kickstart from nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks'

      ~~~

      The variable mntdir=/run/nfs_mnt0/tfdm.ks  has tfdm.ks filename included.

      After checking the /tmp/ks.cfg not present under nsf_fetch_url(), the cp command adds the filename again to the path to cause this failure:

      ~~~
      [ 1876.325934] dracut-initqueue[875]: //lib/url-lib.sh@142(nfs_fetch_url): '[' -z /run/nfs_mnt0/tfdm.ks ']'
      [ 1876.325966] dracut-initqueue[875]: //lib/url-lib.sh@149(nfs_fetch_url): '[' -z /tmp/ks.cfg ']'
      [ 1876.325997] dracut-initqueue[875]: //lib/url-lib.sh@152(nfs_fetch_url): cp -f – /run/nfs_mnt0/tfdm.ks/tfdm.ks /tmp/ks.cfg
      ~~~

      Please provide the package NVR for which the bug is seen:

      dracut-049-233.git20240115.el

       

      Is this a known issue or BUG ,

      Here is the code snippet I got from rhpkg after appliying patches.

      rhpkg/dracut/dracut-049-build/dracut-049/modules.d/45url-lib
      ~~~
      <SNIP>
      121 nfs_already_mounted() {
      122 local server="$1" path="$2" localdir="" s="" p=""
      123 cat /proc/mounts | while read src mnt rest || [ -n "$src" ]; do
      124 splitsep ":" "$src" s p
      125 if [ "$server" = "$s" ]; then
      126 ¦ if [ "$path" = "$p" ]; then
      127 ¦ echo $mnt
      128 ¦ elif str_starts "$path" "$p"; then
      129 ¦ echo $mnt/${path#$p/}
      130 ¦ fi
      131 fi
      132 done
      133 }
      134 
      135 nfs_fetch_url() {
      136 local url="$1" outloc="$2" nfs="" server="" path="" options=""
      137 nfs_to_var "$url" || return 255
      138 local filepath="${path%/}" filename="${path##/}" mntdir=""
      139 
      140 # skip mount if server:/filepath is already mounted
      141 mntdir=$(nfs_already_mounted "$server" "$path")
      142 if [ -z "$mntdir" ]; then
      143 local mntdir="$(mkuniqdir /run nfs_mnt)"
      144 mount_nfs "$nfs:$server:$filepath${options:+:$options}" "$mntdir"
      145 # lazy unmount during pre-pivot hook
      146 inst_hook -hook pre-pivot --name 99url-lib-umount-nfs"$(basename "$mntdir")" umount -l – "$mntdir"
      147 fi
      148 
      149 if [ -z "$outloc" ]; then
      150 outloc="$mntdir/$filename"
      151 else
      152 cp -f – "$mntdir/$filename" "$outloc" || return $?
      153 fi
      154 [ -f "$outloc" ] || return 253
      155 if [ -z "$2" ]; then echo "$outloc" ; fi
      156 } 
      <SNIP>
      ~~~
      99base/dracut-lib.sh
      ~~~
      44 # returns OK if $1 contains literal string $2 at the beginning, and isn't empty
      45 str_starts() {
      46 [ "${1#"$2"*}" != "$1" ]
      47 }
      ~~~
      

       

      Understanding the log and value flow in the code

      ~~~
      <SNIP>
      [ 1875.581917] dracut-initqueue[875]: //lib/url-lib.sh@22(fetch_url): local url=nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks outloc=/tmp/ks.cfg
      <SNIP>
      [ 1875.582494] dracut-initqueue[875]: //lib/url-lib.sh@26(fetch_url): nfs_fetch_url nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks /tmp/ks.cfg
      [ 1875.582526] dracut-initqueue[875]: //lib/url-lib.sh@136(nfs_fetch_url): local url=nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks outloc=/tmp/ks.cfg nfs= server= path= options=
      ###
      Here we call the nfs_to_var function on code #137
      ###
      [ 1875.582558] dracut-initqueue[875]: //lib/url-lib.sh@137(nfs_fetch_url): nfs_to_var nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks
      <SNIP>
      [ 1875.582705] dracut-initqueue[875]: //lib/nfs-lib.sh@80(anaconda_nfs_to_var): nfs=nfs
      [ 1875.582855] dracut-initqueue[875]: //lib/nfs-lib.sh@83(anaconda_nfs_to_var): server= 172.25.114.43
      [ 1875.582901] dracut-initqueue[875]: //lib/nfs-lib.sh@84(anaconda_nfs_to_var): options=vers=3
      [ 1875.582932] dracut-initqueue[875]: //lib/nfs-lib.sh@85(anaconda_nfs_to_var): path=/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks
      <SNIP>
      [ 1875.583112] dracut-initqueue[875]: //lib/nfs-lib.sh@25(nfs_to_var): strstr /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks %s
      [ 1875.583143] dracut-initqueue[875]: //lib/dracut-lib.sh@27(strstr): '[' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks '!=' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks ']'
      [ 1875.714789] dracut-initqueue[875]: //lib/url-lib.sh@138(nfs_fetch_url): local filepath=/opt_repo/TFDM/config_t2501a20/kickstart filename=tfdm.ks mntdir=
      ###
      Now so far the variable values are looking good, we have reached line 140 in code lines
      Variables server & path are populated to contain IP and the complete path.
      140 # skip mount if server:/filepath is already mounted
      141 mntdir=$(nfs_already_mounted "$server" "$path")
      ###
      [ 1875.714930] dracut-initqueue[7858]: ///lib/url-lib.sh@141(nfs_fetch_url): nfs_already_mounted 172.25.114.43 /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks
      [ 1875.714984] dracut-initqueue[7858]: ///lib/url-lib.sh@122(nfs_already_mounted): local server= 172.25.114.43 path=/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks localdir= s= p=
      [ 1875.715094] dracut-initqueue[7859]: ///lib/url-lib.sh@123(nfs_already_mounted): cat /proc/mounts
      [ 1875.715234] dracut-initqueue[7860]: ///lib/url-lib.sh@123(nfs_already_mounted): read src mnt rest
      ###
      After checking multiple mounts and exiting with result code 0, finally it finds the server match on a mount and then compares path string 
      ###
      [ 1876.046026] dracut-initqueue[7860]: ///lib/url-lib.sh@123(nfs_already_mounted): read src mnt rest
      [ 1876.046056] dracut-initqueue[7860]: ///lib/url-lib.sh@124(nfs_already_mounted): splitsep : 172.25.114.43 
      :/opt_repo/RHEL_8/TFDM_CAS/ s p
      [ 1876.324792] dracut-initqueue[7860]: ///lib/dracut-lib.sh@392(splitsep): debug_off
      [ 1876.324832] dracut-initqueue[7860]: ///lib/dracut-lib.sh@18(debug_off): set +x
      [ 1876.324867] dracut-initqueue[7860]: ///lib/dracut-lib.sh@405(splitsep): return 0
      [ 1876.324905] dracut-initqueue[7860]: ///lib/url-lib.sh@125(nfs_already_mounted): '[' 172.25.114.43 = 172.25.114.43 ']'
      [ 1876.324939] dracut-initqueue[7860]: ///lib/url-lib.sh@126(nfs_already_mounted): '[' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks = /opt_repo/RHEL_8/TFDM_CAS/ ']'
      [ 1876.325007] dracut-initqueue[7860]: ///lib/url-lib.sh@128(nfs_already_mounted): str_starts /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks /opt_repo/RHEL_8/TFDM_CAS/
      [ 1876.325056] dracut-initqueue[7860]: ///lib/dracut-lib.sh@46(str_starts): '[' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks '!=' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks ']'
      [ 1876.325092] dracut-initqueue[7860]: ///lib/url-lib.sh@123(nfs_already_mounted): read src mnt rest 
      ###
      Loop continues due to mismatched path though same IP
      ###
      <SNIP>
      [ 1876.325355] dracut-initqueue[7860]: ///lib/url-lib.sh@123(nfs_already_mounted): read src mnt rest
      [ 1876.325409] dracut-initqueue[7860]: ///lib/url-lib.sh@124(nfs_already_mounted): splitsep : 172.25.114.43
      :/opt_repo/TFDM/config_t2501a20/kickstart s p
      [ 1876.325439] dracut-initqueue[7860]: ///lib/dracut-lib.sh@392(splitsep): debug_off
      [ 1876.325529] dracut-initqueue[7860]: ///lib/dracut-lib.sh@18(debug_off): set +x
      [ 1876.325561] dracut-initqueue[7860]: ///lib/dracut-lib.sh@405(splitsep): return 0
      [ 1876.325591] dracut-initqueue[7860]: ///lib/url-lib.sh@125(nfs_already_mounted): '[' 172.25.114.43 = 172.25.114.43 ']'
      [ 1876.325620] dracut-initqueue[7860]: ///lib/url-lib.sh@126(nfs_already_mounted): '[' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks = /opt_repo/TFDM/config_t2501a20/kickstart ']'
      ###
      Since the path is not exact match the code follows str_starts function again followed by echo (which I am struggling to make sense of) 
      128 ¦ elif str_starts "$path" "$p"; then
      129 ¦ echo $mnt/${path#$p/}
      ###
      [ 1876.325664] dracut-initqueue[7860]: ///lib/url-lib.sh@128(nfs_already_mounted): str_starts /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks /opt_repo/TFDM/config_t2501a20/kickstart
      [ 1876.325694] dracut-initqueue[7860]: ///lib/dracut-lib.sh@46(str_starts): '[' /tfdm.ks '!=' /opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks ']'
      [ 1876.325723] dracut-initqueue[7860]: ///lib/url-lib.sh@129(nfs_already_mounted): echo /run/nfs_mnt0/tfdm.ks
      <SNIP>
      ###
      Here we get the mntdir set and then the wrong path issue highlighted by Juanma 
      ###
      [ 1876.325863] dracut-initqueue[875]: //lib/url-lib.sh@141(nfs_fetch_url): mntdir=/run/nfs_mnt0/tfdm.ks
      [ 1876.325934] dracut-initqueue[875]: //lib/url-lib.sh@142(nfs_fetch_url): '[' -z /run/nfs_mnt0/tfdm.ks ']'
      [ 1876.325966] dracut-initqueue[875]: //lib/url-lib.sh@149(nfs_fetch_url): '[' -z /tmp/ks.cfg ']'
      [ 1876.325997] dracut-initqueue[875]: //lib/url-lib.sh@152(nfs_fetch_url): cp -f – /run/nfs_mnt0/tfdm.ks/tfdm.ks /tmp/ks.cfg
      [ 1876.326147] dracut-initqueue[7861]: cp: cannot stat '/run/nfs_mnt0/tfdm.ks/tfdm.ks': Not a directory
      [ 1876.326249] dracut-initqueue[875]: //lib/url-lib.sh@152(nfs_fetch_url): return 1
      [ 1876.326296] dracut-initqueue[875]: //lib/dracut/hooks/initqueue/fetch-ks-eno1.sh@16(source): warn 'anaconda: failed to fetch kickstart from nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks'
      [ 1876.326360] dracut-initqueue[875]: //lib/dracut-lib.sh@79(warn): echo 'Warning: anaconda: failed to fetch kickstart from nfs:vers=3:172.25.114.43:/opt_repo/TFDM/config_t2501a20/kickstart/tfdm.ks'
      ~~~
      

      It is not very clear but somewhere between url-lib.sh(nfs_already_mounted) code lines #128,129 and dracut-lib.sh(str_starts) code line 46 is returning string that includes tfdm.ks in path of "mntdir" and then cp on line #152 adds the tfdm.ks again after checking /tmp/ks.cfg doesn't exist.

      ~~~
      152 cp -f – "$mntdir/$filename" "$outloc" || return $?
      ~~~

              pvalena@redhat.com Pavel Valena
              rhn-support-plawate Pranav Lawate
              bootloader -eng-team bootloader -eng-team
              RHEL CS Plumbers QE Bot RHEL CS Plumbers QE Bot
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated: