Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_domain.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /*!
34 @defgroup domain_xport Domain Functions
35 */
36 
37 #include "ocs.h"
38 
39 #define domain_printf(domain, fmt, ...) \
40  do { \
41  ocs_log_debug(domain ? domain->ocs : NULL, fmt, ##__VA_ARGS__); \
42  } while (0)
43 
44 void ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *domain);
45 void ocs_mgmt_domain_get_all(ocs_textbuf_t *textbuf, void *domain);
46 int ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *domain);
47 int ocs_mgmt_domain_set(char *parent, char *name, char *value, void *domain);
48 int ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
49  void *arg_out, uint32_t arg_out_length, void *domain);
50 
53  .get_handler = ocs_mgmt_domain_get,
54  .get_all_handler = ocs_mgmt_domain_get_all,
55  .set_handler = ocs_mgmt_domain_set,
56  .exec_handler = ocs_mgmt_domain_exec,
57 };
58 
59 /**
60  * @ingroup domain_xport
61  * @brief Allocate a domain object
62  *
63  * A domain object is allocated and initialized. It is associated with the argument 'ocs'
64  *
65  * @param ocs pointer to OCS device
66  *
67  * @return returns pointer to ocs_domain_t object or NULL
68  */
69 
70 ocs_domain_t *
71 ocs_domain_alloc(ocs_t *ocs)
72 {
73  ocs_domain_t *domain;
74 
75  ocs_assert(ocs, NULL);
76 
77  domain = ocs_malloc(ocs, sizeof(*domain), OCS_M_NOWAIT | OCS_M_ZERO);
78  if (domain) {
79  domain->ocs = ocs;
80  domain->instance_index = ocs->domain_instance_count++;
81  ocs_domain_lock_init(domain);
82  ocs_device_lock(ocs);
83  ocs_list_init(&domain->sport_list, ocs_sport_t, link);
84  /* if this is the first domain, then assign it as the "root" domain */
85  if (ocs_list_empty(&ocs->domain_list)) {
86  ocs->domain = domain;
87  }
88  ocs_list_add_tail(&ocs->domain_list, domain);
89  ocs_device_unlock(ocs);
90  domain->mgmt_functions = &domain_mgmt_functions;
91  domain_printf(domain, "Domain allocated\n");
92  } else {
93  ocs_log_err(ocs, "domain allocation failed\n");
94  }
95 
96 
97  return domain;
98 }
99 
100 /**
101  * @ingroup domain_xport
102  * @brief free a domain object
103  *
104  * The domain is freed
105  *
106  * @param domain domain object to free
107  *
108  * @return none
109  */
110 
111 void
112 ocs_domain_free(ocs_domain_t *domain)
113 {
114  ocs_t *ocs;
115 
116  ocs_assert(domain);
117  ocs_assert(domain->ocs);
118 
119  ocs = domain->ocs;
120 
121  domain_printf(domain, "Domain free\n");
122 
123  ocs_device_lock(ocs);
124  ocs_list_remove(&ocs->domain_list, domain);
125  if (domain == ocs->domain) {
126  ocs->domain = NULL;
127  }
128  ocs_device_unlock(ocs);
129 
130  ocs_domain_lock_free(domain);
131 
132  ocs_free(ocs, domain, sizeof(*domain));
133 }
134 
135 /**
136  * @brief Free memory resources of a domain object.
137  *
138  * <h3 class="desc">Description</h3>
139  * After the domain object is freed, its child objects are also freed.
140  *
141  * @param domain Pointer to a domain object.
142  *
143  * @return None.
144  */
145 
146 void
147 ocs_domain_force_free(ocs_domain_t *domain)
148 {
149  ocs_sport_t *sport;
150  ocs_sport_t *next;
151 
152  ocs_domain_lock(domain);
153  ocs_list_foreach_safe(&domain->sport_list, sport, next) {
154  ocs_sport_force_free(sport);
155  }
156  ocs_domain_unlock(domain);
157  ocs_domain_free(domain);
158 }
159 
160 /**
161  * @brief Return a pointer to the domain, given the instance index.
162  *
163  * <h3 class="desc">Description</h3>
164  * A pointer to the domain context, given by the index, is returned.
165  *
166  * @param ocs Pointer to the driver instance context.
167  * @param index Instance index.
168  *
169  * @return Returns a pointer to the domain; or NULL.
170  */
171 
172 ocs_domain_t *
173 ocs_domain_get_instance(ocs_t *ocs, uint32_t index)
174 {
175  ocs_domain_t *domain = NULL;
176 
177  if (index >= OCS_MAX_DOMAINS) {
178  ocs_log_err(ocs, "invalid index: %d\n", index);
179  return NULL;
180  }
181  ocs_device_lock(ocs);
182  ocs_list_foreach(&ocs->domain_list, domain) {
183  if (domain->instance_index == index) {
184  break;
185  }
186  }
187  ocs_device_unlock(ocs);
188  return domain;
189 }
190 
191 
192 /**
193  * @ingroup domain_xport
194  * @brief Generate domain ddump
195  *
196  * Generates domain ddump
197  *
198  * @param textbuf pointer to text buffer
199  * @param domain pointer to domain context
200  *
201  * @return Returns 0 on success, or a negative value on failure.
202  */
203 
204 int
205 ocs_ddump_domain(ocs_textbuf_t *textbuf, ocs_domain_t *domain)
206 {
207  ocs_sport_t *sport;
208  int retval = 0;
209 
210  ocs_ddump_section(textbuf, "domain", 0);
211 
212 
213  // ocs_scsi_ini_ddump(textbuf, OCS_SCSI_DDUMP_DOMAIN, domain);
214  ocs_scsi_tgt_ddump(textbuf, OCS_SCSI_DDUMP_DOMAIN, domain);
215 
216  if (ocs_domain_lock_try(domain) != TRUE) {
217  /* Didn't get the lock */
218  return -1;
219  }
220  ocs_list_foreach(&domain->sport_list, sport) {
221  retval = ocs_ddump_sport(textbuf, sport);
222  if (retval != 0) {
223  break;
224  }
225  }
226  ocs_domain_unlock(domain);
227 
228  ocs_ddump_endsection(textbuf, "domain", 0);
229 
230  return retval;
231 }
232 
233 void
234 ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *object)
235 {
236  ocs_sport_t *sport;
237  ocs_domain_t *domain = (ocs_domain_t *)object;
238 
239  ocs_mgmt_start_section(textbuf, "domain", domain->instance_index);
240 
241  if (ocs_domain_lock_try(domain) == TRUE) {
242 
243  /* Here the domain lock is held */
244  ocs_list_foreach(&domain->sport_list, sport) {
245  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_list_handler)) {
246  sport->mgmt_functions->get_list_handler(textbuf, sport);
247  }
248  }
249  ocs_domain_unlock(domain);
250  }
251 
252  ocs_mgmt_end_section(textbuf, "domain", domain->instance_index);
253 }
254 
255 int
256 ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
257 {
258  ocs_sport_t *sport;
259  ocs_domain_t *domain = (ocs_domain_t *)object;
260  char qualifier[80];
261  int retval = -1;
262 
263  // Assume that iSCSI has only one domain
264  ocs_mgmt_start_section(textbuf, "domain", 0);
265  snprintf(qualifier, sizeof(qualifier), "%s/domain[%d]", parent, 0);
266 
267  /* If it doesn't start with my qualifier I don't know what to do with it */
268  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
269 
270 
271  /* See if it's a value I can supply */
272  /* iSCSI domain has no status */
273  {
274  /* If I didn't know the value of this status pass the request to each of my children */
275  ocs_domain_lock(domain);
276  ocs_list_foreach(&domain->sport_list, sport) {
277  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_handler)) {
278  retval = sport->mgmt_functions->get_handler(textbuf, qualifier, name, sport);
279  }
280 
281  if (retval == 0) {
282  break;
283  }
284 
285  }
286  ocs_domain_unlock(domain);
287  }
288  }
289 
290  ocs_mgmt_end_section(textbuf, "domain", 0);
291 
292  return retval;
293 }
294 
295 void
296 ocs_mgmt_domain_get_all(ocs_textbuf_t *textbuf, void *object)
297 {
298  ocs_sport_t *sport;
299  ocs_domain_t *domain = (ocs_domain_t *)object;
300 
301  ocs_mgmt_start_section(textbuf, "domain", 0);
302 
303  ocs_domain_lock(domain);
304  ocs_list_foreach(&domain->sport_list, sport) {
305  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_all_handler)) {
306  sport->mgmt_functions->get_all_handler(textbuf, sport);
307  }
308  }
309  ocs_domain_unlock(domain);
310 
311  ocs_mgmt_end_section(textbuf, "domain", 0);
312 }
313 
314 
315 int
316 ocs_mgmt_domain_set(char *parent, char *name, char *value, void *object)
317 {
318  ocs_sport_t *sport;
319  ocs_domain_t *domain = (ocs_domain_t *)object;
320  char qualifier[80];
321  int retval = -1;
322 
323  snprintf(qualifier, sizeof(qualifier), "%s.domain%d", parent, 0);
324 
325  /* If it doesn't start with my qualifier I don't know what to do with it */
326  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
327 
328  /* If I didn't know the value of this status pass the request to each of my children */
329  ocs_domain_lock(domain);
330  ocs_list_foreach(&domain->sport_list, sport) {
331  if ((sport->mgmt_functions) && (sport->mgmt_functions->set_handler)) {
332  retval = sport->mgmt_functions->set_handler(qualifier, name, value, sport);
333  }
334 
335  if (retval == 0) {
336  break;
337  }
338  }
339  ocs_domain_unlock(domain);
340  }
341 
342  return retval;
343 }
344 
345 int
346 ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
347  void *arg_out, uint32_t arg_out_length, void *object)
348 {
349  ocs_sport_t *sport;
350  ocs_domain_t *domain = (ocs_domain_t *)object;
351  char qualifier[80];
352  int retval = -1;
353 
354  snprintf(qualifier, sizeof(qualifier), "%s/domain[%d]", parent, 0);
355 
356  /* If it doesn't start with my qualifier I don't know what to do with it */
357  if (ocs_strncmp(action, qualifier, strlen(qualifier)) == 0) {
358  /* If I didn't know how to do this action pass the request to each of my children */
359  ocs_domain_lock(domain);
360  ocs_list_foreach(&domain->sport_list, sport) {
361  if ((sport->mgmt_functions) && (sport->mgmt_functions->exec_handler)) {
362  retval = sport->mgmt_functions->exec_handler(qualifier, action, arg_in, arg_in_length, arg_out, arg_out_length, sport);
363  }
364 
365  if (retval == 0) {
366  break;
367  }
368  }
369  ocs_domain_unlock(domain);
370  }
371 
372  return retval;
373 }
374 
375 
static int32_t ocs_domain_lock_try(ocs_domain_t *domain)
Definition: ocs_common.h:181
void ocs_domain_force_free(ocs_domain_t *domain)
Free memory resources of a domain object.
Definition: ocs_domain.c:147
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
Definition: ocs_list.h:125
ocs_domain_t * ocs_domain_get_instance(ocs_t *ocs, uint32_t index)
Return a pointer to the domain, given the instance index.
Definition: ocs_domain.c:173
static void ocs_device_lock(ocs_t *ocs)
Definition: ocs_drv_fc.h:218
int ocs_ddump_domain(ocs_textbuf_t *textbuf, ocs_domain_t *domain)
Generate domain ddump.
Definition: ocs_domain.c:205
const char * name
Definition: ocs_ddump.h:54
static ocs_mgmt_functions_t domain_mgmt_functions
Definition: ocs_domain.c:51
void ocs_domain_free(ocs_domain_t *domain)
free a domain object
Definition: ocs_domain.c:112
void ocs_ddump_section(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section start data.
Definition: ocs_ddumplib.c:90
void ocs_mgmt_start_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the beginning of a numbered section in a management XML document.
int ocs_ddump_sport(ocs_textbuf_t *textbuf, ocs_sli_port_t *sport)
Generate sli port ddump.
Definition: ocs_sport.c:127
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
Definition: ocs_list.h:385
ocs_domain_t * ocs_domain_alloc(ocs_t *ocs)
Allocate a domain object.
Definition: ocs_domain.c:71
#define ocs_list_init(head, type, link)
Definition: ocs_list.h:113
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
Definition: ocs_list.h:446
static void ocs_device_unlock(ocs_t *ocs)
Definition: ocs_drv_fc.h:223
#define domain_printf(domain, fmt,...)
Definition: ocs_domain.c:39
void ocs_mgmt_domain_get_all(ocs_textbuf_t *textbuf, void *domain)
Definition: ocs_domain.c:296
void ocs_mgmt_end_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the indexed end of a section in a management XML document.
void ocs_sport_force_free(ocs_sport_t *sport)
Free memory resources of a SLI port object.
Definition: ocs_sport.c:67
static void ocs_domain_lock_init(ocs_domain_t *domain)
Definition: ocs_common.h:171
void ocs_ddump_endsection(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section end data.
Definition: ocs_ddumplib.c:108
ocs_mgmt_get_list_handler get_list_handler
Definition: ocs_mgmt.h:83
static void ocs_domain_lock_free(ocs_domain_t *domain)
Definition: ocs_common.h:176
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
Definition: ocs_list.h:263
void ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Definition: ocs_ramd.c:6580
static void ocs_domain_lock(ocs_domain_t *domain)
Definition: ocs_common.h:186
int ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *domain)
Definition: ocs_domain.c:256
#define ocs_assert(cond,...)
Definition: ocs_debug.h:163
void ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *domain)
Definition: ocs_domain.c:234
int ocs_mgmt_domain_set(char *parent, char *name, char *value, void *domain)
Definition: ocs_domain.c:316
#define ocs_list_foreach(list, item)
Iterate a linked list.
Definition: ocs_list.h:428
static void ocs_domain_unlock(ocs_domain_t *domain)
Definition: ocs_common.h:191
int ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length, void *domain)
Definition: ocs_domain.c:346