/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * p30/lib-types.h
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/lib-types.h
*
* Types used by the library side routines that do not need to be
* exposed to the user application
#include <libcfs/list.h>
#include <lnet/types.h>
-#define WIRE_ATTR __attribute__((packed))
+#define WIRE_ATTR __attribute__((packed))
/* The wire handle's interface cookie only matches one network interface in
* one epoch (i.e. new cookie when the interface restarts or the node
* reboots). The object cookie only matches one object on that interface
* during that object's lifetime (i.e. no cookie re-use). */
+#include <libcfs/libcfs_pack.h>
typedef struct {
__u64 wh_interface_cookie;
__u64 wh_object_cookie;
} WIRE_ATTR lnet_handle_wire_t;
-
-/* byte-flip insensitive! */
-#define LNET_WIRE_HANDLE_NONE \
-((const lnet_handle_wire_t) {.wh_interface_cookie = -1, .wh_object_cookie = -1})
+#include <libcfs/libcfs_unpack.h>
typedef enum {
LNET_MSG_ACK = 0,
* byte boundary in the message header. Note that all types used in these
* wire structs MUST be fixed size and the smaller types are placed at the
* end. */
+#include <libcfs/libcfs_pack.h>
typedef struct lnet_ack {
lnet_handle_wire_t dst_wmd;
__u64 match_bits;
/* A HELLO message contains a magic number and protocol version
* code in the header's dest_nid, the peer's NID in the src_nid, and
* LNET_MSG_HELLO in the type field. All other common fields are zero
- * (including payload_size; i.e. no payload).
+ * (including payload_size; i.e. no payload).
* This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
* running the same protocol and to find out its NID. These LNDs should
* exchange HELLO messages when a connection is first established. Individual
* LNDs can put whatever else they fancy in lnet_hdr_t::msg.
*/
typedef struct {
- __u32 magic; /* LNET_PROTO_TCP_MAGIC */
+ __u32 magic; /* LNET_PROTO_TCP_MAGIC */
__u16 version_major; /* increment on incompatible change */
__u16 version_minor; /* increment on compatible change */
} WIRE_ATTR lnet_magicversion_t;
__u32 acr_version; /* protocol version */
__u64 acr_nid; /* target NID */
} WIRE_ATTR lnet_acceptor_connreq_t;
+#include <libcfs/libcfs_unpack.h>
#define LNET_PROTO_ACCEPTOR_VERSION 1
} lnet_libhandle_t;
#define lh_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+ ((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
typedef struct lnet_eq {
struct list_head eq_list;
unsigned int md_flags;
void *md_user_ptr;
lnet_eq_t *md_eq;
- void *md_addrkey;
unsigned int md_niov; /* # frags */
union {
struct iovec iov[LNET_MAX_IOV];
#ifdef LNET_USE_LIB_FREELIST
typedef struct
{
- void *fl_objs; /* single contiguous array of objects */
+ void *fl_objs; /* single contiguous array of objects */
int fl_nobjs; /* the number of them */
int fl_objsize; /* the size (including overhead) of each of them */
struct list_head fl_list; /* where they are enqueued */
/* fields initialised by the LND */
unsigned int lnd_type;
-
+
int (*lnd_startup) (struct lnet_ni *ni);
void (*lnd_shutdown) (struct lnet_ni *ni);
int (*lnd_ctl)(struct lnet_ni *ni, unsigned int cmd, void *arg);
/* In data movement APIs below, payload buffers are described as a set
* of 'niov' fragments which are...
- * EITHER
+ * EITHER
* in virtual memory (struct iovec *iov != NULL)
* OR
* in pages (kernel only: plt_kiov_t *kiov != NULL).
* The LND may NOT overwrite these fragment descriptors.
* An 'offset' and may specify a byte offset within the set of
- * fragments to start from
+ * fragments to start from
*/
/* Start sending a preformatted message. 'private' is NULL for PUT and
- * GET messages; otherwise this is a response to an incoming message
- * and 'private' is the 'private' passed to lnet_parse(). Return
- * non-zero for immediate failure, otherwise complete later with
- * lnet_finalize() */
- int (*lnd_send)(struct lnet_ni *ni, void *private, lnet_msg_t *msg);
+ * GET messages; otherwise this is a response to an incoming message
+ * and 'private' is the 'private' passed to lnet_parse(). Return
+ * non-zero for immediate failure, otherwise complete later with
+ * lnet_finalize() */
+ int (*lnd_send)(struct lnet_ni *ni, void *private, lnet_msg_t *msg);
/* Start receiving 'mlen' bytes of payload data, skipping the following
* 'rlen' - 'mlen' bytes. 'private' is the 'private' passed to
* lnet_parse(). Return non-zero for immedaite failure, otherwise
* complete later with lnet_finalize(). This also gives back a receive
* credit if the LND does flow control. */
- int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
- int delayed, unsigned int niov,
+ int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
+ int delayed, unsigned int niov,
struct iovec *iov, lnet_kiov_t *kiov,
unsigned int offset, unsigned int mlen, unsigned int rlen);
* for success and do NOT give back a receive credit; that has to wait
* until lnd_recv() gets called. On failure return < 0 and
* release resources; lnd_recv() will not be called. */
- int (*lnd_eager_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
+ int (*lnd_eager_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
void **new_privatep);
/* notification of peer health */
void (*lnd_notify)(struct lnet_ni *ni, lnet_nid_t peer, int alive);
-#ifdef __KERNEL__
+ /* query of peer aliveness */
+ void (*lnd_query)(struct lnet_ni *ni, lnet_nid_t peer, cfs_time_t *when);
+
+#if defined(__KERNEL__) || defined(HAVE_LIBPTHREAD)
/* accept a new connection */
int (*lnd_accept)(struct lnet_ni *ni, cfs_socket_t *sock);
-#else
+#endif
+
+#ifndef __KERNEL__
/* wait for something to happen */
void (*lnd_wait)(struct lnet_ni *ni, int milliseconds);
+
+ /* ensure non-RDMA messages can be received outside liblustre */
+ int (*lnd_setasync)(struct lnet_ni *ni, lnet_process_id_t id, int nasync);
#endif
} lnd_t;
+#define LNET_NI_STATUS_UP 0x15aac0de
+#define LNET_NI_STATUS_DOWN 0xdeadface
+#define LNET_NI_STATUS_INVALID 0x00000000
+typedef struct {
+ lnet_nid_t ns_nid;
+ __u32 ns_status;
+ __u32 ns_unused;
+} WIRE_ATTR lnet_ni_status_t;
+
#define LNET_MAX_INTERFACES 16
typedef struct lnet_ni {
int ni_txcredits; /* # tx credits free */
int ni_mintxcredits; /* lowest it's been */
int ni_peertxcredits; /* # per-peer send credits */
+ int ni_peerrtrcredits; /* # per-peer router buffer credits */
+ int ni_peertimeout; /* seconds to consider peer dead */
lnet_nid_t ni_nid; /* interface's NID */
void *ni_data; /* instance-specific data */
lnd_t *ni_lnd; /* procedural interface */
int ni_refcount; /* reference count */
+ cfs_time_t ni_last_alive; /* when I was last alive */
+ lnet_ni_status_t *ni_status; /* my health status */
char *ni_interfaces[LNET_MAX_INTERFACES]; /* equivalent interfaces to use */
} lnet_ni_t;
+#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
+#define LNET_PROTO_PING_VERSION 2
+#define LNET_PROTO_PING_VERSION1 1
+typedef struct {
+ __u32 pi_magic;
+ __u32 pi_version;
+ lnet_pid_t pi_pid;
+ __u32 pi_nnis;
+ lnet_ni_status_t pi_ni[0];
+} WIRE_ATTR lnet_ping_info_t;
+
+/* router checker data, per router */
+#define LNET_MAX_RTR_NIS 16
+#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS])
+typedef struct {
+ struct list_head rcd_list; /* chain on the_lnet.ln_zombie_rcd */
+ lnet_handle_md_t rcd_mdh; /* ping buffer MD */
+ lnet_ping_info_t *rcd_pinginfo; /* ping buffer */
+} lnet_rc_data_t;
+
typedef struct lnet_peer {
struct list_head lp_hashlist; /* chain on peer hash */
struct list_head lp_txq; /* messages blocking for tx credits */
unsigned int lp_ping_notsent; /* SEND event outstanding from ping */
int lp_alive_count; /* # times router went dead<->alive */
long lp_txqnob; /* bytes queued for sending */
- time_t lp_timestamp; /* time of last aliveness news */
- time_t lp_ping_timestamp; /* time of last ping attempt */
- time_t lp_ping_deadline; /* != 0 if ping reply expected */
+ cfs_time_t lp_timestamp; /* time of last aliveness news */
+ cfs_time_t lp_ping_timestamp; /* time of last ping attempt */
+ cfs_time_t lp_ping_deadline; /* != 0 if ping reply expected */
+ cfs_time_t lp_last_alive; /* when I was last alive */
+ cfs_time_t lp_last_query; /* when lp_ni was queried last time */
lnet_ni_t *lp_ni; /* interface peer is on */
lnet_nid_t lp_nid; /* peer's NID */
int lp_refcount; /* # refs */
int lp_rtr_refcount; /* # refs from lnet_route_t::lr_gateway */
+ lnet_rc_data_t *lp_rcd; /* router checker state */
} lnet_peer_t;
typedef struct {
- struct list_head lr_list; /* chain on net */
+ struct list_head lr_list; /* chain on net */
lnet_peer_t *lr_gateway; /* router node */
} lnet_route_t;
lnet_kiov_t rb_kiov[0]; /* the buffer space */
} lnet_rtrbuf_t;
+#include <libcfs/libcfs_pack.h>
typedef struct {
__u32 msgs_alloc;
__u32 msgs_max;
__u64 recv_length;
__u64 route_length;
__u64 drop_length;
-} lnet_counters_t;
+} WIRE_ATTR lnet_counters_t;
+#include <libcfs/libcfs_unpack.h>
#define LNET_PEER_HASHSIZE 503 /* prime! */
#define LNET_NRBPOOLS 3 /* # different router buffer pools */
-#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
-#define LNET_PROTO_PING_VERSION 1
-typedef struct {
- __u32 pi_magic;
- __u32 pi_version;
- lnet_pid_t pi_pid;
- __u32 pi_nnids;
- lnet_nid_t pi_nid[0];
-} WIRE_ATTR lnet_ping_info_t;
-
/* Options for lnet_portal_t::ptl_options */
#define LNET_PTL_LAZY (1 << 0)
typedef struct {
struct list_head ptl_ml; /* match list */
struct list_head ptl_msgq; /* messages blocking for MD */
+ __u64 ptl_ml_version; /* validity stamp, only changed for new attached MD */
__u64 ptl_msgq_version; /* validity stamp */
unsigned int ptl_options;
} lnet_portal_t;
-/* Router Checker */
-/* < 0 == startup error */
+/* Router Checker states */
#define LNET_RC_STATE_SHUTDOWN 0 /* not started */
#define LNET_RC_STATE_RUNNING 1 /* started up OK */
#define LNET_RC_STATE_STOPTHREAD 2 /* telling thread to stop */
int ln_refcount; /* LNetNIInit/LNetNIFini counter */
int ln_niinit_self; /* Have I called LNetNIInit myself? */
- int ln_ptlcompat; /* do I support talking to portals? */
-
struct list_head ln_lnds; /* registered LNDs */
#ifdef __KERNEL__
struct semaphore ln_api_mutex;
struct semaphore ln_lnd_mutex;
#else
-# if !HAVE_LIBPTHREAD
+# ifndef HAVE_LIBPTHREAD
int ln_lock;
int ln_api_mutex;
int ln_lnd_mutex;
struct list_head *ln_peer_hash; /* NID->peer hash */
int ln_npeers; /* # peers extant */
int ln_peertable_version; /* /proc validity stamp */
-
+
int ln_routing; /* am I a router? */
lnet_rtrbufpool_t ln_rtrpools[LNET_NRBPOOLS]; /* router buffer pools */
-
+
int ln_lh_hash_size; /* size of lib handle hash table */
struct list_head *ln_lh_hash_table; /* all extant lib handles, this interface */
__u64 ln_next_object_cookie; /* cookie generator */
lnet_ping_info_t *ln_ping_info;
#ifdef __KERNEL__
- int ln_rc_state; /* router checker startup/shutdown state */
- struct semaphore ln_rc_signal; /* serialise startup/shutdown */
- lnet_handle_eq_t ln_rc_eqh; /* router checker's event queue */
+ struct semaphore ln_rc_signal; /* serialise startup/shutdown */
#endif
-
+ int ln_rc_state; /* router checker startup/shutdown state */
+ lnet_handle_eq_t ln_rc_eqh; /* router checker's event queue */
+ lnet_handle_md_t ln_rc_mdh;
+ struct list_head ln_zombie_rcd;
+
#ifdef LNET_USE_LIB_FREELIST
lnet_freelist_t ln_free_mes;
lnet_freelist_t ln_free_msgs;
struct list_head ln_active_eqs;
lnet_counters_t ln_counters;
+
+#ifndef __KERNEL__
+ /* Temporary workaround to allow uOSS and test programs force
+ * server mode in userspace. The only place where we use it is
+ * lnet_prepare(). The only way to turn this flag on is to
+ * call lnet_server_mode() */
+
+ int ln_server_mode_flag;
+#endif
} lnet_t;
#endif