[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