From c179ddfc225ba965f61cc3f0a81d2bfddfab531f Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 21 Mar 2007 20:06:36 +0000 Subject: [PATCH] syslink work - Implement code for a reformulated system call, giving the kernel the ability to manage multiple syslink routing hubs. Include the physical id space reservation and allocation and assignment of same. --- sys/kern/init_sysent.c | 2 +- sys/kern/kern_syslink.c | 310 ++++++++++++++++++++++++++++----------- sys/kern/syscalls.c | 2 +- sys/kern/syscalls.master | 4 +- sys/sys/syscall-hide.h | 2 +- sys/sys/syscall.h | 2 +- sys/sys/syscall.mk | 2 +- sys/sys/syslink.h | 66 ++++----- sys/sys/syslink_msg.h | 66 +++------ sys/sys/sysproto.h | 7 +- sys/sys/sysunion.h | 2 +- 11 files changed, 286 insertions(+), 179 deletions(-) diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index ceed0df8e3..cac56b75ad 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/init_sysent.c,v 1.53 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/kern/init_sysent.c,v 1.54 2007/03/21 20:06:34 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ diff --git a/sys/kern/kern_syslink.c b/sys/kern/kern_syslink.c index b05501417c..3933fbb27c 100644 --- a/sys/kern/kern_syslink.c +++ b/sys/kern/kern_syslink.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_syslink.c,v 1.5 2007/01/12 06:06:57 dillon Exp $ + * $DragonFly: src/sys/kern/kern_syslink.c,v 1.6 2007/03/21 20:06:34 dillon Exp $ */ /* * This module implements the syslink() system call and protocol which @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -55,11 +56,35 @@ #include +/* + * Red-Black trees organizing the syslink 'router' nodes and connections + * to router nodes. + */ +struct slrouter; +struct sldata; + +RB_HEAD(slrouter_rb_tree, slrouter); +RB_HEAD(sldata_rb_tree, sldata); +RB_PROTOTYPE2(slrouter_rb_tree, slrouter, rbnode, + rb_slrouter_compare, sysid_t); +RB_PROTOTYPE2(sldata_rb_tree, sldata, rbnode, + rb_sldata_compare, int); + +struct slrouter { + RB_ENTRY(slrouter) rbnode; /* list of routers */ + struct sldata_rb_tree sldata_rb_root; /* connections to router */ + sysid_t logid; /* logical sysid of router */ + int flags; /* flags passed on create */ + int phybits; /* accomodate connections */ + int count; /* number of connections */ + int nextphysid; /* next physid to allocate */ + int refs; +}; + /* * fileops interface. slbuf and sldata are also used in conjunction with a * normal file descriptor. */ - struct slbuf { char *buf; int bufsize; /* must be a power of 2 */ @@ -69,6 +94,8 @@ struct slbuf { }; struct sldata { + RB_ENTRY(sldata) rbnode; + struct slrouter *router; /* organizing router */ struct slbuf rbuf; struct slbuf wbuf; struct file *xfp; /* external file pointer */ @@ -76,7 +103,8 @@ struct sldata { struct lock wlock; /* synchronizing lock */ struct thread *rthread; /* xfp -> rbuf & process */ struct thread *wthread; /* wbuf -> xfp */ - int flags; + int flags; /* connection flags */ + int physid; int refs; }; @@ -87,6 +115,9 @@ struct sldata { #define SYSLINK_BUFSIZE (128*1024) +static int rb_slrouter_compare(struct slrouter *r1, struct slrouter *r2); +static int rb_sldata_compare(struct sldata *d1, struct sldata *d2); + static int syslink_read (struct file *fp, struct uio *uio, struct ucred *cred, int flags); static int syslink_write (struct file *fp, struct uio *uio, @@ -104,9 +135,15 @@ static void syslink_wthread(void *arg); static void slbuf_alloc(struct slbuf *buf, int bytes); static void slbuf_free(struct slbuf *buf); static void sldata_rels(struct sldata *sldata); +static void slrouter_rels(struct slrouter *slrouter); static int process_syslink_msg(struct sldata *sldata, struct syslink_msg *head); static int syslink_validate(struct syslink_msg *head, int bytes); +RB_GENERATE2(slrouter_rb_tree, slrouter, rbnode, + rb_slrouter_compare, sysid_t, logid); +RB_GENERATE2(sldata_rb_tree, sldata, rbnode, + rb_sldata_compare, int, physid); + static struct fileops syslinkops = { .fo_read = syslink_read, .fo_write = syslink_write, @@ -125,95 +162,185 @@ SYSCTL_INT(_kern, OID_AUTO, syslink_enabled, CTLFLAG_RW, &syslink_enabled, 0, "Enable SYSLINK"); /* - * Kernel mask and match bits. These may be modified during early boot, - * before any syslink services have been established, but must remain fixed - * after that. Note that the match value is only used if a message leaves - * the machine's domain. '0' is used for unmasked match bits to indicate - * transport within the machine. + * Support declarations and compare function for our RB trees */ -static sysid_t sl_mask = 0x00000000FFFFFFFFLL; -static sysid_t sl_match = 0x0000000100000000LL; +static struct slrouter_rb_tree slrouter_rb_root; + +static int +rb_slrouter_compare(struct slrouter *r1, struct slrouter *r2) +{ + if (r1->logid < r2->logid) + return(-1); + if (r1->logid > r2->logid) + return(1); + return(0); +} + +static int +rb_sldata_compare(struct sldata *d1, struct sldata *d2) +{ + if (d1->physid < d2->physid) + return(-1); + if (d1->physid > d2->physid) + return(1); + return(0); +} /* * Primary system call interface - associate a full-duplex stream * (typically a pipe or a connected socket) with a sysid namespace, * or create a direct link. * - * syslink(int fd, int cmd, sysid_t *mask, sysid_t *match) + * syslink(int fd, int flags, sysid_t routenode) */ int sys_syslink(struct syslink_args *uap) { - int error; - struct file *fp; + struct slrouter *slrouter; + struct slrouter *slnew; struct sldata *sldata; + struct file *fp; + int numphys; + int physid; + int error; + int n; /* * System call is under construction and disabled by default */ if (syslink_enabled == 0) return (EAUTH); + error = suser(curthread); + if (error) + return (error); - switch(uap->cmd) { - case SYSLINK_ESTABLISH: - error = suser(curthread); - if (error) - break; - sldata = kmalloc(sizeof(struct sldata), M_SYSLINK, M_WAITOK|M_ZERO); - lockinit(&sldata->rlock, "slread", 0, 0); - lockinit(&sldata->wlock, "slwrite", 0, 0); + /* + * Lookup or create the route node using passed flags. + */ + slnew = kmalloc(sizeof(struct slrouter), M_SYSLINK, M_WAITOK|M_ZERO); + slrouter = slrouter_rb_tree_RB_LOOKUP(&slrouter_rb_root, uap->routenode); + if (slrouter) { + /* + * Existing route node + */ + if (uap->flags & SYSLINKF_EXCL) { + kfree(slnew, M_SYSLINK); + return (EEXIST); + } + ++slrouter->refs; + kfree(slnew, M_SYSLINK); + } else if ((uap->flags & SYSLINKF_CREAT) == 0) { + /* + * Non-existent, no create flag specified + */ + kfree(slnew, M_SYSLINK); + return (ENOENT); + } else { + /* + * Create a new route node. Cannot block prior to tree insertion. + * + * Check the number of bits of physical id this route node can + * dispense for validity. The number of connections allowed must + * fit in a signed 32 bit integer. + */ + int phybits = uap->flags & SYSLINKF_PHYSBITS; - if (uap->fd < 0) { - /* - * We create a direct syslink descriptor. Only the reader thread - * is needed. - */ - error = falloc(curproc, &fp, &uap->fd); - if (error == 0) { - fp->f_type = DTYPE_SYSLINK; - fp->f_flag = FREAD | FWRITE; - fp->f_ops = &syslinkops; - fp->f_data = sldata; - slbuf_alloc(&sldata->rbuf, SYSLINK_BUFSIZE); - slbuf_alloc(&sldata->wbuf, SYSLINK_BUFSIZE); - sldata->refs = 2; - sldata->flags = SLF_WQUIT | SLF_WDONE; - lwkt_create(syslink_rthread, sldata, - &sldata->rthread, NULL, - 0, -1, "syslink_r"); - fsetfd(curproc, fp, uap->fd); - fdrop(fp); - uap->sysmsg_result = uap->fd; - } + if (phybits < 2 || phybits > 31) { + kfree(slnew, M_SYSLINK); + return (EINVAL); + } + slnew->logid = uap->routenode; + slnew->refs = 1; + slnew->phybits = phybits; + slnew->flags = uap->flags; + RB_INSERT(slrouter_rb_tree, &slrouter_rb_root, slnew); + RB_INIT(&slnew->sldata_rb_root); + slrouter = slnew; + } + numphys = 1 << slrouter->phybits; + + /* + * Create a connection to the route node and allocate a physical ID. + * Physical ID 0 is reserved for the route node itself. + */ + sldata = kmalloc(sizeof(struct sldata), M_SYSLINK, M_WAITOK|M_ZERO); + + if (slrouter->count + 1 >= numphys) { + error = ENOSPC; + kfree(sldata, M_SYSLINK); + goto done; + } + physid = slrouter->nextphysid; + for (n = 0; n < numphys; ++n) { + if (++physid == numphys) + physid = 1; + if (sldata_rb_tree_RB_LOOKUP(&slrouter->sldata_rb_root, physid) == NULL) + break; + } + if (n == numphys) + panic("sys_syslink: unexpected physical id allocation failure"); + + /* + * Insert the node, initializing enough fields to prevent things from + * being ripped out from under us before we have a chance to complete + * the system call. + */ + slrouter->nextphysid = physid; + sldata->physid = physid; + sldata->refs = 1; + ++slrouter->count; + RB_INSERT(sldata_rb_tree, &slrouter->sldata_rb_root, sldata); + + /* + * Complete initialization of the physical route node. Setting + * sldata->router activates the node. + */ + lockinit(&sldata->rlock, "slread", 0, 0); + lockinit(&sldata->wlock, "slwrite", 0, 0); + + if (uap->fd < 0) { + /* + * We create a direct syslink descriptor. Only the reader thread + * is needed. + */ + error = falloc(curproc, &fp, &uap->fd); + if (error == 0) { + fp->f_type = DTYPE_SYSLINK; + fp->f_flag = FREAD | FWRITE; + fp->f_ops = &syslinkops; + fp->f_data = sldata; + slbuf_alloc(&sldata->rbuf, SYSLINK_BUFSIZE); + slbuf_alloc(&sldata->wbuf, SYSLINK_BUFSIZE); + sldata->refs += 2; /* reader thread and descriptor */ + sldata->flags = SLF_WQUIT | SLF_WDONE; + lwkt_create(syslink_rthread, sldata, + &sldata->rthread, NULL, + 0, -1, "syslink_r"); + fsetfd(curproc, fp, uap->fd); + fdrop(fp); + uap->sysmsg_result = uap->fd; + } + } else { + sldata->xfp = holdfp(curproc->p_fd, uap->fd, -1); + if (sldata->xfp != NULL) { + slbuf_alloc(&sldata->rbuf, SYSLINK_BUFSIZE); + slbuf_alloc(&sldata->wbuf, SYSLINK_BUFSIZE); + sldata->refs += 2; /* reader thread and writer thread */ + lwkt_create(syslink_rthread, sldata, + &sldata->rthread, NULL, + 0, -1, "syslink_r"); + lwkt_create(syslink_wthread, sldata, + &sldata->wthread, NULL, + 0, -1, "syslink_w"); } else { - sldata->xfp = holdfp(curproc->p_fd, uap->fd, -1); - if (sldata->xfp != NULL) { - slbuf_alloc(&sldata->rbuf, SYSLINK_BUFSIZE); - slbuf_alloc(&sldata->wbuf, SYSLINK_BUFSIZE); - sldata->refs = 2; - lwkt_create(syslink_rthread, sldata, - &sldata->rthread, NULL, - 0, -1, "syslink_r"); - lwkt_create(syslink_wthread, sldata, - &sldata->wthread, NULL, - 0, -1, "syslink_w"); - } else { - error = EBADF; - } + error = EBADF; } - if (error) - kfree(sldata, M_SYSLINK); - break; - case SYSLINK_GETSYSMASK: - error = copyout(&sl_mask, uap->mask, sizeof(sl_mask)); - if (error == 0) - error = copyout(&sl_match, uap->match, sizeof(sl_match)); - break; - default: - error = ENOTSUP; - break; } + sldata->router = slrouter; + sldata_rels(sldata); +done: + slrouter_rels(slrouter); return(error); } @@ -228,7 +355,7 @@ syslink_rthread(void *arg) struct sldata *sldata = arg; struct slbuf *slbuf = &sldata->rbuf; struct syslink_msg *head; - const int min_msg_size = offsetof(struct syslink_msg, src_sysid); + const int min_msg_size = offsetof(struct syslink_msg, sm_srcid); while ((sldata->flags & SLF_RQUIT) == 0) { int count; @@ -271,18 +398,18 @@ syslink_rthread(void *arg) /* * Process as many syslink messages as we can. The record length - * must be at least a minimal PAD record (8 bytes). A msgid of 0 + * must be at least a minimal PAD record (8 bytes). A sm_cmd of 0 * is PAD. */ while (slbuf->windex - slbuf->rindex >= min_msg_size) { int aligned_reclen; head = (void *)(slbuf->buf + (slbuf->rindex & slbuf->bufmask)); - if (head->reclen < min_msg_size) { + if (head->sm_bytes < min_msg_size) { error = EINVAL; break; } - aligned_reclen = SLMSG_ALIGN(head->reclen); + aligned_reclen = SLMSG_ALIGN(head->sm_bytes); /* * Disallow wraps @@ -304,8 +431,8 @@ syslink_rthread(void *arg) * Process non-pad messages. Non-pad messages have to be at * least the size of the syslink_msg structure. */ - if (head->msgid) { - if (head->reclen < sizeof(struct syslink_msg)) { + if (head->sm_cmd) { + if (head->sm_bytes < sizeof(struct syslink_msg)) { error = EINVAL; break; } @@ -356,15 +483,15 @@ syslink_wthread(void *arg) int count; used = slbuf->windex - slbuf->rindex; - if (used < offsetof(struct syslink_msg, src_sysid)) + if (used < offsetof(struct syslink_msg, sm_srcid)) break; head = (void *)(slbuf->buf + (slbuf->rindex & slbuf->bufmask)); - if (head->reclen < offsetof(struct syslink_msg, src_sysid)) { + if (head->sm_bytes < offsetof(struct syslink_msg, sm_srcid)) { error = EINVAL; break; } - aligned_reclen = SLMSG_ALIGN(head->reclen); + aligned_reclen = SLMSG_ALIGN(head->sm_bytes); /* * Disallow wraps @@ -426,10 +553,28 @@ static void sldata_rels(struct sldata *sldata) { + struct slrouter *slrouter; + if (--sldata->refs == 0) { + slrouter = sldata->router; + KKASSERT(slrouter != NULL); + ++slrouter->refs; + RB_REMOVE(sldata_rb_tree, &sldata->router->sldata_rb_root, sldata); + sldata->router = NULL; slbuf_free(&sldata->rbuf); slbuf_free(&sldata->wbuf); kfree(sldata, M_SYSLINK); + slrouter_rels(slrouter); + } +} + +static +void +slrouter_rels(struct slrouter *slrouter) +{ + if (--slrouter->refs == 0 && RB_EMPTY(&slrouter->sldata_rb_root)) { + RB_REMOVE(slrouter_rb_tree, &slrouter_rb_root, slrouter); + kfree(slrouter, M_SYSLINK); } } @@ -642,13 +787,14 @@ syslink_kqfilter(struct file *fp, struct knote *kn) } /* - * Process a syslink message + * This routine is called from a route node's reader thread to process a + * syslink message once it has been completely read and its size validated. */ static int process_syslink_msg(struct sldata *sldata, struct syslink_msg *head) { - kprintf("process syslink msg %08x %04x\n", head->msgid, head->cid); + kprintf("process syslink msg %08x\n", head->sm_cmd); return(0); } @@ -659,7 +805,7 @@ static int syslink_validate(struct syslink_msg *head, int bytes) { - const int min_msg_size = offsetof(struct syslink_msg, src_sysid); + const int min_msg_size = offsetof(struct syslink_msg, sm_srcid); int aligned_reclen; while (bytes) { @@ -670,13 +816,13 @@ syslink_validate(struct syslink_msg *head, int bytes) return (EINVAL); if (bytes & SL_ALIGNMASK) return (EINVAL); - if (head->msgid && bytes < sizeof(struct syslink_msg)) + if (head->sm_cmd && bytes < sizeof(struct syslink_msg)) return (EINVAL); /* * Buffer must contain entire record */ - aligned_reclen = SLMSG_ALIGN(head->reclen); + aligned_reclen = SLMSG_ALIGN(head->sm_bytes); if (bytes < aligned_reclen) return (EINVAL); bytes -= aligned_reclen; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index c3f0057772..fecaa99a5c 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,7 +2,7 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/syscalls.c,v 1.52 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/kern/syscalls.c,v 1.53 2007/03/21 20:06:34 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 6869ba1024..1d967f2629 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.52 2007/03/21 20:06:34 dillon Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -658,7 +658,7 @@ int bytes); } 482 STD BSD { int extaccept(int s, int flags, caddr_t name, int *anamelen); } 483 STD BSD { int extconnect(int s, int flags, caddr_t name, int namelen); } -484 STD BSD { int syslink(int fd, int cmd, sysid_t *mask, sysid_t *match); } +484 STD BSD { int syslink(int fd, int flags, sysid_t routenode); } 485 STD BSD { int mcontrol(void *addr, size_t len, int behav, off_t value); } 486 STD BSD { int vmspace_create(void *id, int type, void *data); } 487 STD BSD { int vmspace_destroy(void *id); } diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index ba9927a564..adbdd57fc9 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,7 +2,7 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall-hide.h,v 1.53 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.54 2007/03/21 20:06:36 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index bd587cd585..7324c8e23e 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall.h,v 1.53 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/sys/syscall.h,v 1.54 2007/03/21 20:06:36 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 4837657cec..3a86dba0f3 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,6 +1,6 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/syscall.mk,v 1.53 2007/03/12 23:45:04 corecode Exp $ +# $DragonFly: src/sys/sys/syscall.mk,v 1.54 2007/03/21 20:06:36 dillon Exp $ # created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp MIASM = \ syscall.o \ diff --git a/sys/sys/syslink.h b/sys/sys/syslink.h index d98985f508..d845edd0e7 100644 --- a/sys/sys/syslink.h +++ b/sys/sys/syslink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2006 The DragonFly Project. All rights reserved. + * Copyright (c) 2004-2007 The DragonFly Project. All rights reserved. * * This code is derived from software contributed to The DragonFly Project * by Matthew Dillon @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/syslink.h,v 1.3 2006/08/06 18:56:46 dillon Exp $ + * $DragonFly: src/sys/sys/syslink.h,v 1.4 2007/03/21 20:06:36 dillon Exp $ */ /* @@ -55,23 +55,25 @@ #ifndef _SYS_TYPES_H_ #include #endif +#ifndef _SYS_TREE_H_ +#include +#endif /* - * SYSIDs are 64 bit entities. A SYSID is potentially routed across a - * topology, lsb to msb. End points typically reserve lsb bits - * while each routing layer reserves additional bits. Locality of reference - * is defined as storing a value of 0 in any 'unknown' high bits, - * allowing local meshes to be tied together into larger entities - * without disrupting a running system. + * SYSIDs are 64 bit entities and come in two varieties. Physical SYSIDs + * are used to efficiently route messages across the mesh, while Logical + * SYSIDs are persistently assigned identifiers representing specific devices + * or specific media or named filesystems. That is, the logical SYSID + * assigned to a filesystem or ANVIL partition can be stored in that + * filesystem's superblock and allows the filesystem to migrate or + * be multi-homed (have multiple physical SYSIDs representing the same + * logical entity). * - * Because sysid's are the primary means of identification in a potentially - * huge mesh of machines, a way is needed to detect stale values. For - * this reason, each local node reserves a number of bits starting at bit 0 - * (the lsb) as a boot counter. Sysids whos ref counts are not entirely - * known due to a disconnect must not be recycled after a disconnect for - * at least a number of weeks. 10-16 bits are usually reserved for this - * purpose. Theoretically this also means that the SYSID routing space - * for a disconnected node should not be reassigned to another node. + * Physical SYSIDs can be ever-changing, and any given logical SYSID could + * in fact have multiple physical SYSIDs associated with it. The mesh is + * self-healing and the combination of the logical and physical sysid + * basically validates the message at the target and determines whether + * the physical SYSID must be recalculated (looked up again) or not. */ typedef u_int64_t sysid_t; @@ -93,26 +95,14 @@ struct syslink_generic_args; typedef int (*syslink_func_t)(struct syslink_generic_args *); /* - * Commands for the syslink() system call. - * - * establish - Establish a new system link with the supplied mask and match - * values. A descriptor, if supplied, must be a reliable stream - * or packet descriptor. If -1 is specified the kernel will - * supply a reliable packet descriptor. Returns the descriptor. - * - * The kernel will automatically adjust the mask to fit - * available routing space. The caller typically specifies - * the low one bits of the mask, e.g. 0xFFFF, to indicate to - * the kernel how big a chunk of the sysid space the caller - * needs. If the caller supplies too large a chunk the kernel - * will adjust the mask on return. The kernel sets the match - * bits for the unmasked bits on return. - * - * getsysmask - Retrieve the mask/match values associated with the kernel's - * syslink route node that we have connected to. + * Flags for the syslink system call. Low 8 bits used to specify + * the number of bits to reserve for connections into the route node + * (e.g. '3' would allow up to 8 connections, though its actually 7 + * since the one address is needed for the route node itself). */ -#define SYSLINK_ESTABLISH 0x0001 /* establish a system link */ -#define SYSLINK_GETSYSMASK 0x0004 /* retrieve kernel node mask/match */ +#define SYSLINKF_PHYSBITS 0x000000FF +#define SYSLINKF_CREAT 0x00000100 +#define SYSLINKF_EXCL 0x00000200 /* * A syslink structure represents an end-point for communications. System @@ -133,8 +123,8 @@ typedef int (*syslink_func_t)(struct syslink_generic_args *); * template on a per-mount basis. */ struct syslink { - sysid_t sl_sysid; /* syslink id of this end-point */ - sysid_t sl_remote_id; /* syslink id of remote end-point */ + sysid_t sl_source; + sysid_t sl_target; int sl_refs; /* track references */ struct syslink_ops *sl_ops; /* operations vector */ }; @@ -205,7 +195,7 @@ typedef struct syslink_proto *syslink_proto_t; typedef struct syslink_generic_args *syslink_generic_args_t; #if !defined(_KERNEL) -int syslink(int, int, sysid_t *, sysid_t *); +int syslink(int, int, sysid_t); #endif #endif diff --git a/sys/sys/syslink_msg.h b/sys/sys/syslink_msg.h index b524e0c704..79920cf709 100644 --- a/sys/sys/syslink_msg.h +++ b/sys/sys/syslink_msg.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/syslink_msg.h,v 1.3 2006/08/08 01:27:14 dillon Exp $ + * $DragonFly: src/sys/sys/syslink_msg.h,v 1.4 2007/03/21 20:06:36 dillon Exp $ */ /* * The syslink infrastructure implements an optimized RPC mechanism across a @@ -129,58 +129,30 @@ typedef u_int16_t sl_reclen_t; /* item length */ * as small as 8 bytes (msgid, cid, and reclen fields only). The sysid * fields, if present, are ignored. */ + +/* + * Raw protocol structures + */ struct syslink_msg { - sl_msgid_t msgid; /* (32) transaction id for (src,dst) */ - sl_cid_t cid; /* (16) command or error code */ - sl_reclen_t reclen; /* (16) */ - sysid_t src_sysid; /* (64) end-point identifier */ - sysid_t dst_sysid; /* (64) end-point identifier */ - /* 8-byte aligned */ - /* one or more embedded syslink_item structures */ + u_int16_t sm_cmd; /* protocol command code */ + u_int16_t sm_bytes; /* unaligned size of message */ + u_int32_t sm_seq; + /* minimum syslink_msg size is 8 bytes (special PAD) */ + sysid_t sm_srcid; /* origination logical sysid */ + sysid_t sm_dstid; /* destination logical sysid */ + sysid_t sm_dstpysid; /* cached physical sysid */ +}; + +struct syslink_elm { + u_int16_t se_ctl; + u_int16_t se_bytes; + u_int32_t se_reserved; + /* extended by data */ }; #define SLMSG_ALIGN(bytes) (((bytes) + 7) & ~7) #define SLMSGF_RESPONSE ((sl_msgid_t)0x80000000) -/* - * A transaction contains any number of item structures. Each item - * structure may represent leaf data or a recursion into an array of - * additional item structures. The data type or field id is specified - * by the low 14 bits of the 16 bit itemid. - * - * If the RECURSION bit (15) is set in the itemid, the item's data - * represents any number of recursively embedded items. - * - * If the REFID bit (14) is set, it indicates that a leaf item is a - * sysid with a payload of exactly 8 bytes, and indicates that a recursion - * contains at least one leaf item somewhere within it that is a sysid. - * - * The reserved bits are still counted in the 16 bit itemid so, for example, - * an identifier of 0x0001 is different from 0x8001. However, it is not - * recommended that this sort of field id overloading be done. - * - * Both recursive and non-recursive items may use the aux field to hold - * information. Recursive items ONLY have the aux field available since - * the data payload is the recursed item array. - * - * SYSID's passed as data (i.e. the REFID bit is set in the itemid) are - * ref-counted by the transport layer. XXX (need to flesh this out some - * more w/ regard to temporary cache id's verses more persistent objects, - * and how to deal with disconnection and reconnection). - * - * NOTE! The transport layer usually validates that the item data structure - * is entirely correct before transmitting the message. Additionally, - * locally specified sysid's may have to be modified by the transport layer - * if the message exits the local domain. - */ -struct syslink_item { - sl_itemid_t itemid; - sl_reclen_t reclen; - int32_t auxdata; - /* 8-byte aligned */ - /* may be extended to include more data */ -}; - #define SLIF_RECURSION ((sl_cid_t)0x8000) #define SLIF_REFID ((sl_cid_t)0x4000) diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 05f71aa7df..02a8f9fcf5 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysproto.h,v 1.53 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/sys/sysproto.h,v 1.54 2007/03/21 20:06:36 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ @@ -1982,9 +1982,8 @@ struct syslink_args { struct sysmsg sysmsg; #endif int fd; char fd_[PAD_(int)]; - int cmd; char cmd_[PAD_(int)]; - sysid_t * mask; char mask_[PAD_(sysid_t *)]; - sysid_t * match; char match_[PAD_(sysid_t *)]; + int flags; char flags_[PAD_(int)]; + sysid_t routenode; char routenode_[PAD_(sysid_t)]; }; struct mcontrol_args { #ifdef _KERNEL diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index bf41296e58..eba956b314 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,7 +2,7 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysunion.h,v 1.50 2007/03/12 23:45:04 corecode Exp $ + * $DragonFly: src/sys/sys/sysunion.h,v 1.51 2007/03/21 20:06:36 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp */ -- 2.41.0