1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /*
24   Logging of MyISAM commands and records on logfile for debugging
25   The log can be examined with help of the myisamlog command.
26 */
27 
28 #include "myisamdef.h"
29 #ifdef __WIN__
30 #include <fcntl.h>
31 #endif
32 
33 #undef GETPID					/* For HPUX */
34 #define GETPID() (log_type == 1 ? (long) myisam_pid : (long) my_thread_dbug_id())
35 
36 	/* Activate logging if flag is 1 and reset logging if flag is 0 */
37 
38 static int log_type=0;
39 ulong myisam_pid=0;
40 
mi_log(int activate_log)41 int mi_log(int activate_log)
42 {
43   int error=0;
44   char buff[FN_REFLEN];
45   DBUG_ENTER("mi_log");
46 
47   log_type=activate_log;
48   if (activate_log)
49   {
50     if (!myisam_pid)
51       myisam_pid=(ulong) getpid();
52     if (myisam_log_file < 0)
53     {
54       if ((myisam_log_file= mysql_file_create(mi_key_file_log,
55                                               fn_format(buff,
56                                                         myisam_log_filename,
57                                                         "", ".log", 4),
58                                               0,
59                                               (O_RDWR | O_BINARY | O_APPEND),
60                                               MYF(0))) < 0)
61 	DBUG_RETURN(my_errno);
62     }
63   }
64   else if (myisam_log_file >= 0)
65   {
66     error= mysql_file_close(myisam_log_file, MYF(0)) ? my_errno : 0 ;
67     myisam_log_file= -1;
68   }
69   DBUG_RETURN(error);
70 }
71 
72 
73 	/* Logging of records and commands on logfile */
74 	/* All logs starts with command(1) dfile(2) process(4) result(2) */
75 
_myisam_log(enum myisam_log_commands command,MI_INFO * info,const uchar * buffert,uint length)76 void _myisam_log(enum myisam_log_commands command, MI_INFO *info,
77 		 const uchar *buffert, uint length)
78 {
79   uchar buff[11];
80   int error,old_errno;
81   ulong pid=(ulong) GETPID();
82   old_errno=my_errno;
83   memset(buff, 0, sizeof(buff));
84   buff[0]=(char) command;
85   mi_int2store(buff+1,info->dfile);
86   mi_int4store(buff+3,pid);
87   mi_int2store(buff+9,length);
88 
89   mysql_mutex_lock(&THR_LOCK_myisam);
90   error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
91   (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0));
92   (void) mysql_file_write(myisam_log_file, buffert, length, MYF(0));
93   if (!error)
94     error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
95   mysql_mutex_unlock(&THR_LOCK_myisam);
96   my_errno=old_errno;
97 }
98 
99 
_myisam_log_command(enum myisam_log_commands command,MI_INFO * info,const uchar * buffert,uint length,int result)100 void _myisam_log_command(enum myisam_log_commands command, MI_INFO *info,
101 			 const uchar *buffert, uint length, int result)
102 {
103   uchar buff[9];
104   int error,old_errno;
105   ulong pid=(ulong) GETPID();
106 
107   old_errno=my_errno;
108   buff[0]=(char) command;
109   mi_int2store(buff+1,info->dfile);
110   mi_int4store(buff+3,pid);
111   mi_int2store(buff+7,result);
112   mysql_mutex_lock(&THR_LOCK_myisam);
113   error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
114   (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0));
115   if (buffert)
116     (void) mysql_file_write(myisam_log_file, buffert, length, MYF(0));
117   if (!error)
118     error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
119   mysql_mutex_unlock(&THR_LOCK_myisam);
120   my_errno=old_errno;
121 }
122 
123 
_myisam_log_record(enum myisam_log_commands command,MI_INFO * info,const uchar * record,my_off_t filepos,int result)124 void _myisam_log_record(enum myisam_log_commands command, MI_INFO *info,
125 			const uchar *record, my_off_t filepos, int result)
126 {
127   uchar buff[21],*pos;
128   int error,old_errno;
129   uint length;
130   ulong pid=(ulong) GETPID();
131 
132   old_errno=my_errno;
133   if (!info->s->base.blobs)
134     length=info->s->base.reclength;
135   else
136     length=info->s->base.reclength+ _my_calc_total_blob_length(info,record);
137   buff[0]=(uchar) command;
138   mi_int2store(buff+1,info->dfile);
139   mi_int4store(buff+3,pid);
140   mi_int2store(buff+7,result);
141   mi_sizestore(buff+9,filepos);
142   mi_int4store(buff+17,length);
143   mysql_mutex_lock(&THR_LOCK_myisam);
144   error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
145   (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0));
146   (void) mysql_file_write(myisam_log_file, record, info->s->base.reclength, MYF(0));
147   if (info->s->base.blobs)
148   {
149     MI_BLOB *blob,*end;
150 
151     for (end=info->blobs+info->s->base.blobs, blob= info->blobs;
152 	 blob != end ;
153 	 blob++)
154     {
155       memcpy(&pos, record+blob->offset+blob->pack_length,
156                    sizeof(char*));
157       (void) mysql_file_write(myisam_log_file, pos, blob->length, MYF(0));
158     }
159   }
160   if (!error)
161     error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
162   mysql_mutex_unlock(&THR_LOCK_myisam);
163   my_errno=old_errno;
164 }
165