[Info-vax] Apache + mod_php performance
Dan Cross
cross at spitfire.i.gajendra.net
Wed Oct 2 15:38:26 EDT 2024
In article <vdd2mr$1tq3s$4 at dont-email.me>,
Arne Vajhøj <arne at vajhoej.dk> wrote:
>On 9/29/2024 10:03 PM, Lawrence D'Oliveiro wrote:
>> On Sun, 29 Sep 2024 21:58:45 -0400, Arne Vajhøj wrote:
>>
>>> On 9/29/2024 9:46 PM, Lawrence D'Oliveiro wrote:
>>>>
>>>> On Sun, 29 Sep 2024 21:42:48 -0400, Arne Vajhøj wrote:
>>>>>
>>>>> On 9/29/2024 9:21 PM, Lawrence D'Oliveiro wrote:
>>>>>>
>>>>>> Then it asks another process for a copy of that socket descriptor.
>>>>>> Perhaps there is one overall connection-management process that
>>>>>> accepts all new connections; if not, another worker that has that
>>>>>> socket can pass it along.
>>>>>
>>>>> It should not be a problem of copying a socket descriptor from one
>>>>> process to another process - I believe it is just an int.
>>>>>
>>>>> But will it work in the other process????
>>>>
>>>> Thatâs not how you do it. You pass it with the SCM_RIGHTS
>>>> ancillary-data option in Unix-family sockets
>>>> <https://manpages.debian.org/7/unix.7.en.html>.
>>>
>>> Worker A has a AF_INET socket to client so what AF_UNIX socket does it
>>> pass to worker B?
>>
>> You can pass any FD (AF_INET socket, file, pipe, even another AF_UNIX
>> socket) over an AF_UNIX socket.
>
>Ah. Interesting. Very interesting.
Access rights passing over Unix domain sockets was introduced in
4.2BSD, in 1983: more than 40 years ago. The basic mechanism
was updated in 4.4BSD, in 1994: 30 years ago. Here's a working
example:
// Passing access rights between processes over Unix domain
// sockets.
//
// Dan Cross <cross at gajendra.net>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
// Sends a file descripter, `fd`, over a Unix domain socket `sd`
// via the 4.4BSD access rights passing mechanism.
//
// Returns 1 on success, -1 on failure.
int
sendfd(int sd, int fd)
{
struct msghdr mh;
struct iovec iv;
struct cmsghdr *ptr;
size_t len;
int ret;
char dummy;
// Construct the control message header. Note this is
// malloc'ed to ensure proper alignment.
len = CMSG_SPACE(sizeof(int));
ptr = malloc(len);
if (ptr == NULL)
return -1;
memset(ptr, 0, len);
ptr->cmsg_len = len;
ptr->cmsg_level = SOL_SOCKET;
ptr->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(ptr), &fd, sizeof(int));
// We send a single byte of dummy data in case the
// implementation does not pass control data with an
// otherwise empty data transfer.
dummy = 0;
memset(&iv, 0, sizeof(iv));
iv.iov_base = &dummy;
iv.iov_len = 1;
// Construct the message header. Points to the dummy
// data and the control message header.
memset(&mh, 0, sizeof(mh));
mh.msg_name = NULL;
mh.msg_namelen = 0;
mh.msg_iov = &iv;
mh.msg_iovlen = 1;
mh.msg_control = (caddr_t)ptr;
mh.msg_controllen = len;
mh.msg_flags = 0;
// Loop in case there's no room in the kernel buffer
// to send. Cf.Stevens et al.
do {
ret = sendmsg(sd, &mh, 0);
} while (ret == 0);
free(ptr);
return ret;
}
// Receives a file descriptor over the Unix domain socket `sd`
// and store it into `*fdp` on success.
//
// Returns 1 on success, 0 on EOF, -1 on error.
int
recv_fd(int sd, int *fdp)
{
struct msghdr mh;
struct iovec iv;
struct cmsghdr *ptr;
size_t len;
int ret;
char dummy;
if (fdp == NULL)
return -1;
// Allocate space for the control structure.
len = CMSG_SPACE(sizeof(int));
ptr = malloc(len);
if (ptr == NULL)
return -1;
// Fill in an iovec to receive one byte of dummy data.
// Required on some systems that do not pass control
// messages on empty data transfers.
memset(&iv, 0, sizeof(iv));
iv.iov_base = &dummy;
iv.iov_len = 1;
// Fill in the msghdr structure. `recvmsg(2)` will
// update it.
memset(&mh, 0, sizeof(mh));
mh.msg_name = NULL;
mh.msg_namelen = 0;
mh.msg_iov = &iv;
mh.msg_iovlen = 1;
mh.msg_control = ptr;
mh.msg_controllen = len;
mh.msg_flags = 0;
ret = recvmsg(sd, &mh, 0);
if (ret <= 0) {
free(ptr);
return ret;
}
if (mh.msg_flags != 0) {
free(ptr);
return -1;
}
memcpy(fdp, CMSG_DATA(ptr), sizeof(int));
free(ptr);
return 1;
}
>But I am pretty sure that it will not work on VMS.
There's some chatter that suggests Unix domain sockets were
added in OpenVMS 8.4, in 2010: 14 years ago:
https://de.openvms.org/TUD2011/Unix_Portability_Updates_and_Open_Source.pdf
I haven't checked myself; even if the basic Unix domain sockets
mechanism was added for IPC, it's not clear if the access rights
transfer functionality was also implemented.
- Dan C.
More information about the Info-vax
mailing list