Ticket #237: 0001-Socket-activation-support-for-systemd.patch
| File 0001-Socket-activation-support-for-systemd.patch, 9.7 KB (added by , 14 years ago) |
|---|
-
auto/options
From d9263fccaa22296e28d926ef99be2551d003c423 Mon Sep 17 00:00:00 2001 From: David Strauss <david@davidstrauss.net> Date: Sat, 27 Oct 2012 07:11:58 -0400 Subject: [PATCH] Socket activation support for systemd. --- auto/options | 3 + auto/os/linux | 18 +++++ src/core/ngx_inet.c | 147 ++++++++++++++++++++++++++++++++++++++++ src/core/ngx_inet.h | 3 + src/http/ngx_http.c | 8 +++ src/http/ngx_http_core_module.c | 10 ++- src/http/ngx_http_core_module.h | 3 + 7 files changed, 191 insertions(+), 1 deletion(-) diff --git a/auto/options b/auto/options index a75bead..94ae615 100644
a b USE_THREADS=NO 46 46 47 47 NGX_FILE_AIO=NO 48 48 NGX_IPV6=NO 49 NGX_SYSTEMD=NO 49 50 50 51 HTTP=YES 51 52 … … do 190 191 191 192 --with-file-aio) NGX_FILE_AIO=YES ;; 192 193 --with-ipv6) NGX_IPV6=YES ;; 194 --with-systemd) NGX_SYSTEMD=YES ;; 193 195 194 196 --without-http) HTTP=NO ;; 195 197 --without-http-cache) HTTP_CACHE=NO ;; … … cat << END 347 349 348 350 --with-file-aio enable file AIO support 349 351 --with-ipv6 enable IPv6 support 352 --with-systemd enable systemd socket support 350 353 351 354 --with-http_ssl_module enable ngx_http_ssl_module 352 355 --with-http_realip_module enable ngx_http_realip_module -
auto/os/linux
diff --git a/auto/os/linux b/auto/os/linux index c506d3d..470528f 100644
a b ngx_feature_test="cpu_set_t mask; 134 134 . auto/feature 135 135 136 136 137 # systemd() 138 139 if [ $NGX_SYSTEMD = YES ]; then 140 ngx_feature="systemd()" 141 ngx_feature_name="NGX_HAVE_SYSTEMD" 142 ngx_feature_run=yes 143 ngx_feature_incs="#include <systemd/sd-daemon.h>" 144 ngx_feature_path= 145 ngx_feature_libs=-lsystemd-daemon 146 ngx_feature_test="sd_is_socket(1, 0, 0, 0);" 147 . auto/feature 148 149 if [ $ngx_found = yes ]; then 150 CORE_LIBS="$CORE_LIBS -lsystemd-daemon" 151 fi 152 fi 153 154 137 155 # crypt_r() 138 156 139 157 ngx_feature="crypt_r()" -
src/core/ngx_inet.c
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 3db0136..c8302fc 100644
a b 8 8 #include <ngx_config.h> 9 9 #include <ngx_core.h> 10 10 11 #if (NGX_HAVE_SYSTEMD) 12 #include <systemd/sd-daemon.h> 13 #endif 11 14 12 15 static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u); 13 16 static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u); 14 17 static ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u); 18 static ngx_int_t ngx_parse_file_descriptor_url(ngx_pool_t *pool, ngx_url_t *u); 15 19 16 20 17 21 in_addr_t … … ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u) 522 526 return ngx_parse_unix_domain_url(pool, u); 523 527 } 524 528 529 if (ngx_strncasecmp(p, (u_char *) "fd:", 3) == 0) { 530 return ngx_parse_file_descriptor_url(pool, u); 531 } 532 525 533 if (p[0] == '[') { 526 534 return ngx_parse_inet6_url(pool, u); 527 535 } … … ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u) 607 615 #endif 608 616 } 609 617 618 static ngx_int_t 619 ngx_parse_file_descriptor_url(ngx_pool_t *pool, ngx_url_t *u) 620 { 621 #if (NGX_HAVE_SYSTEMD) 622 u_char *path; 623 size_t len; 624 socklen_t l; 625 int fd; 626 u_char printable[256]; 627 struct sockaddr *sa; 628 struct sockaddr_in *sin; 629 #if (NGX_HAVE_INET6) 630 struct sockaddr_in6 *sin6; 631 #endif 632 #if (NGX_HAVE_UNIX_DOMAIN) 633 struct sockaddr_un *saun; 634 #endif 635 636 printf("Parsing listening URL: %s\n", u->url.data); 637 638 // This doesn't seem to be used for fd: listeners, but validate that assumption. 639 if (u->uri_part) { 640 u->err = "u->uri_part is unsupported for file descriptors"; 641 return NGX_ERROR; 642 } 643 644 // Truncate the preceding "fd:" and ensure there's text left. 645 path = u->url.data + 3; 646 len = u->url.len - 3; 647 if (len == 0) { 648 u->err = "No number specified for the listening file descriptor."; 649 return NGX_ERROR; 650 } 651 652 // Convert the fd text to a numeric file descriptor. 653 fd = ngx_atoi(path, len); 654 printf("Parsed file descriptor #%d\n", fd); 655 656 // Check that it's the proper type of socket. 657 if (!sd_is_socket(fd, 0, SOCK_STREAM, 1)) { 658 u->err = "the systemd file descriptor passed in is not is listening, streaming socket"; 659 return NGX_ERROR; 660 } 661 662 u->fd = fd; 663 sa = (struct sockaddr *) &u->sockaddr; 664 l = sizeof(sa); 665 666 #if (NGX_HAVE_UNIX_DOMAIN) 667 // Bump up the allocation if it's a Unix domain socket. 668 if (sd_is_socket_unix(fd, SOCK_STREAM, 1, NULL, 0) > 0) { 669 printf("Reallocating for socket size %lu\n", sizeof(struct sockaddr_un)); 670 sa = ngx_pcalloc(pool, sizeof(struct sockaddr_un)); 671 if (sa == NULL) { 672 return NGX_ERROR; 673 } 674 memset(sa, 0, sizeof(struct sockaddr_un)); 675 l = sizeof(struct sockaddr_un); 676 } 677 #endif 678 679 // Get the socket information from the file descriptor. 680 if (getsockname(u->fd, sa, &l) < 0) { 681 u->err = "Couldn't read socket information out of the specified file descriptor."; 682 return NGX_ERROR; 683 } 684 685 u->family = sa->sa_family; 686 687 // Get type-specific information. 688 if (u->family == AF_INET) { 689 printf("INET\n"); 690 sin = (struct sockaddr_in *) sa; 691 u->socklen = sizeof(struct sockaddr_in); 692 u->port = ntohs(sin->sin_port); 693 u->no_port = 1; 694 sin->sin_family = AF_INET; 695 696 if (&sin->sin_addr == NULL) { 697 printf("Wildcard address.\n"); 698 u->wildcard = 1; 699 } 700 } 701 #if (NGX_HAVE_INET6) 702 else if (u->family == AF_INET6) { 703 printf("INET6\n"); 704 sin6 = (struct sockaddr_in6 *) sa; 705 u->socklen = sizeof(struct sockaddr_in6); 706 u->port = ntohs(sin6->sin6_port); 707 u->no_port = 1; 708 sin6->sin6_family = AF_INET6; 709 710 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 711 printf("Wildcard address.\n"); 712 u->wildcard = 1; 713 } 714 } 715 #endif 716 #if (NGX_HAVE_UNIX_DOMAIN) 717 else if (u->family == AF_UNIX) { 718 saun = (struct sockaddr_un *) sa; 719 saun->sun_family = AF_UNIX; 720 u->socklen = sizeof(struct sockaddr_un); 721 u->naddrs = 1; 722 u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t)); 723 if (u->addrs == NULL) { 724 return NGX_ERROR; 725 } 726 u->addrs[0].sockaddr = (struct sockaddr *) saun; 727 u->addrs[0].socklen = sizeof(struct sockaddr_un); 728 u->addrs[0].name.len = len + 2; 729 u->addrs[0].name.data = u->url.data; 730 } 731 #endif 732 else { 733 u->err = "File descriptor uses a socket family whose support is not compiled in"; 734 return NGX_ERROR; 735 } 736 737 // Get a human-readable/printable representation of the socket address. 738 ngx_sock_ntop(sa, printable, sizeof(printable), u->port); 739 740 // Set the "host" to the file descriptor number text (for now). 741 u->host.len = len + 1; 742 u->host.data = path; 743 744 printf("Prepared socket: %s\n", printable); 745 746 return NGX_OK; 747 748 #else 749 750 u->err = "the systemd file descriptor sockets are not supported on this platform"; 751 752 return NGX_ERROR; 753 754 #endif 755 } 756 610 757 611 758 static ngx_int_t 612 759 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) -
src/core/ngx_inet.h
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h index c5a3d76..6396e3e 100644
a b typedef struct { 99 99 ngx_uint_t naddrs; 100 100 101 101 char *err; 102 103 // Pre-initialized file descriptor. 104 int fd; 102 105 } ngx_url_t; 103 106 104 107 -
src/http/ngx_http.c
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index f1f8a48..2bdcd90 100644
a b ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr) 1791 1791 ls->setfib = addr->opt.setfib; 1792 1792 #endif 1793 1793 1794 ngx_log_error(NGX_LOG_INFO, cf->log, 0, 1795 "Looking for a file descriptor in the listening options."); 1796 if (addr->opt.fd) { 1797 ngx_log_error(NGX_LOG_INFO, cf->log, 0, 1798 "Found file descriptor %d on listening options. Using it.", addr->opt.fd); 1799 ls->fd = addr->opt.fd; 1800 } 1801 1794 1802 return ls; 1795 1803 } 1796 1804 -
src/http/ngx_http_core_module.c
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 826e4e5..5593b27 100644
a b ngx_http_set_etag(ngx_http_request_t *r) 1820 1820 { 1821 1821 ngx_table_elt_t *etag; 1822 1822 ngx_http_core_loc_conf_t *clcf; 1823 1823 1824 1824 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1825 1825 1826 1826 if (!clcf->etag) { … … ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3905 3905 3906 3906 ngx_memcpy(&lsopt.u.sockaddr, u.sockaddr, u.socklen); 3907 3907 3908 // If there's a file descriptor to inherit, use it. 3909 if (u.fd) { 3910 ngx_conf_log_error(NGX_LOG_INFO, cf, 0, 3911 "Found file descriptor #%d. Setting it as a listening option.\n", 3912 u.fd); 3913 lsopt.fd = u.fd; 3914 } 3915 3908 3916 lsopt.socklen = u.socklen; 3909 3917 lsopt.backlog = NGX_LISTEN_BACKLOG; 3910 3918 lsopt.rcvbuf = -1; -
src/http/ngx_http_core_module.h
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index ff1c2df..21454d2 100644
a b typedef struct { 67 67 } u; 68 68 69 69 socklen_t socklen; 70 71 // Inherited file descriptor. 72 int fd; 70 73 71 74 unsigned set:1; 72 75 unsigned default_server:1;
