From 320ad877fc74b2396fd5dad59cfa990c3ace09f9 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Sat, 9 Jul 2016 18:36:17 -0700
Subject: [PATCH 2/3] Ticket #48914 - db2bak.pl task enters infinitive loop
when bak fs is almost full
Description: A backend helper function dblayer_copyfile returns an error
when any of the copy operation fails. But one of the caller functions
dblayer_backup ignored the error.
This patch checks the error returned from dblayer_copyfile and abort the
back-up.
Also, more error info is added to the log messages.
https://fedorahosted.org/389/ticket/48914
Reviewed by mreynolds@redhat.com (Thank you, Mark!!)
(cherry picked from commit ff997cd6fa5f2a0678721ba0b6a56fdce327feb0)
---
ldap/servers/slapd/back-ldbm/dblayer.c | 95 ++++++++++++++++++++++------------
1 file changed, 61 insertions(+), 34 deletions(-)
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 93d42be..783d104 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5643,18 +5643,16 @@ dblayer_copyfile(char *source, char *destination, int overwrite, int mode)
source_fd = OPEN_FUNCTION(source,O_RDONLY,0);
if (-1 == source_fd)
{
- LDAPDebug1Arg(LDAP_DEBUG_ANY,
- "dblayer_copyfile: failed to open source file: %s\n",
- source);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "dblayer_copyfile: failed to open source file %s by \"%s\"\n",
+ source, strerror(errno));
goto error;
}
/* Open destination file */
dest_fd = OPEN_FUNCTION(destination,O_CREAT | O_WRONLY, mode);
if (-1 == dest_fd)
{
- LDAPDebug1Arg(LDAP_DEBUG_ANY,
- "dblayer_copyfile: failed to open dest file: %s\n",
- destination);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "dblayer_copyfile: failed to open dest file %s by \"%s\"\n",
+ destination, strerror(errno));
goto error;
}
LDAPDebug2Args(LDAP_DEBUG_BACKLDBM,
@@ -5662,24 +5660,38 @@ dblayer_copyfile(char *source, char *destination, int overwrite, int mode)
/* Loop round reading data and writing it */
while (1)
{
+ int i;
+ char *ptr = NULL;
return_value = read(source_fd,buffer,64*1024);
- if (return_value <= 0)
- {
+ if (return_value <= 0) {
/* means error or EOF */
- if (return_value < 0)
- {
- LDAPDebug1Arg(LDAP_DEBUG_ANY,
- "dblayer_copyfile: failed to read: %d\n", errno);
+ if (return_value < 0) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "dblayer_copyfile: failed to read by \"%s\": rval = %d\n",
+ strerror(errno), return_value);
}
break;
}
bytes_to_write = return_value;
- return_value = write(dest_fd,buffer,bytes_to_write);
- if (return_value != bytes_to_write)
- {
- /* means error */
- LDAPDebug1Arg(LDAP_DEBUG_ANY,
- "dblayer_copyfile: failed to write: %d\n", errno);
+ ptr = buffer;
+#define CPRETRY 4
+ for (i = 0; i < CPRETRY; i++) { /* retry twice */
+ return_value = write(dest_fd, ptr, bytes_to_write);
+ if (return_value == bytes_to_write) {
+ break;
+ } else {
+ /* means error */
+ LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copyfile: failed to write by \"%s\"; real: %d bytes, exp: %d bytes\n",
+ strerror(errno), return_value, bytes_to_write);
+ if (return_value > 0) {
+ bytes_to_write -= return_value;
+ ptr += return_value;
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "dblayer_copyfile: retrying to write %d bytes\n", bytes_to_write);
+ } else {
+ break;
+ }
+ }
+ }
+ if ((CPRETRY == i) || (return_value < 0)) {
return_value = -1;
break;
}
@@ -5906,10 +5918,15 @@ dblayer_copy_directory(struct ldbminfo *li,
return_value = dblayer_copyfile(filename1, filename2,
0, priv->dblayer_file_mode);
}
+ if (return_value < 0) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "dblayer_copy_directory: Failed to copy file %s to %s\n",
+ filename1, filename2);
+ slapi_ch_free((void**)&filename1);
+ slapi_ch_free((void**)&filename2);
+ break;
+ }
slapi_ch_free((void**)&filename1);
slapi_ch_free((void**)&filename2);
- if (0 > return_value)
- break;
(*cnt)++;
}
@@ -6165,9 +6182,14 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
changelog_destdir, DBVERSION_FILENAME);
return_value = dblayer_copyfile(pathname1, pathname2,
0, priv->dblayer_file_mode);
- slapi_ch_free_string(&pathname1);
slapi_ch_free_string(&pathname2);
slapi_ch_free_string(&changelog_destdir);
+ if (0 > return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Backup: Failed to copy file %s\n", pathname1);
+ slapi_ch_free_string(&pathname1);
+ goto bail;
+ }
+ slapi_ch_free_string(&pathname1);
}
if (priv->dblayer_enable_transactions) {
/* now, get the list of logfiles that still exist */
@@ -6240,15 +6262,15 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
return_value = dblayer_copyfile(pathname1, pathname2,
0, priv->dblayer_file_mode);
if (0 > return_value) {
- LDAPDebug2Args(LDAP_DEBUG_ANY, "Backup: error in "
- "copying file '%s' (err=%d) -- Starting over...\n",
- pathname1, return_value);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backup: error in copying file '%s' (err=%d)\n",
+ pathname1, return_value);
if (task) {
- slapi_task_log_notice(task,
- "Error copying file '%s' (err=%d) -- Starting "
- "over...", pathname1, return_value);
+ slapi_task_log_notice(task, "Error copying file '%s' (err=%d)",
+ pathname1, return_value);
}
- ok = 0;
+ slapi_ch_free((void **)&pathname1);
+ slapi_ch_free((void **)&pathname2);
+ goto bail;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
@@ -6276,9 +6298,8 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
slapi_task_log_notice(task, "Backing up file %d (%s)", cnt, pathname2);
slapi_task_log_status(task, "Backing up file %d (%s)", cnt, pathname2);
}
- return_value =
- dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode);
- if (return_value) {
+ return_value = dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode);
+ if (0 > return_value) {
LDAPDebug(LDAP_DEBUG_ANY,
"Backup: error in copying version file "
"(%s -> %s): err=%d\n",
@@ -6458,11 +6479,12 @@ static int dblayer_copy_dirand_contents(char* src_dir, char* dst_dir, int mode,
slapi_task_log_status(task, "Moving file %s",
filename2);
}
- return_value = dblayer_copyfile(filename1, filename2, 0,
- mode);
+ return_value = dblayer_copyfile(filename1, filename2, 0, mode);
}
- if (0 > return_value)
+ if (0 > return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "dblayer_copy_dirand_contents: failed to copy file %s\n", filename1);
break;
+ }
}
PR_CloseDir(dirhandle);
}
@@ -6838,6 +6860,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
changelogdir, DBVERSION_FILENAME);
return_value = dblayer_copyfile(filename1, filename2,
0, priv->dblayer_file_mode);
+ if (0 > return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: failed to copy file %s\n", filename1);
+ goto error_out;
+ }
}
continue;
}
@@ -6897,6 +6923,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
return_value = dblayer_copyfile(filename1, filename2, 0,
priv->dblayer_file_mode);
if (0 > return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: failed to copy file %s\n", filename1);
goto error_out;
}
cnt++;
--
2.4.11