amoralej / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 years ago
Clone

Blame SOURCES/0002-Ticket-48914-db2bak.pl-task-enters-infinitive-loop-w.patch

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