diff --git a/config.h.cmake b/config.h.cmake
index 6a05277..a269a65 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -118,6 +118,7 @@
 #cmakedefine HAVE_LIBCRYPT 1
 #cmakedefine HAVE_LIBMTMALLOC 1
 #cmakedefine HAVE_LIBWRAP 1
+#cmakedefine HAVE_SYSTEMD 1
 /* Does "struct timespec" have a "sec" and "nsec" field? */
 #cmakedefine HAVE_TIMESPEC_TS_SEC 1
 
diff --git a/configure.cmake b/configure.cmake
index d16a82a..0857f85 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -171,6 +171,22 @@ IF(UNIX)
       SET(LIBWRAP "wrap")
     ENDIF()
   ENDIF()
+
+  OPTION(WITH_SYSTEMD "Compile with systemd notification on ready" ON)
+  IF(WITH_SYSTEMD)
+    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} systemd-daemon)
+    CHECK_C_SOURCE_COMPILES(
+    "
+    #include <systemd/sd-daemon.h>
+    int main()
+    {
+      sd_listen_fds(0);
+    }"
+    HAVE_SYSTEMD)
+    IF(HAVE_SYSTEMD)
+      SET(LIBSYSTEMD "systemd-daemon")
+    ENDIF()
+  ENDIF()
 ENDIF()
 
 #
@@ -261,6 +277,9 @@ CHECK_INCLUDE_FILES (wchar.h HAVE_WCHAR_H)
 CHECK_INCLUDE_FILES (wctype.h HAVE_WCTYPE_H)
 CHECK_INCLUDE_FILES (sys/sockio.h HAVE_SYS_SOCKIO_H)
 CHECK_INCLUDE_FILES (sys/utsname.h HAVE_SYS_UTSNAME_H)
+IF(WITH_SYSTEMD)
+CHECK_INCLUDE_FILES (systemd/sd-daemon.h HAVE_SYSTEMD_SD_DAEMON_H)
+ENDIF()
 
 IF(BFD_H_EXISTS)
   IF(NOT_FOR_DISTRIBUTION)
@@ -468,6 +487,12 @@ IF(HAVE_SYS_EVENT_H)
 CHECK_FUNCTION_EXISTS (kqueue HAVE_KQUEUE)
 ENDIF()
 
+IF(WITH_SYSTEMD)
+CHECK_FUNCTION_EXISTS (sd_listen_fds HAVE_SYSTEMD_SD_DAEMON_H)
+CHECK_FUNCTION_EXISTS (sd_notify HAVE_SYSTEMD_SD_DAEMON_H)
+CHECK_FUNCTION_EXISTS (sd_notifyf HAVE_SYSTEMD_SD_DAEMON_H)
+ENDIF()
+
 #--------------------------------------------------------------------
 # Support for WL#2373 (Use cycle counter for timing)
 #--------------------------------------------------------------------
diff --git a/debian/dist/Debian/control b/debian/dist/Debian/control
index ffede25..45a35fe 100644
--- a/debian/dist/Debian/control
+++ b/debian/dist/Debian/control
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: MariaDB Developers <maria-developers@lists.launchpad.net>
 XSBC-Original-Maintainer: Maria Developers <maria-developers@lists.launchpad.net>
 Uploaders: MariaDB Developers <maria-developers@lists.launchpad.net>
-Build-Depends: libtool (>= 1.4.2-7), procps | hurd,  debhelper, file (>= 3.28), libncurses5-dev (>= 5.0-6), perl (>= 5.6.0), libwrap0-dev (>= 7.6-8.3), zlib1g-dev (>= 1:1.1.3-5), ${LIBREADLINE_DEV}, libssl-dev, libpam0g-dev, psmisc, po-debconf, chrpath, automake1.9, doxygen, texlive-latex-base, ghostscript | gs-gpl, dpatch, gawk, bison, lsb-release, hardening-wrapper, ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0)
+Build-Depends: libtool (>= 1.4.2-7), procps | hurd,  debhelper, file (>= 3.28), libncurses5-dev (>= 5.0-6), perl (>= 5.6.0), libwrap0-dev (>= 7.6-8.3), zlib1g-dev (>= 1:1.1.3-5), ${LIBREADLINE_DEV}, libssl-dev, libpam0g-dev, psmisc, po-debconf, chrpath, automake1.9, doxygen, texlive-latex-base, ghostscript | gs-gpl, dpatch, gawk, bison, lsb-release, hardening-wrapper, ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0), libsystemd-daemon-dev, dh-systemd
 Standards-Version: 3.8.3
 Homepage: http://mariadb.org/
 Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/10.0/files
@@ -147,7 +147,7 @@ Description: MariaDB database client binaries
 
 Package: mariadb-server-core-10.0
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libmariadbclient18 (>= ${binary:Version})
+Depends: ${shlibs:Depends}, ${misc:Depends}, libmariadbclient18 (>= ${binary:Version}), libsystemd-daemon0
 Provides: mysql-server-core, mysql-server-core-5.1, mysql-server-core-5.5
 Conflicts: mariadb-server-5.1 (<< 5.1.60),
     mariadb-server-5.2 (<< 5.2.10),
diff --git a/debian/dist/Debian/rules b/debian/dist/Debian/rules
index 2122a3c..5dba5d1 100755
--- a/debian/dist/Debian/rules
+++ b/debian/dist/Debian/rules
@@ -216,7 +216,9 @@ binary-indep: build install
 	dh_installexamples -i
 	dh_installmenu -i
 	dh_installlogrotate -i
+	dh_systemd_enable -i support-files/mariadb.service support-files/mariadb.socket
 	dh_installinit -i
+	dh_systemd_start -i --restart-after-upgrade mariadb.socket
 	dh_installcron -i 
 	dh_installman -i
 	dh_installinfo -i
diff --git a/debian/dist/Ubuntu/control b/debian/dist/Ubuntu/control
index 02ace29..65d3907 100644
--- a/debian/dist/Ubuntu/control
+++ b/debian/dist/Ubuntu/control
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: MariaDB Developers <maria-developers@lists.launchpad.net>
 XSBC-Original-Maintainer: Maria Developers <maria-developers@lists.launchpad.net>
 Uploaders: MariaDB Developers <maria-developers@lists.launchpad.net>
-Build-Depends: libtool (>= 1.4.2-7), procps | hurd,  debhelper, file (>= 3.28), libncurses5-dev (>= 5.0-6), perl (>= 5.6.0), libwrap0-dev (>= 7.6-8.3), zlib1g-dev (>= 1:1.1.3-5), ${LIBREADLINE_DEV}, libssl-dev, libpam0g-dev, psmisc, po-debconf, chrpath, automake1.9, doxygen, texlive-latex-base, ghostscript | gs-gpl, dpatch, gawk, bison, lsb-release, hardening-wrapper, ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0)
+Build-Depends: libtool (>= 1.4.2-7), procps | hurd,  debhelper, file (>= 3.28), libncurses5-dev (>= 5.0-6), perl (>= 5.6.0), libwrap0-dev (>= 7.6-8.3), zlib1g-dev (>= 1:1.1.3-5), ${LIBREADLINE_DEV}, libssl-dev, libpam0g-dev, psmisc, po-debconf, chrpath, automake1.9, doxygen, texlive-latex-base, ghostscript | gs-gpl, dpatch, gawk, bison, lsb-release, hardening-wrapper, ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0), libsystemd-daemon-dev, dh-systemd
 Standards-Version: 3.8.2
 Homepage: http://mariadb.org/
 Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/10.0/files
@@ -148,6 +148,7 @@ Description: MariaDB database client binaries
 Package: mariadb-server-core-10.0
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, libmariadbclient18 (>= ${binary:Version})
+    libsystemd-daemon0
 Provides: mysql-server-core, mysql-server-core-5.1, mysql-server-core-5.5
 Conflicts: mysql-server-5.0,
     mysql-server-core-5.0, mysql-server-core-5.1, mysql-server-core-5.5,
diff --git a/debian/dist/Ubuntu/rules b/debian/dist/Ubuntu/rules
index 8d99312..6cd2a15 100755
--- a/debian/dist/Ubuntu/rules
+++ b/debian/dist/Ubuntu/rules
@@ -221,7 +221,9 @@ binary-indep: build install
 	dh_installexamples -i
 	dh_installmenu -i
 	dh_installlogrotate -i
+	dh_systemd_enable -i support-files/mariadb.service support-files/mariadb.socket
 	dh_installinit -i
+	dh_systemd_start -i --restart-after-upgrade mariadb.socket
 	dh_installcron -i 
 	dh_installman -i
 	dh_installinfo -i
diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h
index e1d5653..57658db 100644
--- a/include/mysql/psi/mysql_socket.h
+++ b/include/mysql/psi/mysql_socket.h
@@ -149,7 +149,7 @@ MYSQL_SOCKET socket __attribute__ ((unused))
 /**
   MYSQL_SOCKET helper. Get socket descriptor.
   @param mysql_socket Instrumented socket
-  @sa mysql_socket_setfd
+  @sa mysql_socket_getfd
 */
 static inline my_socket
 mysql_socket_getfd(MYSQL_SOCKET mysql_socket)
@@ -161,7 +161,7 @@ MYSQL_SOCKET socket __attribute__ ((unused))
   MYSQL_SOCKET helper. Set socket descriptor.
   @param mysql_socket Instrumented socket
   @param fd Socket descriptor
-  @sa mysql_socket_getfd
+  @sa mysql_socket_setfd
 */
 static inline void
 mysql_socket_setfd(MYSQL_SOCKET *mysql_socket, my_socket fd)
@@ -282,6 +282,22 @@ MYSQL_SOCKET socket __attribute__ ((unused))
 #endif /* HAVE_PSI_SOCKET_INTERFACE */
 
 /**
+  @def mysql_socket_fd(K, F)
+  Create a socket.
+  @c mysql_socket_socket is a replacement for @c socket.
+  @param K PSI_socket_key for this instrumented socket
+  @param F File descriptor
+*/
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+  #define mysql_socket_fd(K, F) \
+    inline_mysql_socket_fd(K, F)
+#else
+  #define mysql_socket_fd(K, F) \
+    inline_mysql_socket_fd(F)
+#endif
+
+/**
   @def mysql_socket_socket(K, D, T, P)
   Create a socket.
   @c mysql_socket_socket is a replacement for @c socket.
@@ -542,6 +558,28 @@ static inline void inline_mysql_socket_register(
 }
 #endif
 
+/** mysql_socket_fd */
+
+static inline MYSQL_SOCKET
+inline_mysql_socket_fd
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+  PSI_socket_key key,
+#endif
+  int fd)
+{
+  MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET;
+  mysql_socket.fd= fd;
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+  if (likely(mysql_socket.fd != INVALID_SOCKET))
+  {
+    mysql_socket.m_psi= PSI_SOCKET_CALL(init_socket)
+      (key, (const my_socket*)&mysql_socket.fd, NULL, 0);
+  }
+#endif
+  return mysql_socket;
+}
+
 /** mysql_socket_socket */
 
 static inline MYSQL_SOCKET
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index c59ae3b..047de76 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -119,7 +119,7 @@ DTRACE_INSTRUMENT(sql)
 TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} 
   mysys mysys_ssl dbug strings vio pcre ${LIBJEMALLOC}
   ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT}
-  ${SSL_LIBRARIES})
+  ${LIBSYSTEMD} ${SSL_LIBRARIES})
 
 IF(WIN32)
   SET(MYSQLD_SOURCE main.cc nt_servc.cc nt_servc.h message.rc)
@@ -179,6 +179,13 @@ IF(INTERFACE_LIBS)
   "${INTERFACE_LIBS}")
 ENDIF()
 
+IF(WITH_SYSTEMD)
+# Used for notify systemd's feature
+IF(HAVE_SYSTEMD_SD_DAEMON_H)
+  TARGET_LINK_LIBRARIES(mysqld systemd-daemon)
+ENDIF()
+ENDIF()
+
 # On Solaris, some extra effort is required in order to get dtrace probes
 # from static libraries
 DTRACE_INSTRUMENT_STATIC_LIBS(mysqld 
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 760ae6f..959adf1 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -105,6 +105,24 @@
 #include <poll.h>
 #endif
 
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#include <sys/un.h>
+union sockaddr_union {
+  struct sockaddr sa;
+  struct sockaddr_in in;
+  struct sockaddr_in6 in6;
+#ifdef HAVE_SYS_UN_H
+  struct sockaddr_un un;
+#endif
+  struct sockaddr_storage ss;
+};
+#define MAX_LISTEN_SOCKETS 10
+static int systemd_listen_cnt=0;
+#else /* HAVE_SYSTEMD */
+#define MAX_LISTEN_SOCKETS 3
+#endif
+
 #define mysqld_charset &my_charset_latin1
 
 /* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
@@ -1840,6 +1858,9 @@ static void __cdecl kill_server(int sig_ptr)
   else
     sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
 
+#ifdef HAVE_SYSTEMD
+  sd_notify(0, "STOPPING=1");
+#endif
 #ifdef HAVE_SMEM
   /*
     Send event to smem_event_connect_request for aborting
@@ -2517,8 +2538,13 @@ static void network_init(void)
   struct sockaddr_un	UNIXaddr;
   int	arg;
 #endif
+  int systemd_n = 0;
   DBUG_ENTER("network_init");
 
+#ifdef HAVE_SYSTEMD
+  systemd_n = sd_listen_fds(0);
+  DBUG_PRINT("general",("Systemd listen_fds is %d",systemd_n));
+#endif
   if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
     unireg_abort(1);			/* purecov: inspected */
 
@@ -2532,7 +2558,7 @@ static void network_init(void)
   if (!opt_disable_networking)
     DBUG_ASSERT(report_port != 0);
 #endif
-  if (!opt_disable_networking && !opt_bootstrap)
+  if (!opt_disable_networking && !opt_bootstrap && systemd_n==0)
   {
     if (mysqld_port)
       base_ip_sock= activate_tcp_port(mysqld_port);
@@ -2592,7 +2618,7 @@ static void network_init(void)
   /*
   ** Create the UNIX socket
   */
-  if (mysqld_unix_port[0] && !opt_bootstrap)
+  if (mysqld_unix_port[0] && !opt_bootstrap && systemd_n==0)
   {
     DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
 
@@ -6057,6 +6083,14 @@ inline void kill_broken_server()
 
 #ifndef EMBEDDED_LIBRARY
 
+#ifdef HAVE_SYSTEMD
+static MYSQL_SOCKET systemd_sock[MAX_LISTEN_SOCKETS];
+static PSI_socket_key all_systemd_key[MAX_LISTEN_SOCKETS];
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+static PSI_socket_info all_systemd_sockets[MAX_LISTEN_SOCKETS+1];
+#endif
+#endif
+
 void handle_connections_sockets()
 {
   MYSQL_SOCKET sock= mysql_socket_invalid();
@@ -6070,38 +6104,198 @@ void handle_connections_sockets()
   int flags=0,retval;
   st_vio *vio_tmp;
   bool is_unix_sock;
-#ifdef HAVE_POLL
+#ifdef HAVE_SYSTEMD
+  int systemd_n, systemd_fd;
+  union sockaddr_union socketpeer;
+  socklen_t socketpeer_len;
+  char const *family;
+#ifndef HAVE_POLL
+  int  pfs_flags[MAX_LISTEN_SOCKETS];
+  // systemd wants these too
+  MYSQL_SOCKET  pfs_fds[MAX_LISTEN_SOCKETS]; // used for non-polling interfaces
+#endif
+#endif // HAVE_SYSTEMD
   int socket_count= 0;
-  struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
-  MYSQL_SOCKET  pfs_fds[3]; // for performance schema
-#define setup_fds(X)                    \
+  short fd_type[MAX_LISTEN_SOCKETS];
+#ifdef HAVE_POLL
+  struct pollfd fds[MAX_LISTEN_SOCKETS]; // for ip_sock, extra_ip_sock and unix_sock (could be any order for systemd)
+  MYSQL_SOCKET  pfs_fds[MAX_LISTEN_SOCKETS]; // for performance schema
+#define setup_fds(X,T)                    \
     mysql_socket_set_thread_owner(X);             \
     pfs_fds[socket_count]= (X);                   \
     fds[socket_count].fd= mysql_socket_getfd(X);  \
     fds[socket_count].events= POLLIN;   \
+    fd_type[socket_count]= T; \
     socket_count++
 #else
-#define setup_fds(X)    FD_SET(mysql_socket_getfd(X),&clientFDs)
+#ifdef HAVE_SYSTEMD
+#define setup_fds(X,T)    FD_SET(mysql_socket_getfd(X),&clientFDs); \
+  pfs_fds[socket_count]= (X);                   \
+  fd_type[socket_count]= T; \
+  socket_count++
+#else
+#define setup_fds(X,T)    FD_SET(mysql_socket_getfd(X),&clientFDs); \
+    fd_type[socket_count]= T; \
+    socket_count++
+#endif // HAVE_SYSTEMD
   fd_set readFDs,clientFDs;
   FD_ZERO(&clientFDs);
 #endif
 
   DBUG_ENTER("handle_connections_sockets");
 
-  if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
+#ifdef HAVE_SYSTEMD
+  systemd_n = sd_listen_fds(1);
+  if (systemd_n < 0)
   {
-    setup_fds(base_ip_sock);
-    ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0);
+    my_error(ER_SYSTEMD_LISTEN_FDS, MYF(0), 0, -systemd_n);
   }
-  if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
+  else
+  if (systemd_n > 0)
   {
-    setup_fds(extra_ip_sock);
-    extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0);
+    systemd_fd = SD_LISTEN_FDS_START;
+    while (systemd_n-- && systemd_listen_cnt < MAX_LISTEN_SOCKETS)
+    {
+      /* grab socket info */
+      socketpeer_len = sizeof(socketpeer);
+      if (getsockname(systemd_fd, (struct sockaddr *) &socketpeer,
+          &socketpeer_len) < 0)
+      {
+        sql_print_error("getsockname for fd %d failed (errno= %d).",
+                        systemd_fd, errno);
+        sd_notifyf(0, "ERRNO=%d", errno);
+        systemd_fd++;
+        continue;
+      }
+      if (socketpeer_len >=sizeof(socketpeer))
+      {
+        sql_print_error("getsockname for fd %d unsufficient space", systemd_fd);
+        sd_notifyf(0, "ERRNO=%d", EINVAL);
+        systemd_fd++;
+        continue;
+      }
+
+      /* Get listening sockets from systemd library calls
+         and set them up the same as other sockets. */
+#ifdef HAVE_SYS_UN_H
+      if (socketpeer.ss.ss_family == AF_UNIX)
+      {
+        sql_print_information("Listening on systemd unix socket for %s.",
+                              socketpeer.un.sun_path);
+        family= "systemd_unix_socket";
+      }
+      else
+#endif
+      if (socketpeer.ss.ss_family == AF_INET ||
+          socketpeer.ss.ss_family == AF_INET6)
+      {
+        sql_print_information("Listening on systemd family %s port %d.",
+              socketpeer.ss.ss_family == AF_INET ? "IPv4" : "IPv6",
+              ntohs(socketpeer.ss.ss_family == AF_INET ?
+                       socketpeer.in.sin_port : socketpeer.in6.sin6_port));
+        family= socketpeer.ss.ss_family == AF_INET ? "systemd_IPv4" :
+                                                     "systemd_IPv6";
+      }
+      else
+      {
+        sql_print_error("Unrecognised socket family: %d.",
+                         socketpeer.ss.ss_family);
+        systemd_fd++;
+        continue;
+      }
+      systemd_sock[systemd_listen_cnt]= mysql_socket_fd(all_systemd_key[systemd_listen_cnt], systemd_fd);
+      mysql_socket_set_thread_owner(systemd_sock[systemd_listen_cnt]);
+#ifndef HAVE_POLL
+      pfs_flags[socket_count]=
+#endif
+          fcntl(systemd_fd, F_GETFL, 0);
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+      all_systemd_sockets[systemd_listen_cnt]= (PSI_socket_info) { &all_systemd_key[systemd_listen_cnt], family, PSI_FLAG_GLOBAL };
+#endif
+      setup_fds(systemd_sock[systemd_listen_cnt], socketpeer.ss.ss_family);
+      systemd_fd++;
+      systemd_listen_cnt++;
+    }
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+    all_systemd_sockets[systemd_listen_cnt]= (PSI_socket_info) { &key_socket_client_connection, "client_connection", 0};
+    mysql_socket_register("sql", all_systemd_sockets, systemd_listen_cnt + 1);
+#endif
+    /* print out unused ones */
+    while (systemd_n-- > 0)
+    {
+      socketpeer_len = sizeof(socketpeer);
+      if (getsockname(systemd_fd, (struct sockaddr *) &socketpeer,
+          &socketpeer_len) < 0)
+      {
+        sql_print_error("getsockname for fd %d failed (errno= %d).",
+                        systemd_fd, errno);
+        sd_notifyf(0, "ERRNO=%d", errno);
+        systemd_fd++;
+        continue;
+      }
+      if (socketpeer_len >=sizeof(socketpeer))
+      {
+        sql_print_error("getsockname for fd %d unsufficient space", systemd_fd);
+        sd_notifyf(0, "ERRNO=%d", EINVAL);
+        systemd_fd++;
+        continue;
+      }
+#ifdef HAVE_SYS_UN_H
+      if (socketpeer.ss.ss_family == AF_UNIX)
+      {
+        sql_print_error("Exceeded %d sockets NOT listening on systemd unix socket for %s.",
+                         MAX_LISTEN_SOCKETS, socketpeer.un.sun_path);
+      }
+      else
+#endif
+      if (socketpeer.ss.ss_family == AF_INET ||
+          socketpeer.ss.ss_family == AF_INET6)
+      {
+        sql_print_error("Exceeded %d sockets Not listening on systemd family %s port %d.",
+              MAX_LISTEN_SOCKETS,
+              socketpeer.ss.ss_family == AF_INET ? "IPv4" : "IPv6",
+              ntohs(socketpeer.ss.ss_family == AF_INET ?
+                       socketpeer.in.sin_port : socketpeer.in6.sin6_port));
+      }
+      systemd_fd++;
+    }
   }
+  else
+  {
+#endif /* HAVE_SYSTEMD */
+    if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
+    {
+      setup_fds(base_ip_sock, AF_INET);
+      ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0);
+    }
+    if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
+    {
+      setup_fds(extra_ip_sock, AF_INET);
+      extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0);
+    }
 #ifdef HAVE_SYS_UN_H
-  setup_fds(unix_sock);
-  socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0);
+    setup_fds(unix_sock, AF_UNIX);
+    socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0);
+#endif
+
+#ifdef HAVE_SYSTEMD
+  }
+
+#ifdef HAVE_POLL
+  if (systemd_listen_cnt == 0)
+  {
+    sd_notify(0, "STATUS=No listening sockets");
+    abort_loop=1;
+  }
+  else
+  {
 #endif
+    sd_notify(0, "READY=1\n"
+               "STATUS=Taking your SQL requests now...");
+#ifdef HAVE_POLL
+  }
+#endif /* HAVE_POLL */
+#endif /* HAVE_SYSTEMD */
 
   DBUG_PRINT("general",("Waiting for connections."));
   MAYBE_BROKEN_SYSCALL;
@@ -6145,6 +6339,7 @@ void handle_connections_sockets()
       {
         sock= pfs_fds[i];
         flags= fcntl(mysql_socket_getfd(sock), F_GETFL, 0);
+        is_unix_sock= fd_type[i] == AF_UNIX;
         break;
       }
     }
@@ -6153,18 +6348,39 @@ void handle_connections_sockets()
     {
       sock=  base_ip_sock;
       flags= ip_flags;
+      is_unix_sock= FALSE;
     }
     else
     if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
     {
       sock=  extra_ip_sock;
       flags= extra_ip_flags;
+      is_unix_sock= FALSE;
     }
+#ifdef HAVE_SYS_UN_H
     else
+    if (FD_ISSET(mysql_socket_getfd(unix_sock),&readFDs))
     {
       sock = unix_sock;
       flags= socket_flags;
+      is_unix_sock= TRUE;
+    }
+#endif
+#ifdef HAVE_SYSTEMD
+    else
+    {
+      for (int i= 0; i < socket_count; ++i)
+      {
+        if (FD_ISSET(mysql_socket_getfd(pfs_fds[i]),&readFDs))
+        {
+          sock=  pfs_fds[i];
+          flags= pfs_flags[i];
+          is_unix_sock= fd_type[i] == AF_UNIX;
+          break;
+        }
+      }
     }
+#endif // HAVE_SYSTEMD
 #endif // HAVE_POLL
 
 #if !defined(NO_FCNTL_NONBLOCK)
@@ -6276,9 +6492,6 @@ void handle_connections_sockets()
     /* Set to get io buffers to be part of THD */
     set_current_thd(thd);
 
-    is_unix_sock= (mysql_socket_getfd(sock) ==
-                   mysql_socket_getfd(unix_sock));
-
     if (!(vio_tmp=
           mysql_socket_vio_new(new_sock,
                                is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
@@ -6315,6 +6528,9 @@ void handle_connections_sockets()
     create_new_thread(thd);
     set_current_thd(0);
   }
+#ifdef HAVE_SYSTEMD
+  sd_notify(0, "STOPPING=1");
+#endif
   DBUG_VOID_RETURN;
 }
 
@@ -9660,9 +9876,17 @@ void init_server_psi_keys(void)
 
   count= array_elements(all_server_stages);
   mysql_stage_register(category, all_server_stages, count);
-
-  count= array_elements(all_server_sockets);
-  mysql_socket_register(category, all_server_sockets, count);
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+#ifdef HAVE_SYSTEMD
+  if (systemd_listen_cnt == 0)
+  {
+#endif
+    count= array_elements(all_server_sockets);
+    mysql_socket_register(category, all_server_sockets, count);
+#ifdef HAVE_SYSTEMD
+  }
+#endif
+#endif
 
 #ifdef HAVE_PSI_STATEMENT_INTERFACE
   init_sql_statement_info();
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 4980ba0..aa62bdb 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7111,3 +7111,5 @@ ER_SLAVE_SKIP_NOT_IN_GTID
 	eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position."
 ER_TABLE_DEFINITION_TOO_BIG
         eng "The definition for table %`s is too big"
+ER_SYSTEMD_LISTEN_FDS
+        eng "Systemd error for configured ListenStream"
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 467f817..50769e5 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -27,6 +27,9 @@
 
 #include <stdarg.h> /* va_* */
 #include <string.h> /* strerror() */
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 #include "buf0buf.h" /* buf_pool_mutex_enter(), srv_buf_pool_instances */
 #include "buf0dump.h"
@@ -198,6 +201,10 @@ The dump filename can be specified by (relative to srv_data_home):
 
 	buf_dump_status(STATUS_NOTICE, "Dumping buffer pool(s) to %s",
 			full_filename);
+#ifdef HAVE_SYSTEMD
+	sd_notifyf(0, "STATUS=Dumping buffer pool(s) to %s", full_filename);
+#endif
+
 
 	f = fopen(tmp_filename, "w");
 	if (f == NULL) {
@@ -322,6 +329,9 @@ The dump filename can be specified by (relative to srv_data_home):
 
 	buf_dump_status(STATUS_NOTICE,
 			"Buffer pool(s) dump completed at %s", now);
+#ifdef HAVE_SYSTEMD
+	sd_notifyf(0, "STATUS=Buffer pool(s) dump completed at %s", full_filename);
+#endif
 }
 
 /*****************************************************************//**
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 4fe9620..820722c 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -29,6 +29,10 @@
 #include <stdio.h>                              // Solaris/x86 header file bug
 
 #include <vector>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #include "log0recv.h"
 
 #ifdef UNIV_NONINL
@@ -1849,6 +1853,7 @@ static __attribute__((nonnull, warn_unused_result))
 	recv_addr_t* recv_addr;
 	ulint	i;
 	ibool	has_printed	= FALSE;
+	ulong progress;
 	mtr_t	mtr;
 loop:
 	mutex_enter(&(recv_sys->mutex));
@@ -1918,14 +1923,17 @@ static __attribute__((nonnull, warn_unused_result))
 			}
 		}
 
+		progress=(ulong) (i * 100) / hash_get_n_cells(recv_sys->addr_hash);
 		if (has_printed
-		    && (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
-		    != ((i + 1) * 100)
-		    / hash_get_n_cells(recv_sys->addr_hash)) {
+		    && progress  != ((i + 1) * 100) 
+                        / hash_get_n_cells(recv_sys->addr_hash)) {
+
+			fprintf(stderr, "%lu ", progress);
+#ifdef HAVE_SYSTEMD
+			sd_notifyf(0, "STATUS=Applying batch of log records for Innodb: "
+                    "Progress %lu", progress);
+#endif
 
-			fprintf(stderr, "%lu ", (ulong)
-				((i * 100)
-				 / hash_get_n_cells(recv_sys->addr_hash)));
 		}
 	}
 
@@ -1987,6 +1995,9 @@ static __attribute__((nonnull, warn_unused_result))
 
 	if (has_printed) {
 		fprintf(stderr, "InnoDB: Apply batch completed\n");
+#ifdef HAVE_SYSTEMD
+		sd_notify(0, "STATUS=InnoDB: Apply batch completed");
+#endif
 	}
 
 	mutex_exit(&(recv_sys->mutex));
@@ -2134,8 +2145,15 @@ static __attribute__((nonnull, warn_unused_result))
 			fprintf(stderr, "%lu ",
 				(ulong) ((100 * i) / n_hash_cells));
 			fflush(stderr);
+#ifdef HAVE_SYSTEMD
+			sd_notifyf(0, "STATUS=Applying batch of log records for backup Innodb: "
+                    "Progress %lu", (ulong) (100 * i) / n_hash_cells);
+#endif
 		}
 	}
+#ifdef HAVE_SYSTEMD
+	sd_notify(0, "STATUS=InnoDB: Apply batch for backup completed");
+#endif
 
 	recv_sys_empty_hash();
 }
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index 090e8ca..0c45bf9 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -27,6 +27,9 @@
 
 #include <stdarg.h> /* va_* */
 #include <string.h> /* strerror() */
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 #include "buf0buf.h" /* srv_buf_pool_instances */
 #include "buf0dump.h"
@@ -198,6 +201,10 @@ The dump filename can be specified by (relative to srv_data_home):
 
 	buf_dump_status(STATUS_NOTICE, "Dumping buffer pool(s) to %s",
 			full_filename);
+#ifdef HAVE_SYSTEMD
+	sd_notifyf(0, "STATUS=Dumping buffer pool(s) to %s", full_filename);
+#endif
+
 
 	f = fopen(tmp_filename, "w");
 	if (f == NULL) {
@@ -322,6 +329,9 @@ The dump filename can be specified by (relative to srv_data_home):
 
 	buf_dump_status(STATUS_NOTICE,
 			"Buffer pool(s) dump completed at %s", now);
+#ifdef HAVE_SYSTEMD
+	sd_notifyf(0, "STATUS=Buffer pool(s) dump completed at %s", full_filename);
+#endif
 }
 
 /*****************************************************************//**
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index 3e0ec3d..ea5d47c 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -29,6 +29,10 @@
 #include <stdio.h>                              // Solaris/x86 header file bug
 
 #include <vector>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #include "log0recv.h"
 
 #ifdef UNIV_NONINL
@@ -1920,6 +1924,7 @@ static __attribute__((nonnull, warn_unused_result))
 	recv_addr_t* recv_addr;
 	ulint	i;
 	ibool	has_printed	= FALSE;
+	ulong progress;
 	mtr_t	mtr;
 loop:
 	mutex_enter(&(recv_sys->mutex));
@@ -1989,14 +1994,17 @@ static __attribute__((nonnull, warn_unused_result))
 			}
 		}
 
+		progress=(ulong) (i * 100) / hash_get_n_cells(recv_sys->addr_hash);
 		if (has_printed
-		    && (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
-		    != ((i + 1) * 100)
-		    / hash_get_n_cells(recv_sys->addr_hash)) {
+		    && progress  != ((i + 1) * 100) 
+                        / hash_get_n_cells(recv_sys->addr_hash)) {
+
+			fprintf(stderr, "%lu ", progress);
+#ifdef HAVE_SYSTEMD
+			sd_notifyf(0, "STATUS=Applying batch of log records for Innodb: "
+                    "Progress %lu", progress);
+#endif
 
-			fprintf(stderr, "%lu ", (ulong)
-				((i * 100)
-				 / hash_get_n_cells(recv_sys->addr_hash)));
 		}
 	}
 
@@ -2058,6 +2066,9 @@ static __attribute__((nonnull, warn_unused_result))
 
 	if (has_printed) {
 		fprintf(stderr, "InnoDB: Apply batch completed\n");
+#ifdef HAVE_SYSTEMD
+		sd_notify(0, "STATUS=InnoDB: Apply batch completed");
+#endif
 	}
 
 	mutex_exit(&(recv_sys->mutex));
@@ -2205,8 +2216,15 @@ static __attribute__((nonnull, warn_unused_result))
 			fprintf(stderr, "%lu ",
 				(ulong) ((100 * i) / n_hash_cells));
 			fflush(stderr);
+#ifdef HAVE_SYSTEMD
+			sd_notifyf(0, "STATUS=Applying batch of log records for backup Innodb: "
+                    "Progress %lu", (ulong) (100 * i) / n_hash_cells);
+#endif
 		}
 	}
+#ifdef HAVE_SYSTEMD
+	sd_notify(0, "STATUS=InnoDB: Apply batch for backup completed");
+#endif
 
 	recv_sys_empty_hash();
 }
diff --git a/support-files/mariadb-socket-convert b/support-files/mariadb-socket-convert
new file mode 100755
index 0000000..7e62391
--- /dev/null
+++ b/support-files/mariadb-socket-convert
@@ -0,0 +1,150 @@
+#! /bin/bash
+#
+# Used to generate a mariadb.socket file based on the curent mysql/maridb settings
+#
+# This is to assist distro maintainers in migrating to systemd socket activation from 
+# a user system with networking settings somewhere in the my.cnf files.
+#
+# Redirect output to user directory like /etc/systemd/system/mariadb.socket.d/migrated-from-my.cnf-settings.conf
+
+
+print_ports()
+{
+if [ -n "${port}" ]; then
+  echo "ListenStream=${bind}${port}"
+fi
+if [ -n "${extraport}" ]; then
+  echo "ListenStream=${bind}${extraport}"
+fi
+}
+
+bindaddress=
+port=
+extraport=
+backlog=
+maxconnections=
+skip_networking=
+socket=
+
+coproc mysqldefaults { /usr/bin/my_print_defaults --mysqld ; }
+while read var; do
+  key=${var%%=*}
+  val=${var#*=}
+  case "${key}" in
+    --bind-address)
+      bindaddress=$val
+      ;;
+    --bind_address)
+      bindaddress=$val
+      ;;
+    --port)
+      port=$val
+      ;;
+    --extra-port)
+      extraport=$val
+      ;;
+    --extra_port)
+      extraport=$val
+      ;;
+    --backlog)
+      backlog=$val 
+      ;;
+    --max-connections)
+      maxconnections=$val
+      ;;
+    --max_connections)
+      maxconnections=$val
+      ;;
+    --skip-networking)
+      if [ -z "${val}" ]; then
+        skipnetworking=1
+      else
+        skipnetworking=$val
+      fi
+      ;;
+    --skip_networking)
+      if [ -z "${val}" ]; then
+        skipnetworking=1
+      else
+        skipnetworking=$val
+      fi
+      ;;
+    --socket)
+      socket=$val
+      ;;
+  esac
+done < /dev/fd/${mysqldefaults[0]}
+
+echo '[Socket]'
+
+if [ -n "${backlog}" ]; then
+  echo "Backlog=${backlog}"
+elif [ -n "${maxconnections}" ]; then
+  if [ $maxconnections -gt 150 ]; then
+    echo "Backlog=150"
+  else
+    echo "Backlog=${maxconnections}"
+  fi
+fi
+
+if [ -n "${port}" -o \
+     -n "${extraport}" -o \
+    "${skipnetworking}" = '0' -o \
+    -n "${bindaddress}" -o \
+    -n "${socket}" ]; then
+  # we've set unix or inet sockets to non default
+  # reset the ListenStream list to empty
+  echo "ListenStream="
+  # if port isn't set it really needs to be to 
+  # fill out the details
+  [ -z "${port}" ] && port=3306
+  # socket has a default value so ensure that is set
+  [ -z "${socket}" ] && socket=/var/lib/mysql/mysql.sock
+else
+  exit 0
+fi
+
+if [ -n "${socket}" ]; then
+  echo "ListenStream=${socket}"
+fi
+
+if [ -n "${skipnetworking}" ]; then
+  [ "${skipnetworking}" = '0' ] &&  exit 0
+fi
+
+if [ -n "${bindaddress}" ]; then
+  if [ "${bindaddress}" = "*" ]; then
+    # old wildcard
+    bind=
+    print_ports
+  elif [[ "${bindaddress}" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
+    # roughly IPv4
+    bind=${bindaddress}:
+    print_ports
+  elif [[ "${bindaddress}" =~ ([0-9a-fA-F]{0,4}::?){1,7}[0-9a-fA-F]{0,4} ]]; then
+    # roughly IPv6
+    bind=[${bindaddress}]:
+    print_ports
+  else
+    # hostname
+    # Systemd.sockets don't support it so look it up
+    coproc hosts { host ${bindaddress}; }
+    while read var; do
+      if [[ "${var}"  = *IPv6\ address* ]]; then
+        bind=[${var##* }]:
+        print_ports
+        break
+      else
+        bind=${var##* }:
+        print_ports
+      fi
+    done < /dev/fd/${hosts[0]}
+  fi
+else
+  bind=''
+  print_ports
+fi
+
+
+exit 0
+
diff --git a/support-files/mariadb-systemd-start b/support-files/mariadb-systemd-start
new file mode 100644
index 0000000..08f0c87
--- /dev/null
+++ b/support-files/mariadb-systemd-start
@@ -0,0 +1,44 @@
+#! /bin/bash
+#
+# Scripts to run by MySQL systemd service
+#
+#
+# try to run mysql_install_db and fix perms and SELinux contexts
+
+install_db () {    
+    # Note: something different than datadir=/var/lib/mysql requires SELinux policy changes (in enforcing mode)
+    datadir=/var/lib/mysql
+    log=/var/log/mysqld.log
+    coproc mysqldefaults { /usr/bin/my_print_defaults --mysqld ; }
+    while read var; do
+      key=${var%%=*}
+      if [ "${key}" = '--datadir' ]; then
+        datadir=${var#*=}
+      fi
+      if [ "${key}" = '--log-error' ] || [ "${key}" = '--log_error' ]; then
+        log=${var#*=}
+      fi
+    done < /dev/fd/${mysqldefaults[0]}
+
+    # Restore log, dir, perms and SELinux contexts
+    [ -d "$datadir" ] || install -d -m 0755 -omysql -gmysql "$datadir" || exit 1
+    [ -e $log ] || touch $log
+    chmod 0640 $log
+    chown mysql:mysql $log || exit 1
+    if [ -x /usr/sbin/restorecon ]; then
+        /usr/sbin/restorecon "$datadir"
+        /usr/sbin/restorecon $log
+    fi
+
+    # If special mysql dir is in place, skip db install 
+    [ -d "$datadir/mysql" ] && exit 0
+
+    # Create initial db
+    /usr/bin/mysql_install_db --rpm --datadir="$datadir" --user=mysql
+    exit 0
+}
+
+install_db
+
+exit 0
+
diff --git a/support-files/mariadb.service b/support-files/mariadb.service
new file mode 100644
index 0000000..09e321f
--- /dev/null
+++ b/support-files/mariadb.service
@@ -0,0 +1,104 @@
+#
+#  /etc/systemd/system/mariadb.service
+#
+
+[Unit]
+Description=MariaDB database server
+After=network.target
+After=syslog.target
+Requires=%p.socket
+
+[Install]
+WantedBy=multi-user.target
+Alias=mysql.service
+Alias=mysqld.service
+
+
+[Service]
+
+##############################################################################
+## Core requirements
+##
+
+Type=Notify
+
+# Setting this to true can break replication and the Type=Notify settings
+PrivateNetwork=false
+
+##############################################################################
+## Package maintainers
+##
+
+User=mysql
+
+# Execute pre and post scripts as root
+PermissionsStartOnly=true
+
+# Needed to create system tables etc.
+ExecStartPre=/usr/bin/mariadb-systemd-start
+
+# Start main service
+# skip-networking as its socket activation based
+ExecStart=/usr/sbin/mysqld $OPTIONS
+
+KillMode=process
+KillSignal=SIGTERM
+# Don't want to see an automated SIGKILL ever
+SendSIGKILL=no
+
+RestartPreventExitStatus=1
+Restart=on-fail
+RestartSec=5s
+
+PrivateTmp=true
+PrivateDevices=true
+
+UMask=077
+WorkingDirectory=/
+# To avoid mysql reading /root/.my.cnf which according to debian init script is
+# problematic
+Environment="HOME="
+
+##############################################################################
+## USERs can override
+##
+##
+## by creating a file in /etc/systemd/system/mariadb.server.d/MY_SPECIAL.conf
+
+# Useful options not previously available in [mysqld_safe]
+
+OOMScoreAdjust=-600
+
+BlockIOWeight=1000
+
+##
+## Options previously available to be set via [mysqld_safe]
+## that now needs to be set by systemd config files as mysqld_safe
+## isn't executed.
+##
+
+# Number of files limit. previously [mysqld_safe] open-file-limit
+LimitNOFILE=16364
+
+# Maximium core size. previously [mysqld_safe] core-file-size
+# LimitCore=
+
+# Nice priority. previously [mysqld_safe] nice
+# Nice=-5
+
+# Timezone. previously [mysqld_safe] timezone
+# Environment="TZ=UTC"
+
+# Library substitutions. previously [mysqld_safe] malloc-lib with explict paths
+# (in LD_LIBRARY_PATH) and library name (in LD_PRELOAD).
+# Environment="LD_LIBRARY_PATH=/path1 /path2" "LD_PRELOAD=
+
+# Flush caches. previously [mysqld_safe] flush-caches=1
+# ExecStartPre=sync
+# ExecStartPre=sysctl -q -w vm.drop_caches=3
+
+# numa-interleave=1 equalivant
+# Change ExecStart=numactl --interleave=all /usr/sbin/mysqld......
+
+# crash-script equalivent
+# FailureAction=
diff --git a/support-files/mariadb.socket b/support-files/mariadb.socket
new file mode 100644
index 0000000..5b71ca5
--- /dev/null
+++ b/support-files/mariadb.socket
@@ -0,0 +1,41 @@
+[Unit]
+Description=MySQL/MariaDB Sockets
+
+[Install]
+WantedBy=sockets.target
+Alias=mysql.socket
+Alias=mysqld.socket
+
+[Socket]
+##############################################################################
+## Core requirements
+##
+
+KeepAlive=true
+
+#
+# NonBlocking=true and NoDelay=true (if NonBlocking=true is unavailable) are
+# already set by MariaDB
+
+##############################################################################
+## DISTRIBUTION maintainers
+##
+
+SocketUser=mysql
+SocketMode=777
+
+##############################################################################
+##
+## USERs can override
+##
+## See man systemd.socket.5 for meanings
+##
+## Override by creating a file in /etc/systemd/system/mariadb.socket.d/MY_SPECIAL.conf
+## see man systemd.unit.5
+
+ListenStream=/var/lib/mysql/mysql.sock
+ListenStream=[::1]:3306
+ListenStream=127.0.0.1:3306
+BindToDevice=
+
+Backlog=150
