~drizzle-trunk/drizzle/development

1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Brian Aker
5
 *
6
 *  This program 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
 *  This program 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 this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
21
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
22
#include <config.h>
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
23
#include <drizzled/gettext.h>
24
#include <drizzled/error.h>
25
#include <drizzled/query_id.h>
26
#include <drizzled/session.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
27
#include <drizzled/internal/my_sys.h>
28
#include <drizzled/internal/m_string.h>
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
29
#include <algorithm>
30
#include <iostream>
31
#include <boost/program_options.hpp>
1945.1.4 by Monty Taylor
Fixes the issues with socket
32
#include <boost/filesystem.hpp>
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
33
#include <drizzled/module/option_map.h>
34
35
#include <sys/un.h>
36
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
37
#include <plugin/mysql_unix_socket_protocol/protocol.h>
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
38
39
#define DRIZZLE_UNIX_SOCKET_PATH "/tmp/mysql.socket"
40
41
namespace po= boost::program_options;
1945.1.4 by Monty Taylor
Fixes the issues with socket
42
namespace fs= boost::filesystem;
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
43
using namespace drizzled;
44
using namespace std;
45
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
46
namespace drizzle_plugin
47
{
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
48
namespace mysql_unix_socket_protocol
49
{
50
1945.1.7 by Monty Taylor
Added clobber option which will make drizzle delete/overwrite an existing
51
static bool clobber= false;
52
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
53
ProtocolCounters *Protocol::mysql_unix_counters= new ProtocolCounters();
1953.2.5 by Andrew Hutchings
Make max-connections unique per-protocol
54
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
55
Protocol::~Protocol()
56
{
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
57
  fs::remove(_unix_socket_path);
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
58
}
59
60
in_port_t Protocol::getPort(void) const
61
{
1888 by Brian Aker
Merge in POTFILES changes.
62
  return 0;
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
63
}
64
65
static int init(drizzled::module::Context &context)
66
{  
67
  const module::option_map &vm= context.getOptions();
68
1945.1.4 by Monty Taylor
Fixes the issues with socket
69
  fs::path uds_path(vm["path"].as<fs::path>());
70
  if (not fs::exists(uds_path))
71
  {
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
72
    Protocol *listen_obj= new Protocol("mysql_unix_socket_protocol",
1945.1.4 by Monty Taylor
Fixes the issues with socket
73
                             true,
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
74
                             uds_path);
2131.7.1 by Andrew Hutchings
Add protocol counters table
75
    listen_obj->addCountersToTable();
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
76
    context.add(listen_obj);
1945.1.5 by Monty Taylor
zomg. I was passing in a reference to a temporary. Jeeze.
77
    context.registerVariable(new sys_var_const_string_val("path", fs::system_complete(uds_path).file_string()));
1945.1.7 by Monty Taylor
Added clobber option which will make drizzle delete/overwrite an existing
78
    context.registerVariable(new sys_var_bool_ptr_readonly("clobber", &clobber));
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
79
    context.registerVariable(new sys_var_uint32_t_ptr("max-connections", &Protocol::mysql_unix_counters->max_connections));
1945.1.4 by Monty Taylor
Fixes the issues with socket
80
  }
81
  else
82
  {
83
    cerr << uds_path << _(" exists already. Do you have another Drizzle or "
84
                          "MySQL running? Or perhaps the file is stale and "
85
                          "should be removed?") << std::endl;
1945.1.6 by Monty Taylor
Make it non-fatal.
86
    return 0;
1945.1.4 by Monty Taylor
Fixes the issues with socket
87
  }
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
88
89
  return 0;
90
}
91
92
bool Protocol::getFileDescriptors(std::vector<int> &fds)
93
{
94
  int unix_sock;
95
96
  if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
97
  {
98
    std::cerr << "Can't start server : UNIX Socket";
99
    return false;
100
  }
101
1945.1.1 by Brian Aker
We move the unix socket file aside, and then start up. Any clients already
102
  // In case we restart and find something in our way we move it aside and
103
  // then attempt to remove it.
1945.1.7 by Monty Taylor
Added clobber option which will make drizzle delete/overwrite an existing
104
  if (clobber)
1945.1.1 by Brian Aker
We move the unix socket file aside, and then start up. Any clients already
105
  {
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
106
    fs::path move_file(_unix_socket_path.file_string() + ".old");
107
    fs::rename(_unix_socket_path, move_file);
1945.1.4 by Monty Taylor
Fixes the issues with socket
108
    unlink(move_file.file_string().c_str());
1945.1.1 by Brian Aker
We move the unix socket file aside, and then start up. Any clients already
109
  }
110
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
111
112
  int arg= 1;
113
114
  (void) setsockopt(unix_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
115
  unlink(_unix_socket_path.file_string().c_str());
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
116
1945.1.8 by Monty Taylor
We were overrunning the buffer everywhere, but glibc on ubuntu was
117
  struct sockaddr_un servAddr;
118
  memset(&servAddr, 0, sizeof(servAddr));
119
120
  servAddr.sun_family= AF_UNIX;
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
121
  if (_unix_socket_path.file_string().size() > sizeof(servAddr.sun_path))
1945.1.8 by Monty Taylor
We were overrunning the buffer everywhere, but glibc on ubuntu was
122
  {
123
    std::cerr << "Unix Socket Path length too long. Must be under "
124
      << sizeof(servAddr.sun_path) << " bytes." << endl;
125
    return false;
126
  }
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
127
  memcpy(servAddr.sun_path, _unix_socket_path.file_string().c_str(), min(sizeof(servAddr.sun_path)-1,_unix_socket_path.file_string().size()));
1945.1.8 by Monty Taylor
We were overrunning the buffer everywhere, but glibc on ubuntu was
128
129
  socklen_t addrlen= sizeof(servAddr);
1891.1.1 by Monty Taylor
Fixed an issue that pops up when compiling with -std=c++0x turned on. Bind
130
  if (::bind(unix_sock, reinterpret_cast<sockaddr *>(&servAddr), addrlen) < 0)
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
131
  { 
1945.1.4 by Monty Taylor
Fixes the issues with socket
132
    std::cerr << "Can't start server : Bind on unix socket." << std::endl;
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
133
    std::cerr << "Do you already have another of drizzled or mysqld running on socket: " << _unix_socket_path << "?" << std::endl;
1945.1.4 by Monty Taylor
Fixes the issues with socket
134
    std::cerr << "Can't start server : UNIX Socket" << std::endl;
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
135
136
    return false;
137
  }
138
1945.1.4 by Monty Taylor
Fixes the issues with socket
139
  if (listen(unix_sock, (int) 1000) < 0)
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
140
  {
141
    std::cerr << "listen() on Unix socket failed with error " << errno << "\n";
142
  }
143
  else
144
  {
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
145
    std::cerr << "Listening on " << _unix_socket_path << "\n";
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
146
  }
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
147
  (void) unlink(_unix_socket_path.file_string().c_str());
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
148
149
  fds.push_back(unix_sock);
150
151
  return false;
152
}
153
1960.2.6 by Andrew Hutchings
Add ip address limitation for admin connections
154
plugin::Client *Protocol::getClient(int fd)
155
{
156
  int new_fd;
157
  new_fd= acceptTcp(fd);
158
  if (new_fd == -1)
159
    return NULL;
160
161
  return new ClientMySQLUnixSocketProtocol(new_fd, _using_mysql41_protocol, getCounters());
162
}
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
163
164
static void init_options(drizzled::module::option_context &context)
165
{
166
  context("path",
1945.1.4 by Monty Taylor
Fixes the issues with socket
167
          po::value<fs::path>()->default_value(DRIZZLE_UNIX_SOCKET_PATH),
2068.4.1 by Andrew Hutchings
Fix intl domain
168
          _("Path used for MySQL UNIX Socket Protocol."));
1945.1.7 by Monty Taylor
Added clobber option which will make drizzle delete/overwrite an existing
169
  context("clobber",
2068.4.1 by Andrew Hutchings
Fix intl domain
170
          _("Clobber socket file if one is there already."));
1953.2.3 by Andrew Hutchings
Add UNIX socket protocol variable
171
  context("max-connections",
1953.2.6 by Andrew Hutchings
Completely redo max-connections so it is independant per-protocol. Also make counters independant
172
          po::value<uint32_t>(&Protocol::mysql_unix_counters->max_connections)->default_value(1000),
2068.4.1 by Andrew Hutchings
Fix intl domain
173
          _("Maximum simultaneous connections."));
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
174
}
175
176
} /* namespace mysql_unix_socket_protocol */
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
177
} /* namespace drizzle_plugin */
1887.1.1 by Brian Aker
Adding uninux socket protocol for real.
178
1964.2.9 by Monty Taylor
All protocol stuff except for the buffer_length. WTF?
179
DRIZZLE_PLUGIN(drizzle_plugin::mysql_unix_socket_protocol::init, NULL, drizzle_plugin::mysql_unix_socket_protocol::init_options);