Bug #63305 Function "my_copy()" does not report which operation failed
Submitted: 17 Nov 2011 13:33
Reporter: Joerg Bruehe Email Updates:
Status: Verified Impact on me:
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:5.1.50 and up OS:Any
Assigned to: CPU Architecture:Any

[17 Nov 2011 13:33] Joerg Bruehe
Function "my_copy()" will copy a file.

Depending on flags, it may do a "chmod()" and/or a "chown()" on the result file.

If either of these calls fails, it depends on the flags whether some error message will be generated.

See "How To Repeat" for an example.

How to repeat:
Run any test that calls "copy_file" (for example, test "rpl_cross_version" in 5.5) in a
setting such that the user has write privileges on "mysql-test/" and all its
subdirectories, but is not the owner (and is not privileged).

Most Unix systems will not allow the "chown()" call and return EPERM (value 1).

The test will fail with these lines:
   mysqltest: In included file "./include/setup_fake_relay_log.inc":
   included from ./include/setup_fake_relay_log.inc at line 81:
   At line 80: command "copy_file" failed with error 1. my_errno=1

There is no indication that it is the "chown()", not even if you run a debug build of "mysqltest" and switch debugging on.

Alternatively, inspect the code.

Suggested fix:
Rather than inspect and modify the flags that control the message generation or change their evaluation, I added debug output and used the debug "mysqltest":

=== modified file 'mysys/my_copy.c'
--- mysys/my_copy.c     2011-06-30 15:37:13 +0000
+++ mysys/my_copy.c     2011-11-17 13:29:53 +0000
@@ -108,8 +108,10 @@ int my_copy(const char *from, const char
     if (chmod(to, stat_buff.st_mode & 07777))
       my_errno= errno;
+      DBUG_PRINT("my_copy:", ("chmod() stat_buff.st_mode & 07777 = %d failed: %d",
+                             stat_buff.st_mode & 07777, my_errno));
       if (MyFlags & (MY_FAE+MY_WME))
-        my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
+        my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, my_errno);
       goto err;
 #if !defined(__WIN__) && !defined(__NETWARE__)
@@ -117,8 +119,10 @@ int my_copy(const char *from, const char
     if (chown(to, stat_buff.st_uid,stat_buff.st_gid))
       my_errno= errno;
+      DBUG_PRINT("my_copy:", ("chown() uid=%d gid=%d failed: %d",
+                             stat_buff.st_uid, stat_buff.st_gid, my_errno));
       if (MyFlags & (MY_FAE+MY_WME))
-        my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
+        my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, my_errno);
       goto err;

As an alternative, modify the flags and/or their evaluation such that the "my_error()" call will not be suppressed.
[22 May 2015 7:08] Andrii Nikitin
see also bug #77127