1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #ifndef _KRRP_SESSION_H
17 #define _KRRP_SESSION_H
18
19 #include <sys/kstat.h>
20 #include <sys/avl.h>
21 #include <sys/uuid.h>
22
23 #include <sys/krrp.h>
24 #include <krrp_error.h>
25
26 #include "krrp_stream.h"
27 #include "krrp_connection.h"
28 #include "krrp_pdu.h"
29 #include "krrp_queue.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 typedef char krrp_sess_id_str_t[UUID_PRINTABLE_STRING_LENGTH];
36
37 typedef enum {
38 KRRP_SESS_SENDER = 1,
39 KRRP_SESS_RECEIVER,
40 KRRP_SESS_COMPOUND,
41 } krrp_sess_type_t;
42
43 /*
44 * To extend stats need to add to the following define new field and
45 * write corresponding update-code in krrp_sess_sender_kstat_update()
46 */
47 #define KRRP_SESS_SENDER_STAT_NAME_MAP(X) \
48 X(avg_rpo, KSTAT_DATA_UINT64, 0) \
49 X(avg_network_rpo, KSTAT_DATA_UINT64, 0) \
50 X(cur_send_stream_txg, KSTAT_DATA_UINT64, 0) \
51 X(cur_send_network_txg, KSTAT_DATA_UINT64, 0) \
52 X(last_stream_ack_txg, KSTAT_DATA_UINT64, 0) \
53 X(last_network_ack_txg, KSTAT_DATA_UINT64, 0) \
54 X(max_pdu_seq_num, KSTAT_DATA_UINT64, 0) \
55 X(max_pdu_seq_num_adjusted, KSTAT_DATA_UINT64, 0) \
56 X(cur_pdu_seq_num, KSTAT_DATA_UINT64, 0) \
57 X(fl_ctrl_window_size, KSTAT_DATA_UINT64, 0) \
58 X(bytes_tx, KSTAT_DATA_UINT64, 0) \
59 X(bytes_rx, KSTAT_DATA_UINT64, 0) \
60 X(rbytes, KSTAT_DATA_UINT64, 0) \
61 X(mem_used, KSTAT_DATA_UINT64, 0) \
62 X(uptime, KSTAT_DATA_UINT64, 0) \
63
64 /*
65 * To extend stats need to add to the following define new field and
66 * write corresponding update-code in krrp_sess_receiver_kstat_update()
67 */
68 #define KRRP_SESS_RECEIVER_STAT_NAME_MAP(X) \
69 X(cur_recv_stream_txg, KSTAT_DATA_UINT64, 0) \
70 X(cur_recv_network_txg, KSTAT_DATA_UINT64, 0) \
71 X(max_pdu_seq_num, KSTAT_DATA_UINT64, 0) \
72 X(cur_pdu_seq_num, KSTAT_DATA_UINT64, 0) \
73 X(bytes_tx, KSTAT_DATA_UINT64, 0) \
74 X(bytes_rx, KSTAT_DATA_UINT64, 0) \
75 X(wbytes, KSTAT_DATA_UINT64, 0) \
76 X(mem_used, KSTAT_DATA_UINT64, 0) \
77 X(uptime, KSTAT_DATA_UINT64, 0) \
78
79 /*
80 * To extend stats need to add to the following define new field and
81 * write corresponding update-code in krrp_sess_compound_kstat_update()
82 */
83 #define KRRP_SESS_COMPOUND_STAT_NAME_MAP(X) \
84 X(avg_rpo, KSTAT_DATA_UINT64, 0) \
85 X(cur_send_stream_txg, KSTAT_DATA_UINT64, 0) \
86 X(cur_recv_stream_txg, KSTAT_DATA_UINT64, 0) \
87 X(rbytes, KSTAT_DATA_UINT64, 0) \
88 X(wbytes, KSTAT_DATA_UINT64, 0) \
89 X(mem_used, KSTAT_DATA_UINT64, 0) \
90 X(uptime, KSTAT_DATA_UINT64, 0) \
91
92 #define NUM_OF_FIELDS(S) (sizeof (S) / sizeof (kstat_named_t))
93
94 #define KRRP_SESS_STAT_NAME_GEN(name, dtype, def_value) kstat_named_t name;
95 typedef struct krrp_sess_sender_kstat_s {
96 KRRP_SESS_SENDER_STAT_NAME_MAP(KRRP_SESS_STAT_NAME_GEN)
97 } krrp_sess_sender_kstat_t;
98
99 typedef struct krrp_sess_receiver_kstat_s {
100 KRRP_SESS_RECEIVER_STAT_NAME_MAP(KRRP_SESS_STAT_NAME_GEN)
101 } krrp_sess_receiver_kstat_t;
102
103 typedef struct krrp_sess_compound_kstat_s {
104 KRRP_SESS_COMPOUND_STAT_NAME_MAP(KRRP_SESS_STAT_NAME_GEN)
105 } krrp_sess_compound_kstat_t;
106 #undef KRRP_SESS_STAT_NAME_GEN
107
108 typedef struct krrp_fl_ctrl_s {
109 uint64_t max_pdu_seq_num_orig;
110 uint64_t max_pdu_seq_num;
111 uint64_t ack_pdu_seq_num;
112 uint64_t cur_pdu_seq_num;
113 uint64_t cwnd;
114 boolean_t disabled;
115 kmutex_t mtx;
116 kcondvar_t cv;
117 } krrp_fl_ctrl_t;
118
119 typedef struct krrp_sess_s {
120 avl_node_t node;
121 krrp_sess_id_str_t id;
122 krrp_sess_type_t type;
123 boolean_t fake_mode;
124 boolean_t started;
125 boolean_t running;
126 boolean_t destroying;
127 boolean_t shutdown;
128 boolean_t on_hold;
129
130 size_t ref_cnt;
131
132 kmutex_t mtx;
133 kcondvar_t cv;
134
135 krrp_pdu_engine_t *data_pdu_engine;
136 krrp_stream_t *stream_read;
137 krrp_stream_t *stream_write;
138 krrp_conn_t *conn;
139
140 krrp_queue_t *ctrl_tx_queue;
141 krrp_queue_t *data_tx_queue;
142 krrp_queue_t *data_write_queue;
143 krrp_fl_ctrl_t fl_ctrl;
144
145 struct {
146 kstat_t *ctx;
147 union {
148 krrp_sess_sender_kstat_t sender;
149 krrp_sess_receiver_kstat_t receiver;
150 krrp_sess_compound_kstat_t compound;
151 } data;
152 char id[KRRP_KSTAT_ID_STRING_LENGTH];
153 } kstat;
154
155 timeout_id_t ping_timer;
156 boolean_t ping_wait_for_response;
157
158 char auth_digest[KRRP_AUTH_DIGEST_MAX_LEN];
159
160 krrp_error_t error;
161 nvlist_t *private_data;
162 } krrp_sess_t;
163
164 int krrp_sess_create(krrp_sess_t **result_sess, const char *id,
165 const char *kstat_id, const char *auth_digest,
166 boolean_t sender, boolean_t fake_mode,
167 boolean_t compound, krrp_error_t *error);
168 void krrp_sess_destroy(krrp_sess_t *sess);
169
170 int krrp_sess_attach_pdu_engine(krrp_sess_t *sess,
171 krrp_pdu_engine_t *pdu_engine, krrp_error_t *error);
172
173 int krrp_sess_attach_read_stream(krrp_sess_t *sess,
174 krrp_stream_t *stream, krrp_error_t *error);
175 int krrp_sess_attach_write_stream(krrp_sess_t *sess,
176 krrp_stream_t *stream, krrp_error_t *error);
177
178 int krrp_sess_initiator_attach_conn(krrp_sess_t *sess, krrp_conn_t *conn,
179 krrp_error_t *error);
180 int krrp_sess_target_attach_conn(krrp_sess_t *sess, krrp_conn_t *conn,
181 nvlist_t *params, krrp_error_t *error);
182
183 void krrp_sess_get_status(krrp_sess_t *sess, nvlist_t *result);
184
185 int krrp_sess_run(krrp_sess_t *sess, boolean_t only_once,
186 krrp_error_t *error);
187 int krrp_sess_send_stop(krrp_sess_t *sess, krrp_error_t *error);
188
189 int krrp_sess_throttle_conn(krrp_sess_t *sess, size_t limit,
190 krrp_error_t *error);
191
192 int krrp_sess_get_conn_info(krrp_sess_t *sess, nvlist_t *result,
193 krrp_error_t *error);
194
195 int krrp_sess_set_id(krrp_sess_t *sess, const char *sess_id_str,
196 krrp_error_t *error);
197 int krrp_sess_compare_id(const void *opaque_sess1, const void *opaque_sess2);
198
199 boolean_t krrp_sess_is_started(krrp_sess_t *sess);
200 boolean_t krrp_sess_is_running(krrp_sess_t *sess);
201
202 int krrp_sess_try_hold(krrp_sess_t *sess);
203 void krrp_sess_rele(krrp_sess_t *sess);
204
205 #ifdef __cplusplus
206 }
207 #endif
208
209 #endif /* _KRRP_SESSION_H */