00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __cplusplus
00020 #define _GNU_SOURCE
00021 #endif
00022
00023 #include <stdio.h>
00024
00025 #include "lsm_datatypes.hpp"
00026
00027 #include "libstoragemgmt/libstoragemgmt_accessgroups.h"
00028 #include "libstoragemgmt/libstoragemgmt_common.h"
00029 #include "libstoragemgmt/libstoragemgmt_disk.h"
00030 #include "libstoragemgmt/libstoragemgmt_error.h"
00031 #include "libstoragemgmt/libstoragemgmt_fs.h"
00032 #include "libstoragemgmt/libstoragemgmt_nfsexport.h"
00033 #include "libstoragemgmt/libstoragemgmt_plug_interface.h"
00034 #include "libstoragemgmt/libstoragemgmt_pool.h"
00035 #include "libstoragemgmt/libstoragemgmt_snapshot.h"
00036 #include "libstoragemgmt/libstoragemgmt_systems.h"
00037 #include "libstoragemgmt/libstoragemgmt_targetport.h"
00038 #include "libstoragemgmt/libstoragemgmt_types.h"
00039 #include "libstoragemgmt/libstoragemgmt_volumes.h"
00040
00041 #include <string.h>
00042 #include <stdlib.h>
00043 #include <unistd.h>
00044 #include <dlfcn.h>
00045 #include <glib.h>
00046 #include <regex.h>
00047
00048 #ifdef __cplusplus
00049 extern "C" {
00050 #endif
00051 #define LSM_DEFAULT_PLUGIN_DIR "/var/run/lsm/ipc"
00052
00053 #define MEMBER_GET(x, validation, member, error) \
00054 if( validation(x) ) { \
00055 return x->member; \
00056 } else { \
00057 return error; \
00058 }
00059 int lsm_string_list_append(lsm_string_list * sl, const char *value)
00060 {
00061 int rc = LSM_ERR_INVALID_ARGUMENT;
00062
00063 if (LSM_IS_STRING_LIST(sl)) {
00064 char *d = strdup(value);
00065 if (d) {
00066 g_ptr_array_add(sl->values, d);
00067 rc = LSM_ERR_OK;
00068 } else {
00069 rc = LSM_ERR_NO_MEMORY;
00070 }
00071 }
00072 return rc;
00073 }
00074
00075 int lsm_string_list_delete(lsm_string_list * sl, uint32_t index)
00076 {
00077 int rc = LSM_ERR_INVALID_ARGUMENT;
00078
00079 if (LSM_IS_STRING_LIST(sl)) {
00080 if (index < sl->values->len) {
00081 g_ptr_array_remove_index(sl->values, index);
00082 rc = LSM_ERR_OK;
00083 }
00084 }
00085 return rc;
00086 }
00087
00088
00089 int lsm_string_list_elem_set(lsm_string_list * sl, uint32_t index,
00090 const char *value)
00091 {
00092 int rc = LSM_ERR_OK;
00093 if (LSM_IS_STRING_LIST(sl)) {
00094 if (index < sl->values->len) {
00095
00096 char *i = (char *) g_ptr_array_index(sl->values, index);
00097
00098 if (i) {
00099 free(i);
00100 }
00101
00102 g_ptr_array_index(sl->values, index) = strdup(value);
00103
00104 if (!g_ptr_array_index(sl->values, index)) {
00105 rc = LSM_ERR_NO_MEMORY;
00106 }
00107 } else {
00108 g_ptr_array_set_size(sl->values, index + 1);
00109 g_ptr_array_index(sl->values, index) = strdup(value);
00110
00111 if (!g_ptr_array_index(sl->values, index)) {
00112 rc = LSM_ERR_NO_MEMORY;
00113 }
00114 }
00115 } else {
00116 rc = LSM_ERR_INVALID_ARGUMENT;
00117 }
00118 return rc;
00119 }
00120
00121 const char *lsm_string_list_elem_get(lsm_string_list * sl, uint32_t index)
00122 {
00123 if (LSM_IS_STRING_LIST(sl)) {
00124 if (index < sl->values->len) {
00125 return (const char *) g_ptr_array_index(sl->values, index);
00126 }
00127 }
00128 return NULL;
00129 }
00130
00131 lsm_string_list *lsm_string_list_alloc(uint32_t size)
00132 {
00133 lsm_string_list *rc = NULL;
00134
00135 rc = (lsm_string_list *) malloc(sizeof(lsm_string_list));
00136 if (rc) {
00137 rc->magic = LSM_STRING_LIST_MAGIC;
00138 rc->values = g_ptr_array_sized_new(size);
00139 if (!rc->values) {
00140 rc->magic = LSM_DEL_MAGIC(LSM_STRING_LIST_MAGIC);
00141 free(rc);
00142 rc = NULL;
00143 } else {
00144 g_ptr_array_set_size(rc->values, size);
00145 g_ptr_array_set_free_func(rc->values, free);
00146 }
00147 }
00148
00149 return rc;
00150 }
00151
00152 int lsm_string_list_free(lsm_string_list * sl)
00153 {
00154 if (LSM_IS_STRING_LIST(sl)) {
00155 sl->magic = LSM_DEL_MAGIC(LSM_STRING_LIST_MAGIC);
00156 g_ptr_array_free(sl->values, TRUE);
00157 sl->values = NULL;
00158 free(sl);
00159 return LSM_ERR_OK;
00160 }
00161 return LSM_ERR_INVALID_ARGUMENT;
00162 }
00163
00164 uint32_t lsm_string_list_size(lsm_string_list * sl)
00165 {
00166 if (LSM_IS_STRING_LIST(sl)) {
00167 return (uint32_t) sl->values->len;
00168 }
00169 return 0;
00170 }
00171
00172 lsm_string_list *lsm_string_list_copy(lsm_string_list * src)
00173 {
00174 lsm_string_list *dest = NULL;
00175
00176 if (LSM_IS_STRING_LIST(src)) {
00177 uint32_t size = lsm_string_list_size(src);
00178 dest = lsm_string_list_alloc(size);
00179
00180 if (dest) {
00181 uint32_t i;
00182
00183 for (i = 0; i < size; ++i) {
00184 if (LSM_ERR_OK !=
00185 lsm_string_list_elem_set(dest, i,
00186 lsm_string_list_elem_get
00187 (src, i))) {
00189 lsm_string_list_free(dest);
00190 dest = NULL;
00191 break;
00192 }
00193 }
00194 }
00195 }
00196 return dest;
00197 }
00198
00199 lsm_connect *connection_get()
00200 {
00201 lsm_connect *c = (lsm_connect *) calloc(1, sizeof(lsm_connect));
00202 if (c) {
00203 c->magic = LSM_CONNECT_MAGIC;
00204 }
00205 return c;
00206 }
00207
00208 void connection_free(lsm_connect * c)
00209 {
00210 if (LSM_IS_CONNECT(c)) {
00211
00212 c->magic = LSM_DEL_MAGIC(LSM_CONNECT_MAGIC);
00213 c->flags = 0;
00214
00215 if (c->uri) {
00216 xmlFreeURI(c->uri);
00217 c->uri = NULL;
00218 }
00219
00220 if (c->error) {
00221 lsm_error_free(c->error);
00222 c->error = NULL;
00223 }
00224
00225 if (c->tp) {
00226 delete(c->tp);
00227 c->tp = NULL;
00228 }
00229
00230 if (c->raw_uri) {
00231 free(c->raw_uri);
00232 c->raw_uri = NULL;
00233 }
00234
00235 free(c);
00236 }
00237 }
00238
00239 static int connection_establish(lsm_connect * c, const char *password,
00240 uint32_t timeout, lsm_error_ptr * e,
00241 lsm_flag flags)
00242 {
00243 int rc = LSM_ERR_OK;
00244 std::map < std::string, Value > params;
00245
00246 try {
00247 params["uri"] = Value(c->raw_uri);
00248
00249 if (password) {
00250 params["password"] = Value(password);
00251 } else {
00252 params["password"] = Value();
00253 }
00254 params["timeout"] = Value(timeout);
00255 params["flags"] = Value(flags);
00256 Value p(params);
00257
00258 c->tp->rpc("plugin_register", p);
00259 }
00260 catch(const ValueException & ve) {
00261 *e = lsm_error_create(LSM_ERR_TRANSPORT_SERIALIZATION,
00262 "Error in serialization", ve.what(), NULL, NULL,
00263 0);
00264 rc = LSM_ERR_TRANSPORT_SERIALIZATION;
00265 } catch(const LsmException & le) {
00266 *e = lsm_error_create(LSM_ERR_TRANSPORT_COMMUNICATION,
00267 "Error in communication", le.what(), NULL, NULL,
00268 0);
00269 rc = LSM_ERR_TRANSPORT_COMMUNICATION;
00270 } catch( ...) {
00271 *e = lsm_error_create(LSM_ERR_LIB_BUG, "Undefined exception",
00272 NULL, NULL, NULL, 0);
00273 rc = LSM_ERR_LIB_BUG;
00274 }
00275 return rc;
00276 }
00277
00278 const char *uds_path(void)
00279 {
00280 const char *plugin_dir = getenv("LSM_UDS_PATH");
00281
00282 if (plugin_dir == NULL) {
00283 plugin_dir = LSM_DEFAULT_PLUGIN_DIR;
00284 }
00285 return plugin_dir;
00286 }
00287
00288
00289 int driver_load(lsm_connect * c, const char *plugin_name, const char *password,
00290 uint32_t timeout, lsm_error_ptr * e, int startup,
00291 lsm_flag flags)
00292 {
00293 int rc = LSM_ERR_OK;
00294 char *plugin_file = NULL;
00295 const char *plugin_dir = uds_path();
00296
00297 if (asprintf(&plugin_file, "%s/%s", plugin_dir, plugin_name) == -1) {
00298 return LSM_ERR_NO_MEMORY;
00299 }
00300
00301 if (access(plugin_file, F_OK) != 0) {
00302 rc = LSM_ERR_PLUGIN_NOT_EXIST;
00303 } else {
00304 if (access(plugin_file, R_OK | W_OK) == 0) {
00305 int ec;
00306 int sd = Transport::socket_get(std::string(plugin_file), ec);
00307
00308 if (sd >= 0) {
00309 c->tp = new Ipc(sd);
00310 if (startup) {
00311 if (connection_establish(c, password, timeout, e, flags)) {
00312 rc = LSM_ERR_PLUGIN_IPC_FAIL;
00313 }
00314 }
00315 } else {
00316 *e = lsm_error_create(LSM_ERR_PLUGIN_IPC_FAIL,
00317 "Unable to connect to plugin", NULL,
00318 dlerror(), NULL, 0);
00319
00320 rc = LSM_ERR_PLUGIN_IPC_FAIL;
00321 }
00322 } else {
00323 *e = lsm_error_create(LSM_ERR_PLUGIN_SOCKET_PERMISSION,
00324 "Unable to access plugin", NULL, NULL, NULL,
00325 0);
00326
00327 rc = LSM_ERR_PLUGIN_SOCKET_PERMISSION;
00328 }
00329 }
00330
00331 free(plugin_file);
00332 return rc;
00333 }
00334
00335 lsm_error_ptr lsm_error_create(lsm_error_number code, const char *msg,
00336 const char *exception, const char *debug,
00337 const void *debug_data, uint32_t debug_data_size)
00338 {
00339 lsm_error_ptr err = (lsm_error_ptr) calloc(1, sizeof(lsm_error));
00340
00341 if (err) {
00342 err->magic = LSM_ERROR_MAGIC;
00343 err->code = code;
00344
00345
00346 if (msg) {
00347 err->message = strdup(msg);
00348 }
00349
00350 if (exception) {
00351 err->exception = strdup(exception);
00352 }
00353
00354 if (debug) {
00355 err->debug = strdup(debug);
00356 }
00357
00358
00359
00360
00361 if (debug_data && (debug_data_size > 0)) {
00362 err->debug_data = malloc(debug_data_size);
00363
00364 if (err->debug_data) {
00365 err->debug_data_size = debug_data_size;
00366 memcpy(err->debug_data, debug_data, debug_data_size);
00367 }
00368 }
00369 }
00370 return (lsm_error_ptr) err;
00371 }
00372
00373 int lsm_error_free(lsm_error_ptr e)
00374 {
00375 if (!LSM_IS_ERROR(e)) {
00376 return LSM_ERR_INVALID_ARGUMENT;
00377 }
00378
00379 if (e->debug_data) {
00380 free(e->debug_data);
00381 e->debug_data = NULL;
00382 e->debug_data_size = 0;
00383 }
00384
00385 if (e->debug) {
00386 free(e->debug);
00387 e->debug = NULL;
00388 }
00389
00390 if (e->exception) {
00391 free(e->exception);
00392 e->exception = NULL;
00393 }
00394
00395 if (e->message) {
00396 free(e->message);
00397 e->message = NULL;
00398 }
00399
00400 e->magic = LSM_DEL_MAGIC(LSM_ERROR_MAGIC);
00401 free(e);
00402
00403 return LSM_ERR_OK;
00404 }
00405
00406 #define LSM_RETURN_ERR_VAL(type_t, e, x, error) \
00407 if( LSM_IS_ERROR(e) ) { \
00408 return e->x; \
00409 } \
00410 return (type_t)error; \
00411
00412
00413 lsm_error_number lsm_error_number_get(lsm_error_ptr e)
00414 {
00415 LSM_RETURN_ERR_VAL(lsm_error_number, e, code, -1);
00416 }
00417
00418 char *lsm_error_message_get(lsm_error_ptr e)
00419 {
00420 LSM_RETURN_ERR_VAL(char *, e, message, NULL);
00421 }
00422
00423 char *lsm_error_exception_get(lsm_error_ptr e)
00424 {
00425 LSM_RETURN_ERR_VAL(char *, e, exception, NULL);
00426 }
00427
00428 char *lsm_error_debug_get(lsm_error_ptr e)
00429 {
00430 LSM_RETURN_ERR_VAL(char *, e, debug, NULL);
00431 }
00432
00433 void *lsm_error_debug_data_get(lsm_error_ptr e, uint32_t * size)
00434 {
00435 if (LSM_IS_ERROR(e) && size != NULL) {
00436 if (e->debug_data) {
00437 *size = e->debug_data_size;
00438 return e->debug_data;
00439 } else {
00440 *size = 0;
00441 }
00442 }
00443 return NULL;
00444 }
00445
00453 #define CREATE_ALLOC_ARRAY_FUNC(name, rtype)\
00454 rtype *name(uint32_t size) \
00455 { \
00456 rtype *rc = NULL; \
00457 if (size > 0) { \
00458 rc = (rtype *) calloc(size, sizeof(rtype)); \
00459 } \
00460 return rc; \
00461 }
00462
00472 #define CREATE_FREE_ARRAY_FUNC(name, free_func, record_type, error)\
00473 int name( record_type pa[], uint32_t size) \
00474 { \
00475 if (pa) { \
00476 uint32_t i = 0; \
00477 for (i = 0; i < size; ++i) { \
00478 free_func(pa[i]); \
00479 } \
00480 free(pa); \
00481 return LSM_ERR_OK; \
00482 } \
00483 return error; \
00484 }
00485
00486
00487 CREATE_ALLOC_ARRAY_FUNC(lsm_pool_record_array_alloc, lsm_pool *)
00488
00489 lsm_pool *lsm_pool_record_alloc(const char *id, const char *name,
00490 uint64_t element_type,
00491 uint64_t unsupported_actions,
00492 uint64_t totalSpace, uint64_t freeSpace,
00493 uint64_t status, const char *status_info,
00494 const char *system_id, const char *plugin_data)
00495 {
00496 lsm_pool *rc = (lsm_pool *) calloc(1, sizeof(lsm_pool));
00497 if (rc) {
00498 rc->magic = LSM_POOL_MAGIC;
00499 rc->id = strdup(id);
00500 rc->name = strdup(name);
00501 rc->element_type = element_type;
00502 rc->unsupported_actions = unsupported_actions;
00503 rc->total_space = totalSpace;
00504 rc->free_space = freeSpace;
00505 rc->status = status;
00506 rc->status_info = strdup(status_info);
00507 rc->system_id = strdup(system_id);
00508
00509 if (plugin_data) {
00510 rc->plugin_data = strdup(plugin_data);
00511 }
00512
00513 if (!rc->id || !rc->name || !rc->system_id || !rc->status_info ||
00514 (plugin_data && !rc->plugin_data)) {
00515 lsm_pool_record_free(rc);
00516 rc = NULL;
00517 }
00518 }
00519 return rc;
00520 }
00521
00522 void lsm_pool_free_space_set(lsm_pool * p, uint64_t free_space)
00523 {
00524 if (LSM_IS_POOL(p)) {
00525 p->free_space = free_space;
00526 }
00527 }
00528
00529 lsm_pool *lsm_pool_record_copy(lsm_pool * toBeCopied)
00530 {
00531 if (LSM_IS_POOL(toBeCopied)) {
00532 return lsm_pool_record_alloc(toBeCopied->id, toBeCopied->name,
00533 toBeCopied->element_type,
00534 toBeCopied->unsupported_actions,
00535 toBeCopied->total_space,
00536 toBeCopied->free_space,
00537 toBeCopied->status,
00538 toBeCopied->status_info,
00539 toBeCopied->system_id,
00540 toBeCopied->plugin_data);
00541 }
00542 return NULL;
00543 }
00544
00545 int lsm_pool_record_free(lsm_pool * p)
00546 {
00547 if (LSM_IS_POOL(p)) {
00548 p->magic = LSM_DEL_MAGIC(LSM_POOL_MAGIC);
00549 if (p->name) {
00550 free(p->name);
00551 p->name = NULL;
00552 }
00553
00554 if (p->status_info) {
00555 free(p->status_info);
00556 p->status_info = NULL;
00557 }
00558
00559 if (p->id) {
00560 free(p->id);
00561 p->id = NULL;
00562 }
00563
00564 if (p->system_id) {
00565 free(p->system_id);
00566 p->system_id = NULL;
00567 }
00568
00569 free(p->plugin_data);
00570 p->plugin_data = NULL;
00571
00572 free(p);
00573 return LSM_ERR_OK;
00574 }
00575 return LSM_ERR_INVALID_ARGUMENT;
00576 }
00577
00578 CREATE_FREE_ARRAY_FUNC(lsm_pool_record_array_free, lsm_pool_record_free,
00579 lsm_pool *, LSM_ERR_INVALID_ARGUMENT)
00580
00581 char *lsm_pool_name_get(lsm_pool * p)
00582 {
00583 if (LSM_IS_POOL(p)) {
00584 return p->name;
00585 }
00586 return NULL;
00587 }
00588
00589 char *lsm_pool_id_get(lsm_pool * p)
00590 {
00591 if (LSM_IS_POOL(p)) {
00592 return p->id;
00593 }
00594 return NULL;
00595 }
00596
00597 uint64_t lsm_pool_total_space_get(lsm_pool * p)
00598 {
00599 if (LSM_IS_POOL(p)) {
00600 return p->total_space;
00601 }
00602 return 0;
00603 }
00604
00605 uint64_t lsm_pool_free_space_get(lsm_pool * p)
00606 {
00607 if (LSM_IS_POOL(p)) {
00608 return p->free_space;
00609 }
00610 return 0;
00611 }
00612
00613 uint64_t lsm_pool_status_get(lsm_pool * p)
00614 {
00615 if (LSM_IS_POOL(p)) {
00616 return p->status;
00617 }
00618 return UINT64_MAX;
00619 }
00620
00621 const char *lsm_pool_status_info_get(lsm_pool * p)
00622 {
00623 if (LSM_IS_POOL(p)) {
00624 return p->status_info;
00625 }
00626 return NULL;
00627 }
00628
00629 char *lsm_pool_system_id_get(lsm_pool * p)
00630 {
00631 if (LSM_IS_POOL(p)) {
00632 return p->system_id;
00633 }
00634 return NULL;
00635 }
00636
00637 MEMBER_FUNC_GET(const char *, lsm_pool_plugin_data_get, lsm_pool * p,
00638 p, LSM_IS_POOL, plugin_data, NULL)
00639
00640 MEMBER_FUNC_GET(uint64_t, lsm_pool_element_type_get, lsm_pool * p, p,
00641 LSM_IS_POOL, element_type, 0)
00642
00643 MEMBER_FUNC_GET(uint64_t, lsm_pool_unsupported_actions_get, lsm_pool * p, p,
00644 LSM_IS_POOL, element_type, 0)
00645
00646 CREATE_ALLOC_ARRAY_FUNC(lsm_volume_record_array_alloc, lsm_volume *)
00647
00648 lsm_volume *lsm_volume_record_alloc(const char *id, const char *name,
00649 const char *vpd83, uint64_t blockSize,
00650 uint64_t numberOfBlocks,
00651 uint32_t status, const char *system_id,
00652 const char *pool_id,
00653 const char *plugin_data)
00654 {
00655 if (vpd83 && (LSM_ERR_OK != lsm_volume_vpd83_verify(vpd83))) {
00656 return NULL;
00657 }
00658
00659 lsm_volume *rc = (lsm_volume *) calloc(1, sizeof(lsm_volume));
00660 if (rc) {
00661 rc->magic = LSM_VOL_MAGIC;
00662 rc->id = strdup(id);
00663 rc->name = strdup(name);
00664
00665 if (vpd83) {
00666 rc->vpd83 = strdup(vpd83);
00667 }
00668
00669 rc->block_size = blockSize;
00670 rc->number_of_blocks = numberOfBlocks;
00671 rc->admin_state = status;
00672 rc->system_id = strdup(system_id);
00673 rc->pool_id = strdup(pool_id);
00674
00675 if (plugin_data) {
00676 rc->plugin_data = strdup(plugin_data);
00677 }
00678
00679 if (!rc->id || !rc->name || (vpd83 && !rc->vpd83) || !rc->system_id ||
00680 !rc->pool_id || (plugin_data && !rc->plugin_data)) {
00681 lsm_volume_record_free(rc);
00682 rc = NULL;
00683 }
00684 }
00685 return rc;
00686 }
00687
00688 CREATE_ALLOC_ARRAY_FUNC(lsm_disk_record_array_alloc, lsm_disk *)
00689
00690 lsm_disk *lsm_disk_record_alloc(const char *id, const char *name,
00691 lsm_disk_type disk_type, uint64_t block_size,
00692 uint64_t block_count, uint64_t disk_status,
00693 const char *system_id)
00694 {
00695 lsm_disk *rc = (lsm_disk *) malloc(sizeof(lsm_disk));
00696 if (rc) {
00697 rc->magic = LSM_DISK_MAGIC;
00698 rc->id = strdup(id);
00699 rc->name = strdup(name);
00700 rc->disk_type = disk_type;
00701 rc->block_size = block_size;
00702 rc->block_count = block_count;
00703 rc->disk_status = disk_status;
00704 rc->system_id = strdup(system_id);
00705
00706 if (!rc->id || !rc->name || !rc->system_id) {
00707 lsm_disk_record_free(rc);
00708 rc = NULL;
00709 }
00710 }
00711 return rc;
00712 }
00713
00714 CREATE_ALLOC_ARRAY_FUNC(lsm_system_record_array_alloc, lsm_system *)
00715
00716 lsm_system *lsm_system_record_alloc(const char *id, const char *name,
00717 uint32_t status, const char *status_info,
00718 const char *plugin_data)
00719 {
00720 lsm_system *rc = (lsm_system *) calloc(1, sizeof(lsm_system));
00721 if (rc) {
00722 rc->magic = LSM_SYSTEM_MAGIC;
00723 rc->id = strdup(id);
00724 rc->name = strdup(name);
00725 rc->status = status;
00726 rc->status_info = strdup(status_info);
00727
00728 if (plugin_data) {
00729 rc->plugin_data = strdup(plugin_data);
00730 }
00731
00732 if (!rc->name || !rc->id || !rc->status_info ||
00733 (plugin_data && !rc->plugin_data)) {
00734 lsm_system_record_free(rc);
00735 rc = NULL;
00736 }
00737 }
00738 return rc;
00739 }
00740
00741 int lsm_system_record_free(lsm_system * s)
00742 {
00743 if (LSM_IS_SYSTEM(s)) {
00744 s->magic = LSM_DEL_MAGIC(LSM_SYSTEM_MAGIC);
00745
00746 if (s->id) {
00747 free(s->id);
00748 s->id = NULL;
00749 }
00750
00751 if (s->name) {
00752 free(s->name);
00753 s->name = NULL;
00754 }
00755
00756 if (s->status_info) {
00757 free(s->status_info);
00758 s->status_info = NULL;
00759 }
00760
00761 free(s->plugin_data);
00762
00763 free(s);
00764 return LSM_ERR_OK;
00765 }
00766 return LSM_ERR_INVALID_ARGUMENT;
00767 }
00768
00769 CREATE_FREE_ARRAY_FUNC(lsm_system_record_array_free, lsm_system_record_free,
00770 lsm_system *, LSM_ERR_INVALID_ARGUMENT)
00771
00772 lsm_system *lsm_system_record_copy(lsm_system * s)
00773 {
00774 lsm_system *rc = NULL;
00775 if (LSM_IS_SYSTEM(s)) {
00776 rc = lsm_system_record_alloc(s->id, s->name, s->status, s->status_info,
00777 s->plugin_data);
00778 }
00779 return rc;
00780 }
00781
00782 const char *lsm_system_id_get(lsm_system * s)
00783 {
00784 if (LSM_IS_SYSTEM(s)) {
00785 return s->id;
00786 }
00787 return NULL;
00788 }
00789
00790 const char *lsm_system_name_get(lsm_system * s)
00791 {
00792 if (LSM_IS_SYSTEM(s)) {
00793 return s->name;
00794 }
00795 return NULL;
00796 }
00797
00798 uint32_t lsm_system_status_get(lsm_system * s)
00799 {
00800 if (LSM_IS_SYSTEM(s)) {
00801 return s->status;
00802 }
00803 return UINT32_MAX;
00804 }
00805
00806 MEMBER_FUNC_GET(const char *, lsm_system_plugin_data_get, lsm_system * s,
00807 s, LSM_IS_SYSTEM, plugin_data, NULL)
00808
00809 lsm_volume *lsm_volume_record_copy(lsm_volume * vol)
00810 {
00811 lsm_volume *rc = NULL;
00812 if (LSM_IS_VOL(vol)) {
00813 rc = lsm_volume_record_alloc(vol->id, vol->name, vol->vpd83,
00814 vol->block_size, vol->number_of_blocks,
00815 vol->admin_state, vol->system_id,
00816 vol->pool_id, vol->plugin_data);
00817 }
00818 return rc;
00819 }
00820
00821 int lsm_volume_record_free(lsm_volume * v)
00822 {
00823 if (LSM_IS_VOL(v)) {
00824 v->magic = LSM_DEL_MAGIC(LSM_VOL_MAGIC);
00825
00826 if (v->id) {
00827 free(v->id);
00828 v->id = NULL;
00829 }
00830
00831 if (v->name) {
00832 free(v->name);
00833 v->name = NULL;
00834 }
00835
00836 if (v->vpd83) {
00837 free(v->vpd83);
00838 v->vpd83 = NULL;
00839 }
00840
00841 if (v->system_id) {
00842 free(v->system_id);
00843 v->system_id = NULL;
00844 }
00845
00846 if (v->pool_id) {
00847 free(v->pool_id);
00848 v->pool_id = NULL;
00849 }
00850
00851 free(v->plugin_data);
00852 v->plugin_data = NULL;
00853
00854 free(v);
00855 return LSM_ERR_OK;
00856 }
00857 return LSM_ERR_INVALID_ARGUMENT;
00858 }
00859
00860 CREATE_FREE_ARRAY_FUNC(lsm_volume_record_array_free, lsm_volume_record_free,
00861 lsm_volume *, LSM_ERR_INVALID_ARGUMENT)
00862
00863 lsm_disk *lsm_disk_record_copy(lsm_disk * disk)
00864 {
00865 if (LSM_IS_DISK(disk)) {
00866 return lsm_disk_record_alloc(disk->id, disk->name, disk->disk_type,
00867 disk->block_size, disk->block_count,
00868 disk->disk_status, disk->system_id);
00869 }
00870 return NULL;
00871 }
00872
00873 int lsm_disk_record_free(lsm_disk * d)
00874 {
00875 if (LSM_IS_DISK(d)) {
00876 d->magic = LSM_DEL_MAGIC(LSM_DISK_MAGIC);
00877
00878 free(d->id);
00879 d->id = NULL;
00880
00881 free(d->name);
00882 d->name = NULL;
00883
00884 free(d->system_id);
00885 d->system_id = NULL;
00886
00887 free(d);
00888 return LSM_ERR_OK;
00889 }
00890 return LSM_ERR_INVALID_ARGUMENT;
00891 }
00892
00893 CREATE_FREE_ARRAY_FUNC(lsm_disk_record_array_free, lsm_disk_record_free,
00894 lsm_disk *, LSM_ERR_INVALID_ARGUMENT)
00895
00896
00897 #define MEMBER_SET_REF(x, validation, member, value, alloc_func, \
00898 free_func, error) \
00899 if( validation(x) ) { \
00900 if(x->member) { \
00901 free_func(x->member); \
00902 x->member = NULL; \
00903 } \
00904 if( value ) { \
00905 x->member = alloc_func(value); \
00906 if( !x->member ) { \
00907 return LSM_ERR_NO_MEMORY; \
00908 } \
00909 } \
00910 return LSM_ERR_OK; \
00911 } else { \
00912 return error; \
00913 }
00914
00915 #define MEMBER_SET_VAL(x, validation, member, value, error) \
00916 if( validation(x) ) { \
00917 x->member = value; \
00918 return LSM_ERR_OK; \
00919 } else { \
00920 return error; \
00921 }
00922 const char *lsm_volume_id_get(lsm_volume * v)
00923 {
00924 MEMBER_GET(v, LSM_IS_VOL, id, NULL);
00925 }
00926
00927 const char *lsm_volume_name_get(lsm_volume * v)
00928 {
00929 MEMBER_GET(v, LSM_IS_VOL, name, NULL);
00930 }
00931
00932 const char *lsm_volume_vpd83_get(lsm_volume * v)
00933 {
00934 MEMBER_GET(v, LSM_IS_VOL, vpd83, NULL);
00935 }
00936
00937 uint64_t lsm_volume_block_size_get(lsm_volume * v)
00938 {
00939 MEMBER_GET(v, LSM_IS_VOL, block_size, 0);
00940 }
00941
00942 uint64_t lsm_volume_number_of_blocks_get(lsm_volume * v)
00943 {
00944 MEMBER_GET(v, LSM_IS_VOL, number_of_blocks, 0);
00945 }
00946
00947 uint32_t lsm_volume_admin_state_get(lsm_volume * v)
00948 {
00949 MEMBER_GET(v, LSM_IS_VOL, admin_state, 0);
00950 }
00951
00952 char *lsm_volume_system_id_get(lsm_volume * v)
00953 {
00954 MEMBER_GET(v, LSM_IS_VOL, system_id, NULL);
00955 }
00956
00957 char *lsm_volume_pool_id_get(lsm_volume * v)
00958 {
00959 MEMBER_GET(v, LSM_IS_VOL, pool_id, NULL);
00960 }
00961
00962 MEMBER_FUNC_GET(const char *, lsm_volume_plugin_data_get, lsm_volume * v, v,
00963 LSM_IS_VOL, plugin_data, NULL)
00964
00965 const char *lsm_disk_id_get(lsm_disk * d)
00966 {
00967 MEMBER_GET(d, LSM_IS_DISK, id, NULL);
00968 }
00969
00970 const char *lsm_disk_name_get(lsm_disk * d)
00971 {
00972 MEMBER_GET(d, LSM_IS_DISK, name, NULL);
00973 }
00974
00975 lsm_disk_type lsm_disk_type_get(lsm_disk * d)
00976 {
00977 MEMBER_GET(d, LSM_IS_DISK, disk_type, LSM_DISK_TYPE_OTHER);
00978 }
00979
00980 uint64_t lsm_disk_block_size_get(lsm_disk * d)
00981 {
00982 MEMBER_GET(d, LSM_IS_DISK, block_size, 0);
00983 }
00984
00985 uint64_t lsm_disk_number_of_blocks_get(lsm_disk * d)
00986 {
00987 MEMBER_GET(d, LSM_IS_DISK, block_count, 0);
00988 }
00989
00990 uint64_t lsm_disk_status_get(lsm_disk * d)
00991 {
00992 MEMBER_GET(d, LSM_IS_DISK, disk_status, LSM_DISK_STATUS_UNKNOWN);
00993 }
00994
00995 const char *lsm_disk_system_id_get(lsm_disk * d)
00996 {
00997 MEMBER_GET(d, LSM_IS_DISK, system_id, NULL);
00998 }
00999
01000 CREATE_ALLOC_ARRAY_FUNC(lsm_access_group_record_array_alloc, lsm_access_group *)
01001
01002 static lsm_string_list *standardize_init_list(lsm_string_list * initiators)
01003 {
01004 uint32_t i = 0;
01005 lsm_string_list *rc = lsm_string_list_copy(initiators);
01006 char *wwpn = NULL;
01007
01008 if (rc) {
01009 for (i = 0; i < lsm_string_list_size(rc); ++i) {
01010 if (LSM_ERR_OK == wwpn_validate(lsm_string_list_elem_get(rc, i))) {
01011
01012 wwpn = wwpn_convert(lsm_string_list_elem_get(rc, i));
01013 if (!wwpn ||
01014 LSM_ERR_OK != lsm_string_list_elem_set(rc, i, wwpn)) {
01015 free(wwpn);
01016 lsm_string_list_free(rc);
01017 rc = NULL;
01018 break;
01019 }
01020 free(wwpn);
01021 wwpn = NULL;
01022 }
01023 }
01024 }
01025
01026 return rc;
01027 }
01028
01029
01030 lsm_access_group *lsm_access_group_record_alloc(const char *id,
01031 const char *name,
01032 lsm_string_list * initiators,
01033 lsm_access_group_init_type
01034 init_type,
01035 const char *system_id,
01036 const char *plugin_data)
01037 {
01038 lsm_access_group *rc = NULL;
01039 if (id && name && system_id) {
01040 rc = (lsm_access_group *) malloc(sizeof(lsm_access_group));
01041 if (rc) {
01042 rc->magic = LSM_ACCESS_GROUP_MAGIC;
01043 rc->id = strdup(id);
01044 rc->name = strdup(name);
01045 rc->system_id = strdup(system_id);
01046 rc->initiators = standardize_init_list(initiators);
01047 rc->init_type = init_type;
01048
01049 if (plugin_data) {
01050 rc->plugin_data = strdup(plugin_data);
01051 } else {
01052 rc->plugin_data = NULL;
01053 }
01054
01055 if (!rc->id || !rc->name || !rc->system_id ||
01056 (plugin_data && !rc->plugin_data) ||
01057 (initiators && !rc->initiators)) {
01058 lsm_access_group_record_free(rc);
01059 rc = NULL;
01060 }
01061 }
01062 }
01063 return rc;
01064 }
01065
01066 lsm_access_group *lsm_access_group_record_copy(lsm_access_group * ag)
01067 {
01068 lsm_access_group *rc = NULL;
01069 if (LSM_IS_ACCESS_GROUP(ag)) {
01070 rc = lsm_access_group_record_alloc(ag->id, ag->name,
01071 ag->initiators, ag->init_type,
01072 ag->system_id, ag->plugin_data);
01073 }
01074 return rc;
01075 }
01076
01077 int lsm_access_group_record_free(lsm_access_group * ag)
01078 {
01079 if (LSM_IS_ACCESS_GROUP(ag)) {
01080 ag->magic = LSM_DEL_MAGIC(LSM_ACCESS_GROUP_MAGIC);
01081 free(ag->id);
01082 free(ag->name);
01083 free(ag->system_id);
01084 lsm_string_list_free(ag->initiators);
01085 free(ag->plugin_data);
01086 free(ag);
01087 return LSM_ERR_OK;
01088 }
01089 return LSM_ERR_INVALID_ARGUMENT;
01090 }
01091
01092 CREATE_FREE_ARRAY_FUNC(lsm_access_group_record_array_free,
01093 lsm_access_group_record_free, lsm_access_group *,
01094 LSM_ERR_INVALID_ARGUMENT)
01095
01096 const char *lsm_access_group_id_get(lsm_access_group * group)
01097 {
01098 if (LSM_IS_ACCESS_GROUP(group)) {
01099 return group->id;
01100 }
01101 return NULL;
01102 }
01103
01104 const char *lsm_access_group_name_get(lsm_access_group * group)
01105 {
01106 if (LSM_IS_ACCESS_GROUP(group)) {
01107 return group->name;
01108 }
01109 return NULL;
01110 }
01111
01112 const char *lsm_access_group_system_id_get(lsm_access_group * group)
01113 {
01114 if (LSM_IS_ACCESS_GROUP(group)) {
01115 return group->system_id;
01116 }
01117 return NULL;
01118 }
01119
01120 lsm_string_list *lsm_access_group_initiator_id_get(lsm_access_group * group)
01121 {
01122 if (LSM_IS_ACCESS_GROUP(group)) {
01123 return group->initiators;
01124 }
01125 return NULL;
01126 }
01127
01128 void lsm_access_group_initiator_id_set(lsm_access_group * group,
01129 lsm_string_list * il)
01130 {
01131 if (LSM_IS_ACCESS_GROUP(group)) {
01132 if (group->initiators && group->initiators != il) {
01133 lsm_string_list_free(group->initiators);
01134 }
01135
01136 group->initiators = lsm_string_list_copy(il);
01137 }
01138 }
01139
01140 lsm_error_ptr lsm_error_last_get(lsm_connect * c)
01141 {
01142 if (LSM_IS_CONNECT(c)) {
01143 lsm_error_ptr e = c->error;
01144 c->error = NULL;
01145 return e;
01146 }
01147 return NULL;
01148 }
01149
01150 lsm_block_range *lsm_block_range_record_alloc(uint64_t source_start,
01151 uint64_t dest_start,
01152 uint64_t block_count)
01153 {
01154 lsm_block_range *rc = NULL;
01155
01156 rc = (lsm_block_range *) malloc(sizeof(lsm_block_range));
01157 if (rc) {
01158 rc->magic = LSM_BLOCK_RANGE_MAGIC;
01159 rc->source_start = source_start;
01160 rc->dest_start = dest_start;
01161 rc->block_count = block_count;
01162 }
01163 return rc;
01164 }
01165
01166 int lsm_block_range_record_free(lsm_block_range * br)
01167 {
01168 if (LSM_IS_BLOCK_RANGE(br)) {
01169 br->magic = LSM_DEL_MAGIC(LSM_BLOCK_RANGE_MAGIC);
01170 free(br);
01171 return LSM_ERR_OK;
01172 }
01173 return LSM_ERR_INVALID_ARGUMENT;
01174 }
01175
01176 lsm_block_range *lsm_block_range_record_copy(lsm_block_range * source)
01177 {
01178 lsm_block_range *dest = NULL;
01179
01180 if (LSM_IS_BLOCK_RANGE(source)) {
01181 dest = lsm_block_range_record_alloc(source->source_start,
01182 source->dest_start,
01183 source->block_count);
01184 }
01185 return dest;
01186 }
01187
01188 CREATE_ALLOC_ARRAY_FUNC(lsm_block_range_record_array_alloc, lsm_block_range *)
01189 CREATE_FREE_ARRAY_FUNC(lsm_block_range_record_array_free,
01190 lsm_block_range_record_free, lsm_block_range *,
01191 LSM_ERR_INVALID_ARGUMENT)
01192
01193
01194 uint64_t lsm_block_range_source_start_get(lsm_block_range * br)
01195 {
01196 MEMBER_GET(br, LSM_IS_BLOCK_RANGE, source_start, 0);
01197 }
01198
01199 uint64_t lsm_block_range_dest_start_get(lsm_block_range * br)
01200 {
01201 MEMBER_GET(br, LSM_IS_BLOCK_RANGE, dest_start, 0);
01202 }
01203
01204 uint64_t lsm_block_range_block_count_get(lsm_block_range * br)
01205 {
01206 MEMBER_GET(br, LSM_IS_BLOCK_RANGE, block_count, 0);
01207 }
01208
01209 lsm_fs *lsm_fs_record_alloc(const char *id, const char *name,
01210 uint64_t total_space,
01211 uint64_t free_space,
01212 const char *pool_id,
01213 const char *system_id, const char *plugin_data)
01214 {
01215 lsm_fs *rc = NULL;
01216 rc = (lsm_fs *) calloc(1, sizeof(lsm_fs));
01217 if (rc) {
01218 rc->magic = LSM_FS_MAGIC;
01219 rc->id = strdup(id);
01220 rc->name = strdup(name);
01221 rc->pool_id = strdup(pool_id);
01222 rc->system_id = strdup(system_id);
01223 rc->total_space = total_space;
01224 rc->free_space = free_space;
01225
01226 if (plugin_data) {
01227 rc->plugin_data = strdup(plugin_data);
01228 }
01229
01230 if (!rc->id || !rc->name || !rc->pool_id || !rc->system_id ||
01231 (plugin_data && !rc->plugin_data)) {
01232 lsm_fs_record_free(rc);
01233 rc = NULL;
01234 }
01235 }
01236 return rc;
01237 }
01238
01239 int lsm_fs_record_free(lsm_fs * fs)
01240 {
01241 if (LSM_IS_FS(fs)) {
01242 fs->magic = LSM_DEL_MAGIC(LSM_FS_MAGIC);
01243 free(fs->id);
01244 free(fs->name);
01245 free(fs->pool_id);
01246 free(fs->system_id);
01247 free(fs->plugin_data);
01248 free(fs);
01249 return LSM_ERR_OK;
01250 }
01251 return LSM_ERR_INVALID_ARGUMENT;
01252 }
01253
01254 lsm_fs *lsm_fs_record_copy(lsm_fs * source)
01255 {
01256 lsm_fs *dest = NULL;
01257
01258 if (LSM_IS_FS(source)) {
01259 dest = lsm_fs_record_alloc(source->id, source->name,
01260 source->total_space, source->free_space,
01261 source->pool_id,
01262 source->system_id, source->plugin_data);
01263 }
01264 return dest;
01265 }
01266
01267 CREATE_ALLOC_ARRAY_FUNC(lsm_fs_record_array_alloc, lsm_fs *)
01268 CREATE_FREE_ARRAY_FUNC(lsm_fs_record_array_free, lsm_fs_record_free, lsm_fs *,
01269 LSM_ERR_INVALID_ARGUMENT)
01270
01271 const char *lsm_fs_id_get(lsm_fs * fs)
01272 {
01273 MEMBER_GET(fs, LSM_IS_FS, id, NULL);
01274 }
01275
01276 const char *lsm_fs_name_get(lsm_fs * fs)
01277 {
01278 MEMBER_GET(fs, LSM_IS_FS, name, NULL);
01279 }
01280
01281 const char *lsm_fs_system_id_get(lsm_fs * fs)
01282 {
01283 MEMBER_GET(fs, LSM_IS_FS, system_id, NULL);
01284 }
01285
01286 const char *lsm_fs_pool_id_get(lsm_fs * fs)
01287 {
01288 MEMBER_GET(fs, LSM_IS_FS, pool_id, NULL);
01289 }
01290
01291 uint64_t lsm_fs_total_space_get(lsm_fs * fs)
01292 {
01293 MEMBER_GET(fs, LSM_IS_FS, total_space, 0);
01294 }
01295
01296 uint64_t lsm_fs_free_space_get(lsm_fs * fs)
01297 {
01298 MEMBER_GET(fs, LSM_IS_FS, free_space, 0);
01299 }
01300
01301 MEMBER_FUNC_GET(const char *, lsm_fs_plugin_data_get, lsm_fs * fs,
01302 fs, LSM_IS_POOL, plugin_data, NULL)
01303
01304 lsm_fs_ss *lsm_fs_ss_record_alloc(const char *id, const char *name,
01305 uint64_t ts, const char *plugin_data)
01306 {
01307 lsm_fs_ss *rc = (lsm_fs_ss *) calloc(1, sizeof(lsm_fs_ss));
01308 if (rc) {
01309 rc->magic = LSM_SS_MAGIC;
01310 rc->id = strdup(id);
01311 rc->name = strdup(name);
01312 rc->ts = ts;
01313 if (plugin_data) {
01314 rc->plugin_data = strdup(plugin_data);
01315 }
01316
01317 if (!rc->id || !rc->name || (plugin_data && !rc->plugin_data)) {
01318 lsm_fs_ss_record_free(rc);
01319 rc = NULL;
01320 }
01321 }
01322 return rc;
01323 }
01324
01325 lsm_fs_ss *lsm_fs_ss_record_copy(lsm_fs_ss * source)
01326 {
01327 lsm_fs_ss *rc = NULL;
01328 if (LSM_IS_SS(source)) {
01329 rc = lsm_fs_ss_record_alloc(source->id,
01330 source->name,
01331 source->ts, source->plugin_data);
01332 }
01333 return rc;
01334 }
01335
01336 int lsm_fs_ss_record_free(lsm_fs_ss * ss)
01337 {
01338 if (LSM_IS_SS(ss)) {
01339 ss->magic = LSM_DEL_MAGIC(LSM_SS_MAGIC);
01340 free(ss->id);
01341 free(ss->name);
01342 free(ss->plugin_data);
01343
01344 free(ss);
01345 return LSM_ERR_OK;
01346 }
01347 return LSM_ERR_INVALID_ARGUMENT;
01348 }
01349
01350 CREATE_ALLOC_ARRAY_FUNC(lsm_fs_ss_record_array_alloc, lsm_fs_ss *)
01351
01352 CREATE_FREE_ARRAY_FUNC(lsm_fs_ss_record_array_free, lsm_fs_ss_record_free,
01353 lsm_fs_ss *, LSM_ERR_INVALID_ARGUMENT)
01354
01355 const char *lsm_fs_ss_id_get(lsm_fs_ss * ss)
01356 {
01357 MEMBER_GET(ss, LSM_IS_SS, id, NULL);
01358 }
01359
01360 const char *lsm_fs_ss_name_get(lsm_fs_ss * ss)
01361 {
01362 MEMBER_GET(ss, LSM_IS_SS, name, NULL);
01363 }
01364
01365 uint64_t lsm_fs_ss_time_stamp_get(lsm_fs_ss * ss)
01366 {
01367 MEMBER_GET(ss, LSM_IS_SS, ts, 0);
01368 }
01369
01370 MEMBER_FUNC_GET(const char *, lsm_fs_ss_plugin_data_get, lsm_fs_ss * ss,
01371 ss, LSM_IS_SS, plugin_data, NULL)
01372
01373 lsm_nfs_export *lsm_nfs_export_record_alloc(const char *id,
01374 const char *fs_id,
01375 const char *export_path,
01376 const char *auth,
01377 lsm_string_list * root,
01378 lsm_string_list * rw,
01379 lsm_string_list * ro,
01380 uint64_t anonuid,
01381 uint64_t anongid,
01382 const char *options,
01383 const char *plugin_data)
01384 {
01385 lsm_nfs_export *rc = NULL;
01386
01387
01388 if (fs_id) {
01389 rc = (lsm_nfs_export *) calloc(1, sizeof(lsm_nfs_export));
01390 if (rc) {
01391 rc->magic = LSM_NFS_EXPORT_MAGIC;
01392 rc->id = (id) ? strdup(id) : NULL;
01393 rc->fs_id = strdup(fs_id);
01394 rc->export_path = (export_path) ? strdup(export_path) : NULL;
01395 rc->auth_type = (auth) ? strdup(auth) : NULL;
01396 rc->root = lsm_string_list_copy(root);
01397 rc->rw = lsm_string_list_copy(rw);
01398 rc->ro = lsm_string_list_copy(ro);
01399 rc->anonuid = anonuid;
01400 rc->anongid = anongid;
01401 rc->options = (options) ? strdup(options) : NULL;
01402
01403 if (plugin_data) {
01404 rc->plugin_data = strdup(plugin_data);
01405 }
01406
01407 if (!rc->id ||
01408 !rc->fs_id ||
01409 (export_path && !rc->export_path) ||
01410 (auth && !rc->auth_type) ||
01411 (root && !rc->root) ||
01412 (rw && !rc->rw) ||
01413 (ro && !rc->ro) ||
01414 (options && !rc->options) ||
01415 (plugin_data && !rc->plugin_data)) {
01416 lsm_nfs_export_record_free(rc);
01417 rc = NULL;
01418 }
01419 }
01420 }
01421
01422 return rc;
01423 }
01424
01425 int lsm_nfs_export_record_free(lsm_nfs_export * exp)
01426 {
01427 if (LSM_IS_NFS_EXPORT(exp)) {
01428 exp->magic = LSM_DEL_MAGIC(LSM_NFS_EXPORT_MAGIC);
01429 free(exp->id);
01430 free(exp->fs_id);
01431 free(exp->export_path);
01432 free(exp->auth_type);
01433 lsm_string_list_free(exp->root);
01434 lsm_string_list_free(exp->rw);
01435 lsm_string_list_free(exp->ro);
01436 free(exp->options);
01437 free(exp->plugin_data);
01438
01439 free(exp);
01440 return LSM_ERR_OK;
01441 }
01442 return LSM_ERR_INVALID_ARGUMENT;
01443 }
01444
01445
01446 lsm_nfs_export *lsm_nfs_export_record_copy(lsm_nfs_export * s)
01447 {
01448 if (LSM_IS_NFS_EXPORT(s)) {
01449 return lsm_nfs_export_record_alloc(s->id, s->fs_id, s->export_path,
01450 s->auth_type, s->root, s->rw, s->ro,
01451 s->anonuid, s->anongid, s->options,
01452 s->plugin_data);
01453 }
01454 return NULL;
01455 }
01456
01457 CREATE_ALLOC_ARRAY_FUNC(lsm_nfs_export_record_array_alloc, lsm_nfs_export *)
01458 CREATE_FREE_ARRAY_FUNC(lsm_nfs_export_record_array_free,
01459 lsm_nfs_export_record_free, lsm_nfs_export *,
01460 LSM_ERR_INVALID_ARGUMENT)
01461
01462 const char *lsm_nfs_export_id_get(lsm_nfs_export * exp)
01463 {
01464 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, id, NULL);
01465 }
01466
01467 int lsm_nfs_export_id_set(lsm_nfs_export * exp, const char *ep)
01468 {
01469 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, id, ep, strdup, free,
01470 LSM_ERR_INVALID_ARGUMENT);
01471 }
01472
01473 const char *lsm_nfs_export_fs_id_get(lsm_nfs_export * exp)
01474 {
01475 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, fs_id, NULL);
01476 }
01477
01478 int lsm_nfs_export_fs_id_set(lsm_nfs_export * exp, const char *fs_id)
01479 {
01480 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, fs_id, fs_id, strdup, free,
01481 LSM_ERR_INVALID_ARGUMENT);
01482 }
01483
01484 const char *lsm_nfs_export_export_path_get(lsm_nfs_export * exp)
01485 {
01486 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, export_path, NULL);
01487 }
01488
01489 int lsm_nfs_export_export_path_set(lsm_nfs_export * exp, const char *ep)
01490 {
01491 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, export_path, ep, strdup, free,
01492 LSM_ERR_INVALID_ARGUMENT);
01493 }
01494
01495 const char *lsm_nfs_export_auth_type_get(lsm_nfs_export * exp)
01496 {
01497 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, auth_type, NULL);
01498 }
01499
01500 int lsm_nfs_export_auth_type_set(lsm_nfs_export * exp, const char *auth)
01501 {
01502 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, auth_type, auth, strdup, free,
01503 LSM_ERR_INVALID_ARGUMENT);
01504 }
01505
01506 lsm_string_list *lsm_nfs_export_root_get(lsm_nfs_export * exp)
01507 {
01508 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, root, NULL);
01509 }
01510
01511 int lsm_nfs_export_root_set(lsm_nfs_export * exp, lsm_string_list * root)
01512 {
01513 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, root, root, lsm_string_list_copy,
01514 lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
01515 }
01516
01517 lsm_string_list *lsm_nfs_export_read_write_get(lsm_nfs_export * exp)
01518 {
01519 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, rw, NULL);
01520 }
01521
01522 int lsm_nfs_export_read_write_set(lsm_nfs_export * exp, lsm_string_list * rw)
01523 {
01524 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, rw, rw, lsm_string_list_copy,
01525 lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
01526 }
01527
01528 lsm_string_list *lsm_nfs_export_read_only_get(lsm_nfs_export * exp)
01529 {
01530 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, ro, NULL);
01531 }
01532
01533 int lsm_nfs_export_read_only_set(lsm_nfs_export * exp, lsm_string_list * ro)
01534 {
01535 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, ro, ro, lsm_string_list_copy,
01536 lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
01537 }
01538
01539 uint64_t lsm_nfs_export_anon_uid_get(lsm_nfs_export * exp)
01540 {
01541 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, anonuid, ANON_UID_GID_ERROR);
01542 }
01543
01544 int lsm_nfs_export_anon_uid_set(lsm_nfs_export * exp, uint64_t value)
01545 {
01546 MEMBER_SET_VAL(exp, LSM_IS_NFS_EXPORT, anonuid, value,
01547 LSM_ERR_INVALID_ARGUMENT);
01548 }
01549
01550 uint64_t lsm_nfs_export_anon_gid_get(lsm_nfs_export * exp)
01551 {
01552 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, anongid, ANON_UID_GID_ERROR);
01553 }
01554
01555 int lsm_nfs_export_anon_gid_set(lsm_nfs_export * exp, uint64_t value)
01556 {
01557 MEMBER_SET_VAL(exp, LSM_IS_NFS_EXPORT, anongid, value,
01558 LSM_ERR_INVALID_ARGUMENT);
01559 }
01560
01561 const char *lsm_nfs_export_options_get(lsm_nfs_export * exp)
01562 {
01563 MEMBER_GET(exp, LSM_IS_NFS_EXPORT, options, NULL);
01564 }
01565
01566 int lsm_nfs_export_options_set(lsm_nfs_export * exp, const char *value)
01567 {
01568 MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, options, value, strdup, free,
01569 LSM_ERR_INVALID_ARGUMENT);
01570 }
01571
01572 MEMBER_FUNC_GET(const char *, lsm_nfs_export_plugin_data_get,
01573 lsm_nfs_export * exp, exp, LSM_IS_NFS_EXPORT, plugin_data, NULL)
01574
01575 lsm_capability_value_type lsm_capability_get(lsm_storage_capabilities * cap,
01576 lsm_capability_type t)
01577 {
01578 lsm_capability_value_type rc = LSM_CAP_UNSUPPORTED;
01579
01580 if (LSM_IS_CAPABILITIY(cap) && (uint32_t) t < cap->len) {
01581 rc = (lsm_capability_value_type) cap->cap[t];
01582 }
01583 return rc;
01584 }
01585
01586 int LSM_DLL_EXPORT lsm_capability_supported(lsm_storage_capabilities * cap,
01587 lsm_capability_type t)
01588 {
01589 if (lsm_capability_get(cap, t) == LSM_CAP_SUPPORTED) {
01590 return 1;
01591 }
01592 return 0;
01593 }
01594
01595 int lsm_capability_set(lsm_storage_capabilities * cap, lsm_capability_type t,
01596 lsm_capability_value_type v)
01597 {
01598 int rc = LSM_ERR_INVALID_ARGUMENT;
01599
01600 if (LSM_IS_CAPABILITIY(cap)) {
01601 if ((uint32_t) t < cap->len) {
01602 cap->cap[t] = v;
01603 rc = LSM_ERR_OK;
01604 }
01605 }
01606
01607 return rc;
01608 }
01609
01610 int lsm_capability_set_n(lsm_storage_capabilities * cap,
01611 lsm_capability_value_type v, ...)
01612 {
01613 int rc = LSM_ERR_OK;
01614 int index = 0;
01615
01616 if (!LSM_IS_CAPABILITIY(cap)) {
01617 return LSM_ERR_INVALID_ARGUMENT;
01618 }
01619
01620 va_list var_arg;
01621 va_start(var_arg, v);
01622
01623 while ((index = va_arg(var_arg, int)) != -1) {
01624 if (index < (int) cap->len) {
01625 cap->cap[index] = v;
01626 } else {
01627 rc = LSM_ERR_INVALID_ARGUMENT;
01628 break;
01629 }
01630 }
01631
01632 va_end(var_arg);
01633 return rc;
01634 }
01635
01636 static char *bytes_to_string(uint8_t * a, uint32_t len)
01637 {
01638 char *buff = NULL;
01639
01640 if (a && len) {
01641 uint32_t i = 0;
01642 char *tmp = NULL;
01643 size_t str_len = ((sizeof(char) * 2) * len + 1);
01644 buff = (char *) malloc(str_len);
01645
01646 if (buff) {
01647 tmp = buff;
01648 for (i = 0; i < len; ++i) {
01649 tmp += sprintf(tmp, "%02x", a[i]);
01650 }
01651 buff[str_len - 1] = '\0';
01652 }
01653 }
01654 return buff;
01655 }
01656
01657 static uint8_t *string_to_bytes(const char *hex_string, uint32_t * l)
01658 {
01659 uint8_t *rc = NULL;
01660
01661 if (hex_string && l) {
01662 size_t len = strlen(hex_string);
01663 if (len && (len % 2) == 0) {
01664 len /= 2;
01665 rc = (uint8_t *) malloc(sizeof(uint8_t) * len);
01666 if (rc) {
01667 size_t i;
01668 const char *t = hex_string;
01669 *l = len;
01670
01671 for (i = 0; i < len; ++i) {
01672 if (1 != sscanf(t, "%02hhx", &rc[i])) {
01673 free(rc);
01674 rc = NULL;
01675 *l = 0;
01676 break;
01677 }
01678 t += 2;
01679 }
01680 }
01681 }
01682 }
01683 return rc;
01684 }
01685
01686
01687 lsm_storage_capabilities *lsm_capability_record_alloc(const char *value)
01688 {
01689 lsm_storage_capabilities *rc = NULL;
01690 rc = (lsm_storage_capabilities *)
01691 malloc(sizeof(struct _lsm_storage_capabilities));
01692 if (rc) {
01693 rc->magic = LSM_CAPABILITIES_MAGIC;
01694
01695 if (value) {
01696 rc->cap = string_to_bytes(value, &rc->len);
01697 } else {
01698 rc->cap = (uint8_t *) calloc(LSM_CAP_MAX, sizeof(uint8_t));
01699 if (rc->cap) {
01700 rc->len = LSM_CAP_MAX;
01701 }
01702 }
01703
01704 if (!rc->cap) {
01705 lsm_capability_record_free(rc);
01706 rc = NULL;
01707 }
01708 }
01709 return rc;
01710 }
01711
01712 int lsm_capability_record_free(lsm_storage_capabilities * cap)
01713 {
01714 if (LSM_IS_CAPABILITIY(cap)) {
01715 cap->magic = LSM_DEL_MAGIC(LSM_CAPABILITIES_MAGIC);
01716 free(cap->cap);
01717 free(cap);
01718 return LSM_ERR_OK;
01719 }
01720 return LSM_ERR_INVALID_ARGUMENT;
01721 }
01722
01723 char *capability_string(lsm_storage_capabilities * c)
01724 {
01725 char *rc = NULL;
01726 if (LSM_IS_CAPABILITIY(c)) {
01727 rc = bytes_to_string(c->cap, c->len);
01728 }
01729 return rc;
01730 }
01731
01732 lsm_hash *lsm_hash_alloc(void)
01733 {
01734 lsm_hash *rc = NULL;
01735
01736 rc = (lsm_hash *) malloc(sizeof(lsm_hash));
01737 if (rc) {
01738 rc->magic = LSM_HASH_MAGIC;
01739 rc->data = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
01740 if (!rc->data) {
01741 lsm_hash_free(rc);
01742 rc = NULL;
01743 }
01744 }
01745 return rc;
01746 }
01747
01748 lsm_hash *lsm_hash_copy(lsm_hash * src)
01749 {
01750 GHashTableIter iter;
01751 gpointer key;
01752 gpointer value;
01753
01754 lsm_hash *dest = NULL;
01755 if (LSM_IS_HASH(src)) {
01756 dest = lsm_hash_alloc();
01757 if (dest) {
01758
01759 g_hash_table_iter_init(&iter, src->data);
01760 while (g_hash_table_iter_next(&iter, &key, &value)) {
01761 if (LSM_ERR_OK != lsm_hash_string_set(dest,
01762 (const char *) key,
01763 (const char *) value)) {
01764 lsm_hash_free(dest);
01765 dest = NULL;
01766 }
01767 }
01768 }
01769 }
01770 return dest;
01771 }
01772
01773 int lsm_hash_free(lsm_hash * op)
01774 {
01775 if (LSM_IS_HASH(op)) {
01776 op->magic = LSM_DEL_MAGIC(LSM_HASH_MAGIC);
01777
01778 if (op->data) {
01779 g_hash_table_destroy(op->data);
01780 }
01781
01782 free(op);
01783 return LSM_ERR_OK;
01784 }
01785 return LSM_ERR_INVALID_ARGUMENT;
01786 }
01787
01788 int lsm_hash_keys(lsm_hash * op, lsm_string_list ** l)
01789 {
01790 GHashTableIter iter;
01791 gpointer key;
01792 gpointer value;
01793
01794
01795 if (LSM_IS_HASH(op)) {
01796 int count = g_hash_table_size(op->data);
01797
01798 if (count) {
01799 *l = lsm_string_list_alloc(0);
01800 g_hash_table_iter_init(&iter, op->data);
01801 while (g_hash_table_iter_next(&iter, &key, &value)) {
01802 if (LSM_ERR_OK != lsm_string_list_append(*l, (char *) key)) {
01803 lsm_string_list_free(*l);
01804 *l = NULL;
01805 return LSM_ERR_NO_MEMORY;
01806 }
01807 }
01808 }
01809 return LSM_ERR_OK;
01810 }
01811 return LSM_ERR_INVALID_ARGUMENT;
01812 }
01813
01814 const char *lsm_hash_string_get(lsm_hash * op, const char *key)
01815 {
01816 if (LSM_IS_HASH(op)) {
01817 return (const char *) g_hash_table_lookup(op->data, key);
01818 }
01819 return NULL;
01820 }
01821
01822 int lsm_hash_string_set(lsm_hash * op, const char *key, const char *value)
01823 {
01824 if (LSM_IS_HASH(op)) {
01825 char *k_value = strdup(key);
01826 char *d_value = strdup(value);
01827
01828 if (k_value && d_value) {
01829 g_hash_table_remove(op->data, (gpointer) k_value);
01830 g_hash_table_insert(op->data, (gpointer) k_value,
01831 (gpointer) d_value);
01832 return LSM_ERR_OK;
01833 } else {
01834 free(k_value);
01835 free(d_value);
01836 return LSM_ERR_NO_MEMORY;
01837 }
01838 }
01839 return LSM_ERR_INVALID_ARGUMENT;
01840 }
01841
01842 lsm_target_port *lsm_target_port_record_alloc(const char *id,
01843 lsm_target_port_type port_type,
01844 const char *service_address,
01845 const char *network_address,
01846 const char *physical_address,
01847 const char *physical_name,
01848 const char *system_id,
01849 const char *plugin_data)
01850 {
01851 lsm_target_port *rc =
01852 (lsm_target_port *) calloc(1, sizeof(lsm_target_port));
01853 if (rc) {
01854 rc->magic = LSM_TARGET_PORT_MAGIC;
01855 rc->id = strdup(id);
01856 rc->port_type = port_type;
01857 rc->service_address = strdup(service_address);
01858 rc->network_address = strdup(network_address);
01859 rc->physical_address = strdup(physical_address);
01860 rc->physical_name = strdup(physical_name);
01861 rc->system_id = strdup(system_id);
01862 rc->plugin_data = (plugin_data) ? strdup(plugin_data) : NULL;
01863
01864 if (!rc->id || !rc->service_address || !rc->network_address ||
01865 !rc->physical_address || !rc->physical_name ||
01866 !rc->system_id || (plugin_data && !rc->plugin_data)) {
01867 lsm_target_port_record_free(rc);
01868 rc = NULL;
01869 }
01870 }
01871 return rc;
01872 }
01873
01874 int lsm_target_port_record_free(lsm_target_port * tp)
01875 {
01876 if (LSM_IS_TARGET_PORT(tp)) {
01877 tp->magic = LSM_DEL_MAGIC(LSM_TARGET_PORT_MAGIC);
01878 free(tp->id);
01879 tp->id = NULL;
01880 free(tp->plugin_data);
01881 tp->plugin_data = NULL;
01882 free(tp->system_id);
01883 tp->system_id = NULL;
01884 free(tp->physical_name);
01885 tp->physical_name = NULL;
01886 free(tp->physical_address);
01887 tp->physical_address = NULL;
01888 free(tp->network_address);
01889 tp->network_address = NULL;
01890 free(tp->service_address);
01891 tp->service_address = NULL;
01892 free(tp);
01893 return LSM_ERR_OK;
01894 }
01895 return LSM_ERR_INVALID_ARGUMENT;
01896 }
01897
01898 lsm_target_port LSM_DLL_EXPORT *lsm_target_port_copy(lsm_target_port * tp)
01899 {
01900 lsm_target_port *rc = NULL;
01901
01902 if (LSM_IS_TARGET_PORT(tp)) {
01903 rc = lsm_target_port_record_alloc(tp->id, tp->port_type,
01904 tp->service_address,
01905 tp->network_address,
01906 tp->physical_address,
01907 tp->physical_name,
01908 tp->system_id, tp->plugin_data);
01909 }
01910 return rc;
01911 }
01912
01913 MEMBER_FUNC_GET(const char *, lsm_target_port_id_get, lsm_target_port * tp, tp,
01914 LSM_IS_TARGET_PORT, id, NULL)
01915
01916 MEMBER_FUNC_GET(lsm_target_port_type, lsm_target_port_type_get,
01917 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, port_type,
01918 LSM_TARGET_PORT_TYPE_OTHER)
01919
01920 MEMBER_FUNC_GET(const char *, lsm_target_port_service_address_get,
01921 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, service_address,
01922 NULL)
01923
01924 MEMBER_FUNC_GET(const char *, lsm_target_port_network_address_get,
01925 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, network_address,
01926 NULL)
01927
01928 MEMBER_FUNC_GET(const char *, lsm_target_port_physical_address_get,
01929 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, physical_address,
01930 NULL)
01931
01932 MEMBER_FUNC_GET(const char *, lsm_target_port_physical_name_get,
01933 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, physical_name,
01934 NULL)
01935
01936 MEMBER_FUNC_GET(const char *, lsm_target_port_system_id_get,
01937 lsm_target_port * tp, tp, LSM_IS_TARGET_PORT, system_id, NULL)
01938
01939 CREATE_ALLOC_ARRAY_FUNC(lsm_target_port_record_array_alloc,
01940 lsm_target_port *)
01941
01942 CREATE_FREE_ARRAY_FUNC(lsm_target_port_record_array_free,
01943 lsm_target_port_record_free, lsm_target_port *,
01944 LSM_ERR_INVALID_ARGUMENT)
01945
01946 static int reg_ex_match(const char *pattern, const char *str)
01947 {
01948 regex_t start_state;
01949 int status = 0;
01950 int rc = regcomp(&start_state, pattern, REG_EXTENDED);
01951
01952 if (rc) {
01953
01954
01955 return -1;
01956 }
01957
01958 status = regexec(&start_state, str, 0, NULL, 0);
01959 regfree(&start_state);
01960
01961 return status;
01962 }
01963
01964 int iqn_validate(const char *iqn)
01965 {
01966 if ((iqn && strlen(iqn) > 4) && (0 == strncmp(iqn, "iqn", 3) ||
01967 0 == strncmp(iqn, "naa", 3)
01968 || 0 == strncmp(iqn, "eui", 3))) {
01969 return LSM_ERR_OK;
01970 }
01971 return LSM_ERR_INVALID_ARGUMENT;
01972 }
01973
01974 int wwpn_validate(const char *wwpn)
01975 {
01976 const char *pattern = "^(0x|0X)?([0-9A-Fa-f]{2})"
01977 "(([\\.\\:\\-])?[0-9A-Fa-f]{2}){7}$";
01978 if (0 == reg_ex_match(pattern, wwpn)) {
01979 return LSM_ERR_OK;
01980 }
01981 return LSM_ERR_INVALID_ARGUMENT;
01982 }
01983
01984 char *wwpn_convert(const char *wwpn)
01985 {
01986 size_t i = 0;
01987 size_t out = 0;
01988 char *rc = NULL;
01989
01990 if (LSM_ERR_OK == wwpn_validate(wwpn)) {
01991 rc = (char *) calloc(24, 1);
01992 size_t len = strlen(wwpn);
01993
01994 if (wwpn[1] == 'x' || wwpn[1] == 'X') {
01995 i = 2;
01996 }
01997
01998 for (; i < len; ++i) {
01999 if (wwpn[i] != ':' && wwpn[i] != '-' && wwpn[i] != '.') {
02000 rc[out++] = tolower(wwpn[i]);
02001 } else {
02002 rc[out++] = ':';
02003 }
02004 }
02005 }
02006 return rc;
02007 }
02008
02009 #ifdef __cplusplus
02010 }
02011 #endif