summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordkatz@damien-katzs-computer.local <>2007-06-27 12:03:49 -0400
committerdkatz@damien-katzs-computer.local <>2007-06-27 12:03:49 -0400
commitb36295dd177fea39a9d5cbad69c3b8b61d30e946 (patch)
tree4d195aa0da25f0fbde49f43dbfa4a9a615e3dbf8
parenta38a3c55b136a25eb6d1ca676da5c7adb4cff517 (diff)
parentba63d79e1485c349034283a77683849bcde2d8ec (diff)
downloadmariadb-git-b36295dd177fea39a9d5cbad69c3b8b61d30e946.tar.gz
Merge dkatz@bk-internal.mysql.com:/home/bk/mysql-5.0-maint
into damien-katzs-computer.local:/Users/dkatz/mysql50
-rw-r--r--mysql-test/lib/mtr_process.pl33
-rw-r--r--mysql-test/lib/mtr_timer.pl9
-rwxr-xr-xmysql-test/mysql-test-run.pl27
-rw-r--r--mysql-test/r/windows_shm.result2
-rw-r--r--mysql-test/t/windows_shm-master.opt1
-rw-r--r--mysql-test/t/windows_shm.test9
-rw-r--r--sql/log.cc92
7 files changed, 125 insertions, 48 deletions
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index e4fd3390c5f..f5ef028fa24 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -142,6 +142,7 @@ sub spawn_impl ($$$$$$$) {
if ( $pid )
{
+ select(STDOUT) if $::glob_win32_perl;
return spawn_parent_impl($pid,$mode,$path);
}
else
@@ -163,9 +164,6 @@ sub spawn_impl ($$$$$$$) {
{
# Don't redirect stdout on ActiveState perl since this is
# just another thread in the same process.
- # Should be fixed so that the thread that is created with fork
- # executes the exe in another process and wait's for it to return.
- # In the meanwhile, we get all the output from mysqld's to screen
}
elsif ( ! open(STDOUT,$log_file_open_mode,$output) )
{
@@ -175,7 +173,7 @@ sub spawn_impl ($$$$$$$) {
if ( $error )
{
- if ( $output eq $error )
+ if ( !$::glob_win32_perl and $output eq $error )
{
if ( ! open(STDERR,">&STDOUT") )
{
@@ -184,15 +182,7 @@ sub spawn_impl ($$$$$$$) {
}
else
{
- if ( $::glob_win32_perl )
- {
- # Don't redirect stdout on ActiveState perl since this is
- # just another thread in the same process.
- # Should be fixed so that the thread that is created with fork
- # executes the exe in another process and wait's for it to return.
- # In the meanwhile, we get all the output from mysqld's to screen
- }
- elsif ( ! open(STDERR,$log_file_open_mode,$error) )
+ if ( ! open(STDERR,$log_file_open_mode,$error) )
{
mtr_child_error("can't redirect STDERR to \"$error\": $!");
}
@@ -611,6 +601,11 @@ sub mtr_check_stop_servers ($) {
if ( $pid )
{
# Server is still alive, put it in list to be hard killed
+ if ($::glob_win32_perl)
+ {
+ # Kill the real process if it's known
+ $pid= $srv->{'real_pid'} if ($srv->{'real_pid'});
+ }
$kill_pids{$pid}= 1;
# Write a message to the process's error log (if it has one)
@@ -664,6 +659,16 @@ sub mtr_check_stop_servers ($) {
}
}
+ if ($::glob_win32_perl and $srv->{'real_pid'})
+ {
+ # Wait for the pseudo pid - if the real_pid was known
+ # the pseudo pid has not been waited for yet, wai blocking
+ # since it's "such a simple program"
+ mtr_verbose("Wait for pseudo process $srv->{'pid'}");
+ my $ret_pid= waitpid($srv->{'pid'}, 0);
+ mtr_verbose("Pseudo process $ret_pid died");
+ }
+
$srv->{'pid'}= 0;
}
}
@@ -1041,7 +1046,7 @@ sub sleep_until_file_created ($$$) {
{
if ( -r $pidfile )
{
- return $pid;
+ return 1;
}
# Check if it died after the fork() was successful
diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl
index 523799f7cf5..86a9f58514f 100644
--- a/mysql-test/lib/mtr_timer.pl
+++ b/mysql-test/lib/mtr_timer.pl
@@ -97,9 +97,14 @@ sub mtr_timer_start($$$) {
# clearing the signal handler.
$SIG{INT}= 'DEFAULT';
+ $SIG{TERM}= sub {
+ mtr_verbose("timer woke up, exiting!");
+ exit(0);
+ };
+
$0= "mtr_timer(timers,$name,$duration)";
- mtr_verbose("timer child $name, sleep $duration");
sleep($duration);
+ mtr_verbose("timer expired after $duration seconds");
exit(0);
}
}
@@ -118,7 +123,7 @@ sub mtr_timer_stop ($$) {
# FIXME as Cygwin reuses pids fast, maybe check that is
# the expected process somehow?!
- kill(9, $tpid);
+ kill(15, $tpid);
# As the timers are so simple programs, we trust them to terminate,
# and use blocking wait for it. We wait just to avoid a zombie.
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 08090e5b96f..c58ed308bd8 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2579,10 +2579,19 @@ sub ndbcluster_wait_started($$){
sub mysqld_wait_started($){
my $mysqld= shift;
- my $res= sleep_until_file_created($mysqld->{'path_pid'},
- $mysqld->{'start_timeout'},
- $mysqld->{'pid'});
- return $res == 0;
+ if (sleep_until_file_created($mysqld->{'path_pid'},
+ $mysqld->{'start_timeout'},
+ $mysqld->{'pid'}) == 0)
+ {
+ # Failed to wait for pid file
+ return 1;
+ }
+
+ # Get the "real pid" of the process, it will be used for killing
+ # the process in ActiveState's perl on windows
+ $mysqld->{'real_pid'}= mtr_get_pid_from_file($mysqld->{'path_pid'});
+
+ return 0;
}
@@ -3720,7 +3729,6 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--no-defaults", $prefix);
- mtr_add_arg($args, "%s--console", $prefix);
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
@@ -4093,6 +4101,7 @@ sub stop_all_servers () {
push(@kill_pids,{
pid => $mysqld->{'pid'},
+ real_pid => $mysqld->{'real_pid'},
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
@@ -4300,6 +4309,7 @@ sub run_testcase_stop_servers($$$) {
push(@kill_pids,{
pid => $mysqld->{'pid'},
+ real_pid => $mysqld->{'real_pid'},
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
@@ -4351,6 +4361,7 @@ sub run_testcase_stop_servers($$$) {
push(@kill_pids,{
pid => $mysqld->{'pid'},
+ real_pid => $mysqld->{'real_pid'},
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
@@ -4775,12 +4786,10 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "%s", $_) for @args_saved;
}
- mtr_add_arg($args, "--test-file");
- mtr_add_arg($args, $tinfo->{'path'});
+ mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
if ( defined $tinfo->{'result_file'} ) {
- mtr_add_arg($args, "--result-file");
- mtr_add_arg($args, $tinfo->{'result_file'});
+ mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
}
if ( $opt_record )
diff --git a/mysql-test/r/windows_shm.result b/mysql-test/r/windows_shm.result
new file mode 100644
index 00000000000..c60049bece8
--- /dev/null
+++ b/mysql-test/r/windows_shm.result
@@ -0,0 +1,2 @@
+mysqld is alive
+End of 5.0 tests.
diff --git a/mysql-test/t/windows_shm-master.opt b/mysql-test/t/windows_shm-master.opt
new file mode 100644
index 00000000000..4476ea16360
--- /dev/null
+++ b/mysql-test/t/windows_shm-master.opt
@@ -0,0 +1 @@
+--skip-grant-tables --loose-shared-memory-base-name=HeyMrBaseNameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --loose-shared-memory=1
diff --git a/mysql-test/t/windows_shm.test b/mysql-test/t/windows_shm.test
new file mode 100644
index 00000000000..203471aac56
--- /dev/null
+++ b/mysql-test/t/windows_shm.test
@@ -0,0 +1,9 @@
+# Windows-specific tests
+--source include/windows.inc
+
+#
+# Bug #24924: shared-memory-base-name that is too long causes buffer overflow
+#
+--exec $MYSQLADMIN --no-defaults --shared-memory-base-name=HeyMrBaseNameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ping
+
+--echo End of 5.0 tests.
diff --git a/sql/log.cc b/sql/log.cc
index 465d694ba10..af8168c6a46 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1835,8 +1835,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
if (likely(is_open())) // Should always be true
{
- uint length, group, carry, hdr_offs;
- long val;
+ uint length, group, carry, hdr_offs, val;
byte header[LOG_EVENT_HEADER_LEN];
/*
@@ -1873,57 +1872,104 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
length= my_b_bytes_in_cache(cache);
DBUG_EXECUTE_IF("half_binlogged_transaction", length-=100;);
- group= my_b_tell(&log_file);
+ /*
+ The events in the buffer have incorrect end_log_pos data
+ (relative to beginning of group rather than absolute),
+ so we'll recalculate them in situ so the binlog is always
+ correct, even in the middle of a group. This is possible
+ because we now know the start position of the group (the
+ offset of this cache in the log, if you will); all we need
+ to do is to find all event-headers, and add the position of
+ the group to the end_log_pos of each event. This is pretty
+ straight forward, except that we read the cache in segments,
+ so an event-header might end up on the cache-border and get
+ split.
+ */
+
+ group= (uint)my_b_tell(&log_file);
hdr_offs= carry= 0;
do
{
- if (likely(carry > 0))
+
+ /*
+ if we only got a partial header in the last iteration,
+ get the other half now and process a full header.
+ */
+ if (unlikely(carry > 0))
{
DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
+ /* assemble both halves */
memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
+ /* fix end_log_pos */
val= uint4korr(&header[LOG_POS_OFFSET]) + group;
int4store(&header[LOG_POS_OFFSET], val);
+ /* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
goto err;
+ /*
+ copy fixed second half of header to cache so the correct
+ version will be written later.
+ */
memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
+ /* next event header at ... */
hdr_offs = LOG_EVENT_HEADER_LEN - carry +
uint4korr(&header[EVENT_LEN_OFFSET]);
carry= 0;
}
+ /* if there is anything to write, process it. */
+
if(likely(length > 0))
{
- do {
- DBUG_ASSERT((hdr_offs + max(EVENT_LEN_OFFSET, LOG_POS_OFFSET) + 4) <= length);
+ /*
+ next header beyond current read-buffer? we'll get it later
+ (though not necessarily in the very next iteration).
+ */
+
+ if (hdr_offs >= length)
+ hdr_offs -= length;
+ else
+ {
- val= uint4korr((char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET) + group;
- int4store((char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET, val);
- hdr_offs += uint4korr((char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET);
+ /* process all event-headers in this (partial) cache. */
- /* header beyond current read-buffer? */
- if (hdr_offs >= length)
- {
- hdr_offs -= length;
- break;
- }
+ do {
- /* split header? */
- if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
- {
- carry= length - hdr_offs;
+ /*
+ partial header only? save what we can get, process once
+ we get the rest.
+ */
- memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
- length -= carry;
- }
+ if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
+ {
+ carry= length - hdr_offs;
+ memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
+ length= hdr_offs;
+ }
+ else
+ {
+ /* we've got a full event-header, and it came in one piece */
- } while (hdr_offs < length);
+ char *log_pos= (char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
+
+ /* fix end_log_pos */
+ val= uint4korr(log_pos) + group;
+ int4store(log_pos, val);
+
+ /* next event header at ... */
+ log_pos= (char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
+ hdr_offs += uint4korr(log_pos);
+
+ }
+ } while (hdr_offs < length);
+ }
}
/* Write data to the binary log file */