mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-15655: Add Linux abstract socket support
The functionality of the socket system variable is extended here such that a preciding '@' indicates that the socket will be an abstract socket. Thie socket name wil be the remainder of the name after the '@'. This is consistent with the approached used by systemd in socket activation. Thanks to Sergey Vojtovich: On OS X sockaddr_un is defined as: struct sockaddr_un { u_char sun_len; u_char sun_family; char sun_path[104]; }; There is a comment in man 7 unix (on linux): " On Linux, the above offsetof() expression equates to the same value as sizeof(sa_family_t), but some other implementations include other fields before sun_path, so the offsetof() expression more portably describes the size of the address structure. " As such, use the offsetof for Linux and use the previous sizeof(UNIXaddr) for non-unix platforms as that's what worked before and they don't support abstract sockets so there's no compatibility problem.. strace -fe trace=networking mysqld --skip-networking --socket @abc ... ... [pid 10578] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 22 [pid 10578] setsockopt(22, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 [pid 10578] bind(22, {sa_family=AF_UNIX, sun_path=@"abc"}, 6) = 0 [pid 10578] listen(22, 80) = 0 ... Version: '10.3.6-MariaDB-log' socket: '@abc' port: 0 Source distribution $ lsof -p 10578 mysqld 10578 dan 22u unix 0x00000000087e688c 0t0 4787815 @abc type=STREAM
This commit is contained in:
committed by
Sergey Vojtovich
parent
eaaf004cc1
commit
08098366d2
@ -6010,9 +6010,10 @@ void do_connect(struct st_command *command)
|
||||
{
|
||||
/*
|
||||
If the socket is specified just as a name without path
|
||||
or an abstract socket indicator ('@'), then
|
||||
append tmpdir in front
|
||||
*/
|
||||
if (*ds_sock.str != FN_LIBCHAR)
|
||||
if (*ds_sock.str != FN_LIBCHAR && *ds_sock.str != '@')
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
fn_format(buff, ds_sock.str, TMPDIR, "", 0);
|
||||
|
9
mysql-test/main/connect-abstract.cnf
Normal file
9
mysql-test/main/connect-abstract.cnf
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
!include include/default_my.cnf
|
||||
|
||||
[mysqld.1]
|
||||
socket= @ENV.ABSTRACT_SOCKET
|
||||
|
||||
# Using @OPT.port here for uniqueness
|
||||
[ENV]
|
||||
ABSTRACT_SOCKET= @mtr-test-abstract-socket-@OPT.port
|
5
mysql-test/main/connect-abstract.result
Normal file
5
mysql-test/main/connect-abstract.result
Normal file
@ -0,0 +1,5 @@
|
||||
connect con1,localhost,root,,test,,$ABSTRACT_SOCKET;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
disconnect con1;
|
6
mysql-test/main/connect-abstract.test
Normal file
6
mysql-test/main/connect-abstract.test
Normal file
@ -0,0 +1,6 @@
|
||||
--source include/linux.inc
|
||||
--source include/not_embedded.inc
|
||||
|
||||
connect(con1,localhost,root,,test,,$ABSTRACT_SOCKET);
|
||||
select 1;
|
||||
disconnect con1;
|
@ -2784,9 +2784,10 @@ static void network_init(void)
|
||||
*/
|
||||
if (mysqld_unix_port[0] && !opt_bootstrap)
|
||||
{
|
||||
size_t port_len;
|
||||
DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
|
||||
|
||||
if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
|
||||
if ((port_len=strlen(mysqld_unix_port)) > (sizeof(UNIXaddr.sun_path) - 1))
|
||||
{
|
||||
sql_print_error("The socket file path is too long (> %u): %s",
|
||||
(uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
|
||||
@ -2804,14 +2805,25 @@ static void network_init(void)
|
||||
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
|
||||
UNIXaddr.sun_family = AF_UNIX;
|
||||
strmov(UNIXaddr.sun_path, mysqld_unix_port);
|
||||
(void) unlink(mysqld_unix_port);
|
||||
#if defined(__linux__)
|
||||
/* Abstract socket */
|
||||
if (mysqld_unix_port[0] == '@')
|
||||
UNIXaddr.sun_path[0]= '\0';
|
||||
else
|
||||
#endif
|
||||
(void) unlink(mysqld_unix_port);
|
||||
arg= 1;
|
||||
(void) mysql_socket_setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,
|
||||
(char*)&arg, sizeof(arg));
|
||||
umask(0);
|
||||
if (mysql_socket_bind(unix_sock,
|
||||
reinterpret_cast<struct sockaddr *>(&UNIXaddr),
|
||||
sizeof(UNIXaddr)) < 0)
|
||||
#if defined(__linux__)
|
||||
offsetof(struct sockaddr_un, sun_path) + port_len
|
||||
#else
|
||||
sizeof(UNIXaddr)
|
||||
#endif
|
||||
) < 0)
|
||||
{
|
||||
sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
|
||||
sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
|
||||
|
Reference in New Issue
Block a user