Fix: Vorzeitiger Abbruch bei großen Accounts nach 3600s Laufzeit
Betroffen: scan_, recover_, restore_, recreate_bad_signature.sh
und diagnose_share_key.sh
Bei Accounts mit sehr vielen bzw. sehr großen Dateien konnte der
jeweilige Pro-Account-Durchlauf länger als eine Stunde dauern und
wurde dann von PHP mit "Maximum execution time of 3600 seconds
exceeded" abgebrochen - mitten im Lauf, ohne jedes Ergebnis.
- su -c "$PHP_BIN ..." ruft PHP jetzt zusätzlich mit
-d max_execution_time=0 auf.
- Das allein reicht nicht: Nextclouds eigenes lib/base.php setzt
beim Bootstrap unbedingt (fest einprogrammiert, nicht
konfigurierbar) set_time_limit(3600) und überschreibt damit den
CLI-Flag wieder. Daher zusätzlich direkt nach dem require von
lib/base.php ein erneutes set_time_limit(0) in jedem der fünf
eingebetteten PHP-Scripte, das Nextclouds Reset seinerseits
rückgängig macht.
Kein Verhaltensunterschied für kleine/normale Accounts, betrifft
nur die maximale Laufzeit pro Account.
This commit is contained in:
+12
-1
@@ -645,6 +645,13 @@ if ($oldWorkingDir === false) {
|
|||||||
}
|
}
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
require_once __DIR__ . '/lib/base.php';
|
require_once __DIR__ . '/lib/base.php';
|
||||||
|
// Nextcloud's own bootstrap (lib/base.php) unconditionally calls
|
||||||
|
// set_time_limit(3600) as part of the require above - this OVERRIDES
|
||||||
|
// whatever -d max_execution_time was passed on the PHP command line,
|
||||||
|
// since it is a later, explicit runtime call. Undo that here, now that
|
||||||
|
// the require is done, so diagnosing a large number of files isn't
|
||||||
|
// killed after exactly one hour regardless of the CLI flag.
|
||||||
|
set_time_limit(0);
|
||||||
chdir($oldWorkingDir);
|
chdir($oldWorkingDir);
|
||||||
|
|
||||||
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
||||||
@@ -791,7 +798,11 @@ for _user in "${selected_user_arr[@]}" ; do
|
|||||||
owner_result_tsv="${LOCK_DIR}/owner_${_user}.tsv"
|
owner_result_tsv="${LOCK_DIR}/owner_${_user}.tsv"
|
||||||
|
|
||||||
echononl " Resolving ownership for account \033[1;37m${_user}\033[m (${_user_selected} files).."
|
echononl " Resolving ownership for account \033[1;37m${_user}\033[m (${_user_selected} files).."
|
||||||
su -c "$PHP_BIN $diag_php_file $_user $path_list_file" -s /bin/bash $HTTP_USER > "$owner_result_tsv" 2> "$log_file"
|
# -d max_execution_time=0: resolving ownership/key-material for a
|
||||||
|
# large number of files can run well over an hour; without this the
|
||||||
|
# PHP CLI process is killed by PHP's own execution-time limit
|
||||||
|
# (typically inherited from the webserver's php.ini) mid-run.
|
||||||
|
su -c "$PHP_BIN -d max_execution_time=0 $diag_php_file $_user $path_list_file" -s /bin/bash $HTTP_USER > "$owner_result_tsv" 2> "$log_file"
|
||||||
_rc=$?
|
_rc=$?
|
||||||
|
|
||||||
if [[ $_rc -ne 0 ]]; then
|
if [[ $_rc -ne 0 ]]; then
|
||||||
|
|||||||
@@ -813,13 +813,8 @@ if ! $_revalidate_only_explicit && $terminal ; then
|
|||||||
blank_line
|
blank_line
|
||||||
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " \033[1m[1] Recovery\033[m - decrypt bad-signature files (temporarily skips the signature check),
|
echo -e " \033[1m[1] Recovery\033[m - decrypt bad-signature files (temporarily skips the signature check), write them under ${DEFAULT_RECOVERY_BASE_DIR}/<website> and validate them"
|
||||||
write them under \033[1m${DEFAULT_RECOVERY_BASE_DIR}/<website>\033[m and validate them"
|
echo " [2] Revalidate-only - re-run just the validation checks against files a previous recovery run already wrote to disk (same as '-V'); nothing is decrypted again and no config value is touched"
|
||||||
echo ""
|
|
||||||
echo " [2] Revalidate-only - re-run just the validation checks against files a previous recovery run
|
|
||||||
already wrote to disk (same as '-V'); nothing is decrypted again and no config
|
|
||||||
value is touched"
|
|
||||||
|
|
||||||
info "Just press Return to use the default: [1] Recovery."
|
info "Just press Return to use the default: [1] Recovery."
|
||||||
echo -n " Select mode by number [1]: "
|
echo -n " Select mode by number [1]: "
|
||||||
read _mode_choice
|
read _mode_choice
|
||||||
@@ -1204,6 +1199,13 @@ if ($oldWorkingDir === false) {
|
|||||||
}
|
}
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
require_once __DIR__ . '/lib/base.php';
|
require_once __DIR__ . '/lib/base.php';
|
||||||
|
// Nextcloud's own bootstrap (lib/base.php) unconditionally calls
|
||||||
|
// set_time_limit(3600) as part of the require above - this OVERRIDES
|
||||||
|
// whatever -d max_execution_time was passed on the PHP command line,
|
||||||
|
// since it is a later, explicit runtime call. Undo that here, now that
|
||||||
|
// the require is done, so recovering a large account isn't killed
|
||||||
|
// after exactly one hour regardless of the CLI flag.
|
||||||
|
set_time_limit(0);
|
||||||
chdir($oldWorkingDir);
|
chdir($oldWorkingDir);
|
||||||
|
|
||||||
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
||||||
@@ -1438,7 +1440,11 @@ for _user in "${selected_user_arr[@]}" ; do
|
|||||||
chown -R "$HTTP_USER":"$HTTP_GROUP" "$recovery_dir" 2> /dev/null
|
chown -R "$HTTP_USER":"$HTTP_GROUP" "$recovery_dir" 2> /dev/null
|
||||||
|
|
||||||
echononl " Recovering account \033[1;37m${_user}\033[m (${_user_total} files).."
|
echononl " Recovering account \033[1;37m${_user}\033[m (${_user_total} files).."
|
||||||
su -c "$PHP_BIN $recovery_php_file $_user $list_file $user_out_dir" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
# -d max_execution_time=0: decrypting/validating every file of a
|
||||||
|
# large account can run well over an hour; without this the PHP
|
||||||
|
# CLI process is killed by PHP's own execution-time limit
|
||||||
|
# (typically inherited from the webserver's php.ini) mid-run.
|
||||||
|
su -c "$PHP_BIN -d max_execution_time=0 $recovery_php_file $_user $list_file $user_out_dir" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
||||||
_rc=$?
|
_rc=$?
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -782,12 +782,8 @@ if ! $_dry_run_explicit && $terminal ; then
|
|||||||
blank_line
|
blank_line
|
||||||
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " \033[1m[1] Dry-run\033[m - go through everything (selection, re-validation, share check,
|
echo -e " \033[1m[1] Dry-run\033[m - go through everything (selection, re-validation, share check, reporting), but delete, back up, create or verify NOTHING"
|
||||||
reporting), but delete, back up, create or verify NOTHING"
|
echo " [2] Real recreate - actually back up, DELETE the broken file, create it fresh and verify each one"
|
||||||
echo ""
|
|
||||||
echo " [2] Real recreate - actually back up, DELETE the broken file, create it fresh
|
|
||||||
and verify each one"
|
|
||||||
|
|
||||||
info "Just press Return to use the default: [1] Dry-run."
|
info "Just press Return to use the default: [1] Dry-run."
|
||||||
echo -n " Select mode by number [1]: "
|
echo -n " Select mode by number [1]: "
|
||||||
read _mode_choice
|
read _mode_choice
|
||||||
@@ -1166,6 +1162,13 @@ if ($oldWorkingDir === false) {
|
|||||||
}
|
}
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
require_once __DIR__ . '/lib/base.php';
|
require_once __DIR__ . '/lib/base.php';
|
||||||
|
// Nextcloud's own bootstrap (lib/base.php) unconditionally calls
|
||||||
|
// set_time_limit(3600) as part of the require above - this OVERRIDES
|
||||||
|
// whatever -d max_execution_time was passed on the PHP command line,
|
||||||
|
// since it is a later, explicit runtime call. Undo that here, now that
|
||||||
|
// the require is done, so recreating a large account isn't killed
|
||||||
|
// after exactly one hour regardless of the CLI flag.
|
||||||
|
set_time_limit(0);
|
||||||
chdir($oldWorkingDir);
|
chdir($oldWorkingDir);
|
||||||
|
|
||||||
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
||||||
@@ -1767,7 +1770,11 @@ for _user in "${selected_user_arr[@]}" ; do
|
|||||||
_php_args=("$recreate_php_file" "$_user" "$list_file" "$DATA_DIR")
|
_php_args=("$recreate_php_file" "$_user" "$list_file" "$DATA_DIR")
|
||||||
$DRY_RUN && _php_args+=("--dry-run")
|
$DRY_RUN && _php_args+=("--dry-run")
|
||||||
$FORCE_SHARED && _php_args+=("--force")
|
$FORCE_SHARED && _php_args+=("--force")
|
||||||
su -c "$PHP_BIN ${_php_args[*]}" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
# -d max_execution_time=0: recreating every selected file of a
|
||||||
|
# large account can run well over an hour; without this the PHP
|
||||||
|
# CLI process is killed by PHP's own execution-time limit
|
||||||
|
# (typically inherited from the webserver's php.ini) mid-run.
|
||||||
|
su -c "$PHP_BIN -d max_execution_time=0 ${_php_args[*]}" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
||||||
_rc=$?
|
_rc=$?
|
||||||
else
|
else
|
||||||
echo -e "path\tbytes_written\tstatus\tdetail" > "$user_result_tsv"
|
echo -e "path\tbytes_written\tstatus\tdetail" > "$user_result_tsv"
|
||||||
|
|||||||
@@ -812,11 +812,8 @@ if ! $_dry_run_explicit && $terminal ; then
|
|||||||
blank_line
|
blank_line
|
||||||
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
echo -e "\033[37m\033[1mWhich mode should this run use?\033[m"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " \033[1m[1] Dry-run\033[m - go through everything (selection, re-validation, reporting),
|
echo -e " \033[1m[1] Dry-run\033[m - go through everything (selection, re-validation, reporting), but write, back up and verify NOTHING"
|
||||||
but write, back up and verify NOTHING"
|
|
||||||
echo ""
|
|
||||||
echo " [2] Real restore - actually back up, overwrite and verify each file in Nextcloud"
|
echo " [2] Real restore - actually back up, overwrite and verify each file in Nextcloud"
|
||||||
|
|
||||||
info "Just press Return to use the default: [1] Dry-run."
|
info "Just press Return to use the default: [1] Dry-run."
|
||||||
echo -n " Select mode by number [1]: "
|
echo -n " Select mode by number [1]: "
|
||||||
read _mode_choice
|
read _mode_choice
|
||||||
@@ -1228,6 +1225,13 @@ if ($oldWorkingDir === false) {
|
|||||||
}
|
}
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
require_once __DIR__ . '/lib/base.php';
|
require_once __DIR__ . '/lib/base.php';
|
||||||
|
// Nextcloud's own bootstrap (lib/base.php) unconditionally calls
|
||||||
|
// set_time_limit(3600) as part of the require above - this OVERRIDES
|
||||||
|
// whatever -d max_execution_time was passed on the PHP command line,
|
||||||
|
// since it is a later, explicit runtime call. Undo that here, now that
|
||||||
|
// the require is done, so restoring a large account isn't killed
|
||||||
|
// after exactly one hour regardless of the CLI flag.
|
||||||
|
set_time_limit(0);
|
||||||
chdir($oldWorkingDir);
|
chdir($oldWorkingDir);
|
||||||
|
|
||||||
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
||||||
@@ -1498,10 +1502,15 @@ for _user in "${selected_user_arr[@]}" ; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -s "$list_file" ]] ; then
|
if [[ -s "$list_file" ]] ; then
|
||||||
|
# -d max_execution_time=0: re-validating and writing back every
|
||||||
|
# selected file of a large account can run well over an hour;
|
||||||
|
# without this the PHP CLI process is killed by PHP's own
|
||||||
|
# execution-time limit (typically inherited from the webserver's
|
||||||
|
# php.ini) mid-run.
|
||||||
if $DRY_RUN ; then
|
if $DRY_RUN ; then
|
||||||
su -c "$PHP_BIN $restore_php_file $_user $list_file --dry-run" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
su -c "$PHP_BIN -d max_execution_time=0 $restore_php_file $_user $list_file --dry-run" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
||||||
else
|
else
|
||||||
su -c "$PHP_BIN $restore_php_file $_user $list_file" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
su -c "$PHP_BIN -d max_execution_time=0 $restore_php_file $_user $list_file" -s /bin/bash $HTTP_USER > "$user_result_tsv" 2> "$log_file"
|
||||||
fi
|
fi
|
||||||
_rc=$?
|
_rc=$?
|
||||||
else
|
else
|
||||||
|
|||||||
+14
-1
@@ -582,6 +582,14 @@ fwrite(STDERR, "DEBUG: vor require lib/base.php\n");
|
|||||||
require_once __DIR__ . '/lib/base.php';
|
require_once __DIR__ . '/lib/base.php';
|
||||||
fwrite(STDERR, "DEBUG: nach require lib/base.php - Bootstrap abgeschlossen\n");
|
fwrite(STDERR, "DEBUG: nach require lib/base.php - Bootstrap abgeschlossen\n");
|
||||||
|
|
||||||
|
// Nextcloud's own bootstrap (lib/base.php) unconditionally calls
|
||||||
|
// set_time_limit(3600) as part of require_once above - this OVERRIDES
|
||||||
|
// whatever -d max_execution_time was passed on the PHP command line,
|
||||||
|
// since it is a later, explicit runtime call. Undo that here, now that
|
||||||
|
// the require is done, so a full-content scan of a large account isn't
|
||||||
|
// killed after exactly one hour regardless of the CLI flag.
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
chdir($oldWorkingDir);
|
chdir($oldWorkingDir);
|
||||||
|
|
||||||
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
if (function_exists('posix_getuid') && posix_getuid() === 0) {
|
||||||
@@ -810,7 +818,12 @@ for _user in "${selected_user_arr[@]}" ; do
|
|||||||
} >> "$report_file"
|
} >> "$report_file"
|
||||||
|
|
||||||
echononl " Scanning account \033[1;37m${_user}\033[m.."
|
echononl " Scanning account \033[1;37m${_user}\033[m.."
|
||||||
su -c "$PHP_BIN $scan_php_file $_user" -s /bin/bash $HTTP_USER > "$user_tsv" 2> "$log_file"
|
# -d max_execution_time=0: a full-content read of every file of a
|
||||||
|
# large account can easily run well over an hour; without this the
|
||||||
|
# PHP CLI process is killed by PHP's own execution-time limit
|
||||||
|
# (typically inherited from the webserver's php.ini) mid-scan, long
|
||||||
|
# before any actual error in the account's files.
|
||||||
|
su -c "$PHP_BIN -d max_execution_time=0 $scan_php_file $_user" -s /bin/bash $HTTP_USER > "$user_tsv" 2> "$log_file"
|
||||||
_rc=$?
|
_rc=$?
|
||||||
|
|
||||||
if [[ $_rc -ne 0 ]]; then
|
if [[ $_rc -ne 0 ]]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user