[cmake-developers] [CMake 0013040]: CMakeCache.txt gets killed (zeroed, deleted, data loss data corruption) on out of disk space situation

Mantis Bug Tracker mantis at public.kitware.com
Wed Mar 14 06:22:18 EDT 2012


The following issue has been SUBMITTED. 
====================================================================== 
http://www.itk.org/Bug/view.php?id=13040 
====================================================================== 
Reported By:                Andreas Mohr
Assigned To:                
====================================================================== 
Project:                    CMake
Issue ID:                   13040
Category:                   CMake
Reproducibility:            always
Severity:                   crash
Priority:                   high
Status:                     new
====================================================================== 
Date Submitted:             2012-03-14 06:22 EDT
Last Modified:              2012-03-14 06:22 EDT
====================================================================== 
Summary:                    CMakeCache.txt gets killed (zeroed, deleted, data
loss data corruption) on out of disk space situation
Description: 
CMake 2.8.6.20111108-g92e65 (sorry, did not try trunk)



Steps to Reproduce: 
A simple
dd if=/dev/zero of=cmake_binary_tree_partition/kill_space_zero.dat bs=1048576
count=3131232134
to ensure an unusable HDD will result in a CMake configure run
stomping out its CMakeCache.txt, thereby losing all configuration information,
making a very nice "cmake ." (to re-trigger successful configuration runs *)) in
the _binary tree_ impossible subsequently.

*) e.g. EVEN IN AN OTHERWISE COMPLETELY EMPTY NEWLY RE-LOCATED BUILD TREE! :))


$ ls -l CMakeCache.txt
-rw-rw-r-- 1 amoh amoh 0 Mar 14 10:40 CMakeCache.txt

Additional Information: 
It's considered best practice (some people would say minimum practice) to first
write datasets into _temporary_ files before atomically moving them to the final
location after fully successful completion, to avoid exactly the scenario that
appears to be taking place here, namely an important pre-existing file being
killed by the name-overwriting file having unsuccessfully attempted to gather
storage space.


My (admittedly not fully satisfying) workaround against such data loss is this:

# Implement a check for minimum disk space requirement,
# and error out fatally if it's not covered.
# While a full build with limited disk space will not be successful,
# an even worse problem is that CMake will corrupt a newly written
# CMakeCache.txt when running out of space...
function(detect_build_space_less_than_mb _mb_size _sufficient_space_bool_out)
  set(sufficient_space_bool_ true) # be optimistic :)
  if(UNIX)
    #
http://stackoverflow.com/questions/8110530/check-disk-space-for-current-directory-in-bash
    find_program(stat_BIN stat)
    if(stat_BIN)
      execute_process(COMMAND "${stat_BIN}" -f --format=%a:%S
"${CMAKE_BINARY_DIR}"
        OUTPUT_VARIABLE stat_stdout_
      )
      string(REGEX REPLACE "^(.*):.*$" "\\1" stat_block_count_
"${stat_stdout_}")
      string(REGEX REPLACE "^.*:(.*)$" "\\1" stat_block_size_ "${stat_stdout_}")
      math(EXPR megabytes_remaining_
"(${stat_block_count_}*${stat_block_size_})/(1024*1024)")
      #message(FATAL_ERROR "stat_stdout_ ${stat_stdout_}, stat_block_count_
${stat_block_count_} stat_block_size_ ${stat_block_size_}, megabytes_remaining_
${megabytes_remaining_}")
      if("${megabytes_remaining_}" LESS "${_mb_size}")
        set(sufficient_space_bool_ false)
      endif("${megabytes_remaining_}" LESS "${_mb_size}")
    else(stat_BIN)
      message(FATAL_ERROR "could not find stat binary! Please extend this code
to cope with this situation in a better way, if possible.")
    endif(stat_BIN)
  endif(UNIX)
  set(${_sufficient_space_bool_out} ${sufficient_space_bool_} PARENT_SCOPE)
endfunction(detect_build_space_less_than_mb _mb_size _sufficient_space_bool_out)

function(check_sufficient_free_build_space)
  set(MASTER_BUILD_MINIMUM_SPACE_IN_MEGABYTES 500 CACHE STRING "Minimum free
space (in MB) to require for a successful build (specify 0 to disable check)")
  if(MASTER_BUILD_MINIMUM_SPACE_IN_MEGABYTES GREATER 0)
    detect_build_space_less_than_mb(${MASTER_BUILD_MINIMUM_SPACE_IN_MEGABYTES}
have_sufficient_space_)
    if(NOT have_sufficient_space_)
      message( "There's not enough free space to guarantee a successful build!
(requested: ${MASTER_BUILD_MINIMUM_SPACE_IN_MEGABYTES}MB)")
    endif(NOT have_sufficient_space_)
  endif(MASTER_BUILD_MINIMUM_SPACE_IN_MEGABYTES GREATER 0)
endfunction(check_sufficient_free_build_space)

check_sufficient_free_build_space()


# ...and add a default target to create a backup of CMakeCache.txt,
# since that file might get destroyed too easily (at least CMake 2.6.4
# will kill it on out-of-disk-space, resulting in complete abort of
# configuration run):
if(NOT TARGET master_backup_CMakeCache)
  # Better reference specific CMAKE_CACHEFILE_DIR variable (same as
CMAKE_BINARY_DIR).
  # Unfortunately there's no CMake file name variable for "CMakeCache.txt"
  # (source code of CMake always open-codes that name),
  # thus there's nothing to reference here.
  set(CMakeCache_file "${CMAKE_CACHEFILE_DIR}/CMakeCache.txt")
  set(CMakeCache_file_backup "${CMakeCache_file}.backup")
  add_custom_command(OUTPUT "${CMakeCache_file_backup}"
    # copy_if_different _not_ needed (target dependency needs remaking? --> _do_
copy!)
    COMMAND "${CMAKE_COMMAND}" -E copy "${CMakeCache_file}"
"${CMakeCache_file_backup}"
    COMMENT "creating CMakeCache backup (${CMakeCache_file_backup})"
  )
  add_custom_target(master_backup_CMakeCache ALL DEPENDS
"${CMakeCache_file_backup}")
endif(NOT TARGET master_backup_CMakeCache)


Severity "crash" since it will render a working build irreversibly non-working.


Thanks!
====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2012-03-14 06:22 Andreas Mohr   New Issue                                    
======================================================================




More information about the cmake-developers mailing list