nobody@orca.wv.tek.com (-for inetd server command) (12/25/89)
I am writing some server programs that deal with multiple clients. Each client (typically) has send rights to some ports owned by the server. I've noticed that when the server task receives a port-death notification message, the notify_port member of the message differs by one from the port_name_t variable held by the server. Since this behavior appears consistent, I simply add 1 to the value supplied in the message (after casting to 'int'), and use this value as the key in a table search for the client connection that has been broken. But why the difference? What is the port_name_t supplied in the notify message supposed to mean? In general, what is the algorithm for correlating port names supplied in notifications and reports with the port names held by the task? While in the case mentioned above, my ad hoc solution of 'add one' seems to work, another server I am writing has not yet yielded such an empirical transform. This is an out-of-kernel server to implement System V shared memory semantics. This server uses the netmemoryserver to supply the shared memory. The SysV "shmget" routine is implemented by a netmemory_create() performed by the server; it retains rights to the paging_object and control_port supplied. A unique 'shmid' (shared memoryID) is created by the server and returned. The SysV "shmat" (attach) function is implemented by having the server perform a vm_map() operation on the client's task port. The "shmat" function supplies as argument the shmid created during the shmget; this ID is used as a key for a table search The problem arises in the SysV "shmdt" (detach) function. The sole argument specified in the SVID is the virtual address of the memory to detach from the client's address space. How can the server determine which of many netmemory objects is to be detached? [The PID, UID and GID of the caller is supplied by our kernel layer to the server, along with the caller's task port. This is not enough, because processes may attach a shared memory segment and then fork. The memory is shared between parent and child. We would like not to clutter up the kernel by adding an kernel message to the server on forks. Duplicating the SysV inheritance behaviour is of course no problem; during the vm_map() operation the server specifies VM_INHERIT_SHARE.] My current, partial, solution is to use vm_region() with the supplied virtual address against the client's task port. This gives the server the size of the object, which completes the information necessary to perform a vm_deallocate() on the client's behalf to detach the memory. Vm_region() also supplies a port name corresponding to the paging object of the region. But this value differs from the value of the port_name_t variables retained by the server. How can I use the information supplied by vm_region() to identify the netmemory_object in question? In what "name space" are these port names valid? Thanks, Bill Kerr Tektronix billk@orca.wv.tek.com
Richard.Draves@CS.CMU.EDU (12/26/89)
Excerpts from netnews.comp.os.mach: 24-Dec-89 port name matching -for i. s. command@orca. (2988) > In general, what is the algorithm for correlating port names supplied > in notifications and reports with the port names held by the task? The port name supplied in a port-deleted notification is the name of the erstwhile send right. When a port is destroyed, because its receive right is deallocated, the kernel deallocates any remaining send rights and notifies the holders of those rights with port-deleted notifications. It sounds like you are expecting the notification to be generated before the kernel actually generates it, so that when you expect a notification for port N you are actually getting the notification for the previous port, N-1. (In Mach 2.5, the kernel picks names for port rights sequentially. This is an implementation choice, and is subject to change. The kernel can pick any unused name for a new port right.) I don't understand your scenario, however. You say the clients have send rights for ports owned by the server, and then go on to talk about notifications received by the server. > Vm_region() also supplies a port name corresponding to the paging object of > the region. But this value differs from the value of the port_name_t > variables retained by the server. How can I use the information supplied > by vm_region() to identify the netmemory_object in question? In what > "name space" are these port names valid? The vm_region() call returns send rights for a name port. The external memory management interface deals with three kinds of ports. The memory object is represented by a memory object port, or memory_object_t. The server (netmemoryserver in this case) holds receive rights for the memory object port. You supply send rights to this port in vm_map() calls. When a kernel first encounters a memory object in a vm_map() call, it creates a control port (memory_object_control_t) and name port (memory_object_name_t). If a memory object is mapped into address spaces on multiple machines, a single object will have multiple control and name ports. The kernel has receive rights for the control and name ports. The kernel sends messages (from the memory_object.defs interface) to the memory object port. The server sends messages (from the mach.defs interface) to the control port. Messages aren't sent to the name port; it is used for identification purposes in vm_region() calls. The control port returned by netmemory_create() is different from the memory object control port for which the kernel holds receive rights. The netmemoryserver has receive rights for the control port from netmemory_create(). The control and name ports owned by the kernel haven't yet been created at the time of netmemory_create(); that doesn't happen until somebody maps the object. One possibility would be to use vm_region() immediately after vm_map(), to find out what the name port is. Then you can make use of the name port from later vm_region() calls. Rich