Merge lp:~vlad-lesin/percona-playback/tcpdump-parsing into lp:percona-playback

Proposed by Vlad Lesin
Status: Merged
Merged at revision: 121
Proposed branch: lp:~vlad-lesin/percona-playback/tcpdump-parsing
Merge into: lp:percona-playback
Diff against target: 2069 lines (+1710/-68) (has conflicts)
26 files modified
.bzrignore (+11/-0)
Makefile.am (+36/-2)
configure.ac (+5/-0)
m4/pandora_have_libdrizzle-1.0.m4 (+74/-0)
m4/pandora_have_libdrizzle.m4 (+0/-61)
m4/pandora_have_libmysqlclient.m4 (+103/-0)
percona_playback/dispatcher.cc (+14/-0)
percona_playback/percona_playback.cc (+21/-0)
percona_playback/query_result.h (+7/-0)
percona_playback/tcpdump/connection_state.cc (+325/-0)
percona_playback/tcpdump/connection_state.h (+186/-0)
percona_playback/tcpdump/pcap_packets_parser.cc (+134/-0)
percona_playback/tcpdump/pcap_packets_parser.h (+64/-0)
percona_playback/tcpdump/plugin.ac (+1/-1)
percona_playback/tcpdump/plugin.ini (+3/-1)
percona_playback/tcpdump/sniff_headers.h (+59/-0)
percona_playback/tcpdump/tcpdump.cc (+122/-3)
percona_playback/tcpdump/tcpdump.h (+17/-0)
percona_playback/tcpdump/tcpdump_mysql_parser_stats.h (+33/-0)
percona_playback/tcpdump/tcpdump_query_entries.cc (+129/-0)
percona_playback/tcpdump/tcpdump_query_entries.h (+73/-0)
percona_playback/test/tcpdump_accuracy.cc (+69/-0)
percona_playback/test/tcpdump_fragmented_packet.cc (+56/-0)
percona_playback/test/tcpdump_multiple_connections.cc (+56/-0)
percona_playback/test/tcpdump_stress_test.cc (+56/-0)
percona_playback/test/tcpdump_without_handshake.cc (+56/-0)
Text conflict in Makefile.am
Text conflict in configure.ac
Conflict adding file m4/pandora_have_libmysqlclient.m4.  Moved existing file to m4/pandora_have_libmysqlclient.m4.moved.
Text conflict in percona_playback/percona_playback.cc
Text conflict in percona_playback/tcpdump/tcpdump.h
To merge this branch: bzr merge lp:~vlad-lesin/percona-playback/tcpdump-parsing
Reviewer Review Type Date Requested Status
Stewart Smith Pending
Review via email: mp+111163@code.launchpad.net
To post a comment you must log in.
98. By Vlad Lesin

Add pandora_have_libmysqlclient.m4 pandora_have_libpcap.m4 to the project because it shouldn't depend on pandora-build being installed.

99. By Vlad Lesin

Free drizzle result in ConnectionState destructor.

100. By Vlad Lesin

Fix for memory leak in tcpdump plugin.

101. By Vlad Lesin

Don't use all caps in labels.

102. By Vlad Lesin

One more memory leak fix. See https://bugs.launchpad.net/drizzle/+bug/1015576.

103. By Vlad Lesin

License header is added to dispatcher source.

104. By Vlad Lesin

Merge with 91..94 revisions of trunk(use autoreconf, add gettext support, add po to Makefile subdirs)

105. By Vlad Lesin

Rename pandora_have_libdrizzle.m4 to pandora_have_libdrizzle-1.0.m4 as it finds libdrizzle-1.0 library

106. By Vlad Lesin

Use standard libdrizzle-1.0 instead of modified

107. By Vlad Lesin

Avoid compilation errors in 'set drizzle result options' code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2011-12-30 01:47:04 +0000
+++ .bzrignore 2012-07-02 18:23:18 +0000
@@ -40,3 +40,14 @@
40percona_playback/test/crashme-slow40percona_playback/test/crashme-slow
41percona_playback/test/sqlbench-transactions-slow41percona_playback/test/sqlbench-transactions-slow
42percona_playback/test/sysbench-slow42percona_playback/test/sysbench-slow
43m4/libtool.m4
44m4/ltoptions.m4
45m4/ltversion.m4
46m4/lt~obsolete.m4
47percona_playback/test/preserve_query_time
48percona_playback/test/tcpdump_accuracy
49percona_playback/test/tcpdump_fragmented_packet
50percona_playback/test/tcpdump_multiple_connections
51percona_playback/test/tcpdump_stress_test
52percona_playback/test/tcpdump_without_handshake
53tags
4354
=== modified file 'Makefile.am'
--- Makefile.am 2012-06-22 05:12:15 +0000
+++ Makefile.am 2012-07-02 18:23:18 +0000
@@ -39,6 +39,11 @@
39 percona_playback/test/sqlbench-transactions-slow.log \39 percona_playback/test/sqlbench-transactions-slow.log \
40 percona_playback/test/sysbench-slow.log \40 percona_playback/test/sysbench-slow.log \
41 percona_playback/test/preserve_query_time.log \41 percona_playback/test/preserve_query_time.log \
42 percona_playback/test/tcpdump_without_handshake.dump \
43 percona_playback/test/tcpdump_fragmented_packet.dump \
44 percona_playback/test/tcpdump_multiple_connections.dump \
45 percona_playback/test/tcpdump_stress_test.dump \
46 percona_playback/test/tcpdump_accuracy.dump \
42 test_run.sh47 test_run.sh
4348
44include config/pandora-plugin.am49include config/pandora-plugin.am
@@ -71,9 +76,15 @@
71 $(AM_CXXFLAGS) \76 $(AM_CXXFLAGS) \
72 -DBUILDING_PERCONA_PLAYBACK77 -DBUILDING_PERCONA_PLAYBACK
7378
79<<<<<<< TREE
74libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(TBB_LIBS)80libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(TBB_LIBS)
75libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(TBB_LIBS) $(pandora_plugin_libs)81libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(TBB_LIBS) $(pandora_plugin_libs)
76libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs)82libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs)
83=======
84libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(LTLIBTBB)
85libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(LTLIBTBB) $(pandora_plugin_libs)
86libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs)
87>>>>>>> MERGE-SOURCE
7788
78check_PROGRAMS += \89check_PROGRAMS += \
79 percona_playback/test/basic \90 percona_playback/test/basic \
@@ -82,6 +93,11 @@
82 percona_playback/test/sqlbench-transactions-slow \93 percona_playback/test/sqlbench-transactions-slow \
83 percona_playback/test/sysbench-slow \94 percona_playback/test/sysbench-slow \
84 percona_playback/test/preserve_query_time \95 percona_playback/test/preserve_query_time \
96 percona_playback/test/tcpdump_without_handshake \
97 percona_playback/test/tcpdump_fragmented_packet \
98 percona_playback/test/tcpdump_multiple_connections \
99 percona_playback/test/tcpdump_stress_test \
100 percona_playback/test/tcpdump_accuracy \
85 percona_playback/test/help101 percona_playback/test/help
86102
87percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"103percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
@@ -90,6 +106,11 @@
90percona_playback_test_sqlbench_transactions_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"106percona_playback_test_sqlbench_transactions_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
91percona_playback_test_sysbench_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"107percona_playback_test_sysbench_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
92percona_playback_test_preserve_query_time_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"108percona_playback_test_preserve_query_time_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
109percona_playback_test_tcpdump_without_handshake_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
110percona_playback_test_tcpdump_fragmented_packet_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
111percona_playback_test_tcpdump_multiple_connections_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
112percona_playback_test_tcpdump_stress_test_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
113percona_playback_test_tcpdump_accuracy_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
93114
94percona_playback_test_help_SOURCES= percona_playback/test/help.cc115percona_playback_test_help_SOURCES= percona_playback/test/help.cc
95percona_playback_test_help_LDADD= $(LDADD) $(MYSQL_LIBS)116percona_playback_test_help_LDADD= $(LDADD) $(MYSQL_LIBS)
@@ -112,7 +133,20 @@
112percona_playback_test_preserve_query_time_SOURCES= percona_playback/test/preserve_query_time.cc133percona_playback_test_preserve_query_time_SOURCES= percona_playback/test/preserve_query_time.cc
113percona_playback_test_preserve_query_time_LDADD= $(LDADD) $(MYSQL_LIBS)134percona_playback_test_preserve_query_time_LDADD= $(LDADD) $(MYSQL_LIBS)
114135
115136percona_playback_test_tcpdump_without_handshake_SOURCES= percona_playback/test/tcpdump_without_handshake.cc
137percona_playback_test_tcpdump_without_handshake_LDADD= $(LDADD) $(MYSQL_LIBS)
138
139percona_playback_test_tcpdump_fragmented_packet_SOURCES= percona_playback/test/tcpdump_fragmented_packet.cc
140percona_playback_test_tcpdump_fragmented_packet_LDADD= $(LDADD) $(MYSQL_LIBS)
141
142percona_playback_test_tcpdump_multiple_connections_SOURCES= percona_playback/test/tcpdump_multiple_connections.cc
143percona_playback_test_tcpdump_multiple_connections_LDADD= $(LDADD) $(MYSQL_LIBS)
144
145percona_playback_test_tcpdump_stress_test_SOURCES= percona_playback/test/tcpdump_stress_test.cc
146percona_playback_test_tcpdump_stress_test_LDADD= $(LDADD) $(MYSQL_LIBS)
147
148percona_playback_test_tcpdump_accuracy_SOURCES= percona_playback/test/tcpdump_accuracy.cc
149percona_playback_test_tcpdump_accuracy_LDADD= $(LDADD) $(MYSQL_LIBS)
116150
117#151#
118# Simple percona_playback application152# Simple percona_playback application
@@ -120,7 +154,7 @@
120154
121bin_PROGRAMS += bin/percona_playback155bin_PROGRAMS += bin/percona_playback
122bin_percona_playback_SOURCES = bin/percona_playback.cc156bin_percona_playback_SOURCES = bin/percona_playback.cc
123bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(TBB_LIBS) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS)157bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(LTLIBTBB) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS)
124158
125include docs/include.am159include docs/include.am
126160
127161
=== modified file 'configure.ac'
--- configure.ac 2012-06-24 04:28:41 +0000
+++ configure.ac 2012-07-02 18:23:18 +0000
@@ -58,8 +58,13 @@
5858
59AC_DEFINE_UNQUOTED([PERCONA_PLAYBACK_MODULE_EXT], ["$acl_cv_shlibext"],59AC_DEFINE_UNQUOTED([PERCONA_PLAYBACK_MODULE_EXT], ["$acl_cv_shlibext"],
60 [Extension to use for modules.])60 [Extension to use for modules.])
61<<<<<<< TREE
61AM_CXXFLAGS="${AM_CXXFLAGS} ${NO_EFF_CXX} ${NO_OLD_STYLE_CAST} ${NO_VISIBILITY}"62AM_CXXFLAGS="${AM_CXXFLAGS} ${NO_EFF_CXX} ${NO_OLD_STYLE_CAST} ${NO_VISIBILITY}"
62AC_CONFIG_FILES(Makefile dnl po/Makefile.in63AC_CONFIG_FILES(Makefile dnl po/Makefile.in
64=======
65AM_CXXFLAGS="${NO_EFF_CXX}"
66AC_CONFIG_FILES(Makefile dnl po/Makefile.in
67>>>>>>> MERGE-SOURCE
63 percona_playback/version.h dnl68 percona_playback/version.h dnl
64 docs/header.html)69 docs/header.html)
6570
6671
=== added file 'm4/pandora_have_libdrizzle-1.0.m4'
--- m4/pandora_have_libdrizzle-1.0.m4 1970-01-01 00:00:00 +0000
+++ m4/pandora_have_libdrizzle-1.0.m4 2012-07-02 18:23:18 +0000
@@ -0,0 +1,74 @@
1dnl Copyright (C) 2009 Sun Microsystems, Inc.
2dnl This file is free software; Sun Microsystems, Inc.
3dnl gives unlimited permission to copy and/or distribute it,
4dnl with or without modifications, as long as this notice is preserved.
5
6AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE_1_0],[
7 AC_REQUIRE([AC_LIB_PREFIX])
8
9 dnl --------------------------------------------------------------------
10 dnl Check for libdrizzle
11 dnl --------------------------------------------------------------------
12
13 AC_ARG_ENABLE([libdrizzle],
14 [AS_HELP_STRING([--disable-libdrizzle],
15 [Build with libdrizzle support @<:@default=on@:>@])],
16 [ac_enable_libdrizzle="$enableval"],
17 [ac_enable_libdrizzle="yes"])
18
19 AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[
20 AC_LIB_HAVE_LINKFLAGS(drizzle,,[
21 #include <libdrizzle/drizzle_client.h>
22 ],[
23 drizzle_st drizzle;
24 drizzle_version();
25 ])
26 ],[
27 ac_cv_libdrizzle="no"
28 ])
29
30 AS_IF([test "${ac_cv_libdrizzle}" = "no" -a "${ac_enable_libdrizzle}" = "yes"],[
31 PKG_CHECK_MODULES([LIBDRIZZLE], [libdrizzle-1.0], [
32 ac_cv_libdrizzle=yes
33 LTLIBDRIZZLE=${LIBDRIZZLE_LIBS}
34 LIBDRIZZLE=${LIBDRIZZLE_LIBS}
35 CPPFLAGS=${LIBDRIZZLE_CFLAGS} ${CPPFLAGS}
36 HAVE_LIBDRIZZLE="yes"
37 AC_SUBST(HAVE_LIBDRIZZLE)
38 AC_SUBST(LIBDRIZZLE)
39 AC_SUBST(LTLIBDRIZZLE)
40 ],[])
41 ])
42
43 AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"])
44])
45
46AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE_1_0],[
47 AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE_1_0])
48])
49
50AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE_1_0],[
51 AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE_1_0])
52 AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[
53 AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}])
54 ],[
55 dnl We need at least 0.8 on Solaris non-sparc
56 AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[
57 PANDORA_LIBDRIZZLE_RECENT
58 ])
59 ])
60])
61
62AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[
63 AC_CACHE_CHECK([if libdrizzle is recent enough],
64 [pandora_cv_libdrizzle_recent],
65 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
66#include <libdrizzle/drizzle.h>
67drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL;
68 ]])],
69 [pandora_cv_libdrizzle_recent=yes],
70 [pandora_cv_libdrizzle_recent=no])])
71 AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[
72 AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8])
73 ])
74])
075
=== removed file 'm4/pandora_have_libdrizzle.m4'
--- m4/pandora_have_libdrizzle.m4 2012-04-03 05:13:48 +0000
+++ m4/pandora_have_libdrizzle.m4 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
1dnl Copyright (C) 2009 Sun Microsystems, Inc.
2dnl This file is free software; Sun Microsystems, Inc.
3dnl gives unlimited permission to copy and/or distribute it,
4dnl with or without modifications, as long as this notice is preserved.
5
6AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE],[
7 AC_REQUIRE([AC_LIB_PREFIX])
8
9 dnl --------------------------------------------------------------------
10 dnl Check for libdrizzle
11 dnl --------------------------------------------------------------------
12
13 AC_ARG_ENABLE([libdrizzle],
14 [AS_HELP_STRING([--disable-libdrizzle],
15 [Build with libdrizzle support @<:@default=on@:>@])],
16 [ac_enable_libdrizzle="$enableval"],
17 [ac_enable_libdrizzle="yes"])
18
19 AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[
20 AC_LIB_HAVE_LINKFLAGS(drizzle,,[
21 #include <libdrizzle/drizzle_client.h>
22 ],[
23 drizzle_st drizzle;
24 drizzle_version();
25 ])
26 ],[
27 ac_cv_libdrizzle="no"
28 ])
29
30 AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"])
31])
32
33AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE],[
34 AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE])
35])
36
37AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE],[
38 AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE])
39 AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[
40 AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}])
41 ],[
42 dnl We need at least 0.8 on Solaris non-sparc
43 AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[
44 PANDORA_LIBDRIZZLE_RECENT
45 ])
46 ])
47])
48
49AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[
50 AC_CACHE_CHECK([if libdrizzle is recent enough],
51 [pandora_cv_libdrizzle_recent],
52 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
53#include <libdrizzle/drizzle.h>
54drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL;
55 ]])],
56 [pandora_cv_libdrizzle_recent=yes],
57 [pandora_cv_libdrizzle_recent=no])])
58 AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[
59 AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8])
60 ])
61])
620
=== added file 'm4/pandora_have_libmysqlclient.m4'
--- m4/pandora_have_libmysqlclient.m4 1970-01-01 00:00:00 +0000
+++ m4/pandora_have_libmysqlclient.m4 2012-07-02 18:23:18 +0000
@@ -0,0 +1,103 @@
1dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3dnl
4dnl Copyright (C) 2010 Monty Taylor
5dnl This file is free software; Sun Microsystems
6dnl gives unlimited permission to copy and/or distribute it,
7dnl with or without modifications, as long as this notice is preserved.
8dnl
9
10AC_DEFUN([PANDORA_WITH_MYSQL],[
11 AC_ARG_WITH([mysql],
12 [AS_HELP_STRING([--with-mysql=PATH],
13 [path to mysql_config binary or mysql prefix dir])],
14 [with_mysql=$withval],
15 [with_mysql=":"])
16
17 dnl There are three possibilities:
18 dnl 1) nothing is given: we will search for mysql_config in PATH
19 dnl 2) the location of mysql_config is given: we'll use that to determine
20 dnl 3) a directory argument is given: that will be mysql_base
21
22
23 dnl option 1: nothing, we need to insert something into MYSQL_CONFIG
24 AS_IF([test "x$with_mysql" = "x:"],[
25 AC_CHECK_PROGS(MYSQL_CONFIG,[mysql_config])
26 ],[
27 MYSQL_CONFIG="${with_mysql}"
28 ])
29
30 AC_CACHE_CHECK([for MySQL Base Location],[pandora_cv_mysql_base],[
31
32 dnl option 2: something in MYSQL_CONFIG now, use that to get a base dir
33 AS_IF([test -f "${MYSQL_CONFIG}" -a -x "${MYSQL_CONFIG}"],[
34 pandora_cv_mysql_base=$(dirname $(${MYSQL_CONFIG} --include | sed 's/-I//'))
35 MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include)
36 MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')"
37 MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r)
38 ],[
39 dnl option 1: a directory
40 AS_IF([test -d $with_mysql],
41 [
42 pandora_cv_mysql_base=$with_mysql
43 IBASE="-I${with_mysql}"
44 MYSQL_CONFIG="${with_mysql}/bin/mysql_config"
45 MYSQL_INCLUDES="$IBASE/include/mysql -isystem $IBASE/include/mysql"
46 MYSQL_LIBS="-L${with_mysql}/lib -L${with_mysql}/lib/mysql -lmysqlclient_r"
47 ],
48 [
49 pandora_cv_mysql_base=""
50 ])
51 ])
52 ])
53 AC_SUBST(MYSQL_CONFIG)
54 AC_SUBST(MYSQL_INCLUDES)
55 AC_SUBST(MYSQL_LIBS)
56])
57
58AC_DEFUN([_PANDORA_SEARCH_LIBMYSQLCLIENT],[
59 AC_REQUIRE([AC_LIB_PREFIX])
60
61 AC_ARG_ENABLE([libmysqlclient],
62 [AS_HELP_STRING([--disable-libmysqlclient],
63 [Build with libmysqlclient support @<:@default=on@:>@])],
64 [ac_enable_libmysqlclient="$enableval"],
65 [ac_enable_libmysqlclient="yes"])
66
67 AS_IF([test "x$ac_enable_libmysqlclient" = "xyes"],[
68 AC_LIB_HAVE_LINKFLAGS(mysqlclient_r,,[
69#include <mysql/mysql.h>
70 ],[
71MYSQL mysql;
72 ])],[
73 ac_cv_libmysqlclient_r="no"
74 ])
75
76 AM_CONDITIONAL(HAVE_LIBMYSQLCLIENT, [test "x${ac_cv_libmysqlclient_r}" = "xyes"])
77
78 AS_IF([test "x$MYSQL_CONFIG" = "xISDIR"],[
79 IBASE="-I${with_mysql}"
80 MYSQL_CONFIG="${with_mysql}/scripts/mysql_config"
81 ADDIFLAGS="$IBASE/include -isystem $IBASE/include"
82 ADDLDFLAGS="-L${with_mysql}/libmysql_r/.libs/ -L${with_mysql}/mysys/.libs -L${with_mysql}/mysys -L${with_mysql}/strings/.libs -L${with_mysql}/strings "
83 ],[
84 MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include)
85 MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')"
86 MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r)
87 ])
88
89 AC_SUBST(MYSQL_CONFIG)
90 AC_SUBST(MYSQL_INCLUDES)
91 AC_SUBST(MYSQL_LIBS)
92])
93
94AC_DEFUN([PANDORA_HAVE_LIBMYSQLCLIENT],[
95 AC_REQUIRE([_PANDORA_SEARCH_LIBMYSQLCLIENT])
96])
97
98AC_DEFUN([PANDORA_REQUIRE_LIBMYSQLCLIENT],[
99 AC_REQUIRE([PANDORA_HAVE_LIBMYSQLCLIENT])
100 AS_IF([test "x${ac_cv_libmysqlclient_r}" = "xno"],
101 PANDORA_MSG_ERROR([libmysqlclient_r is required for ${PACKAGE}]))
102])
103
0104
=== renamed file 'm4/pandora_have_libmysqlclient.m4' => 'm4/pandora_have_libmysqlclient.m4.moved'
=== modified file 'percona_playback/dispatcher.cc'
--- percona_playback/dispatcher.cc 2012-06-22 06:20:44 +0000
+++ percona_playback/dispatcher.cc 2012-07-02 18:23:18 +0000
@@ -1,3 +1,17 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
1#include "percona_playback/dispatcher.h"15#include "percona_playback/dispatcher.h"
2#include "percona_playback/db_thread.h"16#include "percona_playback/db_thread.h"
3#include "percona_playback/plugin.h"17#include "percona_playback/plugin.h"
418
=== modified file 'percona_playback/percona_playback.cc'
--- percona_playback/percona_playback.cc 2012-06-24 04:28:41 +0000
+++ percona_playback/percona_playback.cc 2012-07-02 18:23:18 +0000
@@ -90,18 +90,30 @@
90 std::cerr << std::endl;90 std::cerr << std::endl;
91 std::cerr << options_description << std::endl;91 std::cerr << options_description << std::endl;
92 std::cerr << std::endl;92 std::cerr << std::endl;
93<<<<<<< TREE
93 std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl;94 std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl;
94 std::cerr << _("Loaded plugins: ");95 std::cerr << _("Loaded plugins: ");
95 BOOST_FOREACH(const std::string &plugin_name, PluginRegistry::singleton().loaded_plugin_names)96 BOOST_FOREACH(const std::string &plugin_name, PluginRegistry::singleton().loaded_plugin_names)
97=======
98 std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl;
99 std::cerr << _("Loaded plugins: ");
100 BOOST_FOREACH(const std::string &plugin_name, percona_playback::PluginRegistry::singleton().loaded_plugin_names)
101>>>>>>> MERGE-SOURCE
96 {102 {
97 std::cerr << plugin_name << " ";103 std::cerr << plugin_name << " ";
98 }104 }
99105
100 std::cerr << std::endl;106 std::cerr << std::endl;
101107
108<<<<<<< TREE
102 std::cerr << std::endl << _("Loaded DB Plugins: ");109 std::cerr << std::endl << _("Loaded DB Plugins: ");
103 for(PluginRegistry::DBClientPluginMap::iterator it= PluginRegistry::singleton().dbclient_plugins.begin();110 for(PluginRegistry::DBClientPluginMap::iterator it= PluginRegistry::singleton().dbclient_plugins.begin();
104 it != PluginRegistry::singleton().dbclient_plugins.end();111 it != PluginRegistry::singleton().dbclient_plugins.end();
112=======
113 std::cerr << std::endl << _("Loaded DB Plugins: ");
114 for(percona_playback::PluginRegistry::DBClientPluginMap::iterator it= percona_playback::PluginRegistry::singleton().dbclient_plugins.begin();
115 it != percona_playback::PluginRegistry::singleton().dbclient_plugins.end();
116>>>>>>> MERGE-SOURCE
105 it++)117 it++)
106 {118 {
107 std::cerr << it->first << " ";119 std::cerr << it->first << " ";
@@ -110,12 +122,21 @@
110 std::cerr << std::endl;122 std::cerr << std::endl;
111123
112 assert(g_dbclient_plugin);124 assert(g_dbclient_plugin);
125<<<<<<< TREE
113 std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl;126 std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl;
114127
115 std::cerr << std::endl << _("Loaded Input Plugins: ");128 std::cerr << std::endl << _("Loaded Input Plugins: ");
116129
117 BOOST_FOREACH(const PluginRegistry::InputPluginPair &pp,130 BOOST_FOREACH(const PluginRegistry::InputPluginPair &pp,
118 PluginRegistry::singleton().input_plugins)131 PluginRegistry::singleton().input_plugins)
132=======
133 std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl;
134
135 std::cerr << std::endl << _("Loaded Input Plugins: ");
136
137 BOOST_FOREACH(const percona_playback::PluginRegistry::InputPluginPair &pp,
138 percona_playback::PluginRegistry::singleton().input_plugins)
139>>>>>>> MERGE-SOURCE
119 {140 {
120 std::cerr << pp.first << " ";141 std::cerr << pp.first << " ";
121 }142 }
122143
=== modified file 'percona_playback/query_result.h'
--- percona_playback/query_result.h 2012-06-18 23:59:46 +0000
+++ percona_playback/query_result.h 2012-07-02 18:23:18 +0000
@@ -40,6 +40,13 @@
40 {40 {
41 }41 }
4242
43 void clear()
44 {
45 _rows_sent= _rows_examined= 0;
46 _error= _warning_count= 0;
47 _duration= boost::posix_time::time_duration();
48 }
49
43 void setRowsSent(const uint64_t &rows) {50 void setRowsSent(const uint64_t &rows) {
44 _rows_sent= rows;51 _rows_sent= rows;
45 }52 }
4653
=== added file 'percona_playback/tcpdump/connection_state.cc'
--- percona_playback/tcpdump/connection_state.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/connection_state.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,325 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15#include <pcap.h>
16#include <iostream>
17#include <libdrizzle/drizzle_server.h>
18#include <libdrizzle/row_client.h>
19#include <stdio.h>
20#include <stdint.h>
21#include <assert.h>
22
23#include "connection_state.h"
24#include "tcpdump_query_entries.h"
25#include "percona_playback/plugin.h"
26
27extern percona_playback::DBClientPlugin *g_dbclient_plugin;
28
29void
30ConnectionState::ProcessMysqlPkts(const u_char *pkts,
31 u_int pkts_len,
32 const timeval &ts,
33 const AddrPort &addr_port,
34 OUT TcpdumpMysqlParserStats &stats)
35{
36
37 u_int used_len= 0;
38 struct MysqlPkt *m;
39
40 assert(pkts);
41
42 // If last pkt was fragmented, merge with current pkts
43 if (fragmented)
44 {
45 fragmented= false;
46 size_t old_frag_buff_size= frag_buff.size();
47 frag_buff.insert(frag_buff.end(), pkts, pkts + pkts_len);
48 pkts= &frag_buff[0];
49 pkts_len+= old_frag_buff_size;
50 }
51
52 for(;;)
53 {
54 m= (struct MysqlPkt *)pkts; // Packet header
55
56 // Check if pkts > len of pkts actually received (last pkt is fragmented)
57 used_len+= m->full_length();
58
59 if (used_len > pkts_len) {
60 fragmented= true;
61
62 size_t frag_len= m->full_length() - (used_len - pkts_len);
63
64 UCharBuffer new_frag_buff(pkts, pkts + frag_len);
65 frag_buff.swap(new_frag_buff);
66
67 break;
68 }
69
70 if (m->data_length())
71 {
72 UCharBuffer buff(pkts, pkts + m->full_length());
73 std::string query;
74 PktResult retval= ParseMysqlPkt(buff, query);
75 switch(retval)
76 {
77 case PKT_QUERY:
78 if (!query.empty())
79 DispatchQuery(ts, query, addr_port);
80 ++stats.nr_of_parsed_queries;
81 ++stats.nr_of_parsed_packets;
82 break;
83
84 case PKT_RESULT:
85 DispatchResult(ts, addr_port);
86 ++stats.nr_of_parsed_packets;
87 break;
88
89 case PKT_ERROR:
90 ++stats.nr_of_parsing_errors;
91 break;
92
93 default:
94 ++stats.nr_of_parsed_packets;
95 }
96 }
97
98 pkts += m->full_length(); // Next pkt header
99
100 if (used_len == pkts_len)
101 break;
102
103 }
104
105 if (!fragmented)
106 frag_buff.clear();
107
108}
109
110void
111ConnectionState::ProcessFinishConnection()
112{
113 db_thread->queries.push(QueryEntryPtr(new FinishEntry()));
114}
115
116PktResult
117ConnectionState::ParseMysqlPkt(IN UCharBuffer &buff,
118 OUT std::string &query)
119{
120 if (current_origin == CLIENT)
121 return ClientPacket(buff, query);
122
123 if (current_origin == SERVER && was_query)
124 return ServerPacket(buff);
125
126 return PKT_UNKNOWN;
127}
128
129PktResult
130ConnectionState::ServerPacket(IN UCharBuffer &buff)
131{
132 PktResult retval= PKT_OK;
133
134 drizzle_return_t ret;
135
136 drizzle_con->buffer_ptr= &buff[0];
137 drizzle_con->buffer_size= buff.size();
138
139 /*
140 Check if we should continue parsing result set or
141 we can start a new loop of result parsing.
142 */
143 if (!drizzle_con->result)
144 {
145 /*
146 If there are not any parsed results then it can be "Ok",
147 "Error" or "Results set header" packets.
148 */
149 last_query_result.clear();
150
151 drizzle_result_st *res= drizzle_result_read(drizzle_con.get(),
152 NULL,
153 &ret);
154 /* Check if the packet is "Error" packet */
155 if (ret == DRIZZLE_RETURN_ERROR_CODE)
156 {
157 last_query_result.setError(drizzle_result_error_code(res));
158 retval= PKT_RESULT;
159 /*
160 The text representation of error can be got with
161 drizzle_result_error(res)
162 */
163 goto free_and_return;
164 }
165 else if(ret == DRIZZLE_RETURN_OK)
166 {
167 /* Check if the packet is "Ok" packet */
168 if (!drizzle_result_column_count(res))
169 {
170 last_query_result.setRowsSent(drizzle_result_row_count(res));
171 last_query_result.setRowsExamined(drizzle_result_affected_rows(res));
172 last_query_result.setWarningCount(drizzle_result_warning_count(res));
173 retval= PKT_RESULT;
174 goto free_and_return;
175 }
176 /* Else this is "Result set header" packet */
177 }
178 else
179 {
180 std::cerr << "Unknown packet type from server" << std::endl;
181 retval= PKT_ERROR;
182 goto free_and_return;
183 }
184 }
185 /* Parse result set */
186 else
187 {
188 /* "Field" packets */
189 if (eof_count == 0)
190 {
191 drizzle_column_st *column= drizzle_column_read(drizzle_con->result,
192 NULL,
193 &ret);
194 if (ret == DRIZZLE_RETURN_OK)
195 {
196 /* "EOF" packet */
197 if (column == NULL)
198 ++eof_count;
199 retval= PKT_OK;
200 }
201 else
202 {
203 std::cerr << "Parse column error" << std::endl;
204 retval= PKT_ERROR;
205 goto free_and_return;
206 }
207 }
208 /* "Row" packets */
209 else if (eof_count == 1)
210 {
211 uint8_t old_packet_number= drizzle_con->packet_number;
212 uint64_t row= drizzle_row_read(drizzle_con->result, &ret);
213 if (ret != DRIZZLE_RETURN_OK)
214 {
215 std::cerr << "Error in parsing row" << std::endl;
216 retval= PKT_ERROR;
217 goto free_and_return;
218 }
219 else
220 ++sent_rows_count;
221 /* "EOF" packet */
222 if (!row)
223 {
224 eof_count= 0;
225
226 drizzle_con->buffer_ptr= &buff[0];
227 drizzle_con->buffer_size= buff.size();
228
229 drizzle_result_free_all(drizzle_con.get());
230 drizzle_con->packet_number= old_packet_number;
231 drizzle_result_st *res= drizzle_result_read(drizzle_con.get(),
232 NULL,
233 &ret);
234 /*
235 Setting DRIZZLE_RESULT_ALLOCATED in result options
236 helps to avoid memory leak.
237 See https://bugs.launchpad.net/drizzle/+bug/1015576
238 */
239 res->options=
240 (drizzle_result_options_t)
241 ((uint64_t)(res->options) | (uint64_t)DRIZZLE_RESULT_ALLOCATED);
242 last_query_result.setWarningCount(drizzle_result_warning_count(res));
243 /* Don't count the last EOF packet */
244 last_query_result.setRowsSent(sent_rows_count - 1);
245
246 sent_rows_count= 0;
247 retval= PKT_RESULT;
248 goto free_and_return;
249 }
250 else
251 retval= PKT_OK;
252 }
253 }
254
255 return retval;
256
257free_and_return:
258 drizzle_result_free_all(drizzle_con.get());
259 drizzle_con->result= NULL;
260 was_query= false;
261 return retval;
262}
263
264PktResult
265ConnectionState::ClientPacket(IN UCharBuffer &buff,
266 OUT std::string &query)
267{
268 drizzle_command_t command;
269 drizzle_return_t ret;
270 size_t total;
271 uint8_t *data;
272 PktResult result= PKT_UNKNOWN;
273
274 drizzle_con->buffer_ptr= &buff[0];
275 drizzle_con->buffer_size= buff.size();
276 data= (uint8_t *)drizzle_con_command_buffer(drizzle_con.get(),
277 &command,
278 &total,
279 &ret);
280 if (ret == DRIZZLE_RETURN_OK)
281 {
282 switch(command)
283 {
284 case DRIZZLE_COMMAND_QUERY:
285 query.assign((const char *)data);
286 was_query= true;
287 result= PKT_QUERY;
288 break;
289
290 case DRIZZLE_COMMAND_INIT_DB:
291 query.assign("use ");
292 query+= (const char *)data;
293 was_query= true;
294 result= PKT_QUERY;
295 break;
296
297 default:;
298 }
299 }
300
301 free(data);
302 return result;
303}
304
305void
306ConnectionState::DispatchQuery(const timeval &ts,
307 const std::string &query,
308 const AddrPort &addr_port)
309{
310 boost::shared_ptr<TcpdumpQueryEntry>
311 query_entry(new TcpdumpQueryEntry(ts,
312 query,
313 addr_port));
314 db_thread->queries.push(query_entry);
315}
316
317void
318ConnectionState::DispatchResult(const timeval &ts,
319 const AddrPort &addr_port)
320{
321 boost::shared_ptr<TcpdumpResultEntry>
322 result_entry(new TcpdumpResultEntry(addr_port, ts, last_query_result));
323 db_thread->queries.push(result_entry);
324}
325
0326
=== added file 'percona_playback/tcpdump/connection_state.h'
--- percona_playback/tcpdump/connection_state.h 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/connection_state.h 2012-07-02 18:23:18 +0000
@@ -0,0 +1,186 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#ifndef PERCONA_PLAYBACK_CONNECTION_STATE_H
17#define PERCONA_PLAYBACK_CONNECTION_STATE_H
18
19#include <stdlib.h>
20#include <sys/time.h>
21#include <vector>
22#include <string>
23#include <string.h>
24#include <boost/shared_ptr.hpp>
25#include <libdrizzle/drizzle_client.h>
26
27#include "percona_playback/query_result.h"
28#include "percona_playback/db_thread.h"
29#include "tcpdump_mysql_parser_stats.h"
30
31enum PktResult
32{
33 PKT_QUERY,
34 PKT_RESULT,
35 PKT_OK,
36 PKT_UNKNOWN,
37 PKT_ERROR
38};
39
40#define IN
41#define OUT
42
43#pragma pack(push, 1)
44// Every logical MySQL packet starts w/ this 4 byte header
45struct MysqlPkt {
46 uint16_t length_low;
47 uint8_t length_high;
48 uint8_t id;
49 uint8_t data[0];
50
51 size_t data_length() const
52 {
53 return (size_t)length_low | ((size_t)length_high << 16);
54 }
55
56 size_t full_length() const
57 {
58 return data_length() + header_size();
59 }
60
61 static size_t header_size()
62 {
63 return offsetof(MysqlPkt, data);
64 }
65};
66#pragma pack(pop)
67
68struct AddrPort
69{
70 AddrPort() : address(0), port(0) {}
71 AddrPort(uint32_t address, uint16_t port) : address(address), port(port) {}
72 uint32_t address;
73 uint16_t port;
74 uint64_t ThreadId() const
75 {
76 return (uint64_t)address | ((uint64_t)port << 32);
77 }
78};
79
80struct LastExecutedQueryInfo
81{
82 std::string query;
83 QueryResult result;
84 timeval begin_pcap_timestamp;
85 timeval end_pcap_timestamp;
86 timeval end_timestamp;
87
88 LastExecutedQueryInfo()
89 {
90 memset(&begin_pcap_timestamp, 0, sizeof(begin_pcap_timestamp));
91 memset(&end_pcap_timestamp, 0, sizeof(end_pcap_timestamp));
92 memset(&end_timestamp, 0, sizeof(end_timestamp));
93 }
94};
95
96
97class ConnectionState : public DBThreadState
98
99{
100
101public:
102
103 enum Origin
104 {
105 UNDEF,
106 CLIENT,
107 SERVER
108 };
109
110 ConnectionState() :
111 current_origin(UNDEF),
112 fragmented(false),
113 handshake_from_client(false),
114 was_query(false),
115 eof_count(0),
116 sent_rows_count(0),
117 drizzle(drizzle_create(NULL), drizzle_free),
118 drizzle_con(
119 drizzle_con_add_tcp(drizzle.get(),
120 NULL,
121 "localhost",
122 3306,
123 "user",
124 "password",
125 "db",
126 (drizzle_con_options_t)
127 DRIZZLE_CON_MYSQL),
128 drizzle_con_free),
129 db_thread(NULL)
130 {
131 drizzle_con->result= NULL;
132 }
133
134 ~ConnectionState()
135 {
136 drizzle_result_free_all(drizzle_con.get());
137 }
138
139 void ProcessMysqlPkts(const u_char *pkts,
140 u_int total_len,
141 const timeval &ts,
142 const AddrPort &addr_port,
143 OUT TcpdumpMysqlParserStats &stats);
144
145 void ProcessFinishConnection();
146
147 void SetCurrentOrigin(Origin o) { current_origin = o; }
148
149 void SetDBThread(DBThread *t) { db_thread= t; }
150
151 LastExecutedQueryInfo last_executed_query_info;
152
153private:
154
155 typedef std::vector<unsigned char> UCharBuffer;
156
157 PktResult ParseMysqlPkt(IN UCharBuffer &buff, OUT std::string &query);
158
159 PktResult ServerPacket(IN UCharBuffer &buff);
160 PktResult ClientPacket(IN UCharBuffer &buff, OUT std::string &query);
161
162 void DispatchQuery(const timeval &ts,
163 const std::string &query,
164 const AddrPort &addr_port);
165
166 void DispatchResult(const timeval &ts,
167 const AddrPort &addr_port);
168
169 Origin current_origin;
170 bool fragmented;
171 UCharBuffer frag_buff;
172 bool handshake_from_client;
173 bool was_query;
174 size_t eof_count;
175 size_t sent_rows_count;
176
177 boost::shared_ptr<drizzle_st> drizzle;
178 boost::shared_ptr<drizzle_con_st> drizzle_con;
179
180 QueryResult last_query_result;
181
182 DBThread *db_thread;
183
184};
185
186#endif // PERCONA_PLAYBACK_CONNECTION_STATE_H
0187
=== added file 'percona_playback/tcpdump/pcap_packets_parser.cc'
--- percona_playback/tcpdump/pcap_packets_parser.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/pcap_packets_parser.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,134 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15#include "pcap_packets_parser.h"
16#include "sniff_headers.h"
17#include "tcpdump.h"
18
19#include "percona_playback/db_thread.h"
20#include "percona_playback/plugin.h"
21#include "percona_playback/dispatcher.h"
22
23#include <netinet/in.h>
24#include <arpa/inet.h>
25#include <iostream>
26#include <boost/foreach.hpp>
27#include <assert.h>
28
29#define SNAP_LEN 16500 // pcap's max capture size
30
31extern percona_playback::DBClientPlugin *g_dbclient_plugin;
32
33void
34PcapPacketsParser::ParsePkt(const struct pcap_pkthdr *header,
35 const u_char *packet)
36{
37 ConnectionState::Origin origin= ConnectionState::UNDEF;
38 const struct sniff_ethernet *ethernet;
39 const struct sniff_ip *ip;
40 const struct sniff_tcp *tcp;
41 const uint8_t *mysql;
42 size_t size_ip;
43 size_t size_tcp;
44 size_t size_mysql;
45
46 assert(header);
47 assert(packet);
48
49 if(header->len > SNAP_LEN) {
50 std::cerr << "Captured packet too large: "
51 << header->len
52 << " bytes, Max capture packet size: "
53 << SNAP_LEN << " bytes" << std::endl;
54 return;
55 }
56
57 ethernet= (struct sniff_ethernet*)(packet);
58 ip= (struct sniff_ip*)(packet + SIZE_ETHERNET);
59 size_ip= IP_HL(ip) * 4;
60 tcp= (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
61 size_tcp= TH_OFF(tcp) * 4;
62 mysql= (packet + SIZE_ETHERNET + size_ip + size_tcp);
63 size_mysql= ntohs(ip->ip_len) - size_ip - size_tcp;
64
65
66 AddrPort addr_port;
67
68 if (ntohs(tcp->th_sport) == g_tcpdump_port)
69 {
70 addr_port.address= ip->ip_dst.s_addr;
71 addr_port.port= tcp->th_dport;
72 origin= ConnectionState::SERVER;
73 }
74 else
75 {
76 addr_port.address= ip->ip_src.s_addr;
77 addr_port.port= tcp->th_sport;
78 origin= ConnectionState::CLIENT;
79 }
80
81 /* The connection was closed. */
82 if (size_mysql == 0 &&
83 ((tcp->th_flags & TH_FIN) || (tcp->th_flags & TH_RST)))
84 {
85 g_dispatcher.finish(addr_port.ThreadId());
86 return;
87 }
88
89 /* The mysql packet is too small. It may be due to tcp service packets. */
90 if (size_mysql < MysqlPkt::header_size())
91 return;
92
93 if (!was_first_packet)
94 {
95 gettimeofday(&first_packet_timestamp, 0);
96 first_packet_pcap_timestamp= header->ts;
97 was_first_packet= true;
98 }
99
100 /* If there is no DBThread with such id create it */
101 boost::shared_ptr<DBThreadState>
102 state= g_dispatcher.get_thread_state(addr_port.ThreadId(),
103 boost::bind(&PcapPacketsParser::CreateConnectionState,
104 this,
105 _1));
106
107 assert(state.get());
108
109 ((ConnectionState *)state.get())->SetCurrentOrigin(origin);
110 ((ConnectionState *)state.get())->ProcessMysqlPkts(mysql,
111 size_mysql,
112 header->ts,
113 addr_port,
114 stats);
115}
116
117void
118PcapPacketsParser::WaitForUnfinishedTasks()
119{
120 g_dispatcher.finish_all_and_wait();
121}
122
123void
124PcapPacketsParser::CreateConnectionState(DBThread *db_thread)
125{
126 assert(db_thread);
127 boost::shared_ptr<ConnectionState> state(new ConnectionState());
128 state->last_executed_query_info.end_pcap_timestamp=
129 first_packet_pcap_timestamp;
130 state->last_executed_query_info.end_timestamp=
131 first_packet_timestamp;
132 db_thread->set_state(state);
133 state->SetDBThread(db_thread);
134}
0135
=== added file 'percona_playback/tcpdump/pcap_packets_parser.h'
--- percona_playback/tcpdump/pcap_packets_parser.h 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/pcap_packets_parser.h 2012-07-02 18:23:18 +0000
@@ -0,0 +1,64 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#ifndef PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H
17#define PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H
18
19#include "connection_state.h"
20#include "tcpdump_mysql_parser_stats.h"
21
22#include <pcap.h>
23#include <tbb/concurrent_queue.h>
24#include <boost/thread.hpp>
25#include <boost/bind.hpp>
26
27class DBThread;
28
29class PcapPacketsParser
30{
31 TcpdumpMysqlParserStats stats;
32 timeval first_packet_timestamp;
33 timeval first_packet_pcap_timestamp;
34 bool was_first_packet;
35
36public:
37
38 PcapPacketsParser() : was_first_packet(false)
39 {
40 first_packet_timestamp.tv_sec= first_packet_timestamp.tv_usec= 0;
41 first_packet_pcap_timestamp.tv_sec= first_packet_pcap_timestamp.tv_usec= 0;
42 }
43
44 static void Process(u_char *arg,
45 const struct pcap_pkthdr *header,
46 const u_char *packet)
47 {
48 ((PcapPacketsParser *)arg)->ParsePkt(header, packet);
49 }
50
51 const TcpdumpMysqlParserStats &GetStats() const { return stats; }
52
53 void WaitForUnfinishedTasks();
54
55 void CreateConnectionState(DBThread *db_thread);
56
57private:
58
59 void ParsePkt(const struct pcap_pkthdr *header,
60 const u_char *packet);
61
62};
63
64#endif //PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H
065
=== modified file 'percona_playback/tcpdump/plugin.ac'
--- percona_playback/tcpdump/plugin.ac 2012-06-19 01:09:31 +0000
+++ percona_playback/tcpdump/plugin.ac 2012-07-02 18:23:18 +0000
@@ -1,2 +1,2 @@
1PANDORA_HAVE_LIBPCAP1PANDORA_HAVE_LIBPCAP
2PANDORA_HAVE_LIBDRIZZLE2PANDORA_HAVE_LIBDRIZZLE_1_0
33
=== modified file 'percona_playback/tcpdump/plugin.ini'
--- percona_playback/tcpdump/plugin.ini 2012-06-19 01:09:31 +0000
+++ percona_playback/tcpdump/plugin.ini 2012-07-02 18:23:18 +0000
@@ -6,4 +6,6 @@
6headers=tcpdump.h6headers=tcpdump.h
7load_by_default=yes7load_by_default=yes
8ldflags=${PCAP_LIBS} ${LTLIBDRIZZLE} ${LDFLAGS}8ldflags=${PCAP_LIBS} ${LTLIBDRIZZLE} ${LDFLAGS}
9cppflags=${PCAP_INCLUDES} ${CPPFLAGS} 9cppflags=${PCAP_INCLUDES} ${CPPFLAGS}
10headers=tcpdump.h sniff_headers.h connection_state.h pcap_packets_parser.h tcpdump_query_entries.h tcpdump_mysql_parser_stats.h
11sources=tcpdump.cc connection_state.cc pcap_packets_parser.cc tcpdump_query_entries.cc
1012
=== added file 'percona_playback/tcpdump/sniff_headers.h'
--- percona_playback/tcpdump/sniff_headers.h 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/sniff_headers.h 2012-07-02 18:23:18 +0000
@@ -0,0 +1,59 @@
1/* ethernet headers are always exactly 14 bytes [1] */
2#define SIZE_ETHERNET 14
3
4/* Ethernet addresses are 6 bytes */
5#define ETHER_ADDR_LEN 6
6
7//#pragma pack(push, 1)
8/* Ethernet header */
9struct sniff_ethernet {
10 u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */
11 u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */
12 u_short ether_type; /* IP? ARP? RARP? etc */
13};
14
15/* IP header */
16struct sniff_ip {
17 u_char ip_vhl; /* version << 4 | header length >> 2 */
18 u_char ip_tos; /* type of service */
19 u_short ip_len; /* total length */
20 u_short ip_id; /* identification */
21 u_short ip_off; /* fragment offset field */
22 #define IP_RF 0x8000 /* reserved fragment flag */
23 #define IP_DF 0x4000 /* dont fragment flag */
24 #define IP_MF 0x2000 /* more fragments flag */
25 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
26 u_char ip_ttl; /* time to live */
27 u_char ip_p; /* protocol */
28 u_short ip_sum; /* checksum */
29 struct in_addr ip_src,ip_dst; /* source and dest address */
30};
31#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
32#define IP_V(ip) (((ip)->ip_vhl) >> 4)
33
34/* TCP header */
35typedef u_int tcp_seq;
36
37struct sniff_tcp {
38 u_short th_sport; /* source port */
39 u_short th_dport; /* destination port */
40 tcp_seq th_seq; /* sequence number */
41 tcp_seq th_ack; /* acknowledgement number */
42 u_char th_offx2; /* data offset, rsvd */
43#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
44 u_char th_flags;
45 #define TH_FIN 0x01
46 #define TH_SYN 0x02
47 #define TH_RST 0x04
48 #define TH_PUSH 0x08
49 #define TH_ACK 0x10
50 #define TH_URG 0x20
51 #define TH_ECE 0x40
52 #define TH_CWR 0x80
53 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
54 u_short th_win; /* window */
55 u_short th_sum; /* checksum */
56 u_short th_urp; /* urgent pointer */
57};
58
59//#pragma pack(pop)
060
=== modified file 'percona_playback/tcpdump/tcpdump.cc'
--- percona_playback/tcpdump/tcpdump.cc 2012-06-19 01:09:31 +0000
+++ percona_playback/tcpdump/tcpdump.cc 2012-07-02 18:23:18 +0000
@@ -14,15 +14,54 @@
14 * END LICENSE */14 * END LICENSE */
1515
16#include "tcpdump.h"16#include "tcpdump.h"
17#include "pcap_packets_parser.h"
18
19#include "percona_playback/percona_playback.h"
20
17#include <stdio.h>21#include <stdio.h>
22#include <pcap.h>
23
24#define FILTER_EXP_SIZE 11 // max filter expression size
25
26std::string g_tcpdump_file_name;
27uint16_t g_tcpdump_port;
28TcpdumpPluginMode g_tcpdump_mode;
29
30std::istream& operator>>(std::istream& in, TcpdumpPluginMode& unit)
31{
32 std::string token;
33 in >> token;
34 if (token == "fast")
35 unit = TCPDUMP_MODE_FAST;
36 else if (token == "accurate")
37 unit = TCPDUMP_MODE_ACCURATE;
38 else
39 throw
40 boost::program_options::validation_error(
41 "Allowed input-type values are (fast|accurate)"
42 );
43 return in;
44}
1845
19boost::program_options::options_description*46boost::program_options::options_description*
20TcpDumpParserPlugin::getProgramOptions()47TcpDumpParserPlugin::getProgramOptions()
21{48{
22 options.add_options()49 options.add_options()
23 ("tcpdump-file",50 ("tcpdump-file",
24 boost::program_options::value<std::string>(&file_name),51 boost::program_options::value<std::string>(&g_tcpdump_file_name),
25 "Tcpdump file name");52 "Tcpdump file name")
53 ("tcpdump-port",
54 boost::program_options::value<uint16_t>(&g_tcpdump_port)
55 ->default_value(3306),
56 "Tcpdump port")
57 ("tcpdump-mode",
58 boost::program_options::value<TcpdumpPluginMode>(&g_tcpdump_mode)
59 ->multitoken()->default_value(TCPDUMP_MODE_FAST, "fast"),
60 "The mode of tcpdump plugin (fast|accurate), in 'fast' mode "
61 "the plugin executes queries as fast as it can whereas in "
62 "'accurate' mode the plugin preserves queries execution time "
63 "and pauses between queries")
64 ;
2665
27 return &options;66 return &options;
28}67}
@@ -32,7 +71,9 @@
32 boost::program_options::variables_map &vm)71 boost::program_options::variables_map &vm)
33{72{
34 if (!active &&73 if (!active &&
35 (vm.count("tcpdump-file")))74 (vm.count("tcpdump-file") ||
75 !vm["tcpdump-port"].defaulted() ||
76 !vm["tcpdump-mode"].defaulted()))
36 {77 {
37 fprintf(stderr, 78 fprintf(stderr,
38 gettext("tcpdump plugin is not selected, "79 gettext("tcpdump plugin is not selected, "
@@ -40,9 +81,87 @@
40 "command line options\n"));81 "command line options\n"));
41 return -1;82 return -1;
42 }83 }
84
85 if (!active)
86 return 0;
87
88 if (!vm.count("tcpdump-file"))
89 {
90 fprintf(stderr,
91 gettext("tcpdump-file argument is requred\n"));
92 return -1;
93 }
94
43 return 0;95 return 0;
44}96}
4597
98void
99TcpDumpParserPlugin::run(percona_playback_run_result &r)
100{
101 char errbuf[PCAP_ERRBUF_SIZE];
102 pcap_t *handle;
103 struct bpf_program fp;
104 char filter_exp[11];
105 PcapPacketsParser packets_parser;
106
107
108 if (g_tcpdump_file_name.empty())
109 {
110 r.err= -1;
111 return;
112 }
113
114 handle = pcap_open_offline(g_tcpdump_file_name.c_str(), errbuf);
115
116 if (handle == NULL)
117 {
118 std::cerr << "Couldn't open file " << g_tcpdump_file_name << ": "
119 << errbuf << std::endl;
120 r.err= -1;
121 return;
122 }
123
124 snprintf(filter_exp, FILTER_EXP_SIZE, "port %u", (unsigned)g_tcpdump_port);
125
126 if(pcap_compile(handle, &fp, filter_exp, 0, 0) == -1)
127 {
128 std::cerr << "Couldn't parse filter " << filter_exp << ": "
129 << pcap_geterr(handle) << std::endl;
130 r.err= -1;
131 return;
132 }
133
134 if (pcap_setfilter(handle, &fp) == -1)
135 {
136 std::cerr << "Couldn't install filter " << filter_exp << ": "
137 << pcap_geterr(handle) << std::endl;
138 r.err= -1;
139 return;
140 }
141
142 if (pcap_loop(handle,
143 -1,
144 PcapPacketsParser::Process,
145 (u_char *)&packets_parser) < 0)
146 {
147 std::cerr << "pcap_loop error "
148 << pcap_geterr(handle) << std::endl;
149 r.err= -1;
150 return;
151 }
152
153 /* Wait for unfinished DBThreads */
154 packets_parser.WaitForUnfinishedTasks();
155
156 const TcpdumpMysqlParserStats &stats= packets_parser.GetStats();
157
158 r.n_log_entries= stats.nr_of_parsed_packets;
159 r.n_queries= stats.nr_of_parsed_queries;
160 r.err= stats.nr_of_parsing_errors;
161
162 return;
163}
164
46static void init_plugin(percona_playback::PluginRegistry &r)165static void init_plugin(percona_playback::PluginRegistry &r)
47{166{
48 r.add("tcpdump", new TcpDumpParserPlugin("tcpdump"));167 r.add("tcpdump", new TcpDumpParserPlugin("tcpdump"));
49168
=== modified file 'percona_playback/tcpdump/tcpdump.h'
--- percona_playback/tcpdump/tcpdump.h 2012-06-24 04:28:41 +0000
+++ percona_playback/tcpdump/tcpdump.h 2012-07-02 18:23:18 +0000
@@ -19,9 +19,17 @@
19#include <percona_playback/plugin.h>19#include <percona_playback/plugin.h>
2020
21#include <boost/program_options.hpp>21#include <boost/program_options.hpp>
22#include <string>
23
24enum TcpdumpPluginMode
25{
26 TCPDUMP_MODE_FAST,
27 TCPDUMP_MODE_ACCURATE
28};
2229
23class TcpDumpParserPlugin : public percona_playback::InputPlugin30class TcpDumpParserPlugin : public percona_playback::InputPlugin
24{31{
32 boost::program_options::options_description options;
2533
26public:34public:
27 TcpDumpParserPlugin(const std::string &_name) :35 TcpDumpParserPlugin(const std::string &_name) :
@@ -33,11 +41,20 @@
3341
34 virtual int processOptions(boost::program_options::variables_map &vm);42 virtual int processOptions(boost::program_options::variables_map &vm);
3543
44<<<<<<< TREE
36 virtual void run(percona_playback_run_result &) {}45 virtual void run(percona_playback_run_result &) {}
3746
3847
39 std::string file_name;48 std::string file_name;
40 boost::program_options::options_description options;49 boost::program_options::options_description options;
50=======
51 virtual void run(percona_playback_run_result &result);
52>>>>>>> MERGE-SOURCE
41};53};
4254
55extern std::string g_tcpdump_file_name;
56extern uint16_t g_tcpdump_port;
57extern TcpdumpPluginMode g_tcpdump_mode;
58
59
43#endif /* PERCONA_PLAYBACK_TCPDUMP_PARSER_H */60#endif /* PERCONA_PLAYBACK_TCPDUMP_PARSER_H */
4461
=== added file 'percona_playback/tcpdump/tcpdump_mysql_parser_stats.h'
--- percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 2012-07-02 18:23:18 +0000
@@ -0,0 +1,33 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#ifndef PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H
17#define PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H
18
19struct TcpdumpMysqlParserStats
20{
21 size_t nr_of_parsed_packets;
22 size_t nr_of_parsed_queries;
23 size_t nr_of_parsing_errors;
24
25 TcpdumpMysqlParserStats() :
26 nr_of_parsed_packets(0),
27 nr_of_parsed_queries(0),
28 nr_of_parsing_errors(0)
29 {}
30
31};
32
33#endif //PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H
034
=== added file 'percona_playback/tcpdump/tcpdump_query_entries.cc'
--- percona_playback/tcpdump/tcpdump_query_entries.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/tcpdump_query_entries.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,129 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15#include "tcpdump_query_entries.h"
16#include "tcpdump.h"
17#include "percona_playback/db_thread.h"
18#include "percona_playback/plugin.h"
19
20#include <boost/date_time/posix_time/posix_time.hpp>
21#include <boost/foreach.hpp>
22#include <boost/shared_ptr.hpp>
23#include <string.h>
24#include <iostream>
25#include <assert.h>
26
27void
28TcpdumpQueryEntry::execute(DBThread *t)
29{
30 QueryResult expected_result;
31 boost::posix_time::ptime start_time;
32 boost::posix_time::ptime end_time;
33 boost::shared_ptr<DBThreadState> thr_state;
34
35 assert(t);
36
37 thr_state= t->get_state();
38
39 assert(thr_state.get());
40
41 ConnectionState &state= (ConnectionState &)*thr_state;
42
43 LastExecutedQueryInfo &last_query_info= state.last_executed_query_info;
44
45 if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE &&
46 last_query_info.end_timestamp.tv_sec != 0 &&
47 last_query_info.end_timestamp.tv_usec != 0 &&
48 last_query_info.end_pcap_timestamp.tv_sec != 0 &&
49 last_query_info.end_pcap_timestamp.tv_usec != 0)
50 {
51 timeval current_timestamp;
52 timeval pause_time;
53 timeval pcap_pause_time;
54
55 gettimeofday(&current_timestamp, NULL);
56 timersub(&current_timestamp, &last_query_info.end_timestamp, &pause_time);
57
58 timersub(&pcap_timestamp,
59 &last_query_info.end_pcap_timestamp,
60 &pcap_pause_time);
61
62 if (timercmp(&pause_time, &pcap_pause_time, <))
63 {
64 timeval time_to_sleep;
65 timersub(&pcap_pause_time,
66 &pause_time,
67 &time_to_sleep);
68 usleep(time_to_sleep.tv_sec*1000000 + time_to_sleep.tv_usec);
69 }
70 }
71
72 last_query_info.result.clear();
73
74 start_time= boost::posix_time::microsec_clock::universal_time();
75 t->execute_query(query, &last_query_info.result, expected_result);
76 end_time= boost::posix_time::microsec_clock::universal_time();
77
78 boost::posix_time::time_period duration(start_time, end_time);
79 last_query_info.result.setDuration(duration.length());
80 last_query_info.begin_pcap_timestamp= pcap_timestamp;
81 last_query_info.query= query;
82}
83
84void
85TcpdumpResultEntry::execute(DBThread *t)
86{
87 timeval query_execution_time;
88 boost::shared_ptr<DBThreadState> thr_state;
89
90 assert(t);
91
92 thr_state= t->get_state();
93
94 assert(thr_state.get());
95
96
97 ConnectionState &state= (ConnectionState &)*thr_state;
98 LastExecutedQueryInfo &last_query_info= state.last_executed_query_info;
99
100 timersub(&pcap_timestamp,
101 &last_query_info.begin_pcap_timestamp,
102 &query_execution_time);
103
104 expected_result.setDuration(
105 boost::posix_time::microseconds(
106 query_execution_time.tv_usec +
107 query_execution_time.tv_sec*1000000));
108
109 if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE &&
110 (expected_result.getDuration() > last_query_info.result.getDuration()))
111 {
112 boost::posix_time::time_duration us_sleep_time=
113 expected_result.getDuration() - last_query_info.result.getDuration();
114
115 usleep(us_sleep_time.total_microseconds());
116 }
117
118 gettimeofday(&last_query_info.end_timestamp, NULL);
119 last_query_info.end_pcap_timestamp= pcap_timestamp;
120
121 BOOST_FOREACH(const percona_playback::PluginRegistry::ReportPluginPair pp,
122 percona_playback::PluginRegistry::singleton().report_plugins)
123 {
124 pp.second->query_execution(getThreadId(),
125 last_query_info.query,
126 expected_result,
127 last_query_info.result);
128 }
129}
0130
=== added file 'percona_playback/tcpdump/tcpdump_query_entries.h'
--- percona_playback/tcpdump/tcpdump_query_entries.h 1970-01-01 00:00:00 +0000
+++ percona_playback/tcpdump/tcpdump_query_entries.h 2012-07-02 18:23:18 +0000
@@ -0,0 +1,73 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#ifndef PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H
17#define PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H
18
19#include "percona_playback/query_entry.h"
20#include "percona_playback/query_result.h"
21#include "connection_state.h"
22
23#include <sys/time.h>
24
25class TcpdumpQueryEntry : public QueryEntry
26{
27 timeval pcap_timestamp;
28 std::string query;
29
30public:
31
32 TcpdumpQueryEntry()
33 {
34 pcap_timestamp.tv_sec= pcap_timestamp.tv_usec= 0;
35 }
36
37 TcpdumpQueryEntry(const timeval &pcap_timestamp,
38 const std::string &query,
39 const AddrPort &addr_port) :
40 QueryEntry(addr_port.ThreadId(), false),
41 pcap_timestamp(pcap_timestamp),
42 query(query)
43 {}
44
45 bool is_quit() { return false; }
46
47 void execute(DBThread *t);
48};
49
50class TcpdumpResultEntry : public QueryEntry
51{
52
53 timeval pcap_timestamp;
54 QueryResult expected_result;
55
56public:
57 TcpdumpResultEntry() {}
58 TcpdumpResultEntry(const AddrPort &addr_port,
59 const timeval &pcap_timestamp,
60 const QueryResult &expected_result) :
61 QueryEntry(addr_port.ThreadId(), false),
62 pcap_timestamp(pcap_timestamp),
63 expected_result(expected_result)
64 {}
65
66 bool is_quit() { return false; }
67
68 void execute(DBThread *t);
69
70};
71
72#endif// PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H
73
074
=== added file 'percona_playback/test/tcpdump_accuracy.cc'
--- percona_playback/test/tcpdump_accuracy.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/tcpdump_accuracy.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,69 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 3, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17#include <iostream>
18#include <assert.h>
19#include <boost/date_time/posix_time/posix_time.hpp>
20
21#include "percona_playback/percona_playback.h"
22#include "percona_playback/plugin.h"
23
24const size_t pp_argc= 5;
25
26int main(int, char **argv)
27{
28 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
29 assert(the_percona_playback);
30
31 char *pp_argv[pp_argc];
32 char pp_argv_0[]= "--db-plugin=null";
33 char pp_argv_1[]= "--input-plugin=tcpdump";
34 char pp_argv_2[]= "--tcpdump-file="
35 SRCDIR
36 "/percona_playback/test"
37 "/tcpdump_accuracy.dump";
38 char pp_argv_3[]= "--tcpdump-mode=accurate";
39
40 pp_argv[0]= argv[0];
41 pp_argv[1]= pp_argv_0;
42 pp_argv[2]= pp_argv_1;
43 pp_argv[3]= pp_argv_2;
44 pp_argv[4]= pp_argv_3;
45
46 assert(0 == percona_playback_argv(the_percona_playback,
47 pp_argc,
48 pp_argv));
49
50 boost::posix_time::ptime start_time;
51 start_time= boost::posix_time::microsec_clock::universal_time();
52
53 struct percona_playback_run_result *r=
54 percona_playback_run(the_percona_playback);
55
56 boost::posix_time::ptime end_time;
57 end_time= boost::posix_time::microsec_clock::universal_time();
58
59 boost::posix_time::time_period duration(start_time, end_time);
60
61 assert(duration.length().total_microseconds() > 4000000);
62
63 assert(r->err == 0);
64 assert(r->n_queries == 60);
65 assert(r->n_log_entries == 480);
66
67 percona_playback_destroy(&the_percona_playback);
68 return r->err;
69}
070
=== added file 'percona_playback/test/tcpdump_accuracy.dump'
1Binary files percona_playback/test/tcpdump_accuracy.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_accuracy.dump 2012-07-02 18:23:18 +0000 differ71Binary files percona_playback/test/tcpdump_accuracy.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_accuracy.dump 2012-07-02 18:23:18 +0000 differ
=== added file 'percona_playback/test/tcpdump_fragmented_packet.cc'
--- percona_playback/test/tcpdump_fragmented_packet.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/tcpdump_fragmented_packet.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,56 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 3, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17#include <iostream>
18#include <assert.h>
19#include "percona_playback/percona_playback.h"
20#include "percona_playback/plugin.h"
21
22const size_t pp_argc= 4;
23
24int main(int, char **argv)
25{
26 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
27 assert(the_percona_playback);
28
29 char *pp_argv[pp_argc];
30 char pp_argv_0[]= "--db-plugin=null";
31 char pp_argv_1[]= "--input-plugin=tcpdump";
32 char pp_argv_2[]= "--tcpdump-file="
33 SRCDIR
34 "/percona_playback/test"
35 "/tcpdump_fragmented_packet.dump";
36
37
38 pp_argv[0]= argv[0];
39 pp_argv[1]= pp_argv_0;
40 pp_argv[2]= pp_argv_1;
41 pp_argv[3]= pp_argv_2;
42
43 assert(0 == percona_playback_argv(the_percona_playback,
44 pp_argc,
45 pp_argv));
46
47 struct percona_playback_run_result *r=
48 percona_playback_run(the_percona_playback);
49
50 assert(r->err == 0);
51 assert(r->n_queries == 1);
52 assert(r->n_log_entries == 6);
53
54 percona_playback_destroy(&the_percona_playback);
55 return r->err;
56}
057
=== added file 'percona_playback/test/tcpdump_fragmented_packet.dump'
1Binary files percona_playback/test/tcpdump_fragmented_packet.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_fragmented_packet.dump 2012-07-02 18:23:18 +0000 differ58Binary files percona_playback/test/tcpdump_fragmented_packet.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_fragmented_packet.dump 2012-07-02 18:23:18 +0000 differ
=== added file 'percona_playback/test/tcpdump_multiple_connections.cc'
--- percona_playback/test/tcpdump_multiple_connections.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/tcpdump_multiple_connections.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,56 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 3, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17#include <iostream>
18#include <assert.h>
19#include "percona_playback/percona_playback.h"
20#include "percona_playback/plugin.h"
21
22const size_t pp_argc= 4;
23
24int main(int, char **argv)
25{
26 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
27 assert(the_percona_playback);
28
29 char *pp_argv[pp_argc];
30 char pp_argv_0[]= "--db-plugin=null";
31 char pp_argv_1[]= "--input-plugin=tcpdump";
32 char pp_argv_2[]= "--tcpdump-file="
33 SRCDIR
34 "/percona_playback/test"
35 "/tcpdump_multiple_connections.dump";
36
37
38 pp_argv[0]= argv[0];
39 pp_argv[1]= pp_argv_0;
40 pp_argv[2]= pp_argv_1;
41 pp_argv[3]= pp_argv_2;
42
43 assert(0 == percona_playback_argv(the_percona_playback,
44 pp_argc,
45 pp_argv));
46
47 struct percona_playback_run_result *r=
48 percona_playback_run(the_percona_playback);
49
50 assert(r->err == 0);
51 assert(r->n_queries == 2000);
52 assert(r->n_log_entries == 16000);
53
54 percona_playback_destroy(&the_percona_playback);
55 return r->err;
56}
057
=== added file 'percona_playback/test/tcpdump_multiple_connections.dump'
1Binary files percona_playback/test/tcpdump_multiple_connections.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_multiple_connections.dump 2012-07-02 18:23:18 +0000 differ58Binary files percona_playback/test/tcpdump_multiple_connections.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_multiple_connections.dump 2012-07-02 18:23:18 +0000 differ
=== added file 'percona_playback/test/tcpdump_stress_test.cc'
--- percona_playback/test/tcpdump_stress_test.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/tcpdump_stress_test.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,56 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 3, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17#include <iostream>
18#include <assert.h>
19#include "percona_playback/percona_playback.h"
20#include "percona_playback/plugin.h"
21
22const size_t pp_argc= 4;
23
24int main(int, char **argv)
25{
26 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
27 assert(the_percona_playback);
28
29 char *pp_argv[pp_argc];
30 char pp_argv_0[]= "--db-plugin=null";
31 char pp_argv_1[]= "--input-plugin=tcpdump";
32 char pp_argv_2[]= "--tcpdump-file="
33 SRCDIR
34 "/percona_playback/test"
35 "/tcpdump_stress_test.dump";
36
37
38 pp_argv[0]= argv[0];
39 pp_argv[1]= pp_argv_0;
40 pp_argv[2]= pp_argv_1;
41 pp_argv[3]= pp_argv_2;
42
43 assert(0 == percona_playback_argv(the_percona_playback,
44 pp_argc,
45 pp_argv));
46
47 struct percona_playback_run_result *r=
48 percona_playback_run(the_percona_playback);
49
50 assert(r->err == 0);
51 assert(r->n_queries == 9088);
52 assert(r->n_log_entries == 62306);
53
54 percona_playback_destroy(&the_percona_playback);
55 return r->err;
56}
057
=== added file 'percona_playback/test/tcpdump_stress_test.dump'
1Binary files percona_playback/test/tcpdump_stress_test.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_stress_test.dump 2012-07-02 18:23:18 +0000 differ58Binary files percona_playback/test/tcpdump_stress_test.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_stress_test.dump 2012-07-02 18:23:18 +0000 differ
=== added file 'percona_playback/test/tcpdump_without_handshake.cc'
--- percona_playback/test/tcpdump_without_handshake.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/tcpdump_without_handshake.cc 2012-07-02 18:23:18 +0000
@@ -0,0 +1,56 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2012 Percona Inc.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 3, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17#include <iostream>
18#include <assert.h>
19#include "percona_playback/percona_playback.h"
20#include "percona_playback/plugin.h"
21
22const size_t pp_argc= 4;
23
24int main(int, char **argv)
25{
26 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
27 assert(the_percona_playback);
28
29 char *pp_argv[pp_argc];
30 char pp_argv_0[]= "--db-plugin=null";
31 char pp_argv_1[]= "--input-plugin=tcpdump";
32 char pp_argv_2[]= "--tcpdump-file="
33 SRCDIR
34 "/percona_playback/test"
35 "/tcpdump_without_handshake.dump";
36
37
38 pp_argv[0]= argv[0];
39 pp_argv[1]= pp_argv_0;
40 pp_argv[2]= pp_argv_1;
41 pp_argv[3]= pp_argv_2;
42
43 assert(0 == percona_playback_argv(the_percona_playback,
44 pp_argc,
45 pp_argv));
46
47 struct percona_playback_run_result *r=
48 percona_playback_run(the_percona_playback);
49
50 assert(r->err == 0);
51 assert(r->n_queries == 7);
52 assert(r->n_log_entries == 44);
53
54 percona_playback_destroy(&the_percona_playback);
55 return r->err;
56}
057
=== added file 'percona_playback/test/tcpdump_without_handshake.dump'
1Binary files percona_playback/test/tcpdump_without_handshake.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_without_handshake.dump 2012-07-02 18:23:18 +0000 differ58Binary files percona_playback/test/tcpdump_without_handshake.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_without_handshake.dump 2012-07-02 18:23:18 +0000 differ

Subscribers

People subscribed via source and target branches

to all changes: