[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#748962: marked as done (texlive-bastexlive-base: fmtutil-sys --all may not return error exit code under low free space condition.)



Your message dated Fri, 5 Jul 2019 09:38:53 +0200
with message-id <001337f3-c696-fa15-5114-0949b0ff8c7e@web.de>
and subject line Re: Bug#748962: texlive-bastexlive-base: fmtutil-sys --all may not return error exit code under low free space condition.
has caused the Debian Bug report #748962,
regarding texlive-bastexlive-base: fmtutil-sys --all may not return error exit code under low free space condition.
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
748962: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=748962
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---


Package: texlive-base
Version: 2013.20140408-1
Severity: important
Tags: d-i upstream patch

Dear Maintainer,


   * What led up to the situation?
     There was a strange failure of tex installation that was likely to be
caused by low free space condition.
It was not clear what failure could lead to such strange condition.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?
     I tried to figure out which command failed and at the same time failed to
    return proper exit value to the invoking programs.

   * What was the outcome of this action?
      I am attaching a patch to fix a slightly buggy function and
      tighten up checks in fmtutil.sh

   * What outcome did you expect instead?

     I think the installer will catch more errors due to low
free-space conditions during the installation with the patch, and this
should save support man-hours later.

Description

"fmtutil-sys --all" may not return error exit code under low free space condition.

This submission is an extension to 748271, but now with a much more
sharper focus.
Bug#748271: Info received (Bug#748271: [latex-cjk-common] latex command did not
work until I ran it once under superuser!?)

Thank you for the help so far regarding 748271.

Now, I *may* have identified WHY the error condition (under low space
condition) was not propagated to debian aptitude/apt-get installation
command under a very rage circumstance, and that could be the reason
why the incorrect TeX* installation was not caught earlier in my previous case.
(It may not be the root cause, but still the problem noticed in this bug report is
valid and can be fixed by the attached patch.)

I found that fmtutil.sh has a slightly buggy function.
(fmtutil.sh is part of texlive-base and is called eventually when
fmtutil-sys --all is called during installation to create .fmt files.)

I am attaching a patch to re-define the problematic function and to
replace log_warning with log_failure to signal the calling program
that a failure occurred.

Short Summary:

There is one shell-function "verbose()" which is used to invoke a
passed command and redirect stderr based on the exit value of
$mktexfmtMode (which is either "true" or "false").

Here is the definition of  buggy verbose()
from fmtutil.sh ( linked from /usr/bin/fmtutil to
/usr/share/texlive/texmf-dist/scripts/texlive/fmtutil.sh)

###############################################################################
# verbose (cmd)
#   execute cmd. Redirect output depending on $mktexfmtMode.
###############################################################################
verbose()
{
  $mktexfmtMode && ${1+"$@"} >&2 || ${1+"$@"}
}


This function as it is written today is buggy in the sense that
if the command fails when $mktexfmtMode is "true", the failing command
is executed TWICE (!). The first execution is with the rediretion of
STDERR. The second execution is without such redirection.
I think this is quite unintentional.

Also, the exit code from this execution of
"verbose other command options ..." becomes,
when the command fails on the LEFT Hand Side (LHS) of "||",
it is the exit code of the executed command (without re-direction) on
the right-hand side (RHS)

Under very space-tight conditions of a local file system, the failure
may happen while the stderr is re-directed (LHS), but a failure may not
happen when the command is executed as is without re-direction (RHS).

If this rare but possible scenario happens, "set -e" near the top of
fmtutil.sh is useless to catch the error since "verbose ...." 'as a whole'
returns the successful exit code of non-redirected command on the RHS
of "||".

MORE DETAILS:

This slightly buggy function is called within run_initex
(yes, that is where the fmt files are created eventually!)

This "verbose" function should be rewritten to avoid the re-execution
of the command "${1+"$@"}" when it fails when $mktexfmtMode is true.

Correction-1:

verbose()
{
    if $mktexfmtMode
    then
         ${1+"$@"} >&2
    else
        ${1+"$@"}
    fi
}

Background/Detective Work

After bug 748271 was closed, I tried to test what could go wrong a little
further.
I downloaded TeXLive 2013 source file from TUG web site.
I untarred it and began checking fmtutil-sys and found that these end up
as links to fmtutil and that is /usr/bin/fmtutil and again is a symlink
to /usr/share/texlive/texmf-dist/scripts/texlive/fmtutil.sh in Debian.
I tried to check what could go wrong and yet remain undetected, thus
failing to stop apt-get/aptitude as unsuccessful.

First thing, first.
As Norbert noted that there is "set -e" near the installed
fmtutil.sh. Great!
Surprisingly, this "set -e" is missing from the stock TeXLive 2013
source from TUG?! So maybe this is Debian only now?  I hope the upstream
TeXLive 2014 is fixed to have this "set -e" in fmtutil.sh

But then what can possibly go wrong?  My bet was that some commands
that are called are not returning the exit error code correctly.  I
traced what would happen when "--all" is passed to fmtutil, and found
that the user-defined functions are called in this manner.

main
 ->
  recreate_all
  ->
   recreate_loop
   ->
    run_initex
    ->
     verbose

In run_initex, the following piece of code is where the meat of
processing takes place.

--- quote
  verboseMsg "$progname: running \`$engine -ini  $tcxflag $jobswitch $prgswitch
$texargs' ..."

  # run in a subshell to get a local effect of TEXPOOL manipulation:
  (
    # If necessary, set TEXPOOL. Use absolute path, because of KPSE_DOT.
    $localpool && { TEXPOOL="`pwd`:$TEXPOOL"; export TEXPOOL; }
    verbose $engine -ini $tcxflag $jobswitch $prgswitch $texargs
  ) </dev/null
--- end quote

I realized that "verboseMsg" is to print out what is going on to the
log.
and somehow user-defined "verbose" command was used to invoke the
command, "$engine -ini $tcxflag $jobswitch $prgswitch $texargs".

Now, I checked what could go wrong with this small code snippet
by creating a very simplified script as follows.

I traced the function of verbose by running failing command (in this
case, "cp /dev/null /etc" that should fail under ordinary user) and
tested the operation in the following manner.

# /tmp/t-buggy.sh
---- begin quote of /tmp/t-buggy.sh
#!/bin/sh
#

# This script is to show that a failure of
# a command executed in verbose may be executed twice.

# false is not a good failure command sample

set -e

rc=0

verbose()  # original. This is buggy!
{
  $mktexfmtMode && ${1+"$@"} >&2 || ${1+"$@"}
}

#
run_initex()
{
  # run in a subshell to see if this changes anything.
  (
      echo "run_initex called"
      # DO SOMETHING THAT SHOULD FAIL
      cp /dev/null /etc
  ) </dev/null
}

# should succeed
verbose echo "hello, world"
echo "rc = $?"

echo before cp /dev/null /etc
# should fail
verbose cp /dev/null /etc
echo "rc = $?"

echo before subshell execution
# should fail
# run in a subshell ...
  (
    verbose cp /dev/null /etc
  ) </dev/null
echo "rc = $?"

echo before run_initex

mktexfmtMode=true
rc=1
# should fail since run_initex invokes false inside.
verbose run_initex $rc
echo "rc = $?"

echo before cp /dev/null /etc
# should fail under ordinary user account.
verbose cp /dev/null /etc
echo "rc = $?"

exit 0
--- end quote ---

The above is the content of the script.
Now let us run it.

$ /tmp/t-buggy.sh || echo failure
hello, world
rc = 0
before cp /dev/null /etc
cp: cannot create regular file '/etc/null': Permission denied
cp: cannot create regular file '/etc/null': Permission denied
failure
$

Please notice the repeated execution of the failed command by "verbose()".
That is because when the $mktexfmtMode is true the passed command is
executed with redirection.
In this case, the passed command "cp /dev/null /etc" should fail for
ordinary user.
But it is then  reexecited because of ||. Shell figured that Left-Hand
Side (LHS) failed and so tried to execute Right-Hand Side (RHS), too.

Now, when I rewrite verbose() in the suggested manner, what happens?
With fixed verbose (as in correction-1 above):

$ /tmp/t-OK.sh || echo fail
hello, world
rc = 0
before cp /dev/null /etc
cp: cannot create regular file '/etc/null': Permission denied
fail
$

Great. It is executed only once and I think this is the intended behavior.

BTW, suppose the intention of "verbose" was to capture whatever error
message (to file descriptor 2) to a file associated with STDOU and
later check error condition by searching for a certain string pattern, we may encounter a subtle problem *IF and ONLY IF* the command fails during an almost full file system condition when stderr is redirected to standard output, AND IF it succeeds without such redirection.

(If the file system was almost full, then the LHS of the original "||"
in "verbose" may have failed due to redirection, but somehow RHS may
have succeeded since there was no re-direction of error message to
almost full system. This may cause a very perplexing situation, indeed.)

Near line 765, we have the following code snippet in fmtutil.sh:

--- quote
  if test -f "$fmtfile"; then
    grep '^! ' $format.log >/dev/null 2>&1 &&
      log_warning "\`$engine -ini $tcxflag $jobswitch $prgswitch $texargs'
possibly failed."
--- end quote

Like I said, format.log may have failed to capture the error message
under a very space-tight condition in "verbose()".
I would love to see the "log_warning" to be changed to a
failing "log_failure" instead. (correction-2)

There is another usage of "log_warning" near line 796.

--- quote
          if cp "$destfile" "$mplib_mem_file" </dev/null; then
            mktexupd "$fulldestdir" "$mplib_mem_name"
          else
            log_warning "cp $destfile $mplib_mem_file failed."
          fi
--- end quote

The warning is indeed produced when the file system is full and "cp"
can fail then!  So, for obvious reasons, I would like to see this
usage of "log_warning" changed into "log_failure", too. (cprrectopm-3)

To wrap up, I am attaching a patch.
Please find below the diff of modified fmtutil.sh

fmtutil is actually /usr/share/texlive/texmf-dist/scripts/texlive/fmtutil.sh
diff of modified fmtutil in /tmp/fmtutil.sh
and
/usr/bin/fmtutil which is a symlink to the script under
/usr/share/texlive/...
was produced and attached.

Thank you in advance for your attention.

PS: This bug report was created by Debian's reportbug under a PC (32-bit Debian GNU/Linux)
and is not the same PC where the previous bug was reported, but
the shell script should be the same on 32-bit and 64-bit, and the script certainly
has a subtle problem.



-- Package-specific info:
IMPORTANT INFORMATION: We will only consider bug reports concerning
the packaging of TeX Live as relevant. If you have problems with
combination of packages in a LaTeX document, please consult your
local TeX User Group, the comp.text.tex user group, the author of
the original .sty file, or any other help resource.

In particular, bugs that are related to up-upstream, i.e., neither
Debian nor TeX Live (upstream), but the original package authors,
will be closed immediately.

   *** The Debian TeX Team is *not* a LaTeX Help Desk ***

If you report an error when running one of the TeX-related binaries
(latex, pdftex, metafont,...), or if the bug is related to bad or wrong
output, please include a MINIMAL example input file that produces the
error in your report.

Please run your example with
    (pdf)latex -recorder ...
(or any other program that supports -recorder) and send us the generated
file with the extension .fls, it lists all the files loaded during
the run and can easily explain problems induced by outdated files in
your home directory.

Don't forget to also include minimal examples of other files that are
needed, e.g. bibtex databases. Often it also helps
to include the logfile. Please, never send included pictures!

If your example file isn't short or produces more than one page of
output (except when multiple pages are needed to show the problem),
you can probably minimize it further. Instructions on how to do that
can be found at

http://www.minimalbeispiel.de/mini-en.html (english)

or

http://www.minimalbeispiel.de/mini.html (german)

##################################
minimal input file


##################################
other files

######################################
 List of ls-R files

-rw-r--r-- 1 root root 1047 May 13 17:52 /var/lib/texmf/ls-R
-rw-rw-r-- 1 root staff 80 May 13 16:05 /usr/local/share/texmf/ls-R
lrwxrwxrwx 1 root root 29 Jun 15  2013 /usr/share/texmf/ls-R -> /var/lib/texmf/ls-R-TEXMFMAIN
lrwxrwxrwx 1 root root 31 Apr  8 11:51 /usr/share/texlive/texmf-dist/ls-R -> /var/lib/texmf/ls-R-TEXLIVEDIST
lrwxrwxrwx 1 root root 31 Apr  8 11:51 /usr/share/texlive/texmf-dist/ls-R -> /var/lib/texmf/ls-R-TEXLIVEDIST
######################################
 Config files
-rw-r--r-- 1 root root 838 May 13 17:50 /etc/texmf/web2c/texmf.cnf
-rw-r--r-- 1 root root 4589 May 13 17:52 /var/lib/texmf/web2c/fmtutil.cnf
lrwxrwxrwx 1 root root 32 Apr  8 11:51 /usr/share/texmf/web2c/updmap.cfg -> /var/lib/texmf/updmap.cfg-DEBIAN
-rw-r--r-- 1 root root 3497 May 13 17:52 /var/lib/texmf/tex/generic/config/language.dat
######################################
 Files in /etc/texmf/web2c/
total 2
-rw-r--r-- 1 root root 283 Nov 10  2008 mktex.cnf
-rw-r--r-- 1 root root 838 May 13 17:50 texmf.cnf
######################################
 md5sums of texmf.d
ca40c66f144b4bafc3e59a2dd32ecb9c  /etc/texmf/texmf.d/00debian.cnf
d41d8cd98f00b204e9800998ecf8427e  /etc/texmf/texmf.d/20ptexjtex.bak
1df66bc319cec731e202eaf39f5d85e1  /etc/texmf/texmf.d/96JadeTeX.cnf

-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 3.2.0-4-686-pae (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)
Shell: /bin/sh linked to /bin/dash

Versions of packages texlive-base depends on:
ii  debconf [debconf-2.0]  1.5.52
ii  dpkg                   1.17.6
ii  libpaper-utils         1.1.24+nmu3
ii  luatex                 0.76.0-3
ii  tex-common             4.04
ii  texlive-binaries       2013.20130729.30972-2+b3
ii  ucf                    3.0027+nmu1
ii  xdg-utils              1.1.0~rc1+git20111210-7

Versions of packages texlive-base recommends:
ii  lmodern  2.004.4-3

Versions of packages texlive-base suggests:
ii  evince [postscript-viewer]       3.4.0-3.1+b1
ii  ghostscript [postscript-viewer]  9.05~dfsg-8+b1
pn  perl-tk                          <none>
pn  xpdf-reader | pdf-viewer         <none>

Versions of packages tex-common depends on:
ii  debconf [debconf-2.0]  1.5.52
ii  dpkg                   1.17.6
ii  ucf                    3.0027+nmu1

Versions of packages tex-common suggests:
ii  debhelper  9.20140228

Versions of packages texlive-base is related to:
ii  tex-common        4.04
ii  texlive-binaries  2013.20130729.30972-2+b3

-- debconf information:
  texlive-base/texconfig_ignorant:
  tex-common/check_texmf_wrong:
  texlive-base/binary_chooser: pdftex, dvips, dvipdfmx, xdvi
  tex-common/check_texmf_missing:


diff -u8 /usr/bin/fmtutil /tmp/fmtutil.sh
--- /usr/bin/fmtutil	2014-04-08 11:49:34.000000000 +0900
+++ /tmp/fmtutil.sh	2014-05-22 18:39:38.000000000 +0900
@@ -370,17 +370,22 @@
 }
 
 ###############################################################################
 # verbose (cmd)
 #   execute cmd. Redirect output depending on $mktexfmtMode.
 ###############################################################################
 verbose()
 {
-  $mktexfmtMode && ${1+"$@"} >&2 || ${1+"$@"}
+  if $mktexfmtMode 
+  then
+    ${1+"$@"} >&2;
+  else
+    ${1+"$@"};
+  fi
 }
 
 ###############################################################################
 # mktexdir(args)
 #   call mktexdir script, disable all features (to prevent sticky directories)
 ###############################################################################
 mktexdir()
 {      
@@ -758,17 +763,17 @@
   if test $use_engine_dir; then
     fulldestdir="$destdir/$texengine"
   else
     fulldestdir="$destdir"
   fi
   mkdir -p "$fulldestdir"
   if test -f "$fmtfile"; then
     grep '^! ' $format.log >/dev/null 2>&1 &&
-      log_warning "\`$engine -ini $tcxflag $jobswitch $prgswitch $texargs' possibly failed."
+      log_failure "\`$engine -ini $tcxflag $jobswitch $prgswitch $texargs' possibly failed."
 
     # We don't want user-interaction for the following "mv" commands:
     #
     destfile=$fulldestdir/$fmtfile
     if mv "$fmtfile" "$destfile" </dev/null; then
       verboseMsg "$progname: $destfile installed."
       #
       # As a special special case, we create mplib-luatex.mem for use by
@@ -783,17 +788,17 @@
       if test "x$format" = xmpost && test "x$engine" = xmpost; then
         mplib_mem_name=mplib-luatex.mem
         mplib_mem_file=$fulldestdir/$mplib_mem_name
         if test \! -f $mplib_mem_file; then
           verboseMsg "$progname: copying $destfile to $mplib_mem_file"
           if cp "$destfile" "$mplib_mem_file" </dev/null; then
             mktexupd "$fulldestdir" "$mplib_mem_name"
           else
-            log_warning "cp $destfile $mplib_mem_file failed."
+            log_failure "cp $destfile $mplib_mem_file failed."
           fi
         else
           verboseMsg "$progname: $mplib_mem_file already exists, not updating."
         fi
       fi
       #
       # Echo the (main) output filename for our caller.
       $mktexfmtMode && $mktexfmtFirst \

--===============0674187946==--

--- End Message ---
--- Begin Message ---
Version: 2016.20170123-5

On 05.07.19 04:32, Norbert Preining wrote:

Hi,

>> Can we close?
> 
> No idea, sorry. I would say yes, but I haven't tested on a full disk.
> 
Test:

root@amd64-sid:~# fmtutil-sys --all
fmtutil: fmtutil is using the following fmtutil.cnf files (in precedence
order):
fmtutil:   /usr/share/texmf/web2c/fmtutil.cnf
fmtutil:   /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf
fmtutil: fmtutil is using the following fmtutil.cnf file for writing
changes:
fmtutil:   /etc/texmf/web2c/fmtutil.cnf
Error in tempdir() using /tmp/XXXXXXXXXX: Could not create directory
/tmp/6o_dtx0l2C: No space left on device at /usr/bin/fmtutil line 367.
root@amd64-sid:~# echo $?
28

When there is a little more space and some formats can be built we have
exit code 7:

! Could not write 3297 4-byte item(s) to mptopdf.fmt.
 (preloaded format=mptopdf 2019.7.5)fmtutil [ERROR]: running `pdftex
-ini   -jobname=cont-en -progname=context -8bit *cont-en.mkii
</dev/null' return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [ERROR]: Cannot copy cont-en.fmt to
/var/lib/texmf/web2c/xetex/cont-en.fmt.
fmtutil [ERROR]: running `xetex -ini   -jobname=xelatex
-progname=xelatex -etex xelatex.ini </dev/null' return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [ERROR]: running `luatex -ini   -jobname=dviluatex
-progname=dviluatex dviluatex.ini </dev/null' return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [ERROR]: running `luatex -ini   -jobname=dvilualatex
-progname=dvilualatex dvilualatex.ini </dev/null' return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [ERROR]: running `pdftex -ini   -jobname=etex -progname=etex
-translate-file=cp227.tcx *etex.ini </dev/null' return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [ERROR]: running `pdftex -ini   -jobname=mptopdf
-progname=context -translate-file=cp227.tcx mptopdf.tex </dev/null'
return status 1
fmtutil [ERROR]: return error due to options --strict
fmtutil [INFO]: Disabled formats: 3
fmtutil [INFO]: Successfully rebuilt formats: 9
fmtutil [INFO]: Failed to build: 7 (pdftex/cont-en xetex/cont-en
xetex/xelatex luatex/dviluatex luatex/dvilualatex pdftex/etex
pdftex/mptopdf)
fmtutil [INFO]: Total formats: 19
fmtutil [INFO]: exiting with status 7
root@amd64-sid:~# echo $?
7

So I'd guess the bug is solved. I tested just unstable, but the code
looks basically the same in stable, hence I close w/ the version from
stable (soon oldstable).

Hilmar
-- 
sigfault
#206401 http://counter.li.org

Attachment: signature.asc
Description: OpenPGP digital signature


--- End Message ---

Reply to: