Merge lp:~vlad-lesin/percona-playback/tcpdump-parsing into lp:percona-playback
- tcpdump-parsing
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith | Pending | ||
Review via email: mp+111163@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 98. By Vlad Lesin
-
Add pandora_
have_libmysqlcl ient.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
1 | === modified file '.bzrignore' | |||
2 | --- .bzrignore 2011-12-30 01:47:04 +0000 | |||
3 | +++ .bzrignore 2012-07-02 18:23:18 +0000 | |||
4 | @@ -40,3 +40,14 @@ | |||
5 | 40 | percona_playback/test/crashme-slow | 40 | percona_playback/test/crashme-slow |
6 | 41 | percona_playback/test/sqlbench-transactions-slow | 41 | percona_playback/test/sqlbench-transactions-slow |
7 | 42 | percona_playback/test/sysbench-slow | 42 | percona_playback/test/sysbench-slow |
8 | 43 | m4/libtool.m4 | ||
9 | 44 | m4/ltoptions.m4 | ||
10 | 45 | m4/ltversion.m4 | ||
11 | 46 | m4/lt~obsolete.m4 | ||
12 | 47 | percona_playback/test/preserve_query_time | ||
13 | 48 | percona_playback/test/tcpdump_accuracy | ||
14 | 49 | percona_playback/test/tcpdump_fragmented_packet | ||
15 | 50 | percona_playback/test/tcpdump_multiple_connections | ||
16 | 51 | percona_playback/test/tcpdump_stress_test | ||
17 | 52 | percona_playback/test/tcpdump_without_handshake | ||
18 | 53 | tags | ||
19 | 43 | 54 | ||
20 | === modified file 'Makefile.am' | |||
21 | --- Makefile.am 2012-06-22 05:12:15 +0000 | |||
22 | +++ Makefile.am 2012-07-02 18:23:18 +0000 | |||
23 | @@ -39,6 +39,11 @@ | |||
24 | 39 | percona_playback/test/sqlbench-transactions-slow.log \ | 39 | percona_playback/test/sqlbench-transactions-slow.log \ |
25 | 40 | percona_playback/test/sysbench-slow.log \ | 40 | percona_playback/test/sysbench-slow.log \ |
26 | 41 | percona_playback/test/preserve_query_time.log \ | 41 | percona_playback/test/preserve_query_time.log \ |
27 | 42 | percona_playback/test/tcpdump_without_handshake.dump \ | ||
28 | 43 | percona_playback/test/tcpdump_fragmented_packet.dump \ | ||
29 | 44 | percona_playback/test/tcpdump_multiple_connections.dump \ | ||
30 | 45 | percona_playback/test/tcpdump_stress_test.dump \ | ||
31 | 46 | percona_playback/test/tcpdump_accuracy.dump \ | ||
32 | 42 | test_run.sh | 47 | test_run.sh |
33 | 43 | 48 | ||
34 | 44 | include config/pandora-plugin.am | 49 | include config/pandora-plugin.am |
35 | @@ -71,9 +76,15 @@ | |||
36 | 71 | $(AM_CXXFLAGS) \ | 76 | $(AM_CXXFLAGS) \ |
37 | 72 | -DBUILDING_PERCONA_PLAYBACK | 77 | -DBUILDING_PERCONA_PLAYBACK |
38 | 73 | 78 | ||
39 | 79 | <<<<<<< TREE | ||
40 | 74 | libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(TBB_LIBS) | 80 | libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(TBB_LIBS) |
41 | 75 | libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(TBB_LIBS) $(pandora_plugin_libs) | 81 | libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(TBB_LIBS) $(pandora_plugin_libs) |
42 | 76 | libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs) | 82 | libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs) |
43 | 83 | ======= | ||
44 | 84 | libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(LTLIBTBB) | ||
45 | 85 | libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(LTLIBTBB) $(pandora_plugin_libs) | ||
46 | 86 | libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs) | ||
47 | 87 | >>>>>>> MERGE-SOURCE | ||
48 | 77 | 88 | ||
49 | 78 | check_PROGRAMS += \ | 89 | check_PROGRAMS += \ |
50 | 79 | percona_playback/test/basic \ | 90 | percona_playback/test/basic \ |
51 | @@ -82,6 +93,11 @@ | |||
52 | 82 | percona_playback/test/sqlbench-transactions-slow \ | 93 | percona_playback/test/sqlbench-transactions-slow \ |
53 | 83 | percona_playback/test/sysbench-slow \ | 94 | percona_playback/test/sysbench-slow \ |
54 | 84 | percona_playback/test/preserve_query_time \ | 95 | percona_playback/test/preserve_query_time \ |
55 | 96 | percona_playback/test/tcpdump_without_handshake \ | ||
56 | 97 | percona_playback/test/tcpdump_fragmented_packet \ | ||
57 | 98 | percona_playback/test/tcpdump_multiple_connections \ | ||
58 | 99 | percona_playback/test/tcpdump_stress_test \ | ||
59 | 100 | percona_playback/test/tcpdump_accuracy \ | ||
60 | 85 | percona_playback/test/help | 101 | percona_playback/test/help |
61 | 86 | 102 | ||
62 | 87 | percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | 103 | percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
63 | @@ -90,6 +106,11 @@ | |||
64 | 90 | percona_playback_test_sqlbench_transactions_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | 106 | percona_playback_test_sqlbench_transactions_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
65 | 91 | percona_playback_test_sysbench_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | 107 | percona_playback_test_sysbench_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
66 | 92 | percona_playback_test_preserve_query_time_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | 108 | percona_playback_test_preserve_query_time_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
67 | 109 | percona_playback_test_tcpdump_without_handshake_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | ||
68 | 110 | percona_playback_test_tcpdump_fragmented_packet_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | ||
69 | 111 | percona_playback_test_tcpdump_multiple_connections_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | ||
70 | 112 | percona_playback_test_tcpdump_stress_test_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | ||
71 | 113 | percona_playback_test_tcpdump_accuracy_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" | ||
72 | 93 | 114 | ||
73 | 94 | percona_playback_test_help_SOURCES= percona_playback/test/help.cc | 115 | percona_playback_test_help_SOURCES= percona_playback/test/help.cc |
74 | 95 | percona_playback_test_help_LDADD= $(LDADD) $(MYSQL_LIBS) | 116 | percona_playback_test_help_LDADD= $(LDADD) $(MYSQL_LIBS) |
75 | @@ -112,7 +133,20 @@ | |||
76 | 112 | percona_playback_test_preserve_query_time_SOURCES= percona_playback/test/preserve_query_time.cc | 133 | percona_playback_test_preserve_query_time_SOURCES= percona_playback/test/preserve_query_time.cc |
77 | 113 | percona_playback_test_preserve_query_time_LDADD= $(LDADD) $(MYSQL_LIBS) | 134 | percona_playback_test_preserve_query_time_LDADD= $(LDADD) $(MYSQL_LIBS) |
78 | 114 | 135 | ||
80 | 115 | 136 | percona_playback_test_tcpdump_without_handshake_SOURCES= percona_playback/test/tcpdump_without_handshake.cc | |
81 | 137 | percona_playback_test_tcpdump_without_handshake_LDADD= $(LDADD) $(MYSQL_LIBS) | ||
82 | 138 | |||
83 | 139 | percona_playback_test_tcpdump_fragmented_packet_SOURCES= percona_playback/test/tcpdump_fragmented_packet.cc | ||
84 | 140 | percona_playback_test_tcpdump_fragmented_packet_LDADD= $(LDADD) $(MYSQL_LIBS) | ||
85 | 141 | |||
86 | 142 | percona_playback_test_tcpdump_multiple_connections_SOURCES= percona_playback/test/tcpdump_multiple_connections.cc | ||
87 | 143 | percona_playback_test_tcpdump_multiple_connections_LDADD= $(LDADD) $(MYSQL_LIBS) | ||
88 | 144 | |||
89 | 145 | percona_playback_test_tcpdump_stress_test_SOURCES= percona_playback/test/tcpdump_stress_test.cc | ||
90 | 146 | percona_playback_test_tcpdump_stress_test_LDADD= $(LDADD) $(MYSQL_LIBS) | ||
91 | 147 | |||
92 | 148 | percona_playback_test_tcpdump_accuracy_SOURCES= percona_playback/test/tcpdump_accuracy.cc | ||
93 | 149 | percona_playback_test_tcpdump_accuracy_LDADD= $(LDADD) $(MYSQL_LIBS) | ||
94 | 116 | 150 | ||
95 | 117 | # | 151 | # |
96 | 118 | # Simple percona_playback application | 152 | # Simple percona_playback application |
97 | @@ -120,7 +154,7 @@ | |||
98 | 120 | 154 | ||
99 | 121 | bin_PROGRAMS += bin/percona_playback | 155 | bin_PROGRAMS += bin/percona_playback |
100 | 122 | bin_percona_playback_SOURCES = bin/percona_playback.cc | 156 | bin_percona_playback_SOURCES = bin/percona_playback.cc |
102 | 123 | bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(TBB_LIBS) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS) | 157 | bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(LTLIBTBB) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS) |
103 | 124 | 158 | ||
104 | 125 | include docs/include.am | 159 | include docs/include.am |
105 | 126 | 160 | ||
106 | 127 | 161 | ||
107 | === modified file 'configure.ac' | |||
108 | --- configure.ac 2012-06-24 04:28:41 +0000 | |||
109 | +++ configure.ac 2012-07-02 18:23:18 +0000 | |||
110 | @@ -58,8 +58,13 @@ | |||
111 | 58 | 58 | ||
112 | 59 | AC_DEFINE_UNQUOTED([PERCONA_PLAYBACK_MODULE_EXT], ["$acl_cv_shlibext"], | 59 | AC_DEFINE_UNQUOTED([PERCONA_PLAYBACK_MODULE_EXT], ["$acl_cv_shlibext"], |
113 | 60 | [Extension to use for modules.]) | 60 | [Extension to use for modules.]) |
114 | 61 | <<<<<<< TREE | ||
115 | 61 | AM_CXXFLAGS="${AM_CXXFLAGS} ${NO_EFF_CXX} ${NO_OLD_STYLE_CAST} ${NO_VISIBILITY}" | 62 | AM_CXXFLAGS="${AM_CXXFLAGS} ${NO_EFF_CXX} ${NO_OLD_STYLE_CAST} ${NO_VISIBILITY}" |
116 | 62 | AC_CONFIG_FILES(Makefile dnl po/Makefile.in | 63 | AC_CONFIG_FILES(Makefile dnl po/Makefile.in |
117 | 64 | ======= | ||
118 | 65 | AM_CXXFLAGS="${NO_EFF_CXX}" | ||
119 | 66 | AC_CONFIG_FILES(Makefile dnl po/Makefile.in | ||
120 | 67 | >>>>>>> MERGE-SOURCE | ||
121 | 63 | percona_playback/version.h dnl | 68 | percona_playback/version.h dnl |
122 | 64 | docs/header.html) | 69 | docs/header.html) |
123 | 65 | 70 | ||
124 | 66 | 71 | ||
125 | === added file 'm4/pandora_have_libdrizzle-1.0.m4' | |||
126 | --- m4/pandora_have_libdrizzle-1.0.m4 1970-01-01 00:00:00 +0000 | |||
127 | +++ m4/pandora_have_libdrizzle-1.0.m4 2012-07-02 18:23:18 +0000 | |||
128 | @@ -0,0 +1,74 @@ | |||
129 | 1 | dnl Copyright (C) 2009 Sun Microsystems, Inc. | ||
130 | 2 | dnl This file is free software; Sun Microsystems, Inc. | ||
131 | 3 | dnl gives unlimited permission to copy and/or distribute it, | ||
132 | 4 | dnl with or without modifications, as long as this notice is preserved. | ||
133 | 5 | |||
134 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE_1_0],[ | ||
135 | 7 | AC_REQUIRE([AC_LIB_PREFIX]) | ||
136 | 8 | |||
137 | 9 | dnl -------------------------------------------------------------------- | ||
138 | 10 | dnl Check for libdrizzle | ||
139 | 11 | dnl -------------------------------------------------------------------- | ||
140 | 12 | |||
141 | 13 | AC_ARG_ENABLE([libdrizzle], | ||
142 | 14 | [AS_HELP_STRING([--disable-libdrizzle], | ||
143 | 15 | [Build with libdrizzle support @<:@default=on@:>@])], | ||
144 | 16 | [ac_enable_libdrizzle="$enableval"], | ||
145 | 17 | [ac_enable_libdrizzle="yes"]) | ||
146 | 18 | |||
147 | 19 | AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[ | ||
148 | 20 | AC_LIB_HAVE_LINKFLAGS(drizzle,,[ | ||
149 | 21 | #include <libdrizzle/drizzle_client.h> | ||
150 | 22 | ],[ | ||
151 | 23 | drizzle_st drizzle; | ||
152 | 24 | drizzle_version(); | ||
153 | 25 | ]) | ||
154 | 26 | ],[ | ||
155 | 27 | ac_cv_libdrizzle="no" | ||
156 | 28 | ]) | ||
157 | 29 | |||
158 | 30 | AS_IF([test "${ac_cv_libdrizzle}" = "no" -a "${ac_enable_libdrizzle}" = "yes"],[ | ||
159 | 31 | PKG_CHECK_MODULES([LIBDRIZZLE], [libdrizzle-1.0], [ | ||
160 | 32 | ac_cv_libdrizzle=yes | ||
161 | 33 | LTLIBDRIZZLE=${LIBDRIZZLE_LIBS} | ||
162 | 34 | LIBDRIZZLE=${LIBDRIZZLE_LIBS} | ||
163 | 35 | CPPFLAGS=${LIBDRIZZLE_CFLAGS} ${CPPFLAGS} | ||
164 | 36 | HAVE_LIBDRIZZLE="yes" | ||
165 | 37 | AC_SUBST(HAVE_LIBDRIZZLE) | ||
166 | 38 | AC_SUBST(LIBDRIZZLE) | ||
167 | 39 | AC_SUBST(LTLIBDRIZZLE) | ||
168 | 40 | ],[]) | ||
169 | 41 | ]) | ||
170 | 42 | |||
171 | 43 | AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"]) | ||
172 | 44 | ]) | ||
173 | 45 | |||
174 | 46 | AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE_1_0],[ | ||
175 | 47 | AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE_1_0]) | ||
176 | 48 | ]) | ||
177 | 49 | |||
178 | 50 | AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE_1_0],[ | ||
179 | 51 | AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE_1_0]) | ||
180 | 52 | AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[ | ||
181 | 53 | AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}]) | ||
182 | 54 | ],[ | ||
183 | 55 | dnl We need at least 0.8 on Solaris non-sparc | ||
184 | 56 | AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[ | ||
185 | 57 | PANDORA_LIBDRIZZLE_RECENT | ||
186 | 58 | ]) | ||
187 | 59 | ]) | ||
188 | 60 | ]) | ||
189 | 61 | |||
190 | 62 | AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[ | ||
191 | 63 | AC_CACHE_CHECK([if libdrizzle is recent enough], | ||
192 | 64 | [pandora_cv_libdrizzle_recent], | ||
193 | 65 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | ||
194 | 66 | #include <libdrizzle/drizzle.h> | ||
195 | 67 | drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL; | ||
196 | 68 | ]])], | ||
197 | 69 | [pandora_cv_libdrizzle_recent=yes], | ||
198 | 70 | [pandora_cv_libdrizzle_recent=no])]) | ||
199 | 71 | AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[ | ||
200 | 72 | AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8]) | ||
201 | 73 | ]) | ||
202 | 74 | ]) | ||
203 | 0 | 75 | ||
204 | === removed file 'm4/pandora_have_libdrizzle.m4' | |||
205 | --- m4/pandora_have_libdrizzle.m4 2012-04-03 05:13:48 +0000 | |||
206 | +++ m4/pandora_have_libdrizzle.m4 1970-01-01 00:00:00 +0000 | |||
207 | @@ -1,61 +0,0 @@ | |||
208 | 1 | dnl Copyright (C) 2009 Sun Microsystems, Inc. | ||
209 | 2 | dnl This file is free software; Sun Microsystems, Inc. | ||
210 | 3 | dnl gives unlimited permission to copy and/or distribute it, | ||
211 | 4 | dnl with or without modifications, as long as this notice is preserved. | ||
212 | 5 | |||
213 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE],[ | ||
214 | 7 | AC_REQUIRE([AC_LIB_PREFIX]) | ||
215 | 8 | |||
216 | 9 | dnl -------------------------------------------------------------------- | ||
217 | 10 | dnl Check for libdrizzle | ||
218 | 11 | dnl -------------------------------------------------------------------- | ||
219 | 12 | |||
220 | 13 | AC_ARG_ENABLE([libdrizzle], | ||
221 | 14 | [AS_HELP_STRING([--disable-libdrizzle], | ||
222 | 15 | [Build with libdrizzle support @<:@default=on@:>@])], | ||
223 | 16 | [ac_enable_libdrizzle="$enableval"], | ||
224 | 17 | [ac_enable_libdrizzle="yes"]) | ||
225 | 18 | |||
226 | 19 | AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[ | ||
227 | 20 | AC_LIB_HAVE_LINKFLAGS(drizzle,,[ | ||
228 | 21 | #include <libdrizzle/drizzle_client.h> | ||
229 | 22 | ],[ | ||
230 | 23 | drizzle_st drizzle; | ||
231 | 24 | drizzle_version(); | ||
232 | 25 | ]) | ||
233 | 26 | ],[ | ||
234 | 27 | ac_cv_libdrizzle="no" | ||
235 | 28 | ]) | ||
236 | 29 | |||
237 | 30 | AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"]) | ||
238 | 31 | ]) | ||
239 | 32 | |||
240 | 33 | AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE],[ | ||
241 | 34 | AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE]) | ||
242 | 35 | ]) | ||
243 | 36 | |||
244 | 37 | AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE],[ | ||
245 | 38 | AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE]) | ||
246 | 39 | AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[ | ||
247 | 40 | AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}]) | ||
248 | 41 | ],[ | ||
249 | 42 | dnl We need at least 0.8 on Solaris non-sparc | ||
250 | 43 | AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[ | ||
251 | 44 | PANDORA_LIBDRIZZLE_RECENT | ||
252 | 45 | ]) | ||
253 | 46 | ]) | ||
254 | 47 | ]) | ||
255 | 48 | |||
256 | 49 | AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[ | ||
257 | 50 | AC_CACHE_CHECK([if libdrizzle is recent enough], | ||
258 | 51 | [pandora_cv_libdrizzle_recent], | ||
259 | 52 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | ||
260 | 53 | #include <libdrizzle/drizzle.h> | ||
261 | 54 | drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL; | ||
262 | 55 | ]])], | ||
263 | 56 | [pandora_cv_libdrizzle_recent=yes], | ||
264 | 57 | [pandora_cv_libdrizzle_recent=no])]) | ||
265 | 58 | AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[ | ||
266 | 59 | AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8]) | ||
267 | 60 | ]) | ||
268 | 61 | ]) | ||
269 | 62 | 0 | ||
270 | === added file 'm4/pandora_have_libmysqlclient.m4' | |||
271 | --- m4/pandora_have_libmysqlclient.m4 1970-01-01 00:00:00 +0000 | |||
272 | +++ m4/pandora_have_libmysqlclient.m4 2012-07-02 18:23:18 +0000 | |||
273 | @@ -0,0 +1,103 @@ | |||
274 | 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
275 | 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
276 | 3 | dnl | ||
277 | 4 | dnl Copyright (C) 2010 Monty Taylor | ||
278 | 5 | dnl This file is free software; Sun Microsystems | ||
279 | 6 | dnl gives unlimited permission to copy and/or distribute it, | ||
280 | 7 | dnl with or without modifications, as long as this notice is preserved. | ||
281 | 8 | dnl | ||
282 | 9 | |||
283 | 10 | AC_DEFUN([PANDORA_WITH_MYSQL],[ | ||
284 | 11 | AC_ARG_WITH([mysql], | ||
285 | 12 | [AS_HELP_STRING([--with-mysql=PATH], | ||
286 | 13 | [path to mysql_config binary or mysql prefix dir])], | ||
287 | 14 | [with_mysql=$withval], | ||
288 | 15 | [with_mysql=":"]) | ||
289 | 16 | |||
290 | 17 | dnl There are three possibilities: | ||
291 | 18 | dnl 1) nothing is given: we will search for mysql_config in PATH | ||
292 | 19 | dnl 2) the location of mysql_config is given: we'll use that to determine | ||
293 | 20 | dnl 3) a directory argument is given: that will be mysql_base | ||
294 | 21 | |||
295 | 22 | |||
296 | 23 | dnl option 1: nothing, we need to insert something into MYSQL_CONFIG | ||
297 | 24 | AS_IF([test "x$with_mysql" = "x:"],[ | ||
298 | 25 | AC_CHECK_PROGS(MYSQL_CONFIG,[mysql_config]) | ||
299 | 26 | ],[ | ||
300 | 27 | MYSQL_CONFIG="${with_mysql}" | ||
301 | 28 | ]) | ||
302 | 29 | |||
303 | 30 | AC_CACHE_CHECK([for MySQL Base Location],[pandora_cv_mysql_base],[ | ||
304 | 31 | |||
305 | 32 | dnl option 2: something in MYSQL_CONFIG now, use that to get a base dir | ||
306 | 33 | AS_IF([test -f "${MYSQL_CONFIG}" -a -x "${MYSQL_CONFIG}"],[ | ||
307 | 34 | pandora_cv_mysql_base=$(dirname $(${MYSQL_CONFIG} --include | sed 's/-I//')) | ||
308 | 35 | MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include) | ||
309 | 36 | MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')" | ||
310 | 37 | MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r) | ||
311 | 38 | ],[ | ||
312 | 39 | dnl option 1: a directory | ||
313 | 40 | AS_IF([test -d $with_mysql], | ||
314 | 41 | [ | ||
315 | 42 | pandora_cv_mysql_base=$with_mysql | ||
316 | 43 | IBASE="-I${with_mysql}" | ||
317 | 44 | MYSQL_CONFIG="${with_mysql}/bin/mysql_config" | ||
318 | 45 | MYSQL_INCLUDES="$IBASE/include/mysql -isystem $IBASE/include/mysql" | ||
319 | 46 | MYSQL_LIBS="-L${with_mysql}/lib -L${with_mysql}/lib/mysql -lmysqlclient_r" | ||
320 | 47 | ], | ||
321 | 48 | [ | ||
322 | 49 | pandora_cv_mysql_base="" | ||
323 | 50 | ]) | ||
324 | 51 | ]) | ||
325 | 52 | ]) | ||
326 | 53 | AC_SUBST(MYSQL_CONFIG) | ||
327 | 54 | AC_SUBST(MYSQL_INCLUDES) | ||
328 | 55 | AC_SUBST(MYSQL_LIBS) | ||
329 | 56 | ]) | ||
330 | 57 | |||
331 | 58 | AC_DEFUN([_PANDORA_SEARCH_LIBMYSQLCLIENT],[ | ||
332 | 59 | AC_REQUIRE([AC_LIB_PREFIX]) | ||
333 | 60 | |||
334 | 61 | AC_ARG_ENABLE([libmysqlclient], | ||
335 | 62 | [AS_HELP_STRING([--disable-libmysqlclient], | ||
336 | 63 | [Build with libmysqlclient support @<:@default=on@:>@])], | ||
337 | 64 | [ac_enable_libmysqlclient="$enableval"], | ||
338 | 65 | [ac_enable_libmysqlclient="yes"]) | ||
339 | 66 | |||
340 | 67 | AS_IF([test "x$ac_enable_libmysqlclient" = "xyes"],[ | ||
341 | 68 | AC_LIB_HAVE_LINKFLAGS(mysqlclient_r,,[ | ||
342 | 69 | #include <mysql/mysql.h> | ||
343 | 70 | ],[ | ||
344 | 71 | MYSQL mysql; | ||
345 | 72 | ])],[ | ||
346 | 73 | ac_cv_libmysqlclient_r="no" | ||
347 | 74 | ]) | ||
348 | 75 | |||
349 | 76 | AM_CONDITIONAL(HAVE_LIBMYSQLCLIENT, [test "x${ac_cv_libmysqlclient_r}" = "xyes"]) | ||
350 | 77 | |||
351 | 78 | AS_IF([test "x$MYSQL_CONFIG" = "xISDIR"],[ | ||
352 | 79 | IBASE="-I${with_mysql}" | ||
353 | 80 | MYSQL_CONFIG="${with_mysql}/scripts/mysql_config" | ||
354 | 81 | ADDIFLAGS="$IBASE/include -isystem $IBASE/include" | ||
355 | 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 " | ||
356 | 83 | ],[ | ||
357 | 84 | MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include) | ||
358 | 85 | MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')" | ||
359 | 86 | MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r) | ||
360 | 87 | ]) | ||
361 | 88 | |||
362 | 89 | AC_SUBST(MYSQL_CONFIG) | ||
363 | 90 | AC_SUBST(MYSQL_INCLUDES) | ||
364 | 91 | AC_SUBST(MYSQL_LIBS) | ||
365 | 92 | ]) | ||
366 | 93 | |||
367 | 94 | AC_DEFUN([PANDORA_HAVE_LIBMYSQLCLIENT],[ | ||
368 | 95 | AC_REQUIRE([_PANDORA_SEARCH_LIBMYSQLCLIENT]) | ||
369 | 96 | ]) | ||
370 | 97 | |||
371 | 98 | AC_DEFUN([PANDORA_REQUIRE_LIBMYSQLCLIENT],[ | ||
372 | 99 | AC_REQUIRE([PANDORA_HAVE_LIBMYSQLCLIENT]) | ||
373 | 100 | AS_IF([test "x${ac_cv_libmysqlclient_r}" = "xno"], | ||
374 | 101 | PANDORA_MSG_ERROR([libmysqlclient_r is required for ${PACKAGE}])) | ||
375 | 102 | ]) | ||
376 | 103 | |||
377 | 0 | 104 | ||
378 | === renamed file 'm4/pandora_have_libmysqlclient.m4' => 'm4/pandora_have_libmysqlclient.m4.moved' | |||
379 | === modified file 'percona_playback/dispatcher.cc' | |||
380 | --- percona_playback/dispatcher.cc 2012-06-22 06:20:44 +0000 | |||
381 | +++ percona_playback/dispatcher.cc 2012-07-02 18:23:18 +0000 | |||
382 | @@ -1,3 +1,17 @@ | |||
383 | 1 | /* BEGIN LICENSE | ||
384 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
385 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
386 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
387 | 5 | * by the Free Software Foundation. | ||
388 | 6 | * | ||
389 | 7 | * This program is distributed in the hope that it will be useful, but | ||
390 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
391 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
392 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
393 | 11 | * | ||
394 | 12 | * You should have received a copy of the GNU General Public License along | ||
395 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
396 | 14 | * END LICENSE */ | ||
397 | 1 | #include "percona_playback/dispatcher.h" | 15 | #include "percona_playback/dispatcher.h" |
398 | 2 | #include "percona_playback/db_thread.h" | 16 | #include "percona_playback/db_thread.h" |
399 | 3 | #include "percona_playback/plugin.h" | 17 | #include "percona_playback/plugin.h" |
400 | 4 | 18 | ||
401 | === modified file 'percona_playback/percona_playback.cc' | |||
402 | --- percona_playback/percona_playback.cc 2012-06-24 04:28:41 +0000 | |||
403 | +++ percona_playback/percona_playback.cc 2012-07-02 18:23:18 +0000 | |||
404 | @@ -90,18 +90,30 @@ | |||
405 | 90 | std::cerr << std::endl; | 90 | std::cerr << std::endl; |
406 | 91 | std::cerr << options_description << std::endl; | 91 | std::cerr << options_description << std::endl; |
407 | 92 | std::cerr << std::endl; | 92 | std::cerr << std::endl; |
408 | 93 | <<<<<<< TREE | ||
409 | 93 | std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl; | 94 | std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl; |
410 | 94 | std::cerr << _("Loaded plugins: "); | 95 | std::cerr << _("Loaded plugins: "); |
411 | 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) |
412 | 97 | ======= | ||
413 | 98 | std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl; | ||
414 | 99 | std::cerr << _("Loaded plugins: "); | ||
415 | 100 | BOOST_FOREACH(const std::string &plugin_name, percona_playback::PluginRegistry::singleton().loaded_plugin_names) | ||
416 | 101 | >>>>>>> MERGE-SOURCE | ||
417 | 96 | { | 102 | { |
418 | 97 | std::cerr << plugin_name << " "; | 103 | std::cerr << plugin_name << " "; |
419 | 98 | } | 104 | } |
420 | 99 | 105 | ||
421 | 100 | std::cerr << std::endl; | 106 | std::cerr << std::endl; |
422 | 101 | 107 | ||
423 | 108 | <<<<<<< TREE | ||
424 | 102 | std::cerr << std::endl << _("Loaded DB Plugins: "); | 109 | std::cerr << std::endl << _("Loaded DB Plugins: "); |
425 | 103 | for(PluginRegistry::DBClientPluginMap::iterator it= PluginRegistry::singleton().dbclient_plugins.begin(); | 110 | for(PluginRegistry::DBClientPluginMap::iterator it= PluginRegistry::singleton().dbclient_plugins.begin(); |
426 | 104 | it != PluginRegistry::singleton().dbclient_plugins.end(); | 111 | it != PluginRegistry::singleton().dbclient_plugins.end(); |
427 | 112 | ======= | ||
428 | 113 | std::cerr << std::endl << _("Loaded DB Plugins: "); | ||
429 | 114 | for(percona_playback::PluginRegistry::DBClientPluginMap::iterator it= percona_playback::PluginRegistry::singleton().dbclient_plugins.begin(); | ||
430 | 115 | it != percona_playback::PluginRegistry::singleton().dbclient_plugins.end(); | ||
431 | 116 | >>>>>>> MERGE-SOURCE | ||
432 | 105 | it++) | 117 | it++) |
433 | 106 | { | 118 | { |
434 | 107 | std::cerr << it->first << " "; | 119 | std::cerr << it->first << " "; |
435 | @@ -110,12 +122,21 @@ | |||
436 | 110 | std::cerr << std::endl; | 122 | std::cerr << std::endl; |
437 | 111 | 123 | ||
438 | 112 | assert(g_dbclient_plugin); | 124 | assert(g_dbclient_plugin); |
439 | 125 | <<<<<<< TREE | ||
440 | 113 | std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl; | 126 | std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl; |
441 | 114 | 127 | ||
442 | 115 | std::cerr << std::endl << _("Loaded Input Plugins: "); | 128 | std::cerr << std::endl << _("Loaded Input Plugins: "); |
443 | 116 | 129 | ||
444 | 117 | BOOST_FOREACH(const PluginRegistry::InputPluginPair &pp, | 130 | BOOST_FOREACH(const PluginRegistry::InputPluginPair &pp, |
445 | 118 | PluginRegistry::singleton().input_plugins) | 131 | PluginRegistry::singleton().input_plugins) |
446 | 132 | ======= | ||
447 | 133 | std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl; | ||
448 | 134 | |||
449 | 135 | std::cerr << std::endl << _("Loaded Input Plugins: "); | ||
450 | 136 | |||
451 | 137 | BOOST_FOREACH(const percona_playback::PluginRegistry::InputPluginPair &pp, | ||
452 | 138 | percona_playback::PluginRegistry::singleton().input_plugins) | ||
453 | 139 | >>>>>>> MERGE-SOURCE | ||
454 | 119 | { | 140 | { |
455 | 120 | std::cerr << pp.first << " "; | 141 | std::cerr << pp.first << " "; |
456 | 121 | } | 142 | } |
457 | 122 | 143 | ||
458 | === modified file 'percona_playback/query_result.h' | |||
459 | --- percona_playback/query_result.h 2012-06-18 23:59:46 +0000 | |||
460 | +++ percona_playback/query_result.h 2012-07-02 18:23:18 +0000 | |||
461 | @@ -40,6 +40,13 @@ | |||
462 | 40 | { | 40 | { |
463 | 41 | } | 41 | } |
464 | 42 | 42 | ||
465 | 43 | void clear() | ||
466 | 44 | { | ||
467 | 45 | _rows_sent= _rows_examined= 0; | ||
468 | 46 | _error= _warning_count= 0; | ||
469 | 47 | _duration= boost::posix_time::time_duration(); | ||
470 | 48 | } | ||
471 | 49 | |||
472 | 43 | void setRowsSent(const uint64_t &rows) { | 50 | void setRowsSent(const uint64_t &rows) { |
473 | 44 | _rows_sent= rows; | 51 | _rows_sent= rows; |
474 | 45 | } | 52 | } |
475 | 46 | 53 | ||
476 | === added file 'percona_playback/tcpdump/connection_state.cc' | |||
477 | --- percona_playback/tcpdump/connection_state.cc 1970-01-01 00:00:00 +0000 | |||
478 | +++ percona_playback/tcpdump/connection_state.cc 2012-07-02 18:23:18 +0000 | |||
479 | @@ -0,0 +1,325 @@ | |||
480 | 1 | /* BEGIN LICENSE | ||
481 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
482 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
483 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
484 | 5 | * by the Free Software Foundation. | ||
485 | 6 | * | ||
486 | 7 | * This program is distributed in the hope that it will be useful, but | ||
487 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
488 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
489 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
490 | 11 | * | ||
491 | 12 | * You should have received a copy of the GNU General Public License along | ||
492 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
493 | 14 | * END LICENSE */ | ||
494 | 15 | #include <pcap.h> | ||
495 | 16 | #include <iostream> | ||
496 | 17 | #include <libdrizzle/drizzle_server.h> | ||
497 | 18 | #include <libdrizzle/row_client.h> | ||
498 | 19 | #include <stdio.h> | ||
499 | 20 | #include <stdint.h> | ||
500 | 21 | #include <assert.h> | ||
501 | 22 | |||
502 | 23 | #include "connection_state.h" | ||
503 | 24 | #include "tcpdump_query_entries.h" | ||
504 | 25 | #include "percona_playback/plugin.h" | ||
505 | 26 | |||
506 | 27 | extern percona_playback::DBClientPlugin *g_dbclient_plugin; | ||
507 | 28 | |||
508 | 29 | void | ||
509 | 30 | ConnectionState::ProcessMysqlPkts(const u_char *pkts, | ||
510 | 31 | u_int pkts_len, | ||
511 | 32 | const timeval &ts, | ||
512 | 33 | const AddrPort &addr_port, | ||
513 | 34 | OUT TcpdumpMysqlParserStats &stats) | ||
514 | 35 | { | ||
515 | 36 | |||
516 | 37 | u_int used_len= 0; | ||
517 | 38 | struct MysqlPkt *m; | ||
518 | 39 | |||
519 | 40 | assert(pkts); | ||
520 | 41 | |||
521 | 42 | // If last pkt was fragmented, merge with current pkts | ||
522 | 43 | if (fragmented) | ||
523 | 44 | { | ||
524 | 45 | fragmented= false; | ||
525 | 46 | size_t old_frag_buff_size= frag_buff.size(); | ||
526 | 47 | frag_buff.insert(frag_buff.end(), pkts, pkts + pkts_len); | ||
527 | 48 | pkts= &frag_buff[0]; | ||
528 | 49 | pkts_len+= old_frag_buff_size; | ||
529 | 50 | } | ||
530 | 51 | |||
531 | 52 | for(;;) | ||
532 | 53 | { | ||
533 | 54 | m= (struct MysqlPkt *)pkts; // Packet header | ||
534 | 55 | |||
535 | 56 | // Check if pkts > len of pkts actually received (last pkt is fragmented) | ||
536 | 57 | used_len+= m->full_length(); | ||
537 | 58 | |||
538 | 59 | if (used_len > pkts_len) { | ||
539 | 60 | fragmented= true; | ||
540 | 61 | |||
541 | 62 | size_t frag_len= m->full_length() - (used_len - pkts_len); | ||
542 | 63 | |||
543 | 64 | UCharBuffer new_frag_buff(pkts, pkts + frag_len); | ||
544 | 65 | frag_buff.swap(new_frag_buff); | ||
545 | 66 | |||
546 | 67 | break; | ||
547 | 68 | } | ||
548 | 69 | |||
549 | 70 | if (m->data_length()) | ||
550 | 71 | { | ||
551 | 72 | UCharBuffer buff(pkts, pkts + m->full_length()); | ||
552 | 73 | std::string query; | ||
553 | 74 | PktResult retval= ParseMysqlPkt(buff, query); | ||
554 | 75 | switch(retval) | ||
555 | 76 | { | ||
556 | 77 | case PKT_QUERY: | ||
557 | 78 | if (!query.empty()) | ||
558 | 79 | DispatchQuery(ts, query, addr_port); | ||
559 | 80 | ++stats.nr_of_parsed_queries; | ||
560 | 81 | ++stats.nr_of_parsed_packets; | ||
561 | 82 | break; | ||
562 | 83 | |||
563 | 84 | case PKT_RESULT: | ||
564 | 85 | DispatchResult(ts, addr_port); | ||
565 | 86 | ++stats.nr_of_parsed_packets; | ||
566 | 87 | break; | ||
567 | 88 | |||
568 | 89 | case PKT_ERROR: | ||
569 | 90 | ++stats.nr_of_parsing_errors; | ||
570 | 91 | break; | ||
571 | 92 | |||
572 | 93 | default: | ||
573 | 94 | ++stats.nr_of_parsed_packets; | ||
574 | 95 | } | ||
575 | 96 | } | ||
576 | 97 | |||
577 | 98 | pkts += m->full_length(); // Next pkt header | ||
578 | 99 | |||
579 | 100 | if (used_len == pkts_len) | ||
580 | 101 | break; | ||
581 | 102 | |||
582 | 103 | } | ||
583 | 104 | |||
584 | 105 | if (!fragmented) | ||
585 | 106 | frag_buff.clear(); | ||
586 | 107 | |||
587 | 108 | } | ||
588 | 109 | |||
589 | 110 | void | ||
590 | 111 | ConnectionState::ProcessFinishConnection() | ||
591 | 112 | { | ||
592 | 113 | db_thread->queries.push(QueryEntryPtr(new FinishEntry())); | ||
593 | 114 | } | ||
594 | 115 | |||
595 | 116 | PktResult | ||
596 | 117 | ConnectionState::ParseMysqlPkt(IN UCharBuffer &buff, | ||
597 | 118 | OUT std::string &query) | ||
598 | 119 | { | ||
599 | 120 | if (current_origin == CLIENT) | ||
600 | 121 | return ClientPacket(buff, query); | ||
601 | 122 | |||
602 | 123 | if (current_origin == SERVER && was_query) | ||
603 | 124 | return ServerPacket(buff); | ||
604 | 125 | |||
605 | 126 | return PKT_UNKNOWN; | ||
606 | 127 | } | ||
607 | 128 | |||
608 | 129 | PktResult | ||
609 | 130 | ConnectionState::ServerPacket(IN UCharBuffer &buff) | ||
610 | 131 | { | ||
611 | 132 | PktResult retval= PKT_OK; | ||
612 | 133 | |||
613 | 134 | drizzle_return_t ret; | ||
614 | 135 | |||
615 | 136 | drizzle_con->buffer_ptr= &buff[0]; | ||
616 | 137 | drizzle_con->buffer_size= buff.size(); | ||
617 | 138 | |||
618 | 139 | /* | ||
619 | 140 | Check if we should continue parsing result set or | ||
620 | 141 | we can start a new loop of result parsing. | ||
621 | 142 | */ | ||
622 | 143 | if (!drizzle_con->result) | ||
623 | 144 | { | ||
624 | 145 | /* | ||
625 | 146 | If there are not any parsed results then it can be "Ok", | ||
626 | 147 | "Error" or "Results set header" packets. | ||
627 | 148 | */ | ||
628 | 149 | last_query_result.clear(); | ||
629 | 150 | |||
630 | 151 | drizzle_result_st *res= drizzle_result_read(drizzle_con.get(), | ||
631 | 152 | NULL, | ||
632 | 153 | &ret); | ||
633 | 154 | /* Check if the packet is "Error" packet */ | ||
634 | 155 | if (ret == DRIZZLE_RETURN_ERROR_CODE) | ||
635 | 156 | { | ||
636 | 157 | last_query_result.setError(drizzle_result_error_code(res)); | ||
637 | 158 | retval= PKT_RESULT; | ||
638 | 159 | /* | ||
639 | 160 | The text representation of error can be got with | ||
640 | 161 | drizzle_result_error(res) | ||
641 | 162 | */ | ||
642 | 163 | goto free_and_return; | ||
643 | 164 | } | ||
644 | 165 | else if(ret == DRIZZLE_RETURN_OK) | ||
645 | 166 | { | ||
646 | 167 | /* Check if the packet is "Ok" packet */ | ||
647 | 168 | if (!drizzle_result_column_count(res)) | ||
648 | 169 | { | ||
649 | 170 | last_query_result.setRowsSent(drizzle_result_row_count(res)); | ||
650 | 171 | last_query_result.setRowsExamined(drizzle_result_affected_rows(res)); | ||
651 | 172 | last_query_result.setWarningCount(drizzle_result_warning_count(res)); | ||
652 | 173 | retval= PKT_RESULT; | ||
653 | 174 | goto free_and_return; | ||
654 | 175 | } | ||
655 | 176 | /* Else this is "Result set header" packet */ | ||
656 | 177 | } | ||
657 | 178 | else | ||
658 | 179 | { | ||
659 | 180 | std::cerr << "Unknown packet type from server" << std::endl; | ||
660 | 181 | retval= PKT_ERROR; | ||
661 | 182 | goto free_and_return; | ||
662 | 183 | } | ||
663 | 184 | } | ||
664 | 185 | /* Parse result set */ | ||
665 | 186 | else | ||
666 | 187 | { | ||
667 | 188 | /* "Field" packets */ | ||
668 | 189 | if (eof_count == 0) | ||
669 | 190 | { | ||
670 | 191 | drizzle_column_st *column= drizzle_column_read(drizzle_con->result, | ||
671 | 192 | NULL, | ||
672 | 193 | &ret); | ||
673 | 194 | if (ret == DRIZZLE_RETURN_OK) | ||
674 | 195 | { | ||
675 | 196 | /* "EOF" packet */ | ||
676 | 197 | if (column == NULL) | ||
677 | 198 | ++eof_count; | ||
678 | 199 | retval= PKT_OK; | ||
679 | 200 | } | ||
680 | 201 | else | ||
681 | 202 | { | ||
682 | 203 | std::cerr << "Parse column error" << std::endl; | ||
683 | 204 | retval= PKT_ERROR; | ||
684 | 205 | goto free_and_return; | ||
685 | 206 | } | ||
686 | 207 | } | ||
687 | 208 | /* "Row" packets */ | ||
688 | 209 | else if (eof_count == 1) | ||
689 | 210 | { | ||
690 | 211 | uint8_t old_packet_number= drizzle_con->packet_number; | ||
691 | 212 | uint64_t row= drizzle_row_read(drizzle_con->result, &ret); | ||
692 | 213 | if (ret != DRIZZLE_RETURN_OK) | ||
693 | 214 | { | ||
694 | 215 | std::cerr << "Error in parsing row" << std::endl; | ||
695 | 216 | retval= PKT_ERROR; | ||
696 | 217 | goto free_and_return; | ||
697 | 218 | } | ||
698 | 219 | else | ||
699 | 220 | ++sent_rows_count; | ||
700 | 221 | /* "EOF" packet */ | ||
701 | 222 | if (!row) | ||
702 | 223 | { | ||
703 | 224 | eof_count= 0; | ||
704 | 225 | |||
705 | 226 | drizzle_con->buffer_ptr= &buff[0]; | ||
706 | 227 | drizzle_con->buffer_size= buff.size(); | ||
707 | 228 | |||
708 | 229 | drizzle_result_free_all(drizzle_con.get()); | ||
709 | 230 | drizzle_con->packet_number= old_packet_number; | ||
710 | 231 | drizzle_result_st *res= drizzle_result_read(drizzle_con.get(), | ||
711 | 232 | NULL, | ||
712 | 233 | &ret); | ||
713 | 234 | /* | ||
714 | 235 | Setting DRIZZLE_RESULT_ALLOCATED in result options | ||
715 | 236 | helps to avoid memory leak. | ||
716 | 237 | See https://bugs.launchpad.net/drizzle/+bug/1015576 | ||
717 | 238 | */ | ||
718 | 239 | res->options= | ||
719 | 240 | (drizzle_result_options_t) | ||
720 | 241 | ((uint64_t)(res->options) | (uint64_t)DRIZZLE_RESULT_ALLOCATED); | ||
721 | 242 | last_query_result.setWarningCount(drizzle_result_warning_count(res)); | ||
722 | 243 | /* Don't count the last EOF packet */ | ||
723 | 244 | last_query_result.setRowsSent(sent_rows_count - 1); | ||
724 | 245 | |||
725 | 246 | sent_rows_count= 0; | ||
726 | 247 | retval= PKT_RESULT; | ||
727 | 248 | goto free_and_return; | ||
728 | 249 | } | ||
729 | 250 | else | ||
730 | 251 | retval= PKT_OK; | ||
731 | 252 | } | ||
732 | 253 | } | ||
733 | 254 | |||
734 | 255 | return retval; | ||
735 | 256 | |||
736 | 257 | free_and_return: | ||
737 | 258 | drizzle_result_free_all(drizzle_con.get()); | ||
738 | 259 | drizzle_con->result= NULL; | ||
739 | 260 | was_query= false; | ||
740 | 261 | return retval; | ||
741 | 262 | } | ||
742 | 263 | |||
743 | 264 | PktResult | ||
744 | 265 | ConnectionState::ClientPacket(IN UCharBuffer &buff, | ||
745 | 266 | OUT std::string &query) | ||
746 | 267 | { | ||
747 | 268 | drizzle_command_t command; | ||
748 | 269 | drizzle_return_t ret; | ||
749 | 270 | size_t total; | ||
750 | 271 | uint8_t *data; | ||
751 | 272 | PktResult result= PKT_UNKNOWN; | ||
752 | 273 | |||
753 | 274 | drizzle_con->buffer_ptr= &buff[0]; | ||
754 | 275 | drizzle_con->buffer_size= buff.size(); | ||
755 | 276 | data= (uint8_t *)drizzle_con_command_buffer(drizzle_con.get(), | ||
756 | 277 | &command, | ||
757 | 278 | &total, | ||
758 | 279 | &ret); | ||
759 | 280 | if (ret == DRIZZLE_RETURN_OK) | ||
760 | 281 | { | ||
761 | 282 | switch(command) | ||
762 | 283 | { | ||
763 | 284 | case DRIZZLE_COMMAND_QUERY: | ||
764 | 285 | query.assign((const char *)data); | ||
765 | 286 | was_query= true; | ||
766 | 287 | result= PKT_QUERY; | ||
767 | 288 | break; | ||
768 | 289 | |||
769 | 290 | case DRIZZLE_COMMAND_INIT_DB: | ||
770 | 291 | query.assign("use "); | ||
771 | 292 | query+= (const char *)data; | ||
772 | 293 | was_query= true; | ||
773 | 294 | result= PKT_QUERY; | ||
774 | 295 | break; | ||
775 | 296 | |||
776 | 297 | default:; | ||
777 | 298 | } | ||
778 | 299 | } | ||
779 | 300 | |||
780 | 301 | free(data); | ||
781 | 302 | return result; | ||
782 | 303 | } | ||
783 | 304 | |||
784 | 305 | void | ||
785 | 306 | ConnectionState::DispatchQuery(const timeval &ts, | ||
786 | 307 | const std::string &query, | ||
787 | 308 | const AddrPort &addr_port) | ||
788 | 309 | { | ||
789 | 310 | boost::shared_ptr<TcpdumpQueryEntry> | ||
790 | 311 | query_entry(new TcpdumpQueryEntry(ts, | ||
791 | 312 | query, | ||
792 | 313 | addr_port)); | ||
793 | 314 | db_thread->queries.push(query_entry); | ||
794 | 315 | } | ||
795 | 316 | |||
796 | 317 | void | ||
797 | 318 | ConnectionState::DispatchResult(const timeval &ts, | ||
798 | 319 | const AddrPort &addr_port) | ||
799 | 320 | { | ||
800 | 321 | boost::shared_ptr<TcpdumpResultEntry> | ||
801 | 322 | result_entry(new TcpdumpResultEntry(addr_port, ts, last_query_result)); | ||
802 | 323 | db_thread->queries.push(result_entry); | ||
803 | 324 | } | ||
804 | 325 | |||
805 | 0 | 326 | ||
806 | === added file 'percona_playback/tcpdump/connection_state.h' | |||
807 | --- percona_playback/tcpdump/connection_state.h 1970-01-01 00:00:00 +0000 | |||
808 | +++ percona_playback/tcpdump/connection_state.h 2012-07-02 18:23:18 +0000 | |||
809 | @@ -0,0 +1,186 @@ | |||
810 | 1 | /* BEGIN LICENSE | ||
811 | 2 | * Copyright (C) 2011 Percona Inc. | ||
812 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
813 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
814 | 5 | * by the Free Software Foundation. | ||
815 | 6 | * | ||
816 | 7 | * This program is distributed in the hope that it will be useful, but | ||
817 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
818 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
819 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
820 | 11 | * | ||
821 | 12 | * You should have received a copy of the GNU General Public License along | ||
822 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
823 | 14 | * END LICENSE */ | ||
824 | 15 | |||
825 | 16 | #ifndef PERCONA_PLAYBACK_CONNECTION_STATE_H | ||
826 | 17 | #define PERCONA_PLAYBACK_CONNECTION_STATE_H | ||
827 | 18 | |||
828 | 19 | #include <stdlib.h> | ||
829 | 20 | #include <sys/time.h> | ||
830 | 21 | #include <vector> | ||
831 | 22 | #include <string> | ||
832 | 23 | #include <string.h> | ||
833 | 24 | #include <boost/shared_ptr.hpp> | ||
834 | 25 | #include <libdrizzle/drizzle_client.h> | ||
835 | 26 | |||
836 | 27 | #include "percona_playback/query_result.h" | ||
837 | 28 | #include "percona_playback/db_thread.h" | ||
838 | 29 | #include "tcpdump_mysql_parser_stats.h" | ||
839 | 30 | |||
840 | 31 | enum PktResult | ||
841 | 32 | { | ||
842 | 33 | PKT_QUERY, | ||
843 | 34 | PKT_RESULT, | ||
844 | 35 | PKT_OK, | ||
845 | 36 | PKT_UNKNOWN, | ||
846 | 37 | PKT_ERROR | ||
847 | 38 | }; | ||
848 | 39 | |||
849 | 40 | #define IN | ||
850 | 41 | #define OUT | ||
851 | 42 | |||
852 | 43 | #pragma pack(push, 1) | ||
853 | 44 | // Every logical MySQL packet starts w/ this 4 byte header | ||
854 | 45 | struct MysqlPkt { | ||
855 | 46 | uint16_t length_low; | ||
856 | 47 | uint8_t length_high; | ||
857 | 48 | uint8_t id; | ||
858 | 49 | uint8_t data[0]; | ||
859 | 50 | |||
860 | 51 | size_t data_length() const | ||
861 | 52 | { | ||
862 | 53 | return (size_t)length_low | ((size_t)length_high << 16); | ||
863 | 54 | } | ||
864 | 55 | |||
865 | 56 | size_t full_length() const | ||
866 | 57 | { | ||
867 | 58 | return data_length() + header_size(); | ||
868 | 59 | } | ||
869 | 60 | |||
870 | 61 | static size_t header_size() | ||
871 | 62 | { | ||
872 | 63 | return offsetof(MysqlPkt, data); | ||
873 | 64 | } | ||
874 | 65 | }; | ||
875 | 66 | #pragma pack(pop) | ||
876 | 67 | |||
877 | 68 | struct AddrPort | ||
878 | 69 | { | ||
879 | 70 | AddrPort() : address(0), port(0) {} | ||
880 | 71 | AddrPort(uint32_t address, uint16_t port) : address(address), port(port) {} | ||
881 | 72 | uint32_t address; | ||
882 | 73 | uint16_t port; | ||
883 | 74 | uint64_t ThreadId() const | ||
884 | 75 | { | ||
885 | 76 | return (uint64_t)address | ((uint64_t)port << 32); | ||
886 | 77 | } | ||
887 | 78 | }; | ||
888 | 79 | |||
889 | 80 | struct LastExecutedQueryInfo | ||
890 | 81 | { | ||
891 | 82 | std::string query; | ||
892 | 83 | QueryResult result; | ||
893 | 84 | timeval begin_pcap_timestamp; | ||
894 | 85 | timeval end_pcap_timestamp; | ||
895 | 86 | timeval end_timestamp; | ||
896 | 87 | |||
897 | 88 | LastExecutedQueryInfo() | ||
898 | 89 | { | ||
899 | 90 | memset(&begin_pcap_timestamp, 0, sizeof(begin_pcap_timestamp)); | ||
900 | 91 | memset(&end_pcap_timestamp, 0, sizeof(end_pcap_timestamp)); | ||
901 | 92 | memset(&end_timestamp, 0, sizeof(end_timestamp)); | ||
902 | 93 | } | ||
903 | 94 | }; | ||
904 | 95 | |||
905 | 96 | |||
906 | 97 | class ConnectionState : public DBThreadState | ||
907 | 98 | |||
908 | 99 | { | ||
909 | 100 | |||
910 | 101 | public: | ||
911 | 102 | |||
912 | 103 | enum Origin | ||
913 | 104 | { | ||
914 | 105 | UNDEF, | ||
915 | 106 | CLIENT, | ||
916 | 107 | SERVER | ||
917 | 108 | }; | ||
918 | 109 | |||
919 | 110 | ConnectionState() : | ||
920 | 111 | current_origin(UNDEF), | ||
921 | 112 | fragmented(false), | ||
922 | 113 | handshake_from_client(false), | ||
923 | 114 | was_query(false), | ||
924 | 115 | eof_count(0), | ||
925 | 116 | sent_rows_count(0), | ||
926 | 117 | drizzle(drizzle_create(NULL), drizzle_free), | ||
927 | 118 | drizzle_con( | ||
928 | 119 | drizzle_con_add_tcp(drizzle.get(), | ||
929 | 120 | NULL, | ||
930 | 121 | "localhost", | ||
931 | 122 | 3306, | ||
932 | 123 | "user", | ||
933 | 124 | "password", | ||
934 | 125 | "db", | ||
935 | 126 | (drizzle_con_options_t) | ||
936 | 127 | DRIZZLE_CON_MYSQL), | ||
937 | 128 | drizzle_con_free), | ||
938 | 129 | db_thread(NULL) | ||
939 | 130 | { | ||
940 | 131 | drizzle_con->result= NULL; | ||
941 | 132 | } | ||
942 | 133 | |||
943 | 134 | ~ConnectionState() | ||
944 | 135 | { | ||
945 | 136 | drizzle_result_free_all(drizzle_con.get()); | ||
946 | 137 | } | ||
947 | 138 | |||
948 | 139 | void ProcessMysqlPkts(const u_char *pkts, | ||
949 | 140 | u_int total_len, | ||
950 | 141 | const timeval &ts, | ||
951 | 142 | const AddrPort &addr_port, | ||
952 | 143 | OUT TcpdumpMysqlParserStats &stats); | ||
953 | 144 | |||
954 | 145 | void ProcessFinishConnection(); | ||
955 | 146 | |||
956 | 147 | void SetCurrentOrigin(Origin o) { current_origin = o; } | ||
957 | 148 | |||
958 | 149 | void SetDBThread(DBThread *t) { db_thread= t; } | ||
959 | 150 | |||
960 | 151 | LastExecutedQueryInfo last_executed_query_info; | ||
961 | 152 | |||
962 | 153 | private: | ||
963 | 154 | |||
964 | 155 | typedef std::vector<unsigned char> UCharBuffer; | ||
965 | 156 | |||
966 | 157 | PktResult ParseMysqlPkt(IN UCharBuffer &buff, OUT std::string &query); | ||
967 | 158 | |||
968 | 159 | PktResult ServerPacket(IN UCharBuffer &buff); | ||
969 | 160 | PktResult ClientPacket(IN UCharBuffer &buff, OUT std::string &query); | ||
970 | 161 | |||
971 | 162 | void DispatchQuery(const timeval &ts, | ||
972 | 163 | const std::string &query, | ||
973 | 164 | const AddrPort &addr_port); | ||
974 | 165 | |||
975 | 166 | void DispatchResult(const timeval &ts, | ||
976 | 167 | const AddrPort &addr_port); | ||
977 | 168 | |||
978 | 169 | Origin current_origin; | ||
979 | 170 | bool fragmented; | ||
980 | 171 | UCharBuffer frag_buff; | ||
981 | 172 | bool handshake_from_client; | ||
982 | 173 | bool was_query; | ||
983 | 174 | size_t eof_count; | ||
984 | 175 | size_t sent_rows_count; | ||
985 | 176 | |||
986 | 177 | boost::shared_ptr<drizzle_st> drizzle; | ||
987 | 178 | boost::shared_ptr<drizzle_con_st> drizzle_con; | ||
988 | 179 | |||
989 | 180 | QueryResult last_query_result; | ||
990 | 181 | |||
991 | 182 | DBThread *db_thread; | ||
992 | 183 | |||
993 | 184 | }; | ||
994 | 185 | |||
995 | 186 | #endif // PERCONA_PLAYBACK_CONNECTION_STATE_H | ||
996 | 0 | 187 | ||
997 | === added file 'percona_playback/tcpdump/pcap_packets_parser.cc' | |||
998 | --- percona_playback/tcpdump/pcap_packets_parser.cc 1970-01-01 00:00:00 +0000 | |||
999 | +++ percona_playback/tcpdump/pcap_packets_parser.cc 2012-07-02 18:23:18 +0000 | |||
1000 | @@ -0,0 +1,134 @@ | |||
1001 | 1 | /* BEGIN LICENSE | ||
1002 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1003 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1004 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
1005 | 5 | * by the Free Software Foundation. | ||
1006 | 6 | * | ||
1007 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1008 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1009 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1010 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1011 | 11 | * | ||
1012 | 12 | * You should have received a copy of the GNU General Public License along | ||
1013 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1014 | 14 | * END LICENSE */ | ||
1015 | 15 | #include "pcap_packets_parser.h" | ||
1016 | 16 | #include "sniff_headers.h" | ||
1017 | 17 | #include "tcpdump.h" | ||
1018 | 18 | |||
1019 | 19 | #include "percona_playback/db_thread.h" | ||
1020 | 20 | #include "percona_playback/plugin.h" | ||
1021 | 21 | #include "percona_playback/dispatcher.h" | ||
1022 | 22 | |||
1023 | 23 | #include <netinet/in.h> | ||
1024 | 24 | #include <arpa/inet.h> | ||
1025 | 25 | #include <iostream> | ||
1026 | 26 | #include <boost/foreach.hpp> | ||
1027 | 27 | #include <assert.h> | ||
1028 | 28 | |||
1029 | 29 | #define SNAP_LEN 16500 // pcap's max capture size | ||
1030 | 30 | |||
1031 | 31 | extern percona_playback::DBClientPlugin *g_dbclient_plugin; | ||
1032 | 32 | |||
1033 | 33 | void | ||
1034 | 34 | PcapPacketsParser::ParsePkt(const struct pcap_pkthdr *header, | ||
1035 | 35 | const u_char *packet) | ||
1036 | 36 | { | ||
1037 | 37 | ConnectionState::Origin origin= ConnectionState::UNDEF; | ||
1038 | 38 | const struct sniff_ethernet *ethernet; | ||
1039 | 39 | const struct sniff_ip *ip; | ||
1040 | 40 | const struct sniff_tcp *tcp; | ||
1041 | 41 | const uint8_t *mysql; | ||
1042 | 42 | size_t size_ip; | ||
1043 | 43 | size_t size_tcp; | ||
1044 | 44 | size_t size_mysql; | ||
1045 | 45 | |||
1046 | 46 | assert(header); | ||
1047 | 47 | assert(packet); | ||
1048 | 48 | |||
1049 | 49 | if(header->len > SNAP_LEN) { | ||
1050 | 50 | std::cerr << "Captured packet too large: " | ||
1051 | 51 | << header->len | ||
1052 | 52 | << " bytes, Max capture packet size: " | ||
1053 | 53 | << SNAP_LEN << " bytes" << std::endl; | ||
1054 | 54 | return; | ||
1055 | 55 | } | ||
1056 | 56 | |||
1057 | 57 | ethernet= (struct sniff_ethernet*)(packet); | ||
1058 | 58 | ip= (struct sniff_ip*)(packet + SIZE_ETHERNET); | ||
1059 | 59 | size_ip= IP_HL(ip) * 4; | ||
1060 | 60 | tcp= (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); | ||
1061 | 61 | size_tcp= TH_OFF(tcp) * 4; | ||
1062 | 62 | mysql= (packet + SIZE_ETHERNET + size_ip + size_tcp); | ||
1063 | 63 | size_mysql= ntohs(ip->ip_len) - size_ip - size_tcp; | ||
1064 | 64 | |||
1065 | 65 | |||
1066 | 66 | AddrPort addr_port; | ||
1067 | 67 | |||
1068 | 68 | if (ntohs(tcp->th_sport) == g_tcpdump_port) | ||
1069 | 69 | { | ||
1070 | 70 | addr_port.address= ip->ip_dst.s_addr; | ||
1071 | 71 | addr_port.port= tcp->th_dport; | ||
1072 | 72 | origin= ConnectionState::SERVER; | ||
1073 | 73 | } | ||
1074 | 74 | else | ||
1075 | 75 | { | ||
1076 | 76 | addr_port.address= ip->ip_src.s_addr; | ||
1077 | 77 | addr_port.port= tcp->th_sport; | ||
1078 | 78 | origin= ConnectionState::CLIENT; | ||
1079 | 79 | } | ||
1080 | 80 | |||
1081 | 81 | /* The connection was closed. */ | ||
1082 | 82 | if (size_mysql == 0 && | ||
1083 | 83 | ((tcp->th_flags & TH_FIN) || (tcp->th_flags & TH_RST))) | ||
1084 | 84 | { | ||
1085 | 85 | g_dispatcher.finish(addr_port.ThreadId()); | ||
1086 | 86 | return; | ||
1087 | 87 | } | ||
1088 | 88 | |||
1089 | 89 | /* The mysql packet is too small. It may be due to tcp service packets. */ | ||
1090 | 90 | if (size_mysql < MysqlPkt::header_size()) | ||
1091 | 91 | return; | ||
1092 | 92 | |||
1093 | 93 | if (!was_first_packet) | ||
1094 | 94 | { | ||
1095 | 95 | gettimeofday(&first_packet_timestamp, 0); | ||
1096 | 96 | first_packet_pcap_timestamp= header->ts; | ||
1097 | 97 | was_first_packet= true; | ||
1098 | 98 | } | ||
1099 | 99 | |||
1100 | 100 | /* If there is no DBThread with such id create it */ | ||
1101 | 101 | boost::shared_ptr<DBThreadState> | ||
1102 | 102 | state= g_dispatcher.get_thread_state(addr_port.ThreadId(), | ||
1103 | 103 | boost::bind(&PcapPacketsParser::CreateConnectionState, | ||
1104 | 104 | this, | ||
1105 | 105 | _1)); | ||
1106 | 106 | |||
1107 | 107 | assert(state.get()); | ||
1108 | 108 | |||
1109 | 109 | ((ConnectionState *)state.get())->SetCurrentOrigin(origin); | ||
1110 | 110 | ((ConnectionState *)state.get())->ProcessMysqlPkts(mysql, | ||
1111 | 111 | size_mysql, | ||
1112 | 112 | header->ts, | ||
1113 | 113 | addr_port, | ||
1114 | 114 | stats); | ||
1115 | 115 | } | ||
1116 | 116 | |||
1117 | 117 | void | ||
1118 | 118 | PcapPacketsParser::WaitForUnfinishedTasks() | ||
1119 | 119 | { | ||
1120 | 120 | g_dispatcher.finish_all_and_wait(); | ||
1121 | 121 | } | ||
1122 | 122 | |||
1123 | 123 | void | ||
1124 | 124 | PcapPacketsParser::CreateConnectionState(DBThread *db_thread) | ||
1125 | 125 | { | ||
1126 | 126 | assert(db_thread); | ||
1127 | 127 | boost::shared_ptr<ConnectionState> state(new ConnectionState()); | ||
1128 | 128 | state->last_executed_query_info.end_pcap_timestamp= | ||
1129 | 129 | first_packet_pcap_timestamp; | ||
1130 | 130 | state->last_executed_query_info.end_timestamp= | ||
1131 | 131 | first_packet_timestamp; | ||
1132 | 132 | db_thread->set_state(state); | ||
1133 | 133 | state->SetDBThread(db_thread); | ||
1134 | 134 | } | ||
1135 | 0 | 135 | ||
1136 | === added file 'percona_playback/tcpdump/pcap_packets_parser.h' | |||
1137 | --- percona_playback/tcpdump/pcap_packets_parser.h 1970-01-01 00:00:00 +0000 | |||
1138 | +++ percona_playback/tcpdump/pcap_packets_parser.h 2012-07-02 18:23:18 +0000 | |||
1139 | @@ -0,0 +1,64 @@ | |||
1140 | 1 | /* BEGIN LICENSE | ||
1141 | 2 | * Copyright (C) 2011 Percona Inc. | ||
1142 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1143 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
1144 | 5 | * by the Free Software Foundation. | ||
1145 | 6 | * | ||
1146 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1147 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1148 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1149 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1150 | 11 | * | ||
1151 | 12 | * You should have received a copy of the GNU General Public License along | ||
1152 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1153 | 14 | * END LICENSE */ | ||
1154 | 15 | |||
1155 | 16 | #ifndef PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H | ||
1156 | 17 | #define PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H | ||
1157 | 18 | |||
1158 | 19 | #include "connection_state.h" | ||
1159 | 20 | #include "tcpdump_mysql_parser_stats.h" | ||
1160 | 21 | |||
1161 | 22 | #include <pcap.h> | ||
1162 | 23 | #include <tbb/concurrent_queue.h> | ||
1163 | 24 | #include <boost/thread.hpp> | ||
1164 | 25 | #include <boost/bind.hpp> | ||
1165 | 26 | |||
1166 | 27 | class DBThread; | ||
1167 | 28 | |||
1168 | 29 | class PcapPacketsParser | ||
1169 | 30 | { | ||
1170 | 31 | TcpdumpMysqlParserStats stats; | ||
1171 | 32 | timeval first_packet_timestamp; | ||
1172 | 33 | timeval first_packet_pcap_timestamp; | ||
1173 | 34 | bool was_first_packet; | ||
1174 | 35 | |||
1175 | 36 | public: | ||
1176 | 37 | |||
1177 | 38 | PcapPacketsParser() : was_first_packet(false) | ||
1178 | 39 | { | ||
1179 | 40 | first_packet_timestamp.tv_sec= first_packet_timestamp.tv_usec= 0; | ||
1180 | 41 | first_packet_pcap_timestamp.tv_sec= first_packet_pcap_timestamp.tv_usec= 0; | ||
1181 | 42 | } | ||
1182 | 43 | |||
1183 | 44 | static void Process(u_char *arg, | ||
1184 | 45 | const struct pcap_pkthdr *header, | ||
1185 | 46 | const u_char *packet) | ||
1186 | 47 | { | ||
1187 | 48 | ((PcapPacketsParser *)arg)->ParsePkt(header, packet); | ||
1188 | 49 | } | ||
1189 | 50 | |||
1190 | 51 | const TcpdumpMysqlParserStats &GetStats() const { return stats; } | ||
1191 | 52 | |||
1192 | 53 | void WaitForUnfinishedTasks(); | ||
1193 | 54 | |||
1194 | 55 | void CreateConnectionState(DBThread *db_thread); | ||
1195 | 56 | |||
1196 | 57 | private: | ||
1197 | 58 | |||
1198 | 59 | void ParsePkt(const struct pcap_pkthdr *header, | ||
1199 | 60 | const u_char *packet); | ||
1200 | 61 | |||
1201 | 62 | }; | ||
1202 | 63 | |||
1203 | 64 | #endif //PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H | ||
1204 | 0 | 65 | ||
1205 | === modified file 'percona_playback/tcpdump/plugin.ac' | |||
1206 | --- percona_playback/tcpdump/plugin.ac 2012-06-19 01:09:31 +0000 | |||
1207 | +++ percona_playback/tcpdump/plugin.ac 2012-07-02 18:23:18 +0000 | |||
1208 | @@ -1,2 +1,2 @@ | |||
1209 | 1 | PANDORA_HAVE_LIBPCAP | 1 | PANDORA_HAVE_LIBPCAP |
1211 | 2 | PANDORA_HAVE_LIBDRIZZLE | 2 | PANDORA_HAVE_LIBDRIZZLE_1_0 |
1212 | 3 | 3 | ||
1213 | === modified file 'percona_playback/tcpdump/plugin.ini' | |||
1214 | --- percona_playback/tcpdump/plugin.ini 2012-06-19 01:09:31 +0000 | |||
1215 | +++ percona_playback/tcpdump/plugin.ini 2012-07-02 18:23:18 +0000 | |||
1216 | @@ -6,4 +6,6 @@ | |||
1217 | 6 | headers=tcpdump.h | 6 | headers=tcpdump.h |
1218 | 7 | load_by_default=yes | 7 | load_by_default=yes |
1219 | 8 | ldflags=${PCAP_LIBS} ${LTLIBDRIZZLE} ${LDFLAGS} | 8 | ldflags=${PCAP_LIBS} ${LTLIBDRIZZLE} ${LDFLAGS} |
1221 | 9 | cppflags=${PCAP_INCLUDES} ${CPPFLAGS} | 9 | cppflags=${PCAP_INCLUDES} ${CPPFLAGS} |
1222 | 10 | headers=tcpdump.h sniff_headers.h connection_state.h pcap_packets_parser.h tcpdump_query_entries.h tcpdump_mysql_parser_stats.h | ||
1223 | 11 | sources=tcpdump.cc connection_state.cc pcap_packets_parser.cc tcpdump_query_entries.cc | ||
1224 | 10 | 12 | ||
1225 | === added file 'percona_playback/tcpdump/sniff_headers.h' | |||
1226 | --- percona_playback/tcpdump/sniff_headers.h 1970-01-01 00:00:00 +0000 | |||
1227 | +++ percona_playback/tcpdump/sniff_headers.h 2012-07-02 18:23:18 +0000 | |||
1228 | @@ -0,0 +1,59 @@ | |||
1229 | 1 | /* ethernet headers are always exactly 14 bytes [1] */ | ||
1230 | 2 | #define SIZE_ETHERNET 14 | ||
1231 | 3 | |||
1232 | 4 | /* Ethernet addresses are 6 bytes */ | ||
1233 | 5 | #define ETHER_ADDR_LEN 6 | ||
1234 | 6 | |||
1235 | 7 | //#pragma pack(push, 1) | ||
1236 | 8 | /* Ethernet header */ | ||
1237 | 9 | struct sniff_ethernet { | ||
1238 | 10 | u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ | ||
1239 | 11 | u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ | ||
1240 | 12 | u_short ether_type; /* IP? ARP? RARP? etc */ | ||
1241 | 13 | }; | ||
1242 | 14 | |||
1243 | 15 | /* IP header */ | ||
1244 | 16 | struct sniff_ip { | ||
1245 | 17 | u_char ip_vhl; /* version << 4 | header length >> 2 */ | ||
1246 | 18 | u_char ip_tos; /* type of service */ | ||
1247 | 19 | u_short ip_len; /* total length */ | ||
1248 | 20 | u_short ip_id; /* identification */ | ||
1249 | 21 | u_short ip_off; /* fragment offset field */ | ||
1250 | 22 | #define IP_RF 0x8000 /* reserved fragment flag */ | ||
1251 | 23 | #define IP_DF 0x4000 /* dont fragment flag */ | ||
1252 | 24 | #define IP_MF 0x2000 /* more fragments flag */ | ||
1253 | 25 | #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ | ||
1254 | 26 | u_char ip_ttl; /* time to live */ | ||
1255 | 27 | u_char ip_p; /* protocol */ | ||
1256 | 28 | u_short ip_sum; /* checksum */ | ||
1257 | 29 | struct in_addr ip_src,ip_dst; /* source and dest address */ | ||
1258 | 30 | }; | ||
1259 | 31 | #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) | ||
1260 | 32 | #define IP_V(ip) (((ip)->ip_vhl) >> 4) | ||
1261 | 33 | |||
1262 | 34 | /* TCP header */ | ||
1263 | 35 | typedef u_int tcp_seq; | ||
1264 | 36 | |||
1265 | 37 | struct sniff_tcp { | ||
1266 | 38 | u_short th_sport; /* source port */ | ||
1267 | 39 | u_short th_dport; /* destination port */ | ||
1268 | 40 | tcp_seq th_seq; /* sequence number */ | ||
1269 | 41 | tcp_seq th_ack; /* acknowledgement number */ | ||
1270 | 42 | u_char th_offx2; /* data offset, rsvd */ | ||
1271 | 43 | #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) | ||
1272 | 44 | u_char th_flags; | ||
1273 | 45 | #define TH_FIN 0x01 | ||
1274 | 46 | #define TH_SYN 0x02 | ||
1275 | 47 | #define TH_RST 0x04 | ||
1276 | 48 | #define TH_PUSH 0x08 | ||
1277 | 49 | #define TH_ACK 0x10 | ||
1278 | 50 | #define TH_URG 0x20 | ||
1279 | 51 | #define TH_ECE 0x40 | ||
1280 | 52 | #define TH_CWR 0x80 | ||
1281 | 53 | #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) | ||
1282 | 54 | u_short th_win; /* window */ | ||
1283 | 55 | u_short th_sum; /* checksum */ | ||
1284 | 56 | u_short th_urp; /* urgent pointer */ | ||
1285 | 57 | }; | ||
1286 | 58 | |||
1287 | 59 | //#pragma pack(pop) | ||
1288 | 0 | 60 | ||
1289 | === modified file 'percona_playback/tcpdump/tcpdump.cc' | |||
1290 | --- percona_playback/tcpdump/tcpdump.cc 2012-06-19 01:09:31 +0000 | |||
1291 | +++ percona_playback/tcpdump/tcpdump.cc 2012-07-02 18:23:18 +0000 | |||
1292 | @@ -14,15 +14,54 @@ | |||
1293 | 14 | * END LICENSE */ | 14 | * END LICENSE */ |
1294 | 15 | 15 | ||
1295 | 16 | #include "tcpdump.h" | 16 | #include "tcpdump.h" |
1296 | 17 | #include "pcap_packets_parser.h" | ||
1297 | 18 | |||
1298 | 19 | #include "percona_playback/percona_playback.h" | ||
1299 | 20 | |||
1300 | 17 | #include <stdio.h> | 21 | #include <stdio.h> |
1301 | 22 | #include <pcap.h> | ||
1302 | 23 | |||
1303 | 24 | #define FILTER_EXP_SIZE 11 // max filter expression size | ||
1304 | 25 | |||
1305 | 26 | std::string g_tcpdump_file_name; | ||
1306 | 27 | uint16_t g_tcpdump_port; | ||
1307 | 28 | TcpdumpPluginMode g_tcpdump_mode; | ||
1308 | 29 | |||
1309 | 30 | std::istream& operator>>(std::istream& in, TcpdumpPluginMode& unit) | ||
1310 | 31 | { | ||
1311 | 32 | std::string token; | ||
1312 | 33 | in >> token; | ||
1313 | 34 | if (token == "fast") | ||
1314 | 35 | unit = TCPDUMP_MODE_FAST; | ||
1315 | 36 | else if (token == "accurate") | ||
1316 | 37 | unit = TCPDUMP_MODE_ACCURATE; | ||
1317 | 38 | else | ||
1318 | 39 | throw | ||
1319 | 40 | boost::program_options::validation_error( | ||
1320 | 41 | "Allowed input-type values are (fast|accurate)" | ||
1321 | 42 | ); | ||
1322 | 43 | return in; | ||
1323 | 44 | } | ||
1324 | 18 | 45 | ||
1325 | 19 | boost::program_options::options_description* | 46 | boost::program_options::options_description* |
1326 | 20 | TcpDumpParserPlugin::getProgramOptions() | 47 | TcpDumpParserPlugin::getProgramOptions() |
1327 | 21 | { | 48 | { |
1328 | 22 | options.add_options() | 49 | options.add_options() |
1329 | 23 | ("tcpdump-file", | 50 | ("tcpdump-file", |
1332 | 24 | boost::program_options::value<std::string>(&file_name), | 51 | boost::program_options::value<std::string>(&g_tcpdump_file_name), |
1333 | 25 | "Tcpdump file name"); | 52 | "Tcpdump file name") |
1334 | 53 | ("tcpdump-port", | ||
1335 | 54 | boost::program_options::value<uint16_t>(&g_tcpdump_port) | ||
1336 | 55 | ->default_value(3306), | ||
1337 | 56 | "Tcpdump port") | ||
1338 | 57 | ("tcpdump-mode", | ||
1339 | 58 | boost::program_options::value<TcpdumpPluginMode>(&g_tcpdump_mode) | ||
1340 | 59 | ->multitoken()->default_value(TCPDUMP_MODE_FAST, "fast"), | ||
1341 | 60 | "The mode of tcpdump plugin (fast|accurate), in 'fast' mode " | ||
1342 | 61 | "the plugin executes queries as fast as it can whereas in " | ||
1343 | 62 | "'accurate' mode the plugin preserves queries execution time " | ||
1344 | 63 | "and pauses between queries") | ||
1345 | 64 | ; | ||
1346 | 26 | 65 | ||
1347 | 27 | return &options; | 66 | return &options; |
1348 | 28 | } | 67 | } |
1349 | @@ -32,7 +71,9 @@ | |||
1350 | 32 | boost::program_options::variables_map &vm) | 71 | boost::program_options::variables_map &vm) |
1351 | 33 | { | 72 | { |
1352 | 34 | if (!active && | 73 | if (!active && |
1354 | 35 | (vm.count("tcpdump-file"))) | 74 | (vm.count("tcpdump-file") || |
1355 | 75 | !vm["tcpdump-port"].defaulted() || | ||
1356 | 76 | !vm["tcpdump-mode"].defaulted())) | ||
1357 | 36 | { | 77 | { |
1358 | 37 | fprintf(stderr, | 78 | fprintf(stderr, |
1359 | 38 | gettext("tcpdump plugin is not selected, " | 79 | gettext("tcpdump plugin is not selected, " |
1360 | @@ -40,9 +81,87 @@ | |||
1361 | 40 | "command line options\n")); | 81 | "command line options\n")); |
1362 | 41 | return -1; | 82 | return -1; |
1363 | 42 | } | 83 | } |
1364 | 84 | |||
1365 | 85 | if (!active) | ||
1366 | 86 | return 0; | ||
1367 | 87 | |||
1368 | 88 | if (!vm.count("tcpdump-file")) | ||
1369 | 89 | { | ||
1370 | 90 | fprintf(stderr, | ||
1371 | 91 | gettext("tcpdump-file argument is requred\n")); | ||
1372 | 92 | return -1; | ||
1373 | 93 | } | ||
1374 | 94 | |||
1375 | 43 | return 0; | 95 | return 0; |
1376 | 44 | } | 96 | } |
1377 | 45 | 97 | ||
1378 | 98 | void | ||
1379 | 99 | TcpDumpParserPlugin::run(percona_playback_run_result &r) | ||
1380 | 100 | { | ||
1381 | 101 | char errbuf[PCAP_ERRBUF_SIZE]; | ||
1382 | 102 | pcap_t *handle; | ||
1383 | 103 | struct bpf_program fp; | ||
1384 | 104 | char filter_exp[11]; | ||
1385 | 105 | PcapPacketsParser packets_parser; | ||
1386 | 106 | |||
1387 | 107 | |||
1388 | 108 | if (g_tcpdump_file_name.empty()) | ||
1389 | 109 | { | ||
1390 | 110 | r.err= -1; | ||
1391 | 111 | return; | ||
1392 | 112 | } | ||
1393 | 113 | |||
1394 | 114 | handle = pcap_open_offline(g_tcpdump_file_name.c_str(), errbuf); | ||
1395 | 115 | |||
1396 | 116 | if (handle == NULL) | ||
1397 | 117 | { | ||
1398 | 118 | std::cerr << "Couldn't open file " << g_tcpdump_file_name << ": " | ||
1399 | 119 | << errbuf << std::endl; | ||
1400 | 120 | r.err= -1; | ||
1401 | 121 | return; | ||
1402 | 122 | } | ||
1403 | 123 | |||
1404 | 124 | snprintf(filter_exp, FILTER_EXP_SIZE, "port %u", (unsigned)g_tcpdump_port); | ||
1405 | 125 | |||
1406 | 126 | if(pcap_compile(handle, &fp, filter_exp, 0, 0) == -1) | ||
1407 | 127 | { | ||
1408 | 128 | std::cerr << "Couldn't parse filter " << filter_exp << ": " | ||
1409 | 129 | << pcap_geterr(handle) << std::endl; | ||
1410 | 130 | r.err= -1; | ||
1411 | 131 | return; | ||
1412 | 132 | } | ||
1413 | 133 | |||
1414 | 134 | if (pcap_setfilter(handle, &fp) == -1) | ||
1415 | 135 | { | ||
1416 | 136 | std::cerr << "Couldn't install filter " << filter_exp << ": " | ||
1417 | 137 | << pcap_geterr(handle) << std::endl; | ||
1418 | 138 | r.err= -1; | ||
1419 | 139 | return; | ||
1420 | 140 | } | ||
1421 | 141 | |||
1422 | 142 | if (pcap_loop(handle, | ||
1423 | 143 | -1, | ||
1424 | 144 | PcapPacketsParser::Process, | ||
1425 | 145 | (u_char *)&packets_parser) < 0) | ||
1426 | 146 | { | ||
1427 | 147 | std::cerr << "pcap_loop error " | ||
1428 | 148 | << pcap_geterr(handle) << std::endl; | ||
1429 | 149 | r.err= -1; | ||
1430 | 150 | return; | ||
1431 | 151 | } | ||
1432 | 152 | |||
1433 | 153 | /* Wait for unfinished DBThreads */ | ||
1434 | 154 | packets_parser.WaitForUnfinishedTasks(); | ||
1435 | 155 | |||
1436 | 156 | const TcpdumpMysqlParserStats &stats= packets_parser.GetStats(); | ||
1437 | 157 | |||
1438 | 158 | r.n_log_entries= stats.nr_of_parsed_packets; | ||
1439 | 159 | r.n_queries= stats.nr_of_parsed_queries; | ||
1440 | 160 | r.err= stats.nr_of_parsing_errors; | ||
1441 | 161 | |||
1442 | 162 | return; | ||
1443 | 163 | } | ||
1444 | 164 | |||
1445 | 46 | static void init_plugin(percona_playback::PluginRegistry &r) | 165 | static void init_plugin(percona_playback::PluginRegistry &r) |
1446 | 47 | { | 166 | { |
1447 | 48 | r.add("tcpdump", new TcpDumpParserPlugin("tcpdump")); | 167 | r.add("tcpdump", new TcpDumpParserPlugin("tcpdump")); |
1448 | 49 | 168 | ||
1449 | === modified file 'percona_playback/tcpdump/tcpdump.h' | |||
1450 | --- percona_playback/tcpdump/tcpdump.h 2012-06-24 04:28:41 +0000 | |||
1451 | +++ percona_playback/tcpdump/tcpdump.h 2012-07-02 18:23:18 +0000 | |||
1452 | @@ -19,9 +19,17 @@ | |||
1453 | 19 | #include <percona_playback/plugin.h> | 19 | #include <percona_playback/plugin.h> |
1454 | 20 | 20 | ||
1455 | 21 | #include <boost/program_options.hpp> | 21 | #include <boost/program_options.hpp> |
1456 | 22 | #include <string> | ||
1457 | 23 | |||
1458 | 24 | enum TcpdumpPluginMode | ||
1459 | 25 | { | ||
1460 | 26 | TCPDUMP_MODE_FAST, | ||
1461 | 27 | TCPDUMP_MODE_ACCURATE | ||
1462 | 28 | }; | ||
1463 | 22 | 29 | ||
1464 | 23 | class TcpDumpParserPlugin : public percona_playback::InputPlugin | 30 | class TcpDumpParserPlugin : public percona_playback::InputPlugin |
1465 | 24 | { | 31 | { |
1466 | 32 | boost::program_options::options_description options; | ||
1467 | 25 | 33 | ||
1468 | 26 | public: | 34 | public: |
1469 | 27 | TcpDumpParserPlugin(const std::string &_name) : | 35 | TcpDumpParserPlugin(const std::string &_name) : |
1470 | @@ -33,11 +41,20 @@ | |||
1471 | 33 | 41 | ||
1472 | 34 | virtual int processOptions(boost::program_options::variables_map &vm); | 42 | virtual int processOptions(boost::program_options::variables_map &vm); |
1473 | 35 | 43 | ||
1474 | 44 | <<<<<<< TREE | ||
1475 | 36 | virtual void run(percona_playback_run_result &) {} | 45 | virtual void run(percona_playback_run_result &) {} |
1476 | 37 | 46 | ||
1477 | 38 | 47 | ||
1478 | 39 | std::string file_name; | 48 | std::string file_name; |
1479 | 40 | boost::program_options::options_description options; | 49 | boost::program_options::options_description options; |
1480 | 50 | ======= | ||
1481 | 51 | virtual void run(percona_playback_run_result &result); | ||
1482 | 52 | >>>>>>> MERGE-SOURCE | ||
1483 | 41 | }; | 53 | }; |
1484 | 42 | 54 | ||
1485 | 55 | extern std::string g_tcpdump_file_name; | ||
1486 | 56 | extern uint16_t g_tcpdump_port; | ||
1487 | 57 | extern TcpdumpPluginMode g_tcpdump_mode; | ||
1488 | 58 | |||
1489 | 59 | |||
1490 | 43 | #endif /* PERCONA_PLAYBACK_TCPDUMP_PARSER_H */ | 60 | #endif /* PERCONA_PLAYBACK_TCPDUMP_PARSER_H */ |
1491 | 44 | 61 | ||
1492 | === added file 'percona_playback/tcpdump/tcpdump_mysql_parser_stats.h' | |||
1493 | --- percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 1970-01-01 00:00:00 +0000 | |||
1494 | +++ percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 2012-07-02 18:23:18 +0000 | |||
1495 | @@ -0,0 +1,33 @@ | |||
1496 | 1 | /* BEGIN LICENSE | ||
1497 | 2 | * Copyright (C) 2011 Percona Inc. | ||
1498 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1499 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
1500 | 5 | * by the Free Software Foundation. | ||
1501 | 6 | * | ||
1502 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1503 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1504 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1505 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1506 | 11 | * | ||
1507 | 12 | * You should have received a copy of the GNU General Public License along | ||
1508 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1509 | 14 | * END LICENSE */ | ||
1510 | 15 | |||
1511 | 16 | #ifndef PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H | ||
1512 | 17 | #define PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H | ||
1513 | 18 | |||
1514 | 19 | struct TcpdumpMysqlParserStats | ||
1515 | 20 | { | ||
1516 | 21 | size_t nr_of_parsed_packets; | ||
1517 | 22 | size_t nr_of_parsed_queries; | ||
1518 | 23 | size_t nr_of_parsing_errors; | ||
1519 | 24 | |||
1520 | 25 | TcpdumpMysqlParserStats() : | ||
1521 | 26 | nr_of_parsed_packets(0), | ||
1522 | 27 | nr_of_parsed_queries(0), | ||
1523 | 28 | nr_of_parsing_errors(0) | ||
1524 | 29 | {} | ||
1525 | 30 | |||
1526 | 31 | }; | ||
1527 | 32 | |||
1528 | 33 | #endif //PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H | ||
1529 | 0 | 34 | ||
1530 | === added file 'percona_playback/tcpdump/tcpdump_query_entries.cc' | |||
1531 | --- percona_playback/tcpdump/tcpdump_query_entries.cc 1970-01-01 00:00:00 +0000 | |||
1532 | +++ percona_playback/tcpdump/tcpdump_query_entries.cc 2012-07-02 18:23:18 +0000 | |||
1533 | @@ -0,0 +1,129 @@ | |||
1534 | 1 | /* BEGIN LICENSE | ||
1535 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1536 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1537 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
1538 | 5 | * by the Free Software Foundation. | ||
1539 | 6 | * | ||
1540 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1541 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1542 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1543 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1544 | 11 | * | ||
1545 | 12 | * You should have received a copy of the GNU General Public License along | ||
1546 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1547 | 14 | * END LICENSE */ | ||
1548 | 15 | #include "tcpdump_query_entries.h" | ||
1549 | 16 | #include "tcpdump.h" | ||
1550 | 17 | #include "percona_playback/db_thread.h" | ||
1551 | 18 | #include "percona_playback/plugin.h" | ||
1552 | 19 | |||
1553 | 20 | #include <boost/date_time/posix_time/posix_time.hpp> | ||
1554 | 21 | #include <boost/foreach.hpp> | ||
1555 | 22 | #include <boost/shared_ptr.hpp> | ||
1556 | 23 | #include <string.h> | ||
1557 | 24 | #include <iostream> | ||
1558 | 25 | #include <assert.h> | ||
1559 | 26 | |||
1560 | 27 | void | ||
1561 | 28 | TcpdumpQueryEntry::execute(DBThread *t) | ||
1562 | 29 | { | ||
1563 | 30 | QueryResult expected_result; | ||
1564 | 31 | boost::posix_time::ptime start_time; | ||
1565 | 32 | boost::posix_time::ptime end_time; | ||
1566 | 33 | boost::shared_ptr<DBThreadState> thr_state; | ||
1567 | 34 | |||
1568 | 35 | assert(t); | ||
1569 | 36 | |||
1570 | 37 | thr_state= t->get_state(); | ||
1571 | 38 | |||
1572 | 39 | assert(thr_state.get()); | ||
1573 | 40 | |||
1574 | 41 | ConnectionState &state= (ConnectionState &)*thr_state; | ||
1575 | 42 | |||
1576 | 43 | LastExecutedQueryInfo &last_query_info= state.last_executed_query_info; | ||
1577 | 44 | |||
1578 | 45 | if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE && | ||
1579 | 46 | last_query_info.end_timestamp.tv_sec != 0 && | ||
1580 | 47 | last_query_info.end_timestamp.tv_usec != 0 && | ||
1581 | 48 | last_query_info.end_pcap_timestamp.tv_sec != 0 && | ||
1582 | 49 | last_query_info.end_pcap_timestamp.tv_usec != 0) | ||
1583 | 50 | { | ||
1584 | 51 | timeval current_timestamp; | ||
1585 | 52 | timeval pause_time; | ||
1586 | 53 | timeval pcap_pause_time; | ||
1587 | 54 | |||
1588 | 55 | gettimeofday(¤t_timestamp, NULL); | ||
1589 | 56 | timersub(¤t_timestamp, &last_query_info.end_timestamp, &pause_time); | ||
1590 | 57 | |||
1591 | 58 | timersub(&pcap_timestamp, | ||
1592 | 59 | &last_query_info.end_pcap_timestamp, | ||
1593 | 60 | &pcap_pause_time); | ||
1594 | 61 | |||
1595 | 62 | if (timercmp(&pause_time, &pcap_pause_time, <)) | ||
1596 | 63 | { | ||
1597 | 64 | timeval time_to_sleep; | ||
1598 | 65 | timersub(&pcap_pause_time, | ||
1599 | 66 | &pause_time, | ||
1600 | 67 | &time_to_sleep); | ||
1601 | 68 | usleep(time_to_sleep.tv_sec*1000000 + time_to_sleep.tv_usec); | ||
1602 | 69 | } | ||
1603 | 70 | } | ||
1604 | 71 | |||
1605 | 72 | last_query_info.result.clear(); | ||
1606 | 73 | |||
1607 | 74 | start_time= boost::posix_time::microsec_clock::universal_time(); | ||
1608 | 75 | t->execute_query(query, &last_query_info.result, expected_result); | ||
1609 | 76 | end_time= boost::posix_time::microsec_clock::universal_time(); | ||
1610 | 77 | |||
1611 | 78 | boost::posix_time::time_period duration(start_time, end_time); | ||
1612 | 79 | last_query_info.result.setDuration(duration.length()); | ||
1613 | 80 | last_query_info.begin_pcap_timestamp= pcap_timestamp; | ||
1614 | 81 | last_query_info.query= query; | ||
1615 | 82 | } | ||
1616 | 83 | |||
1617 | 84 | void | ||
1618 | 85 | TcpdumpResultEntry::execute(DBThread *t) | ||
1619 | 86 | { | ||
1620 | 87 | timeval query_execution_time; | ||
1621 | 88 | boost::shared_ptr<DBThreadState> thr_state; | ||
1622 | 89 | |||
1623 | 90 | assert(t); | ||
1624 | 91 | |||
1625 | 92 | thr_state= t->get_state(); | ||
1626 | 93 | |||
1627 | 94 | assert(thr_state.get()); | ||
1628 | 95 | |||
1629 | 96 | |||
1630 | 97 | ConnectionState &state= (ConnectionState &)*thr_state; | ||
1631 | 98 | LastExecutedQueryInfo &last_query_info= state.last_executed_query_info; | ||
1632 | 99 | |||
1633 | 100 | timersub(&pcap_timestamp, | ||
1634 | 101 | &last_query_info.begin_pcap_timestamp, | ||
1635 | 102 | &query_execution_time); | ||
1636 | 103 | |||
1637 | 104 | expected_result.setDuration( | ||
1638 | 105 | boost::posix_time::microseconds( | ||
1639 | 106 | query_execution_time.tv_usec + | ||
1640 | 107 | query_execution_time.tv_sec*1000000)); | ||
1641 | 108 | |||
1642 | 109 | if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE && | ||
1643 | 110 | (expected_result.getDuration() > last_query_info.result.getDuration())) | ||
1644 | 111 | { | ||
1645 | 112 | boost::posix_time::time_duration us_sleep_time= | ||
1646 | 113 | expected_result.getDuration() - last_query_info.result.getDuration(); | ||
1647 | 114 | |||
1648 | 115 | usleep(us_sleep_time.total_microseconds()); | ||
1649 | 116 | } | ||
1650 | 117 | |||
1651 | 118 | gettimeofday(&last_query_info.end_timestamp, NULL); | ||
1652 | 119 | last_query_info.end_pcap_timestamp= pcap_timestamp; | ||
1653 | 120 | |||
1654 | 121 | BOOST_FOREACH(const percona_playback::PluginRegistry::ReportPluginPair pp, | ||
1655 | 122 | percona_playback::PluginRegistry::singleton().report_plugins) | ||
1656 | 123 | { | ||
1657 | 124 | pp.second->query_execution(getThreadId(), | ||
1658 | 125 | last_query_info.query, | ||
1659 | 126 | expected_result, | ||
1660 | 127 | last_query_info.result); | ||
1661 | 128 | } | ||
1662 | 129 | } | ||
1663 | 0 | 130 | ||
1664 | === added file 'percona_playback/tcpdump/tcpdump_query_entries.h' | |||
1665 | --- percona_playback/tcpdump/tcpdump_query_entries.h 1970-01-01 00:00:00 +0000 | |||
1666 | +++ percona_playback/tcpdump/tcpdump_query_entries.h 2012-07-02 18:23:18 +0000 | |||
1667 | @@ -0,0 +1,73 @@ | |||
1668 | 1 | /* BEGIN LICENSE | ||
1669 | 2 | * Copyright (C) 2011 Percona Inc. | ||
1670 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1671 | 4 | * under the terms of the GNU General Public License version 2, as published | ||
1672 | 5 | * by the Free Software Foundation. | ||
1673 | 6 | * | ||
1674 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1675 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1676 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1677 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1678 | 11 | * | ||
1679 | 12 | * You should have received a copy of the GNU General Public License along | ||
1680 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1681 | 14 | * END LICENSE */ | ||
1682 | 15 | |||
1683 | 16 | #ifndef PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H | ||
1684 | 17 | #define PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H | ||
1685 | 18 | |||
1686 | 19 | #include "percona_playback/query_entry.h" | ||
1687 | 20 | #include "percona_playback/query_result.h" | ||
1688 | 21 | #include "connection_state.h" | ||
1689 | 22 | |||
1690 | 23 | #include <sys/time.h> | ||
1691 | 24 | |||
1692 | 25 | class TcpdumpQueryEntry : public QueryEntry | ||
1693 | 26 | { | ||
1694 | 27 | timeval pcap_timestamp; | ||
1695 | 28 | std::string query; | ||
1696 | 29 | |||
1697 | 30 | public: | ||
1698 | 31 | |||
1699 | 32 | TcpdumpQueryEntry() | ||
1700 | 33 | { | ||
1701 | 34 | pcap_timestamp.tv_sec= pcap_timestamp.tv_usec= 0; | ||
1702 | 35 | } | ||
1703 | 36 | |||
1704 | 37 | TcpdumpQueryEntry(const timeval &pcap_timestamp, | ||
1705 | 38 | const std::string &query, | ||
1706 | 39 | const AddrPort &addr_port) : | ||
1707 | 40 | QueryEntry(addr_port.ThreadId(), false), | ||
1708 | 41 | pcap_timestamp(pcap_timestamp), | ||
1709 | 42 | query(query) | ||
1710 | 43 | {} | ||
1711 | 44 | |||
1712 | 45 | bool is_quit() { return false; } | ||
1713 | 46 | |||
1714 | 47 | void execute(DBThread *t); | ||
1715 | 48 | }; | ||
1716 | 49 | |||
1717 | 50 | class TcpdumpResultEntry : public QueryEntry | ||
1718 | 51 | { | ||
1719 | 52 | |||
1720 | 53 | timeval pcap_timestamp; | ||
1721 | 54 | QueryResult expected_result; | ||
1722 | 55 | |||
1723 | 56 | public: | ||
1724 | 57 | TcpdumpResultEntry() {} | ||
1725 | 58 | TcpdumpResultEntry(const AddrPort &addr_port, | ||
1726 | 59 | const timeval &pcap_timestamp, | ||
1727 | 60 | const QueryResult &expected_result) : | ||
1728 | 61 | QueryEntry(addr_port.ThreadId(), false), | ||
1729 | 62 | pcap_timestamp(pcap_timestamp), | ||
1730 | 63 | expected_result(expected_result) | ||
1731 | 64 | {} | ||
1732 | 65 | |||
1733 | 66 | bool is_quit() { return false; } | ||
1734 | 67 | |||
1735 | 68 | void execute(DBThread *t); | ||
1736 | 69 | |||
1737 | 70 | }; | ||
1738 | 71 | |||
1739 | 72 | #endif// PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H | ||
1740 | 73 | |||
1741 | 0 | 74 | ||
1742 | === added file 'percona_playback/test/tcpdump_accuracy.cc' | |||
1743 | --- percona_playback/test/tcpdump_accuracy.cc 1970-01-01 00:00:00 +0000 | |||
1744 | +++ percona_playback/test/tcpdump_accuracy.cc 2012-07-02 18:23:18 +0000 | |||
1745 | @@ -0,0 +1,69 @@ | |||
1746 | 1 | /* BEGIN LICENSE | ||
1747 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1748 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1749 | 4 | * under the terms of the GNU General Public License version 3, as published | ||
1750 | 5 | * by the Free Software Foundation. | ||
1751 | 6 | * | ||
1752 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1753 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1754 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1755 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1756 | 11 | * | ||
1757 | 12 | * You should have received a copy of the GNU General Public License along | ||
1758 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1759 | 14 | * END LICENSE */ | ||
1760 | 15 | |||
1761 | 16 | #include "config.h" | ||
1762 | 17 | #include <iostream> | ||
1763 | 18 | #include <assert.h> | ||
1764 | 19 | #include <boost/date_time/posix_time/posix_time.hpp> | ||
1765 | 20 | |||
1766 | 21 | #include "percona_playback/percona_playback.h" | ||
1767 | 22 | #include "percona_playback/plugin.h" | ||
1768 | 23 | |||
1769 | 24 | const size_t pp_argc= 5; | ||
1770 | 25 | |||
1771 | 26 | int main(int, char **argv) | ||
1772 | 27 | { | ||
1773 | 28 | percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); | ||
1774 | 29 | assert(the_percona_playback); | ||
1775 | 30 | |||
1776 | 31 | char *pp_argv[pp_argc]; | ||
1777 | 32 | char pp_argv_0[]= "--db-plugin=null"; | ||
1778 | 33 | char pp_argv_1[]= "--input-plugin=tcpdump"; | ||
1779 | 34 | char pp_argv_2[]= "--tcpdump-file=" | ||
1780 | 35 | SRCDIR | ||
1781 | 36 | "/percona_playback/test" | ||
1782 | 37 | "/tcpdump_accuracy.dump"; | ||
1783 | 38 | char pp_argv_3[]= "--tcpdump-mode=accurate"; | ||
1784 | 39 | |||
1785 | 40 | pp_argv[0]= argv[0]; | ||
1786 | 41 | pp_argv[1]= pp_argv_0; | ||
1787 | 42 | pp_argv[2]= pp_argv_1; | ||
1788 | 43 | pp_argv[3]= pp_argv_2; | ||
1789 | 44 | pp_argv[4]= pp_argv_3; | ||
1790 | 45 | |||
1791 | 46 | assert(0 == percona_playback_argv(the_percona_playback, | ||
1792 | 47 | pp_argc, | ||
1793 | 48 | pp_argv)); | ||
1794 | 49 | |||
1795 | 50 | boost::posix_time::ptime start_time; | ||
1796 | 51 | start_time= boost::posix_time::microsec_clock::universal_time(); | ||
1797 | 52 | |||
1798 | 53 | struct percona_playback_run_result *r= | ||
1799 | 54 | percona_playback_run(the_percona_playback); | ||
1800 | 55 | |||
1801 | 56 | boost::posix_time::ptime end_time; | ||
1802 | 57 | end_time= boost::posix_time::microsec_clock::universal_time(); | ||
1803 | 58 | |||
1804 | 59 | boost::posix_time::time_period duration(start_time, end_time); | ||
1805 | 60 | |||
1806 | 61 | assert(duration.length().total_microseconds() > 4000000); | ||
1807 | 62 | |||
1808 | 63 | assert(r->err == 0); | ||
1809 | 64 | assert(r->n_queries == 60); | ||
1810 | 65 | assert(r->n_log_entries == 480); | ||
1811 | 66 | |||
1812 | 67 | percona_playback_destroy(&the_percona_playback); | ||
1813 | 68 | return r->err; | ||
1814 | 69 | } | ||
1815 | 0 | 70 | ||
1816 | === added file 'percona_playback/test/tcpdump_accuracy.dump' | |||
1817 | 1 | Binary 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 | 71 | Binary 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 |
1818 | === added file 'percona_playback/test/tcpdump_fragmented_packet.cc' | |||
1819 | --- percona_playback/test/tcpdump_fragmented_packet.cc 1970-01-01 00:00:00 +0000 | |||
1820 | +++ percona_playback/test/tcpdump_fragmented_packet.cc 2012-07-02 18:23:18 +0000 | |||
1821 | @@ -0,0 +1,56 @@ | |||
1822 | 1 | /* BEGIN LICENSE | ||
1823 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1824 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1825 | 4 | * under the terms of the GNU General Public License version 3, as published | ||
1826 | 5 | * by the Free Software Foundation. | ||
1827 | 6 | * | ||
1828 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1829 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1830 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1831 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1832 | 11 | * | ||
1833 | 12 | * You should have received a copy of the GNU General Public License along | ||
1834 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1835 | 14 | * END LICENSE */ | ||
1836 | 15 | |||
1837 | 16 | #include "config.h" | ||
1838 | 17 | #include <iostream> | ||
1839 | 18 | #include <assert.h> | ||
1840 | 19 | #include "percona_playback/percona_playback.h" | ||
1841 | 20 | #include "percona_playback/plugin.h" | ||
1842 | 21 | |||
1843 | 22 | const size_t pp_argc= 4; | ||
1844 | 23 | |||
1845 | 24 | int main(int, char **argv) | ||
1846 | 25 | { | ||
1847 | 26 | percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); | ||
1848 | 27 | assert(the_percona_playback); | ||
1849 | 28 | |||
1850 | 29 | char *pp_argv[pp_argc]; | ||
1851 | 30 | char pp_argv_0[]= "--db-plugin=null"; | ||
1852 | 31 | char pp_argv_1[]= "--input-plugin=tcpdump"; | ||
1853 | 32 | char pp_argv_2[]= "--tcpdump-file=" | ||
1854 | 33 | SRCDIR | ||
1855 | 34 | "/percona_playback/test" | ||
1856 | 35 | "/tcpdump_fragmented_packet.dump"; | ||
1857 | 36 | |||
1858 | 37 | |||
1859 | 38 | pp_argv[0]= argv[0]; | ||
1860 | 39 | pp_argv[1]= pp_argv_0; | ||
1861 | 40 | pp_argv[2]= pp_argv_1; | ||
1862 | 41 | pp_argv[3]= pp_argv_2; | ||
1863 | 42 | |||
1864 | 43 | assert(0 == percona_playback_argv(the_percona_playback, | ||
1865 | 44 | pp_argc, | ||
1866 | 45 | pp_argv)); | ||
1867 | 46 | |||
1868 | 47 | struct percona_playback_run_result *r= | ||
1869 | 48 | percona_playback_run(the_percona_playback); | ||
1870 | 49 | |||
1871 | 50 | assert(r->err == 0); | ||
1872 | 51 | assert(r->n_queries == 1); | ||
1873 | 52 | assert(r->n_log_entries == 6); | ||
1874 | 53 | |||
1875 | 54 | percona_playback_destroy(&the_percona_playback); | ||
1876 | 55 | return r->err; | ||
1877 | 56 | } | ||
1878 | 0 | 57 | ||
1879 | === added file 'percona_playback/test/tcpdump_fragmented_packet.dump' | |||
1880 | 1 | Binary 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 | 58 | Binary 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 |
1881 | === added file 'percona_playback/test/tcpdump_multiple_connections.cc' | |||
1882 | --- percona_playback/test/tcpdump_multiple_connections.cc 1970-01-01 00:00:00 +0000 | |||
1883 | +++ percona_playback/test/tcpdump_multiple_connections.cc 2012-07-02 18:23:18 +0000 | |||
1884 | @@ -0,0 +1,56 @@ | |||
1885 | 1 | /* BEGIN LICENSE | ||
1886 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1887 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1888 | 4 | * under the terms of the GNU General Public License version 3, as published | ||
1889 | 5 | * by the Free Software Foundation. | ||
1890 | 6 | * | ||
1891 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1892 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1893 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1894 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1895 | 11 | * | ||
1896 | 12 | * You should have received a copy of the GNU General Public License along | ||
1897 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1898 | 14 | * END LICENSE */ | ||
1899 | 15 | |||
1900 | 16 | #include "config.h" | ||
1901 | 17 | #include <iostream> | ||
1902 | 18 | #include <assert.h> | ||
1903 | 19 | #include "percona_playback/percona_playback.h" | ||
1904 | 20 | #include "percona_playback/plugin.h" | ||
1905 | 21 | |||
1906 | 22 | const size_t pp_argc= 4; | ||
1907 | 23 | |||
1908 | 24 | int main(int, char **argv) | ||
1909 | 25 | { | ||
1910 | 26 | percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); | ||
1911 | 27 | assert(the_percona_playback); | ||
1912 | 28 | |||
1913 | 29 | char *pp_argv[pp_argc]; | ||
1914 | 30 | char pp_argv_0[]= "--db-plugin=null"; | ||
1915 | 31 | char pp_argv_1[]= "--input-plugin=tcpdump"; | ||
1916 | 32 | char pp_argv_2[]= "--tcpdump-file=" | ||
1917 | 33 | SRCDIR | ||
1918 | 34 | "/percona_playback/test" | ||
1919 | 35 | "/tcpdump_multiple_connections.dump"; | ||
1920 | 36 | |||
1921 | 37 | |||
1922 | 38 | pp_argv[0]= argv[0]; | ||
1923 | 39 | pp_argv[1]= pp_argv_0; | ||
1924 | 40 | pp_argv[2]= pp_argv_1; | ||
1925 | 41 | pp_argv[3]= pp_argv_2; | ||
1926 | 42 | |||
1927 | 43 | assert(0 == percona_playback_argv(the_percona_playback, | ||
1928 | 44 | pp_argc, | ||
1929 | 45 | pp_argv)); | ||
1930 | 46 | |||
1931 | 47 | struct percona_playback_run_result *r= | ||
1932 | 48 | percona_playback_run(the_percona_playback); | ||
1933 | 49 | |||
1934 | 50 | assert(r->err == 0); | ||
1935 | 51 | assert(r->n_queries == 2000); | ||
1936 | 52 | assert(r->n_log_entries == 16000); | ||
1937 | 53 | |||
1938 | 54 | percona_playback_destroy(&the_percona_playback); | ||
1939 | 55 | return r->err; | ||
1940 | 56 | } | ||
1941 | 0 | 57 | ||
1942 | === added file 'percona_playback/test/tcpdump_multiple_connections.dump' | |||
1943 | 1 | Binary 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 | 58 | Binary 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 |
1944 | === added file 'percona_playback/test/tcpdump_stress_test.cc' | |||
1945 | --- percona_playback/test/tcpdump_stress_test.cc 1970-01-01 00:00:00 +0000 | |||
1946 | +++ percona_playback/test/tcpdump_stress_test.cc 2012-07-02 18:23:18 +0000 | |||
1947 | @@ -0,0 +1,56 @@ | |||
1948 | 1 | /* BEGIN LICENSE | ||
1949 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
1950 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
1951 | 4 | * under the terms of the GNU General Public License version 3, as published | ||
1952 | 5 | * by the Free Software Foundation. | ||
1953 | 6 | * | ||
1954 | 7 | * This program is distributed in the hope that it will be useful, but | ||
1955 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1956 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1957 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
1958 | 11 | * | ||
1959 | 12 | * You should have received a copy of the GNU General Public License along | ||
1960 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1961 | 14 | * END LICENSE */ | ||
1962 | 15 | |||
1963 | 16 | #include "config.h" | ||
1964 | 17 | #include <iostream> | ||
1965 | 18 | #include <assert.h> | ||
1966 | 19 | #include "percona_playback/percona_playback.h" | ||
1967 | 20 | #include "percona_playback/plugin.h" | ||
1968 | 21 | |||
1969 | 22 | const size_t pp_argc= 4; | ||
1970 | 23 | |||
1971 | 24 | int main(int, char **argv) | ||
1972 | 25 | { | ||
1973 | 26 | percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); | ||
1974 | 27 | assert(the_percona_playback); | ||
1975 | 28 | |||
1976 | 29 | char *pp_argv[pp_argc]; | ||
1977 | 30 | char pp_argv_0[]= "--db-plugin=null"; | ||
1978 | 31 | char pp_argv_1[]= "--input-plugin=tcpdump"; | ||
1979 | 32 | char pp_argv_2[]= "--tcpdump-file=" | ||
1980 | 33 | SRCDIR | ||
1981 | 34 | "/percona_playback/test" | ||
1982 | 35 | "/tcpdump_stress_test.dump"; | ||
1983 | 36 | |||
1984 | 37 | |||
1985 | 38 | pp_argv[0]= argv[0]; | ||
1986 | 39 | pp_argv[1]= pp_argv_0; | ||
1987 | 40 | pp_argv[2]= pp_argv_1; | ||
1988 | 41 | pp_argv[3]= pp_argv_2; | ||
1989 | 42 | |||
1990 | 43 | assert(0 == percona_playback_argv(the_percona_playback, | ||
1991 | 44 | pp_argc, | ||
1992 | 45 | pp_argv)); | ||
1993 | 46 | |||
1994 | 47 | struct percona_playback_run_result *r= | ||
1995 | 48 | percona_playback_run(the_percona_playback); | ||
1996 | 49 | |||
1997 | 50 | assert(r->err == 0); | ||
1998 | 51 | assert(r->n_queries == 9088); | ||
1999 | 52 | assert(r->n_log_entries == 62306); | ||
2000 | 53 | |||
2001 | 54 | percona_playback_destroy(&the_percona_playback); | ||
2002 | 55 | return r->err; | ||
2003 | 56 | } | ||
2004 | 0 | 57 | ||
2005 | === added file 'percona_playback/test/tcpdump_stress_test.dump' | |||
2006 | 1 | Binary 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 | 58 | Binary 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 |
2007 | === added file 'percona_playback/test/tcpdump_without_handshake.cc' | |||
2008 | --- percona_playback/test/tcpdump_without_handshake.cc 1970-01-01 00:00:00 +0000 | |||
2009 | +++ percona_playback/test/tcpdump_without_handshake.cc 2012-07-02 18:23:18 +0000 | |||
2010 | @@ -0,0 +1,56 @@ | |||
2011 | 1 | /* BEGIN LICENSE | ||
2012 | 2 | * Copyright (C) 2011-2012 Percona Inc. | ||
2013 | 3 | * This program is free software: you can redistribute it and/or modify it | ||
2014 | 4 | * under the terms of the GNU General Public License version 3, as published | ||
2015 | 5 | * by the Free Software Foundation. | ||
2016 | 6 | * | ||
2017 | 7 | * This program is distributed in the hope that it will be useful, but | ||
2018 | 8 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2019 | 9 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2020 | 10 | * PURPOSE. See the GNU General Public License for more details. | ||
2021 | 11 | * | ||
2022 | 12 | * You should have received a copy of the GNU General Public License along | ||
2023 | 13 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2024 | 14 | * END LICENSE */ | ||
2025 | 15 | |||
2026 | 16 | #include "config.h" | ||
2027 | 17 | #include <iostream> | ||
2028 | 18 | #include <assert.h> | ||
2029 | 19 | #include "percona_playback/percona_playback.h" | ||
2030 | 20 | #include "percona_playback/plugin.h" | ||
2031 | 21 | |||
2032 | 22 | const size_t pp_argc= 4; | ||
2033 | 23 | |||
2034 | 24 | int main(int, char **argv) | ||
2035 | 25 | { | ||
2036 | 26 | percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); | ||
2037 | 27 | assert(the_percona_playback); | ||
2038 | 28 | |||
2039 | 29 | char *pp_argv[pp_argc]; | ||
2040 | 30 | char pp_argv_0[]= "--db-plugin=null"; | ||
2041 | 31 | char pp_argv_1[]= "--input-plugin=tcpdump"; | ||
2042 | 32 | char pp_argv_2[]= "--tcpdump-file=" | ||
2043 | 33 | SRCDIR | ||
2044 | 34 | "/percona_playback/test" | ||
2045 | 35 | "/tcpdump_without_handshake.dump"; | ||
2046 | 36 | |||
2047 | 37 | |||
2048 | 38 | pp_argv[0]= argv[0]; | ||
2049 | 39 | pp_argv[1]= pp_argv_0; | ||
2050 | 40 | pp_argv[2]= pp_argv_1; | ||
2051 | 41 | pp_argv[3]= pp_argv_2; | ||
2052 | 42 | |||
2053 | 43 | assert(0 == percona_playback_argv(the_percona_playback, | ||
2054 | 44 | pp_argc, | ||
2055 | 45 | pp_argv)); | ||
2056 | 46 | |||
2057 | 47 | struct percona_playback_run_result *r= | ||
2058 | 48 | percona_playback_run(the_percona_playback); | ||
2059 | 49 | |||
2060 | 50 | assert(r->err == 0); | ||
2061 | 51 | assert(r->n_queries == 7); | ||
2062 | 52 | assert(r->n_log_entries == 44); | ||
2063 | 53 | |||
2064 | 54 | percona_playback_destroy(&the_percona_playback); | ||
2065 | 55 | return r->err; | ||
2066 | 56 | } | ||
2067 | 0 | 57 | ||
2068 | === added file 'percona_playback/test/tcpdump_without_handshake.dump' | |||
2069 | 1 | Binary 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 | 58 | Binary 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 |