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