1 /*
2  * Copyright (C) 2018 Codership Oy <info@codership.com>
3  *
4  * This file is part of wsrep-lib.
5  *
6  * Wsrep-lib is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Wsrep-lib is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with wsrep-lib.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "wsrep/provider.hpp"
21 #include "wsrep/logger.hpp"
22 
23 #include "wsrep_provider_v26.hpp"
24 
25 #include <dlfcn.h>
26 #include <memory>
27 
make_provider(wsrep::server_state & server_state,const std::string & provider_spec,const std::string & provider_options,const wsrep::provider::services & services)28 wsrep::provider* wsrep::provider::make_provider(
29     wsrep::server_state& server_state,
30     const std::string& provider_spec,
31     const std::string& provider_options,
32     const wsrep::provider::services& services)
33 {
34     try
35     {
36         return new wsrep::wsrep_provider_v26(
37             server_state, provider_options, provider_spec, services);
38     }
39     catch (const wsrep::runtime_error& e)
40     {
41         wsrep::log_error() << "Failed to create a new provider '"
42                            << provider_spec << "'"
43                            << " with options '" << provider_options
44                            << "': " << e.what();
45     }
46     catch (...)
47     {
48         wsrep::log_error() << "Caught unknown exception when trying to "
49                            << "create a new provider '"
50                            << provider_spec << "'"
51                            << " with options '" << provider_options;
52     }
53     return 0;
54 }
55 
56 std::string
to_string(enum wsrep::provider::status const val)57 wsrep::provider::to_string(enum wsrep::provider::status const val)
58 {
59     switch(val)
60     {
61     case success:
62         return "Success";
63     case error_warning:
64         return "Warning";
65     case error_transaction_missing:
66         return "Transaction not registered with provider";
67     case error_certification_failed:
68         return "Certification failed";
69     case error_bf_abort:
70         return "Transaction was BF aborted";
71     case error_size_exceeded:
72         return "Transaction size exceeded";
73     case error_connection_failed:
74         return "Not connected to Primary Component";
75     case error_provider_failed:
76         return "Provider in bad state, needs to be reinitialized.";
77     case error_fatal:
78         return "Fatal error, must abort.";
79     case error_not_implemented:
80         return "Function not implemented";
81     case error_not_allowed:
82         return "Operation not allowed";
83     case error_unknown:
84         return "Unknown error";
85     }
86 
87     assert(0);
88 
89     std::ostringstream os;
90     os << "Invalid error code: " << val;
91     return os.str();
92 }
93 
str(int caps)94 std::string wsrep::provider::capability::str(int caps)
95 {
96     std::ostringstream os;
97 
98 #define WSREP_PRINT_CAPABILITY(cap_value, cap_string) \
99     if (caps & cap_value) {                           \
100         os << cap_string ", ";                        \
101         caps &= ~cap_value;                           \
102     }
103 
104     WSREP_PRINT_CAPABILITY(multi_master,         "MULTI-MASTER");
105     WSREP_PRINT_CAPABILITY(certification,        "CERTIFICATION");
106     WSREP_PRINT_CAPABILITY(parallel_applying,    "PARALLEL_APPLYING");
107     WSREP_PRINT_CAPABILITY(transaction_replay,   "REPLAY");
108     WSREP_PRINT_CAPABILITY(isolation,            "ISOLATION");
109     WSREP_PRINT_CAPABILITY(pause,                "PAUSE");
110     WSREP_PRINT_CAPABILITY(causal_reads,         "CAUSAL_READ");
111     WSREP_PRINT_CAPABILITY(causal_transaction,   "CAUSAL_TRX");
112     WSREP_PRINT_CAPABILITY(incremental_writeset, "INCREMENTAL_WS");
113     WSREP_PRINT_CAPABILITY(session_locks,        "SESSION_LOCK");
114     WSREP_PRINT_CAPABILITY(distributed_locks,    "DISTRIBUTED_LOCK");
115     WSREP_PRINT_CAPABILITY(consistency_check,    "CONSISTENCY_CHECK");
116     WSREP_PRINT_CAPABILITY(unordered,            "UNORDERED");
117     WSREP_PRINT_CAPABILITY(annotation,           "ANNOTATION");
118     WSREP_PRINT_CAPABILITY(preordered,           "PREORDERED");
119     WSREP_PRINT_CAPABILITY(streaming,            "STREAMING");
120     WSREP_PRINT_CAPABILITY(snapshot,             "READ_VIEW");
121     WSREP_PRINT_CAPABILITY(nbo,                  "NBO");
122 
123 #undef WSREP_PRINT_CAPABILITY
124 
125     if (caps)
126     {
127         assert(caps == 0); // to catch missed capabilities
128         os << "UNKNOWN(" << caps << ")  ";
129     }
130 
131     std::string ret(os.str());
132     if (ret.size() > 2) ret.erase(ret.size() - 2);
133     return ret;
134 }
135 
flags_to_string(int flags)136 std::string wsrep::flags_to_string(int flags)
137 {
138     std::ostringstream oss;
139     if (flags & provider::flag::start_transaction)
140         oss << "start_transaction | ";
141     if (flags & provider::flag::commit)
142         oss << "commit | ";
143     if (flags & provider::flag::rollback)
144         oss << "rollback | ";
145     if (flags & provider::flag::isolation)
146         oss << "isolation | ";
147     if (flags & provider::flag::pa_unsafe)
148         oss << "pa_unsafe | ";
149     if (flags & provider::flag::prepare)
150         oss << "prepare | ";
151     if (flags & provider::flag::snapshot)
152         oss << "read_view | ";
153     if (flags & provider::flag::implicit_deps)
154         oss << "implicit_deps | ";
155 
156     std::string ret(oss.str());
157     if (ret.size() > 3) ret.erase(ret.size() - 3);
158     return ret;
159 }
160 
operator <<(std::ostream & os,const wsrep::ws_meta & ws_meta)161 std::ostream& wsrep::operator<<(std::ostream& os, const wsrep::ws_meta& ws_meta)
162 {
163     os <<  "gtid: "      << ws_meta.gtid()
164        << " server_id: " << ws_meta.server_id()
165        << " client_id: " << ws_meta.client_id()
166        << " trx_id: "    << ws_meta.transaction_id()
167        << " flags: "     << ws_meta.flags()
168        << " (" << wsrep::flags_to_string(ws_meta.flags()) << ")";
169     return os;
170 }
171