00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "lsm_plugin_ipc.hpp"
00020 #include "lsm_datatypes.hpp"
00021 #include "lsm_ipc.hpp"
00022 #include "lsm_convert.hpp"
00023 #include "libstoragemgmt/libstoragemgmt_systems.h"
00024 #include "libstoragemgmt/libstoragemgmt_blockrange.h"
00025 #include "libstoragemgmt/libstoragemgmt_disk.h"
00026 #include "libstoragemgmt/libstoragemgmt_accessgroups.h"
00027 #include "libstoragemgmt/libstoragemgmt_fs.h"
00028 #include "libstoragemgmt/libstoragemgmt_snapshot.h"
00029 #include "libstoragemgmt/libstoragemgmt_nfsexport.h"
00030 #include "libstoragemgmt/libstoragemgmt_plug_interface.h"
00031 #include "libstoragemgmt/libstoragemgmt_targetport.h"
00032 #include "libstoragemgmt/libstoragemgmt_volumes.h"
00033 #include "libstoragemgmt/libstoragemgmt_pool.h"
00034 #include <errno.h>
00035 #include <string.h>
00036 #include <libxml/uri.h>
00037 #include "util/qparams.h"
00038 #include <syslog.h>
00039
00040
00041 static int lsm_plugin_run(lsm_plugin_ptr plug);
00042
00048 static std::string ss(char *s)
00049 {
00050 if (s) {
00051 return std::string(s);
00052 }
00053 return std::string();
00054 }
00055
00056 void *lsm_data_type_copy(lsm_data_type t, void *item)
00057 {
00058 void *rc = NULL;
00059
00060 if (item) {
00061 switch (t) {
00062 case (LSM_DATA_TYPE_ACCESS_GROUP):
00063 rc = lsm_access_group_record_copy((lsm_access_group *) item);
00064 break;
00065 case (LSM_DATA_TYPE_BLOCK_RANGE):
00066 rc = lsm_block_range_record_copy((lsm_block_range *) item);
00067 break;
00068 case (LSM_DATA_TYPE_FS):
00069 rc = lsm_fs_record_copy((lsm_fs *) item);
00070 break;
00071 case (LSM_DATA_TYPE_NFS_EXPORT):
00072 rc = lsm_nfs_export_record_copy((lsm_nfs_export *) item);
00073 break;
00074 case (LSM_DATA_TYPE_POOL):
00075 rc = lsm_pool_record_copy((lsm_pool *) item);
00076 break;
00077 case (LSM_DATA_TYPE_SS):
00078 rc = lsm_fs_ss_record_copy((lsm_fs_ss *) item);
00079 break;
00080 case (LSM_DATA_TYPE_STRING_LIST):
00081 rc = lsm_string_list_copy((lsm_string_list *) item);
00082 break;
00083 case (LSM_DATA_TYPE_SYSTEM):
00084 rc = lsm_system_record_copy((lsm_system *) item);
00085 break;
00086 case (LSM_DATA_TYPE_VOLUME):
00087 rc = lsm_volume_record_copy((lsm_volume *) item);
00088 break;
00089 case (LSM_DATA_TYPE_DISK):
00090 rc = lsm_disk_record_copy((lsm_disk *) item);
00091 break;
00092 default:
00093 break;
00094 }
00095 }
00096 return rc;
00097 }
00098
00099 static Value job_handle(const Value & val, char *job)
00100 {
00101 std::vector < Value > r;
00102 r.push_back(Value(job));
00103 r.push_back(val);
00104 return Value(r);
00105 }
00106
00107 int lsm_register_plugin_v1(lsm_plugin_ptr plug,
00108 void *private_data,
00109 struct lsm_mgmt_ops_v1 *mgm_op,
00110 struct lsm_san_ops_v1 *san_op,
00111 struct lsm_fs_ops_v1 *fs_op,
00112 struct lsm_nas_ops_v1 *nas_op)
00113 {
00114 int rc = LSM_ERR_INVALID_ARGUMENT;
00115
00116 if (LSM_IS_PLUGIN(plug)) {
00117 plug->private_data = private_data;
00118 plug->mgmt_ops = mgm_op;
00119 plug->san_ops = san_op;
00120 plug->fs_ops = fs_op;
00121 plug->nas_ops = nas_op;
00122 rc = LSM_ERR_OK;
00123 }
00124 return rc;
00125 }
00126
00127 int lsm_register_plugin_v1_2(lsm_plugin_ptr plug, void *private_data,
00128 struct lsm_mgmt_ops_v1 *mgm_op,
00129 struct lsm_san_ops_v1 *san_op,
00130 struct lsm_fs_ops_v1 *fs_op,
00131 struct lsm_nas_ops_v1 *nas_op,
00132 struct lsm_ops_v1_2 *ops_v1_2)
00133 {
00134 int rc = lsm_register_plugin_v1(plug, private_data, mgm_op, san_op, fs_op,
00135 nas_op);
00136
00137 if (rc != LSM_ERR_OK) {
00138 return rc;
00139 }
00140 plug->ops_v1_2 = ops_v1_2;
00141 return rc;
00142 }
00143
00144 void *lsm_private_data_get(lsm_plugin_ptr plug)
00145 {
00146 if (!LSM_IS_PLUGIN(plug)) {
00147 return NULL;
00148 }
00149
00150 return plug->private_data;
00151 }
00152
00153 static void lsm_plugin_free(lsm_plugin_ptr p, lsm_flag flags)
00154 {
00155 if (LSM_IS_PLUGIN(p)) {
00156
00157 delete(p->tp);
00158 p->tp = NULL;
00159
00160 if (p->unreg) {
00161 p->unreg(p, flags);
00162 }
00163
00164 free(p->desc);
00165 p->desc = NULL;
00166
00167 free(p->version);
00168 p->version = NULL;
00169
00170 lsm_error_free(p->error);
00171 p->error = NULL;
00172
00173 p->magic = LSM_DEL_MAGIC(LSM_PLUGIN_MAGIC);
00174
00175 free(p);
00176 }
00177 }
00178
00179 static lsm_plugin_ptr lsm_plugin_alloc(lsm_plugin_register reg,
00180 lsm_plugin_unregister unreg,
00181 const char *desc, const char *version)
00182 {
00183
00184 if (!reg || !unreg) {
00185 return NULL;
00186 }
00187
00188 lsm_plugin_ptr rc = (lsm_plugin_ptr) calloc(1, sizeof(lsm_plugin));
00189 if (rc) {
00190 rc->magic = LSM_PLUGIN_MAGIC;
00191 rc->reg = reg;
00192 rc->unreg = unreg;
00193 rc->desc = strdup(desc);
00194 rc->version = strdup(version);
00195
00196 if (!rc->desc || !rc->version) {
00197 lsm_plugin_free(rc, LSM_CLIENT_FLAG_RSVD);
00198 rc = NULL;
00199 }
00200 }
00201 return rc;
00202 }
00203
00204 static void error_send(lsm_plugin_ptr p, int error_code)
00205 {
00206 if (!LSM_IS_PLUGIN(p)) {
00207 return;
00208 }
00209
00210 if (p->error) {
00211 if (p->tp) {
00212 p->tp->errorSend(p->error->code, ss(p->error->message),
00213 ss(p->error->debug));
00214 lsm_error_free(p->error);
00215 p->error = NULL;
00216 }
00217 } else {
00218 p->tp->errorSend(error_code, "Plugin didn't provide error message", "");
00219 }
00220 }
00221
00222 static int get_search_params(Value & params, char **k, char **v)
00223 {
00224 int rc = LSM_ERR_OK;
00225 Value key = params["search_key"];
00226 Value val = params["search_value"];
00227
00228 if (Value::string_t == key.valueType()) {
00229 if (Value::string_t == val.valueType()) {
00230 *k = strdup(key.asC_str());
00231 *v = strdup(val.asC_str());
00232
00233 if (*k == NULL || *v == NULL) {
00234 free(*k);
00235 *k = NULL;
00236 free(*v);
00237 *v = NULL;
00238 rc = LSM_ERR_NO_MEMORY;
00239 }
00240 } else {
00241 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00242 }
00243 } else if (Value::null_t != key.valueType()) {
00244 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00245 }
00246
00247 return rc;
00248 }
00249
00256 static bool get_num(char *sn, int &num)
00257 {
00258 errno = 0;
00259
00260 num = strtol(sn, NULL, 10);
00261 if (!errno) {
00262 return true;
00263 }
00264 return false;
00265 }
00266
00267 int lsm_plugin_init_v1(int argc, char *argv[], lsm_plugin_register reg,
00268 lsm_plugin_unregister unreg,
00269 const char *desc, const char *version)
00270 {
00271 int rc = 1;
00272 lsm_plugin_ptr plug = NULL;
00273
00274 if (NULL == desc || NULL == version) {
00275 return LSM_ERR_INVALID_ARGUMENT;
00276 }
00277
00278 int sd = 0;
00279 if (argc == 2 && get_num(argv[1], sd)) {
00280 plug = lsm_plugin_alloc(reg, unreg, desc, version);
00281 if (plug) {
00282 plug->tp = new Ipc(sd);
00283 if (plug->tp) {
00284 rc = lsm_plugin_run(plug);
00285 } else {
00286 lsm_plugin_free(plug, LSM_CLIENT_FLAG_RSVD);
00287 rc = LSM_ERR_NO_MEMORY;
00288 }
00289 } else {
00290 rc = LSM_ERR_NO_MEMORY;
00291 }
00292 } else {
00293
00294 rc = 2;
00295 }
00296
00297 return rc;
00298 }
00299
00300 typedef int (*handler) (lsm_plugin_ptr p, Value & params, Value & response);
00301
00302 static int handle_unregister(lsm_plugin_ptr p, Value & params, Value & response)
00303 {
00304
00305 return LSM_ERR_OK;
00306 }
00307
00308 static int handle_register(lsm_plugin_ptr p, Value & params, Value & response)
00309 {
00310 int rc = LSM_ERR_NO_SUPPORT;
00311 std::string uri_string;
00312 std::string password;
00313
00314 if (p && p->reg) {
00315
00316 Value uri_v = params["uri"];
00317 Value passwd_v = params["password"];
00318 Value tmo_v = params["timeout"];
00319
00320 if (Value::string_t == uri_v.valueType() &&
00321 (Value::string_t == passwd_v.valueType() ||
00322 Value::null_t == passwd_v.valueType()) &&
00323 Value::numeric_t == tmo_v.valueType()) {
00324 lsm_flag flags = LSM_FLAG_GET_VALUE(params);
00325
00326 uri_string = uri_v.asString();
00327
00328 if (Value::string_t == params["password"].valueType()) {
00329 password = params["password"].asString();
00330 }
00331
00332 rc = p->reg(p, uri_string.c_str(), password.c_str(),
00333 tmo_v.asUint32_t(), flags);
00334 } else {
00335 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00336 }
00337 } else {
00338 rc = LSM_ERR_NO_SUPPORT;
00339 }
00340 return rc;
00341 }
00342
00343 static int handle_set_time_out(lsm_plugin_ptr p, Value & params,
00344 Value & response)
00345 {
00346 if (p && p->mgmt_ops && p->mgmt_ops->tmo_set) {
00347 if (Value::numeric_t == params["ms"].valueType() &&
00348 LSM_FLAG_EXPECTED_TYPE(params)) {
00349 return p->mgmt_ops->tmo_set(p, params["ms"].asUint32_t(),
00350 LSM_FLAG_GET_VALUE(params));
00351 } else {
00352 return LSM_ERR_TRANSPORT_INVALID_ARG;
00353 }
00354 }
00355 return LSM_ERR_NO_SUPPORT;
00356 }
00357
00358 static int handle_get_time_out(lsm_plugin_ptr p, Value & params,
00359 Value & response)
00360 {
00361 uint32_t tmo = 0;
00362 int rc = LSM_ERR_NO_SUPPORT;
00363
00364 if (p && p->mgmt_ops && p->mgmt_ops->tmo_get) {
00365
00366 if (LSM_FLAG_EXPECTED_TYPE(params)) {
00367 rc = p->mgmt_ops->tmo_get(p, &tmo, LSM_FLAG_GET_VALUE(params));
00368 if (LSM_ERR_OK == rc) {
00369 response = Value(tmo);
00370 }
00371 } else {
00372 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00373 }
00374 }
00375 return rc;
00376 }
00377
00378 static int handle_job_status(lsm_plugin_ptr p, Value & params, Value & response)
00379 {
00380 std::string job_id;
00381 lsm_job_status status;
00382 uint8_t percent;
00383 lsm_data_type t = LSM_DATA_TYPE_UNKNOWN;
00384 void *value = NULL;
00385 int rc = LSM_ERR_NO_SUPPORT;
00386
00387 if (p && p->mgmt_ops && p->mgmt_ops->job_status) {
00388
00389 if (Value::string_t != params["job_id"].valueType() &&
00390 !LSM_FLAG_EXPECTED_TYPE(params)) {
00391 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00392 } else {
00393
00394 job_id = params["job_id"].asString();
00395
00396 rc = p->mgmt_ops->job_status(p, job_id.c_str(), &status,
00397 &percent, &t, &value,
00398 LSM_FLAG_GET_VALUE(params));
00399
00400 if (LSM_ERR_OK == rc) {
00401 std::vector < Value > result;
00402
00403 result.push_back(Value((int32_t) status));
00404 result.push_back(Value(percent));
00405
00406 if (NULL == value) {
00407 result.push_back(Value());
00408 } else {
00409 if (LSM_DATA_TYPE_VOLUME == t &&
00410 LSM_IS_VOL((lsm_volume *) value)) {
00411 result.push_back(volume_to_value((lsm_volume *) value));
00412 lsm_volume_record_free((lsm_volume *) value);
00413 } else if (LSM_DATA_TYPE_FS == t &&
00414 LSM_IS_FS((lsm_fs *) value)) {
00415 result.push_back(fs_to_value((lsm_fs *) value));
00416 lsm_fs_record_free((lsm_fs *) value);
00417 } else if (LSM_DATA_TYPE_SS == t &&
00418 LSM_IS_SS((lsm_fs_ss *) value)) {
00419 result.push_back(ss_to_value((lsm_fs_ss *) value));
00420 lsm_fs_ss_record_free((lsm_fs_ss *) value);
00421 } else if (LSM_DATA_TYPE_POOL == t &&
00422 LSM_IS_POOL((lsm_pool *) value)) {
00423 result.push_back(pool_to_value((lsm_pool *) value));
00424 lsm_pool_record_free((lsm_pool *) value);
00425 } else {
00426 rc = LSM_ERR_PLUGIN_BUG;
00427 }
00428 }
00429 response = Value(result);
00430 }
00431 }
00432 }
00433 return rc;
00434 }
00435
00436 static int handle_plugin_info(lsm_plugin_ptr p, Value & params,
00437 Value & response)
00438 {
00439 int rc = LSM_ERR_NO_SUPPORT;
00440 if (p) {
00441 std::vector < Value > result;
00442 result.push_back(Value(p->desc));
00443 result.push_back(Value(p->version));
00444 response = Value(result);
00445 rc = LSM_ERR_OK;
00446 }
00447 return rc;
00448 }
00449
00450 static int handle_job_free(lsm_plugin_ptr p, Value & params, Value & response)
00451 {
00452 int rc = LSM_ERR_NO_SUPPORT;
00453 if (p && p->mgmt_ops && p->mgmt_ops->job_free) {
00454 if (Value::string_t == params["job_id"].valueType() &&
00455 LSM_FLAG_EXPECTED_TYPE(params)) {
00456 std::string job_num = params["job_id"].asString();
00457 char *j = (char *) job_num.c_str();
00458 rc = p->mgmt_ops->job_free(p, j, LSM_FLAG_GET_VALUE(params));
00459 } else {
00460 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00461 }
00462 }
00463 return rc;
00464 }
00465
00466 static int handle_system_list(lsm_plugin_ptr p, Value & params,
00467 Value & response)
00468 {
00469 int rc = LSM_ERR_NO_SUPPORT;
00470
00471 if (p && p->mgmt_ops && p->mgmt_ops->system_list) {
00472 lsm_system **systems;
00473 uint32_t count = 0;
00474
00475 if (LSM_FLAG_EXPECTED_TYPE(params)) {
00476
00477 rc = p->mgmt_ops->system_list(p, &systems, &count,
00478 LSM_FLAG_GET_VALUE(params));
00479 if (LSM_ERR_OK == rc) {
00480 std::vector < Value > result;
00481 result.reserve(count);
00482
00483 for (uint32_t i = 0; i < count; ++i) {
00484 result.push_back(system_to_value(systems[i]));
00485 }
00486
00487 lsm_system_record_array_free(systems, count);
00488 systems = NULL;
00489 response = Value(result);
00490 }
00491 } else {
00492 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00493 }
00494 }
00495 return rc;
00496 }
00497
00498 static int handle_pools(lsm_plugin_ptr p, Value & params, Value & response)
00499 {
00500 int rc = LSM_ERR_NO_SUPPORT;
00501 char *key = NULL;
00502 char *val = NULL;
00503
00504 if (p && p->mgmt_ops && p->mgmt_ops->pool_list) {
00505 lsm_pool **pools = NULL;
00506 uint32_t count = 0;
00507
00508 if (LSM_FLAG_EXPECTED_TYPE(params) &&
00509 ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK)) {
00510 rc = p->mgmt_ops->pool_list(p, key, val, &pools, &count,
00511 LSM_FLAG_GET_VALUE(params));
00512 if (LSM_ERR_OK == rc) {
00513 std::vector < Value > result;
00514 result.reserve(count);
00515
00516 for (uint32_t i = 0; i < count; ++i) {
00517 result.push_back(pool_to_value(pools[i]));
00518 }
00519
00520 lsm_pool_record_array_free(pools, count);
00521 pools = NULL;
00522 response = Value(result);
00523 }
00524 free(key);
00525 free(val);
00526 } else {
00527 if (rc == LSM_ERR_NO_SUPPORT) {
00528 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00529 }
00530 }
00531 }
00532 return rc;
00533 }
00534
00535 static int handle_target_ports(lsm_plugin_ptr p, Value & params,
00536 Value & response)
00537 {
00538 int rc = LSM_ERR_NO_SUPPORT;
00539 char *key = NULL;
00540 char *val = NULL;
00541
00542 if (p && p->san_ops && p->san_ops->target_port_list) {
00543 lsm_target_port **target_ports = NULL;
00544 uint32_t count = 0;
00545
00546 if (LSM_FLAG_EXPECTED_TYPE(params) &&
00547 ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK)) {
00548 rc = p->san_ops->target_port_list(p, key, val, &target_ports,
00549 &count,
00550 LSM_FLAG_GET_VALUE(params));
00551 if (LSM_ERR_OK == rc) {
00552 std::vector < Value > result;
00553 result.reserve(count);
00554
00555 for (uint32_t i = 0; i < count; ++i) {
00556 result.push_back(target_port_to_value(target_ports[i]));
00557 }
00558
00559 lsm_target_port_record_array_free(target_ports, count);
00560 target_ports = NULL;
00561 response = Value(result);
00562 }
00563 free(key);
00564 free(val);
00565 } else {
00566 if (rc == LSM_ERR_NO_SUPPORT) {
00567 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00568 }
00569 }
00570 }
00571 return rc;
00572 }
00573
00574 static int capabilities(lsm_plugin_ptr p, Value & params, Value & response)
00575 {
00576 int rc = LSM_ERR_NO_SUPPORT;
00577
00578 if (p && p->mgmt_ops && p->mgmt_ops->capablities) {
00579 lsm_storage_capabilities *c = NULL;
00580
00581 Value v_s = params["system"];
00582
00583 if (IS_CLASS_SYSTEM(v_s) && LSM_FLAG_EXPECTED_TYPE(params)) {
00584 lsm_system *sys = value_to_system(v_s);
00585
00586 if (sys) {
00587 rc = p->mgmt_ops->capablities(p, sys, &c,
00588 LSM_FLAG_GET_VALUE(params));
00589 if (LSM_ERR_OK == rc) {
00590 response = capabilities_to_value(c);
00591 lsm_capability_record_free(c);
00592 c = NULL;
00593 }
00594 lsm_system_record_free(sys);
00595 } else {
00596 rc = LSM_ERR_NO_MEMORY;
00597 }
00598 } else {
00599 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00600 }
00601 }
00602 return rc;
00603 }
00604
00605 static void get_volumes(int rc, lsm_volume ** vols, uint32_t count,
00606 Value & response)
00607 {
00608 if (LSM_ERR_OK == rc) {
00609 std::vector < Value > result;
00610 result.reserve(count);
00611
00612 for (uint32_t i = 0; i < count; ++i) {
00613 result.push_back(volume_to_value(vols[i]));
00614 }
00615
00616 lsm_volume_record_array_free(vols, count);
00617 vols = NULL;
00618 response = Value(result);
00619 }
00620 }
00621
00622 static int handle_volumes(lsm_plugin_ptr p, Value & params, Value & response)
00623 {
00624 int rc = LSM_ERR_NO_SUPPORT;
00625 char *key = NULL;
00626 char *val = NULL;
00627
00628
00629 if (p && p->san_ops && p->san_ops->vol_get) {
00630 lsm_volume **vols = NULL;
00631 uint32_t count = 0;
00632
00633 if (LSM_FLAG_EXPECTED_TYPE(params) &&
00634 (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK) {
00635 rc = p->san_ops->vol_get(p, key, val, &vols, &count,
00636 LSM_FLAG_GET_VALUE(params));
00637
00638 get_volumes(rc, vols, count, response);
00639 free(key);
00640 free(val);
00641 } else {
00642 if (rc == LSM_ERR_NO_SUPPORT) {
00643 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00644 }
00645 }
00646 }
00647 return rc;
00648 }
00649
00650 static void get_disks(int rc, lsm_disk ** disks, uint32_t count,
00651 Value & response)
00652 {
00653 if (LSM_ERR_OK == rc) {
00654 std::vector < Value > result;
00655 result.reserve(count);
00656
00657 for (uint32_t i = 0; i < count; ++i) {
00658 result.push_back(disk_to_value(disks[i]));
00659 }
00660
00661 lsm_disk_record_array_free(disks, count);
00662 disks = NULL;
00663 response = Value(result);
00664 }
00665 }
00666
00667 static int handle_disks(lsm_plugin_ptr p, Value & params, Value & response)
00668 {
00669 int rc = LSM_ERR_NO_SUPPORT;
00670 char *key = NULL;
00671 char *val = NULL;
00672
00673 if (p && p->san_ops && p->san_ops->disk_get) {
00674 lsm_disk **disks = NULL;
00675 uint32_t count = 0;
00676
00677 if (LSM_FLAG_EXPECTED_TYPE(params) &&
00678 (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK) {
00679 rc = p->san_ops->disk_get(p, key, val, &disks, &count,
00680 LSM_FLAG_GET_VALUE(params));
00681 get_disks(rc, disks, count, response);
00682 free(key);
00683 free(val);
00684 } else {
00685 if (rc == LSM_ERR_NO_SUPPORT) {
00686 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00687 }
00688 }
00689 }
00690 return rc;
00691 }
00692
00693 static int handle_volume_create(lsm_plugin_ptr p, Value & params,
00694 Value & response)
00695 {
00696 int rc = LSM_ERR_NO_SUPPORT;
00697 if (p && p->san_ops && p->san_ops->vol_create) {
00698
00699 Value v_p = params["pool"];
00700 Value v_name = params["volume_name"];
00701 Value v_size = params["size_bytes"];
00702 Value v_prov = params["provisioning"];
00703
00704 if (IS_CLASS_POOL(v_p) &&
00705 Value::string_t == v_name.valueType() &&
00706 Value::numeric_t == v_size.valueType() &&
00707 Value::numeric_t == v_prov.valueType() &&
00708 LSM_FLAG_EXPECTED_TYPE(params)) {
00709
00710 lsm_pool *pool = value_to_pool(v_p);
00711 if (pool) {
00712 lsm_volume *vol = NULL;
00713 char *job = NULL;
00714 const char *name = v_name.asC_str();
00715 uint64_t size = v_size.asUint64_t();
00716 lsm_volume_provision_type pro =
00717 (lsm_volume_provision_type) v_prov.asInt32_t();
00718
00719 rc = p->san_ops->vol_create(p, pool, name, size, pro, &vol,
00720 &job, LSM_FLAG_GET_VALUE(params));
00721
00722 Value v = volume_to_value(vol);
00723 response = job_handle(v, job);
00724
00725
00726 lsm_pool_record_free(pool);
00727 lsm_volume_record_free(vol);
00728 free(job);
00729
00730 } else {
00731 rc = LSM_ERR_NO_MEMORY;
00732 }
00733
00734 } else {
00735 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00736 }
00737 }
00738 return rc;
00739 }
00740
00741 static int handle_volume_resize(lsm_plugin_ptr p, Value & params,
00742 Value & response)
00743 {
00744 int rc = LSM_ERR_NO_SUPPORT;
00745 if (p && p->san_ops && p->san_ops->vol_resize) {
00746 Value v_vol = params["volume"];
00747 Value v_size = params["new_size_bytes"];
00748
00749 if (IS_CLASS_VOLUME(v_vol) &&
00750 Value::numeric_t == v_size.valueType() &&
00751 LSM_FLAG_EXPECTED_TYPE(params)) {
00752
00753 lsm_volume *vol = value_to_volume(v_vol);
00754 if (vol) {
00755 lsm_volume *resized_vol = NULL;
00756 uint64_t size = v_size.asUint64_t();
00757 char *job = NULL;
00758
00759 rc = p->san_ops->vol_resize(p, vol, size, &resized_vol,
00760 &job, LSM_FLAG_GET_VALUE(params));
00761
00762 Value v = volume_to_value(resized_vol);
00763 response = job_handle(v, job);
00764
00765 lsm_volume_record_free(vol);
00766 lsm_volume_record_free(resized_vol);
00767 free(job);
00768
00769 } else {
00770 rc = LSM_ERR_NO_MEMORY;
00771 }
00772
00773 } else {
00774 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00775 }
00776 }
00777 return rc;
00778 }
00779
00780 static int handle_volume_replicate(lsm_plugin_ptr p, Value & params,
00781 Value & response)
00782 {
00783 int rc = LSM_ERR_NO_SUPPORT;
00784
00785 if (p && p->san_ops && p->san_ops->vol_replicate) {
00786
00787 Value v_pool = params["pool"];
00788 Value v_vol_src = params["volume_src"];
00789 Value v_rep = params["rep_type"];
00790 Value v_name = params["name"];
00791
00792 if (((Value::object_t == v_pool.valueType() &&
00793 IS_CLASS_POOL(v_pool)) ||
00794 Value::null_t == v_pool.valueType()) &&
00795 IS_CLASS_VOLUME(v_vol_src) &&
00796 Value::numeric_t == v_rep.valueType() &&
00797 Value::string_t == v_name.valueType() &&
00798 LSM_FLAG_EXPECTED_TYPE(params)) {
00799
00800 lsm_pool *pool = (Value::null_t == v_pool.valueType())? NULL :
00801 value_to_pool(v_pool);
00802 lsm_volume *vol = value_to_volume(v_vol_src);
00803 lsm_volume *newVolume = NULL;
00804 lsm_replication_type rep = (lsm_replication_type) v_rep.asInt32_t();
00805 const char *name = v_name.asC_str();
00806 char *job = NULL;
00807
00808 if (vol &&
00809 (pool || (!pool && Value::null_t == v_pool.valueType()))) {
00810 rc = p->san_ops->vol_replicate(p, pool, rep, vol, name,
00811 &newVolume, &job,
00812 LSM_FLAG_GET_VALUE(params));
00813
00814 Value v = volume_to_value(newVolume);
00815 response = job_handle(v, job);
00816
00817 lsm_volume_record_free(newVolume);
00818 free(job);
00819 } else {
00820 rc = LSM_ERR_NO_MEMORY;
00821 }
00822
00823 lsm_pool_record_free(pool);
00824 lsm_volume_record_free(vol);
00825
00826 } else {
00827 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00828 }
00829 }
00830 return rc;
00831 }
00832
00833 static int handle_volume_replicate_range_block_size(lsm_plugin_ptr p,
00834 Value & params,
00835 Value & response)
00836 {
00837 int rc = LSM_ERR_NO_SUPPORT;
00838 uint32_t block_size = 0;
00839
00840 if (p && p->san_ops && p->san_ops->vol_rep_range_bs) {
00841 Value v_s = params["system"];
00842
00843 if (IS_CLASS_SYSTEM(v_s) && LSM_FLAG_EXPECTED_TYPE(params)) {
00844 lsm_system *sys = value_to_system(v_s);
00845
00846 if (sys) {
00847 rc = p->san_ops->vol_rep_range_bs(p, sys, &block_size,
00848 LSM_FLAG_GET_VALUE(params));
00849
00850 if (LSM_ERR_OK == rc) {
00851 response = Value(block_size);
00852 }
00853
00854 lsm_system_record_free(sys);
00855 } else {
00856 rc = LSM_ERR_NO_MEMORY;
00857 }
00858 } else {
00859 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00860 }
00861 }
00862 return rc;
00863 }
00864
00865 static int handle_volume_replicate_range(lsm_plugin_ptr p, Value & params,
00866 Value & response)
00867 {
00868 int rc = LSM_ERR_NO_SUPPORT;
00869 uint32_t range_count = 0;
00870 char *job = NULL;
00871 if (p && p->san_ops && p->san_ops->vol_rep_range) {
00872 Value v_rep = params["rep_type"];
00873 Value v_vol_src = params["volume_src"];
00874 Value v_vol_dest = params["volume_dest"];
00875 Value v_ranges = params["ranges"];
00876
00877 if (Value::numeric_t == v_rep.valueType() &&
00878 IS_CLASS_VOLUME(v_vol_src) &&
00879 IS_CLASS_VOLUME(v_vol_dest) &&
00880 Value::array_t == v_ranges.valueType() &&
00881 LSM_FLAG_EXPECTED_TYPE(params)) {
00882
00883 lsm_replication_type repType = (lsm_replication_type)
00884 v_rep.asInt32_t();
00885 lsm_volume *source = value_to_volume(v_vol_src);
00886 lsm_volume *dest = value_to_volume(v_vol_dest);
00887 lsm_block_range **ranges = value_to_block_range_list(v_ranges,
00888 &range_count);
00889
00890 if (source && dest && ranges) {
00891
00892 rc = p->san_ops->vol_rep_range(p, repType, source, dest,
00893 ranges, range_count, &job,
00894 LSM_FLAG_GET_VALUE(params));
00895
00896 if (LSM_ERR_JOB_STARTED == rc) {
00897 response = Value(job);
00898 free(job);
00899 job = NULL;
00900 }
00901
00902 } else {
00903 rc = LSM_ERR_NO_MEMORY;
00904 }
00905
00906 lsm_volume_record_free(source);
00907 lsm_volume_record_free(dest);
00908 lsm_block_range_record_array_free(ranges, range_count);
00909
00910 } else {
00911 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00912 }
00913 }
00914 return rc;
00915 }
00916
00917 static int handle_volume_delete(lsm_plugin_ptr p, Value & params,
00918 Value & response)
00919 {
00920 int rc = LSM_ERR_NO_SUPPORT;
00921 if (p && p->san_ops && p->san_ops->vol_delete) {
00922 Value v_vol = params["volume"];
00923
00924 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
00925 lsm_volume *vol = value_to_volume(v_vol);
00926
00927 if (vol) {
00928 char *job = NULL;
00929
00930 rc = p->san_ops->vol_delete(p, vol, &job,
00931 LSM_FLAG_GET_VALUE(params));
00932
00933 if (LSM_ERR_JOB_STARTED == rc) {
00934 response = Value(job);
00935 }
00936
00937 lsm_volume_record_free(vol);
00938 free(job);
00939 } else {
00940 rc = LSM_ERR_NO_MEMORY;
00941 }
00942
00943 } else {
00944 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00945 }
00946 }
00947 return rc;
00948 }
00949
00950 static int handle_vol_enable_disable(lsm_plugin_ptr p, Value & params,
00951 Value & response, int online)
00952 {
00953 int rc = LSM_ERR_NO_SUPPORT;
00954
00955 if (p && p->san_ops &&
00956 ((online) ? p->san_ops->vol_enable : p->san_ops->vol_disable)) {
00957
00958 Value v_vol = params["volume"];
00959
00960 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
00961 lsm_volume *vol = value_to_volume(v_vol);
00962 if (vol) {
00963 if (online) {
00964 rc = p->san_ops->vol_enable(p, vol,
00965 LSM_FLAG_GET_VALUE(params));
00966 } else {
00967 rc = p->san_ops->vol_disable(p, vol,
00968 LSM_FLAG_GET_VALUE(params));
00969 }
00970
00971 lsm_volume_record_free(vol);
00972 } else {
00973 rc = LSM_ERR_NO_MEMORY;
00974 }
00975 } else {
00976 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
00977 }
00978 }
00979 return rc;
00980 }
00981
00982 static int handle_volume_enable(lsm_plugin_ptr p, Value & params,
00983 Value & response)
00984 {
00985 return handle_vol_enable_disable(p, params, response, 1);
00986 }
00987
00988 static int handle_volume_disable(lsm_plugin_ptr p, Value & params,
00989 Value & response)
00990 {
00991 return handle_vol_enable_disable(p, params, response, 0);
00992 }
00993
00994 static int handle_volume_raid_info(lsm_plugin_ptr p, Value & params,
00995 Value & response)
00996 {
00997 int rc = LSM_ERR_NO_SUPPORT;
00998 if (p && p->ops_v1_2 && p->ops_v1_2->vol_raid_info) {
00999 Value v_vol = params["volume"];
01000
01001 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01002 lsm_volume *vol = value_to_volume(v_vol);
01003 std::vector < Value > result;
01004
01005 if (vol) {
01006 lsm_volume_raid_type raid_type;
01007 uint32_t strip_size;
01008 uint32_t disk_count;
01009 uint32_t min_io_size;
01010 uint32_t opt_io_size;
01011
01012 rc = p->ops_v1_2->vol_raid_info(p, vol, &raid_type,
01013 &strip_size, &disk_count,
01014 &min_io_size, &opt_io_size,
01015 LSM_FLAG_GET_VALUE(params));
01016
01017 if (LSM_ERR_OK == rc) {
01018 result.push_back(Value((int32_t) raid_type));
01019 result.push_back(Value(strip_size));
01020 result.push_back(Value(disk_count));
01021 result.push_back(Value(min_io_size));
01022 result.push_back(Value(opt_io_size));
01023 response = Value(result);
01024 }
01025
01026 lsm_volume_record_free(vol);
01027 } else {
01028 rc = LSM_ERR_NO_MEMORY;
01029 }
01030
01031 } else {
01032 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01033 }
01034 }
01035 return rc;
01036 }
01037
01038 static int handle_pool_member_info(lsm_plugin_ptr p, Value & params,
01039 Value & response)
01040 {
01041 int rc = LSM_ERR_NO_SUPPORT;
01042 if (p && p->ops_v1_2 && p->ops_v1_2->pool_member_info) {
01043 Value v_pool = params["pool"];
01044
01045 if (IS_CLASS_POOL(v_pool) && LSM_FLAG_EXPECTED_TYPE(params)) {
01046 lsm_pool *pool = value_to_pool(v_pool);
01047 std::vector < Value > result;
01048
01049 if (pool) {
01050 lsm_volume_raid_type raid_type = LSM_VOLUME_RAID_TYPE_UNKNOWN;
01051 lsm_pool_member_type member_type = LSM_POOL_MEMBER_TYPE_UNKNOWN;
01052 lsm_string_list *member_ids = NULL;
01053
01054 rc = p->ops_v1_2->pool_member_info(p, pool, &raid_type,
01055 &member_type,
01056 &member_ids,
01057 LSM_FLAG_GET_VALUE(params));
01058
01059 if (LSM_ERR_OK == rc) {
01060 result.push_back(Value((int32_t) raid_type));
01061 result.push_back(Value((int32_t) member_type));
01062 result.push_back(string_list_to_value(member_ids));
01063 if (member_ids != NULL) {
01064 lsm_string_list_free(member_ids);
01065 }
01066 response = Value(result);
01067 }
01068
01069 lsm_pool_record_free(pool);
01070 } else {
01071 rc = LSM_ERR_NO_MEMORY;
01072 }
01073
01074 } else {
01075 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01076 }
01077 }
01078 return rc;
01079 }
01080
01081 static int ag_list(lsm_plugin_ptr p, Value & params, Value & response)
01082 {
01083 int rc = LSM_ERR_NO_SUPPORT;
01084 char *key = NULL;
01085 char *val = NULL;
01086
01087 if (p && p->san_ops && p->san_ops->ag_list) {
01088
01089 if (LSM_FLAG_EXPECTED_TYPE(params) &&
01090 (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK) {
01091 lsm_access_group **groups = NULL;
01092 uint32_t count;
01093
01094 rc = p->san_ops->ag_list(p, key, val, &groups, &count,
01095 LSM_FLAG_GET_VALUE(params));
01096 if (LSM_ERR_OK == rc) {
01097 response = access_group_list_to_value(groups, count);
01098
01099
01100 lsm_access_group_record_array_free(groups, count);
01101 }
01102 free(key);
01103 free(val);
01104 } else {
01105 if (rc == LSM_ERR_NO_SUPPORT) {
01106 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01107 }
01108 }
01109 }
01110 return rc;
01111 }
01112
01113 static int ag_create(lsm_plugin_ptr p, Value & params, Value & response)
01114 {
01115 int rc = LSM_ERR_NO_SUPPORT;
01116
01117 if (p && p->san_ops && p->san_ops->ag_create) {
01118 Value v_name = params["name"];
01119 Value v_init_id = params["init_id"];
01120 Value v_init_type = params["init_type"];
01121 Value v_system = params["system"];
01122
01123 if (Value::string_t == v_name.valueType() &&
01124 Value::string_t == v_init_id.valueType() &&
01125 Value::numeric_t == v_init_type.valueType() &&
01126 IS_CLASS_SYSTEM(v_system) && LSM_FLAG_EXPECTED_TYPE(params)) {
01127
01128 lsm_access_group *ag = NULL;
01129 lsm_system *system = value_to_system(v_system);
01130
01131 if (system) {
01132 rc = p->san_ops->ag_create(p,
01133 v_name.asC_str(),
01134 v_init_id.asC_str(),
01135 (lsm_access_group_init_type)
01136 v_init_type.asInt32_t(), system,
01137 &ag, LSM_FLAG_GET_VALUE(params));
01138 if (LSM_ERR_OK == rc) {
01139 response = access_group_to_value(ag);
01140 lsm_access_group_record_free(ag);
01141 }
01142
01143 lsm_system_record_free(system);
01144 system = NULL;
01145 }
01146 } else {
01147 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01148 }
01149 }
01150 return rc;
01151 }
01152
01153 static int ag_delete(lsm_plugin_ptr p, Value & params, Value & response)
01154 {
01155 int rc = LSM_ERR_NO_SUPPORT;
01156
01157 if (p && p->san_ops && p->san_ops->ag_delete) {
01158 Value v_access_group = params["access_group"];
01159
01160 if (IS_CLASS_ACCESS_GROUP(v_access_group) &&
01161 LSM_FLAG_EXPECTED_TYPE(params)) {
01162
01163 lsm_access_group *ag = value_to_access_group(v_access_group);
01164
01165 if (ag) {
01166 rc = p->san_ops->ag_delete(p, ag, LSM_FLAG_GET_VALUE(params));
01167 lsm_access_group_record_free(ag);
01168 } else {
01169 rc = LSM_ERR_NO_MEMORY;
01170 }
01171
01172 } else {
01173 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01174 }
01175 }
01176 return rc;
01177 }
01178
01179 static int ag_initiator_add(lsm_plugin_ptr p, Value & params, Value & response)
01180 {
01181 int rc = LSM_ERR_NO_SUPPORT;
01182
01183 if (p && p->san_ops && p->san_ops->ag_add_initiator) {
01184
01185 Value v_group = params["access_group"];
01186 Value v_init_id = params["init_id"];
01187 Value v_init_type = params["init_type"];
01188
01189
01190 if (IS_CLASS_ACCESS_GROUP(v_group) &&
01191 Value::string_t == v_init_id.valueType() &&
01192 Value::numeric_t == v_init_type.valueType() &&
01193 LSM_FLAG_EXPECTED_TYPE(params)) {
01194
01195 lsm_access_group *ag = value_to_access_group(v_group);
01196 if (ag) {
01197 lsm_access_group *updated_access_group = NULL;
01198 const char *id = v_init_id.asC_str();
01199 lsm_access_group_init_type id_type =
01200 (lsm_access_group_init_type) v_init_type.asInt32_t();
01201
01202 rc = p->san_ops->ag_add_initiator(p, ag, id, id_type,
01203 &updated_access_group,
01204 LSM_FLAG_GET_VALUE(params));
01205
01206 if (LSM_ERR_OK == rc) {
01207 response = access_group_to_value(updated_access_group);
01208 lsm_access_group_record_free(updated_access_group);
01209 }
01210
01211 lsm_access_group_record_free(ag);
01212 } else {
01213 rc = LSM_ERR_NO_MEMORY;
01214 }
01215
01216 } else {
01217 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01218 }
01219 }
01220
01221 return rc;
01222 }
01223
01224 static int ag_initiator_del(lsm_plugin_ptr p, Value & params, Value & response)
01225 {
01226 int rc = LSM_ERR_NO_SUPPORT;
01227
01228 if (p && p->san_ops && p->san_ops->ag_del_initiator) {
01229
01230 Value v_group = params["access_group"];
01231 Value v_init_id = params["init_id"];
01232 Value v_init_type = params["init_type"];
01233
01234 if (IS_CLASS_ACCESS_GROUP(v_group) &&
01235 Value::string_t == v_init_id.valueType() &&
01236 Value::numeric_t == v_init_type.valueType() &&
01237 LSM_FLAG_EXPECTED_TYPE(params)) {
01238
01239 lsm_access_group *ag = value_to_access_group(v_group);
01240
01241 if (ag) {
01242 lsm_access_group *updated_access_group = NULL;
01243 const char *id = v_init_id.asC_str();
01244 lsm_access_group_init_type id_type =
01245 (lsm_access_group_init_type) v_init_type.asInt32_t();
01246 rc = p->san_ops->ag_del_initiator(p, ag, id, id_type,
01247 &updated_access_group,
01248 LSM_FLAG_GET_VALUE(params));
01249
01250 if (LSM_ERR_OK == rc) {
01251 response = access_group_to_value(updated_access_group);
01252 lsm_access_group_record_free(updated_access_group);
01253 }
01254
01255 lsm_access_group_record_free(ag);
01256 } else {
01257 rc = LSM_ERR_NO_MEMORY;
01258 }
01259
01260 } else {
01261 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01262 }
01263 }
01264 return rc;
01265 }
01266
01267 static int volume_mask(lsm_plugin_ptr p, Value & params, Value & response)
01268 {
01269 int rc = LSM_ERR_NO_SUPPORT;
01270
01271 if (p && p->san_ops && p->san_ops->ag_grant) {
01272
01273 Value v_group = params["access_group"];
01274 Value v_vol = params["volume"];
01275
01276 if (IS_CLASS_ACCESS_GROUP(v_group) &&
01277 IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01278
01279 lsm_access_group *ag = value_to_access_group(v_group);
01280 lsm_volume *vol = value_to_volume(v_vol);
01281
01282 if (ag && vol) {
01283 rc = p->san_ops->ag_grant(p, ag, vol,
01284 LSM_FLAG_GET_VALUE(params));
01285 } else {
01286 rc = LSM_ERR_NO_MEMORY;
01287 }
01288
01289 lsm_access_group_record_free(ag);
01290 lsm_volume_record_free(vol);
01291
01292 } else {
01293 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01294 }
01295 }
01296
01297 return rc;
01298 }
01299
01300 static int volume_unmask(lsm_plugin_ptr p, Value & params, Value & response)
01301 {
01302 int rc = LSM_ERR_NO_SUPPORT;
01303
01304 if (p && p->san_ops && p->san_ops->ag_revoke) {
01305
01306 Value v_group = params["access_group"];
01307 Value v_vol = params["volume"];
01308
01309 if (IS_CLASS_ACCESS_GROUP(v_group) &&
01310 IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01311
01312 lsm_access_group *ag = value_to_access_group(v_group);
01313 lsm_volume *vol = value_to_volume(v_vol);
01314
01315 if (ag && vol) {
01316 rc = p->san_ops->ag_revoke(p, ag, vol,
01317 LSM_FLAG_GET_VALUE(params));
01318 } else {
01319 rc = LSM_ERR_NO_MEMORY;
01320 }
01321
01322 lsm_access_group_record_free(ag);
01323 lsm_volume_record_free(vol);
01324
01325 } else {
01326 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01327 }
01328 }
01329
01330 return rc;
01331 }
01332
01333 static int vol_accessible_by_ag(lsm_plugin_ptr p, Value & params,
01334 Value & response)
01335 {
01336 int rc = LSM_ERR_NO_SUPPORT;
01337
01338 if (p && p->san_ops && p->san_ops->vol_accessible_by_ag) {
01339 Value v_access_group = params["access_group"];
01340
01341 if (IS_CLASS_ACCESS_GROUP(v_access_group) &&
01342 LSM_FLAG_EXPECTED_TYPE(params)) {
01343 lsm_access_group *ag = value_to_access_group(v_access_group);
01344
01345 if (ag) {
01346 lsm_volume **vols = NULL;
01347 uint32_t count = 0;
01348
01349 rc = p->san_ops->vol_accessible_by_ag(p, ag, &vols, &count,
01350 LSM_FLAG_GET_VALUE
01351 (params));
01352
01353 if (LSM_ERR_OK == rc) {
01354 std::vector < Value > result;
01355 result.reserve(count);
01356
01357 for (uint32_t i = 0; i < count; ++i) {
01358 result.push_back(volume_to_value(vols[i]));
01359 }
01360 response = Value(result);
01361 }
01362
01363 lsm_access_group_record_free(ag);
01364 lsm_volume_record_array_free(vols, count);
01365 vols = NULL;
01366 } else {
01367 rc = LSM_ERR_NO_MEMORY;
01368 }
01369
01370 } else {
01371 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01372 }
01373 }
01374 return rc;
01375 }
01376
01377 static int ag_granted_to_volume(lsm_plugin_ptr p, Value & params,
01378 Value & response)
01379 {
01380 int rc = LSM_ERR_NO_SUPPORT;
01381
01382 if (p && p->san_ops && p->san_ops->ag_granted_to_vol) {
01383
01384 Value v_vol = params["volume"];
01385
01386 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01387 lsm_volume *volume = value_to_volume(v_vol);
01388
01389 if (volume) {
01390 lsm_access_group **groups = NULL;
01391 uint32_t count = 0;
01392
01393 rc = p->san_ops->ag_granted_to_vol(p, volume, &groups,
01394 &count,
01395 LSM_FLAG_GET_VALUE(params));
01396
01397 if (LSM_ERR_OK == rc) {
01398 std::vector < Value > result;
01399 result.reserve(count);
01400
01401 for (uint32_t i = 0; i < count; ++i) {
01402 result.push_back(access_group_to_value(groups[i]));
01403 }
01404 response = Value(result);
01405 }
01406
01407 lsm_volume_record_free(volume);
01408 lsm_access_group_record_array_free(groups, count);
01409 groups = NULL;
01410 } else {
01411 rc = LSM_ERR_NO_MEMORY;
01412 }
01413 } else {
01414 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01415 }
01416 }
01417 return rc;
01418 }
01419
01420 static int volume_dependency(lsm_plugin_ptr p, Value & params, Value & response)
01421 {
01422 int rc = LSM_ERR_NO_SUPPORT;
01423
01424 if (p && p->san_ops && p->san_ops->vol_child_depends) {
01425
01426 Value v_vol = params["volume"];
01427
01428 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01429 lsm_volume *volume = value_to_volume(v_vol);
01430
01431 if (volume) {
01432 uint8_t yes;
01433
01434 rc = p->san_ops->vol_child_depends(p, volume, &yes,
01435 LSM_FLAG_GET_VALUE(params));
01436
01437 if (LSM_ERR_OK == rc) {
01438 response = Value((bool) (yes));
01439 }
01440
01441 lsm_volume_record_free(volume);
01442 } else {
01443 rc = LSM_ERR_NO_MEMORY;
01444 }
01445
01446 } else {
01447 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01448 }
01449 }
01450
01451 return rc;
01452 }
01453
01454 static int volume_dependency_rm(lsm_plugin_ptr p, Value & params,
01455 Value & response)
01456 {
01457 int rc = LSM_ERR_NO_SUPPORT;
01458
01459 if (p && p->san_ops && p->san_ops->vol_child_depends_rm) {
01460
01461 Value v_vol = params["volume"];
01462
01463 if (IS_CLASS_VOLUME(v_vol) && LSM_FLAG_EXPECTED_TYPE(params)) {
01464 lsm_volume *volume = value_to_volume(v_vol);
01465
01466 if (volume) {
01467
01468 char *job = NULL;
01469
01470 rc = p->san_ops->vol_child_depends_rm(p, volume, &job,
01471 LSM_FLAG_GET_VALUE
01472 (params));
01473
01474 if (LSM_ERR_JOB_STARTED == rc) {
01475 response = Value(job);
01476 free(job);
01477 }
01478 lsm_volume_record_free(volume);
01479
01480 } else {
01481 rc = LSM_ERR_NO_MEMORY;
01482 }
01483
01484 } else {
01485 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01486 }
01487 }
01488 return rc;
01489 }
01490
01491 static int fs(lsm_plugin_ptr p, Value & params, Value & response)
01492 {
01493 int rc = LSM_ERR_NO_SUPPORT;
01494 char *key = NULL;
01495 char *val = NULL;
01496
01497 if (p && p->fs_ops && p->fs_ops->fs_list) {
01498 if (LSM_FLAG_EXPECTED_TYPE(params) &&
01499 ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK)) {
01500
01501 lsm_fs **fs = NULL;
01502 uint32_t count = 0;
01503
01504 rc = p->fs_ops->fs_list(p, key, val, &fs, &count,
01505 LSM_FLAG_GET_VALUE(params));
01506
01507 if (LSM_ERR_OK == rc) {
01508 std::vector < Value > result;
01509 result.reserve(count);
01510
01511 for (uint32_t i = 0; i < count; ++i) {
01512 result.push_back(fs_to_value(fs[i]));
01513 }
01514
01515 response = Value(result);
01516 lsm_fs_record_array_free(fs, count);
01517 fs = NULL;
01518 }
01519 free(key);
01520 free(val);
01521 } else {
01522 if (rc == LSM_ERR_NO_SUPPORT) {
01523 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01524 }
01525 }
01526 }
01527 return rc;
01528 }
01529
01530 static int fs_create(lsm_plugin_ptr p, Value & params, Value & response)
01531 {
01532 int rc = LSM_ERR_NO_SUPPORT;
01533
01534 if (p && p->fs_ops && p->fs_ops->fs_create) {
01535
01536 Value v_pool = params["pool"];
01537 Value v_name = params["name"];
01538 Value v_size = params["size_bytes"];
01539
01540 if (IS_CLASS_POOL(v_pool) &&
01541 Value::string_t == v_name.valueType() &&
01542 Value::numeric_t == v_size.valueType() &&
01543 LSM_FLAG_EXPECTED_TYPE(params)) {
01544
01545 lsm_pool *pool = value_to_pool(v_pool);
01546
01547 if (pool) {
01548 const char *name = params["name"].asC_str();
01549 uint64_t size_bytes = params["size_bytes"].asUint64_t();
01550 lsm_fs *fs = NULL;
01551 char *job = NULL;
01552
01553 rc = p->fs_ops->fs_create(p, pool, name, size_bytes, &fs,
01554 &job, LSM_FLAG_GET_VALUE(params));
01555
01556 std::vector < Value > r;
01557
01558 if (LSM_ERR_OK == rc) {
01559 r.push_back(Value());
01560 r.push_back(fs_to_value(fs));
01561 response = Value(r);
01562 lsm_fs_record_free(fs);
01563 } else if (LSM_ERR_JOB_STARTED == rc) {
01564 r.push_back(Value(job));
01565 r.push_back(Value());
01566 response = Value(r);
01567 free(job);
01568 }
01569 lsm_pool_record_free(pool);
01570
01571 } else {
01572 rc = LSM_ERR_NO_MEMORY;
01573 }
01574
01575 } else {
01576 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01577 }
01578 }
01579 return rc;
01580 }
01581
01582 static int fs_delete(lsm_plugin_ptr p, Value & params, Value & response)
01583 {
01584 int rc = LSM_ERR_NO_SUPPORT;
01585
01586 if (p && p->fs_ops && p->fs_ops->fs_delete) {
01587
01588 Value v_fs = params["fs"];
01589
01590 if (IS_CLASS_FILE_SYSTEM(v_fs) && LSM_FLAG_EXPECTED_TYPE(params)) {
01591
01592 lsm_fs *fs = value_to_fs(v_fs);
01593
01594 if (fs) {
01595 char *job = NULL;
01596
01597 rc = p->fs_ops->fs_delete(p, fs, &job,
01598 LSM_FLAG_GET_VALUE(params));
01599
01600 if (LSM_ERR_JOB_STARTED == rc) {
01601 response = Value(job);
01602 free(job);
01603 }
01604 lsm_fs_record_free(fs);
01605 } else {
01606 rc = LSM_ERR_NO_MEMORY;
01607 }
01608
01609 } else {
01610 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01611 }
01612 }
01613 return rc;
01614 }
01615
01616 static int fs_resize(lsm_plugin_ptr p, Value & params, Value & response)
01617 {
01618 int rc = LSM_ERR_NO_SUPPORT;
01619
01620 if (p && p->fs_ops && p->fs_ops->fs_resize) {
01621
01622 Value v_fs = params["fs"];
01623 Value v_size = params["new_size_bytes"];
01624
01625 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01626 Value::numeric_t == v_size.valueType() &&
01627 LSM_FLAG_EXPECTED_TYPE(params)) {
01628
01629 lsm_fs *fs = value_to_fs(v_fs);
01630
01631 if (fs) {
01632 uint64_t size_bytes = v_size.asUint64_t();
01633 lsm_fs *rfs = NULL;
01634 char *job = NULL;
01635
01636 rc = p->fs_ops->fs_resize(p, fs, size_bytes, &rfs, &job,
01637 LSM_FLAG_GET_VALUE(params));
01638
01639 std::vector < Value > r;
01640
01641 if (LSM_ERR_OK == rc) {
01642 r.push_back(Value());
01643 r.push_back(fs_to_value(rfs));
01644 response = Value(r);
01645 lsm_fs_record_free(rfs);
01646 } else if (LSM_ERR_JOB_STARTED == rc) {
01647 r.push_back(Value(job));
01648 r.push_back(Value());
01649 response = Value(r);
01650 free(job);
01651 }
01652 lsm_fs_record_free(fs);
01653 } else {
01654 rc = LSM_ERR_NO_MEMORY;
01655 }
01656
01657 } else {
01658 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01659 }
01660 }
01661 return rc;
01662 }
01663
01664 static int fs_clone(lsm_plugin_ptr p, Value & params, Value & response)
01665 {
01666 int rc = LSM_ERR_NO_SUPPORT;
01667
01668 if (p && p->fs_ops && p->fs_ops->fs_clone) {
01669
01670 Value v_src_fs = params["src_fs"];
01671 Value v_name = params["dest_fs_name"];
01672 Value v_ss = params["snapshot"];
01673
01674 if (IS_CLASS_FILE_SYSTEM(v_src_fs) &&
01675 Value::string_t == v_name.valueType() &&
01676 (Value::null_t == v_ss.valueType() ||
01677 Value::object_t == v_ss.valueType()) &&
01678 LSM_FLAG_EXPECTED_TYPE(params)) {
01679
01680 lsm_fs *clonedFs = NULL;
01681 char *job = NULL;
01682 lsm_fs *fs = value_to_fs(v_src_fs);
01683 const char *name = v_name.asC_str();
01684 lsm_fs_ss *ss = (Value::null_t == v_ss.valueType())?
01685 NULL : value_to_ss(v_ss);
01686
01687 if (fs &&
01688 ((ss && v_ss.valueType() == Value::object_t) ||
01689 (!ss && v_ss.valueType() == Value::null_t))) {
01690
01691 rc = p->fs_ops->fs_clone(p, fs, name, &clonedFs, ss, &job,
01692 LSM_FLAG_GET_VALUE(params));
01693
01694 std::vector < Value > r;
01695 if (LSM_ERR_OK == rc) {
01696 r.push_back(Value());
01697 r.push_back(fs_to_value(clonedFs));
01698 response = Value(r);
01699 lsm_fs_record_free(clonedFs);
01700 } else if (LSM_ERR_JOB_STARTED == rc) {
01701 r.push_back(Value(job));
01702 r.push_back(Value());
01703 response = Value(r);
01704 free(job);
01705 }
01706
01707 } else {
01708 rc = LSM_ERR_NO_MEMORY;
01709 }
01710
01711 lsm_fs_record_free(fs);
01712 lsm_fs_ss_record_free(ss);
01713
01714 } else {
01715 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01716 }
01717 }
01718 return rc;
01719 }
01720
01721 static int fs_file_clone(lsm_plugin_ptr p, Value & params, Value & response)
01722 {
01723 int rc = LSM_ERR_OK;
01724
01725 if (p && p->fs_ops && p->fs_ops->fs_file_clone) {
01726
01727 Value v_fs = params["fs"];
01728 Value v_src_name = params["src_file_name"];
01729 Value v_dest_name = params["dest_file_name"];
01730 Value v_ss = params["snapshot"];
01731
01732 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01733 Value::string_t == v_src_name.valueType() &&
01734 Value::string_t == v_dest_name.valueType() &&
01735 (Value::null_t == v_ss.valueType() ||
01736 Value::object_t == v_ss.valueType()) &&
01737 LSM_FLAG_EXPECTED_TYPE(params)) {
01738
01739
01740 lsm_fs *fs = value_to_fs(v_fs);
01741 lsm_fs_ss *ss = (Value::null_t == v_ss.valueType())?
01742 NULL : value_to_ss(v_ss);
01743
01744 if (fs &&
01745 ((ss && v_ss.valueType() == Value::object_t) ||
01746 (!ss && v_ss.valueType() == Value::null_t))) {
01747
01748 const char *src = v_src_name.asC_str();
01749 const char *dest = v_dest_name.asC_str();
01750
01751 char *job = NULL;
01752
01753 rc = p->fs_ops->fs_file_clone(p, fs, src, dest, ss, &job,
01754 LSM_FLAG_GET_VALUE(params));
01755
01756 if (LSM_ERR_JOB_STARTED == rc) {
01757 response = Value(job);
01758 free(job);
01759 }
01760
01761 } else {
01762 rc = LSM_ERR_NO_MEMORY;
01763 }
01764
01765 lsm_fs_record_free(fs);
01766 lsm_fs_ss_record_free(ss);
01767
01768 } else {
01769 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01770 }
01771 }
01772 return rc;
01773 }
01774
01775 static int fs_child_dependency(lsm_plugin_ptr p, Value & params,
01776 Value & response)
01777 {
01778 int rc = LSM_ERR_NO_SUPPORT;
01779 if (p && p->fs_ops && p->fs_ops->fs_child_dependency) {
01780
01781 Value v_fs = params["fs"];
01782 Value v_files = params["files"];
01783
01784 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01785 (Value::array_t == v_files.valueType() ||
01786 Value::null_t == v_files.valueType()) &&
01787 LSM_FLAG_EXPECTED_TYPE(params)) {
01788
01789 lsm_fs *fs = value_to_fs(v_fs);
01790 lsm_string_list *files =
01791 (Value::null_t ==
01792 v_files.valueType())? NULL : value_to_string_list(v_files);
01793
01794 if (fs && (files ||
01795 (!files && Value::null_t == v_files.valueType()))) {
01796 uint8_t yes = 0;
01797
01798 rc = p->fs_ops->fs_child_dependency(p, fs, files, &yes);
01799
01800 if (LSM_ERR_OK == rc) {
01801 response = Value((bool) yes);
01802 }
01803 } else {
01804 rc = LSM_ERR_NO_MEMORY;
01805 }
01806
01807 lsm_fs_record_free(fs);
01808 lsm_string_list_free(files);
01809
01810 } else {
01811 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01812 }
01813 }
01814 return rc;
01815 }
01816
01817 static int fs_child_dependency_rm(lsm_plugin_ptr p, Value & params,
01818 Value & response)
01819 {
01820 int rc = LSM_ERR_NO_SUPPORT;
01821 if (p && p->fs_ops && p->fs_ops->fs_child_dependency_rm) {
01822
01823 Value v_fs = params["fs"];
01824 Value v_files = params["files"];
01825
01826 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01827 (Value::array_t == v_files.valueType() ||
01828 Value::null_t == v_files.valueType()) &&
01829 LSM_FLAG_EXPECTED_TYPE(params)) {
01830
01831 lsm_fs *fs = value_to_fs(v_fs);
01832 lsm_string_list *files =
01833 (Value::null_t ==
01834 v_files.valueType())? NULL : value_to_string_list(v_files);
01835
01836 if (fs &&
01837 (files || (!files && Value::null_t == v_files.valueType()))) {
01838 char *job = NULL;
01839
01840 rc = p->fs_ops->fs_child_dependency_rm(p, fs, files, &job,
01841 LSM_FLAG_GET_VALUE
01842 (params));
01843
01844 if (LSM_ERR_JOB_STARTED == rc) {
01845 response = Value(job);
01846 free(job);
01847 }
01848 } else {
01849 rc = LSM_ERR_NO_MEMORY;
01850 }
01851
01852 lsm_fs_record_free(fs);
01853 lsm_string_list_free(files);
01854 } else {
01855 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01856 }
01857 }
01858 return rc;
01859 }
01860
01861 static int ss_list(lsm_plugin_ptr p, Value & params, Value & response)
01862 {
01863 int rc = LSM_ERR_NO_SUPPORT;
01864 if (p && p->fs_ops && p->fs_ops->fs_ss_list) {
01865
01866 Value v_fs = params["fs"];
01867
01868 if (IS_CLASS_FILE_SYSTEM(v_fs) && LSM_FLAG_EXPECTED_TYPE(params)) {
01869
01870 lsm_fs *fs = value_to_fs(v_fs);
01871
01872 if (fs) {
01873 lsm_fs_ss **ss = NULL;
01874 uint32_t count = 0;
01875
01876 rc = p->fs_ops->fs_ss_list(p, fs, &ss, &count,
01877 LSM_FLAG_GET_VALUE(params));
01878
01879 if (LSM_ERR_OK == rc) {
01880 std::vector < Value > result;
01881 result.reserve(count);
01882
01883 for (uint32_t i = 0; i < count; ++i) {
01884 result.push_back(ss_to_value(ss[i]));
01885 }
01886 response = Value(result);
01887
01888 lsm_fs_record_free(fs);
01889 fs = NULL;
01890 lsm_fs_ss_record_array_free(ss, count);
01891 ss = NULL;
01892 }
01893 }
01894
01895 } else {
01896 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01897 }
01898 }
01899 return rc;
01900 }
01901
01902 static int ss_create(lsm_plugin_ptr p, Value & params, Value & response)
01903 {
01904 int rc = LSM_ERR_NO_SUPPORT;
01905 if (p && p->fs_ops && p->fs_ops->fs_ss_create) {
01906
01907 Value v_fs = params["fs"];
01908 Value v_ss_name = params["snapshot_name"];
01909
01910 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01911 Value::string_t == v_ss_name.valueType() &&
01912 LSM_FLAG_EXPECTED_TYPE(params)) {
01913 lsm_fs *fs = value_to_fs(v_fs);
01914
01915 if (fs) {
01916 lsm_fs_ss *ss = NULL;
01917 char *job = NULL;
01918
01919 const char *name = v_ss_name.asC_str();
01920
01921 rc = p->fs_ops->fs_ss_create(p, fs, name, &ss, &job,
01922 LSM_FLAG_GET_VALUE(params));
01923
01924 std::vector < Value > r;
01925 if (LSM_ERR_OK == rc) {
01926 r.push_back(Value());
01927 r.push_back(ss_to_value(ss));
01928 response = Value(r);
01929 lsm_fs_ss_record_free(ss);
01930 } else if (LSM_ERR_JOB_STARTED == rc) {
01931 r.push_back(Value(job));
01932 r.push_back(Value());
01933 response = Value(r);
01934 free(job);
01935 }
01936
01937 } else {
01938 rc = LSM_ERR_NO_MEMORY;
01939 }
01940
01941 lsm_fs_record_free(fs);
01942
01943 } else {
01944 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01945 }
01946 }
01947 return rc;
01948 }
01949
01950 static int ss_delete(lsm_plugin_ptr p, Value & params, Value & response)
01951 {
01952 int rc = LSM_ERR_NO_SUPPORT;
01953 if (p && p->fs_ops && p->fs_ops->fs_ss_delete) {
01954
01955 Value v_fs = params["fs"];
01956 Value v_ss = params["snapshot"];
01957
01958 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01959 IS_CLASS_FS_SNAPSHOT(v_ss) && LSM_FLAG_EXPECTED_TYPE(params)) {
01960
01961 lsm_fs *fs = value_to_fs(v_fs);
01962 lsm_fs_ss *ss = value_to_ss(v_ss);
01963
01964 if (fs && ss) {
01965 char *job = NULL;
01966 rc = p->fs_ops->fs_ss_delete(p, fs, ss, &job,
01967 LSM_FLAG_GET_VALUE(params));
01968
01969 if (LSM_ERR_JOB_STARTED == rc) {
01970 response = Value(job);
01971 free(job);
01972 }
01973 } else {
01974 rc = LSM_ERR_NO_MEMORY;
01975 }
01976
01977 lsm_fs_record_free(fs);
01978 lsm_fs_ss_record_free(ss);
01979 } else {
01980 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
01981 }
01982 }
01983 return rc;
01984 }
01985
01986 static int ss_restore(lsm_plugin_ptr p, Value & params, Value & response)
01987 {
01988 int rc = LSM_ERR_NO_SUPPORT;
01989 if (p && p->fs_ops && p->fs_ops->fs_ss_restore) {
01990
01991 Value v_fs = params["fs"];
01992 Value v_ss = params["snapshot"];
01993 Value v_files = params["files"];
01994 Value v_restore_files = params["restore_files"];
01995 Value v_all_files = params["all_files"];
01996
01997 if (IS_CLASS_FILE_SYSTEM(v_fs) &&
01998 IS_CLASS_FS_SNAPSHOT(v_ss) &&
01999 (Value::array_t == v_files.valueType() ||
02000 Value::null_t == v_files.valueType()) &&
02001 (Value::array_t == v_restore_files.valueType() ||
02002 Value::null_t == v_restore_files.valueType()) &&
02003 Value::boolean_t == v_all_files.valueType() &&
02004 LSM_FLAG_EXPECTED_TYPE(params)) {
02005
02006 char *job = NULL;
02007 lsm_fs *fs = value_to_fs(v_fs);
02008 lsm_fs_ss *ss = value_to_ss(v_ss);
02009 lsm_string_list *files =
02010 (Value::null_t ==
02011 v_files.valueType())? NULL : value_to_string_list(v_files);
02012 lsm_string_list *restore_files =
02013 (Value::null_t ==
02014 v_restore_files.valueType())? NULL :
02015 value_to_string_list(v_restore_files);
02016 int all_files = (v_all_files.asBool())? 1 : 0;
02017
02018 if (fs && ss &&
02019 (files || (!files && Value::null_t == v_files.valueType()))
02020 && (restore_files
02021 || (!restore_files
02022 && Value::null_t == v_restore_files.valueType()))) {
02023 rc = p->fs_ops->fs_ss_restore(p, fs, ss, files,
02024 restore_files, all_files,
02025 &job, LSM_FLAG_GET_VALUE(params));
02026
02027 if (LSM_ERR_JOB_STARTED == rc) {
02028 response = Value(job);
02029 free(job);
02030 }
02031 } else {
02032 rc = LSM_ERR_NO_MEMORY;
02033 }
02034
02035 lsm_fs_record_free(fs);
02036 lsm_fs_ss_record_free(ss);
02037 lsm_string_list_free(files);
02038 lsm_string_list_free(restore_files);
02039 } else {
02040 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02041 }
02042 }
02043 return rc;
02044 }
02045
02046 static int export_auth(lsm_plugin_ptr p, Value & params, Value & response)
02047 {
02048 int rc = LSM_ERR_NO_SUPPORT;
02049 if (p && p->nas_ops && p->nas_ops->nfs_auth_types) {
02050 lsm_string_list *types = NULL;
02051
02052 if (LSM_FLAG_EXPECTED_TYPE(params)) {
02053
02054 rc = p->nas_ops->nfs_auth_types(p, &types,
02055 LSM_FLAG_GET_VALUE(params));
02056 if (LSM_ERR_OK == rc) {
02057 response = string_list_to_value(types);
02058 lsm_string_list_free(types);
02059 }
02060 } else {
02061 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02062 }
02063
02064 }
02065 return rc;
02066 }
02067
02068 static int exports(lsm_plugin_ptr p, Value & params, Value & response)
02069 {
02070 int rc = LSM_ERR_NO_SUPPORT;
02071 char *key = NULL;
02072 char *val = NULL;
02073
02074 if (p && p->nas_ops && p->nas_ops->nfs_list) {
02075 lsm_nfs_export **exports = NULL;
02076 uint32_t count = 0;
02077
02078 if (LSM_FLAG_EXPECTED_TYPE(params) &&
02079 (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK) {
02080 rc = p->nas_ops->nfs_list(p, key, val, &exports, &count,
02081 LSM_FLAG_GET_VALUE(params));
02082
02083 if (LSM_ERR_OK == rc) {
02084 std::vector < Value > result;
02085 result.reserve(count);
02086
02087 for (uint32_t i = 0; i < count; ++i) {
02088 result.push_back(nfs_export_to_value(exports[i]));
02089 }
02090 response = Value(result);
02091
02092 lsm_nfs_export_record_array_free(exports, count);
02093 exports = NULL;
02094 count = 0;
02095 }
02096 free(key);
02097 free(val);
02098 } else {
02099 if (rc == LSM_ERR_NO_SUPPORT) {
02100 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02101 }
02102 }
02103 }
02104
02105 return rc;
02106 }
02107
02108 static int64_t get_uid_gid(Value & id)
02109 {
02110 if (Value::null_t == id.valueType()) {
02111 return ANON_UID_GID_NA;
02112 } else {
02113 return id.asInt64_t();
02114 }
02115 }
02116
02117 static int export_fs(lsm_plugin_ptr p, Value & params, Value & response)
02118 {
02119 int rc = LSM_ERR_NO_SUPPORT;
02120
02121 if (p && p->nas_ops && p->nas_ops->nfs_export) {
02122
02123 Value v_fs_id = params["fs_id"];
02124 Value v_export_path = params["export_path"];
02125 Value v_root_list = params["root_list"];
02126 Value v_rw_list = params["rw_list"];
02127 Value v_ro_list = params["ro_list"];
02128 Value v_auth_type = params["auth_type"];
02129 Value v_options = params["options"];
02130 Value v_anon_uid = params["anon_uid"];
02131 Value v_anon_gid = params["anon_gid"];
02132
02133 if (Value::string_t == v_fs_id.valueType() &&
02134 (Value::string_t == v_export_path.valueType() ||
02135 Value::null_t == v_export_path.valueType()) &&
02136 Value::array_t == v_root_list.valueType() &&
02137 Value::array_t == v_rw_list.valueType() &&
02138 Value::array_t == v_ro_list.valueType() &&
02139 (Value::string_t == v_auth_type.valueType() ||
02140 Value::null_t == v_auth_type.valueType()) &&
02141 (Value::string_t == v_options.valueType() ||
02142 Value::null_t == v_options.valueType()) &&
02143 Value::numeric_t == v_anon_uid.valueType() &&
02144 Value::numeric_t == v_anon_gid.valueType() &&
02145 LSM_FLAG_EXPECTED_TYPE(params)) {
02146
02147 lsm_string_list *root_list = value_to_string_list(v_root_list);
02148 lsm_string_list *rw_list = value_to_string_list(v_rw_list);
02149 lsm_string_list *ro_list = value_to_string_list(v_ro_list);
02150
02151 if (root_list && rw_list && ro_list) {
02152 const char *fs_id = v_fs_id.asC_str();
02153 const char *export_path = v_export_path.asC_str();
02154 const char *auth_type = v_auth_type.asC_str();
02155 const char *options = v_options.asC_str();
02156 lsm_nfs_export *exported = NULL;
02157
02158 int64_t anon_uid = get_uid_gid(v_anon_uid);
02159 int64_t anon_gid = get_uid_gid(v_anon_gid);
02160
02161 rc = p->nas_ops->nfs_export(p, fs_id, export_path,
02162 root_list, rw_list, ro_list,
02163 anon_uid, anon_gid, auth_type,
02164 options, &exported,
02165 LSM_FLAG_GET_VALUE(params));
02166 if (LSM_ERR_OK == rc) {
02167 response = nfs_export_to_value(exported);
02168 lsm_nfs_export_record_free(exported);
02169 }
02170
02171 } else {
02172 rc = LSM_ERR_NO_MEMORY;
02173 }
02174
02175 lsm_string_list_free(root_list);
02176 lsm_string_list_free(rw_list);
02177 lsm_string_list_free(ro_list);
02178
02179 } else {
02180 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02181 }
02182 }
02183 return rc;
02184 }
02185
02186 static int export_remove(lsm_plugin_ptr p, Value & params, Value & response)
02187 {
02188 int rc = LSM_ERR_NO_SUPPORT;
02189
02190 if (p && p->nas_ops && p->nas_ops->nfs_export_remove) {
02191 Value v_export = params["export"];
02192
02193 if (IS_CLASS_FS_EXPORT(v_export) && LSM_FLAG_EXPECTED_TYPE(params)) {
02194 lsm_nfs_export *exp = value_to_nfs_export(v_export);
02195
02196 if (exp) {
02197 rc = p->nas_ops->nfs_export_remove(p, exp,
02198 LSM_FLAG_GET_VALUE(params));
02199 lsm_nfs_export_record_free(exp);
02200 exp = NULL;
02201 } else {
02202 rc = LSM_ERR_NO_MEMORY;
02203 }
02204 } else {
02205 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02206 }
02207 }
02208 return rc;
02209 }
02210
02211 static int iscsi_chap(lsm_plugin_ptr p, Value & params, Value & response)
02212 {
02213 int rc = LSM_ERR_NO_SUPPORT;
02214
02215 if (p && p->san_ops && p->san_ops->iscsi_chap_auth) {
02216 Value v_init = params["init_id"];
02217 Value v_in_user = params["in_user"];
02218 Value v_in_password = params["in_password"];
02219 Value v_out_user = params["out_user"];
02220 Value v_out_password = params["out_password"];
02221
02222 if (Value::string_t == v_init.valueType() &&
02223 (Value::string_t == v_in_user.valueType() ||
02224 Value::null_t == v_in_user.valueType()) &&
02225 (Value::string_t == v_in_password.valueType() ||
02226 Value::null_t == v_in_password.valueType()) &&
02227 (Value::string_t == v_out_user.valueType() ||
02228 Value::null_t == v_out_user.valueType()) &&
02229 (Value::string_t == v_out_password.valueType() ||
02230 Value::null_t == v_out_password.valueType()) &&
02231 LSM_FLAG_EXPECTED_TYPE(params)) {
02232
02233 rc = p->san_ops->iscsi_chap_auth(p, v_init.asC_str(),
02234 v_in_user.asC_str(),
02235 v_in_password.asC_str(),
02236 v_out_user.asC_str(),
02237 v_out_password.asC_str(),
02238 LSM_FLAG_GET_VALUE(params));
02239
02240 } else {
02241 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02242 }
02243 }
02244 return rc;
02245 }
02246
02247 static int handle_volume_raid_create_cap_get(lsm_plugin_ptr p,
02248 Value & params, Value & response)
02249 {
02250 int rc = LSM_ERR_NO_SUPPORT;
02251 if (p && p->ops_v1_2 && p->ops_v1_2->vol_create_raid_cap_get) {
02252 Value v_system = params["system"];
02253
02254 if (IS_CLASS_SYSTEM(v_system) && LSM_FLAG_EXPECTED_TYPE(params)) {
02255
02256 uint32_t *supported_raid_types = NULL;
02257 uint32_t supported_raid_type_count = 0;
02258
02259 uint32_t *supported_strip_sizes = NULL;
02260 uint32_t supported_strip_size_count = 0;
02261
02262 lsm_system *sys = value_to_system(v_system);
02263
02264 if (sys) {
02265
02266 rc = p->ops_v1_2->vol_create_raid_cap_get
02267 (p, sys, &supported_raid_types, &supported_raid_type_count,
02268 &supported_strip_sizes, &supported_strip_size_count,
02269 LSM_FLAG_GET_VALUE (params));
02270
02271 if (LSM_ERR_OK == rc) {
02272 std::vector < Value > result;
02273 result.push_back(uint32_array_to_value
02274 (supported_raid_types,
02275 supported_raid_type_count));
02276 result.push_back(uint32_array_to_value
02277 (supported_strip_sizes,
02278 supported_strip_size_count));
02279 response = Value(result);
02280 free(supported_raid_types);
02281 free(supported_strip_sizes);
02282 }
02283 } else {
02284 rc = LSM_ERR_NO_MEMORY;
02285 }
02286
02287 lsm_system_record_free(sys);
02288
02289 } else {
02290 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02291 }
02292 }
02293 return rc;
02294 }
02295
02296 static int handle_volume_raid_create(lsm_plugin_ptr p, Value & params,
02297 Value & response)
02298 {
02299 int rc = LSM_ERR_NO_SUPPORT;
02300 if (p && p->ops_v1_2 && p->ops_v1_2->vol_create_raid) {
02301 Value v_name = params["name"];
02302 Value v_raid_type = params["raid_type"];
02303 Value v_strip_size = params["strip_size"];
02304 Value v_disks = params["disks"];
02305
02306 if (Value::string_t == v_name.valueType() &&
02307 Value::numeric_t == v_raid_type.valueType() &&
02308 Value::numeric_t == v_strip_size.valueType() &&
02309 Value::array_t == v_disks.valueType() &&
02310 LSM_FLAG_EXPECTED_TYPE(params)) {
02311
02312 lsm_disk **disks = NULL;
02313 uint32_t disk_count = 0;
02314 rc = value_array_to_disks(v_disks, &disks, &disk_count);
02315 if (LSM_ERR_OK != rc) {
02316 lsm_disk_record_array_free(disks, disk_count);
02317 return rc;
02318 }
02319
02320 const char *name = v_name.asC_str();
02321 lsm_volume_raid_type raid_type =
02322 (lsm_volume_raid_type) v_raid_type.asInt32_t();
02323 uint32_t strip_size = v_strip_size.asUint32_t();
02324
02325 lsm_volume *new_vol = NULL;
02326
02327 rc = p->ops_v1_2->vol_create_raid(p, name, raid_type, disks,
02328 disk_count, strip_size,
02329 &new_vol,
02330 LSM_FLAG_GET_VALUE(params));
02331
02332 if (LSM_ERR_OK == rc) {
02333 response = volume_to_value(new_vol);
02334 lsm_volume_record_free(new_vol);
02335 }
02336
02337 lsm_disk_record_array_free(disks, disk_count);
02338
02339 } else {
02340 rc = LSM_ERR_TRANSPORT_INVALID_ARG;
02341 }
02342 }
02343 return rc;
02344 }
02345
02349 static std::map < std::string, handler > dispatch =
02350 static_map < std::string, handler > ("access_group_initiator_add",
02351 ag_initiator_add)
02352 ("access_group_create", ag_create)
02353 ("access_group_delete", ag_delete)
02354 ("access_group_initiator_delete", ag_initiator_del)
02355 ("volume_mask", volume_mask)
02356 ("access_groups", ag_list)
02357 ("volume_unmask", volume_unmask)
02358 ("access_groups_granted_to_volume", ag_granted_to_volume)
02359 ("capabilities", capabilities)
02360 ("disks", handle_disks)
02361 ("export_auth", export_auth)
02362 ("export_fs", export_fs)
02363 ("export_remove", export_remove)
02364 ("exports", exports)
02365 ("fs_file_clone", fs_file_clone)
02366 ("fs_child_dependency", fs_child_dependency)
02367 ("fs_child_dependency_rm", fs_child_dependency_rm)
02368 ("fs_clone", fs_clone)
02369 ("fs_create", fs_create)
02370 ("fs_delete", fs_delete)
02371 ("fs", fs)
02372 ("fs_resize", fs_resize)
02373 ("fs_snapshot_create", ss_create)
02374 ("fs_snapshot_delete", ss_delete)
02375 ("fs_snapshot_restore", ss_restore)
02376 ("fs_snapshots", ss_list)
02377 ("time_out_get", handle_get_time_out)
02378 ("iscsi_chap_auth", iscsi_chap)
02379 ("job_free", handle_job_free)
02380 ("job_status", handle_job_status)
02381 ("plugin_info", handle_plugin_info)
02382 ("pools", handle_pools)
02383 ("target_ports", handle_target_ports)
02384 ("time_out_set", handle_set_time_out)
02385 ("plugin_unregister", handle_unregister)
02386 ("plugin_register", handle_register)
02387 ("systems", handle_system_list)
02388 ("volume_child_dependency_rm", volume_dependency_rm)
02389 ("volume_child_dependency", volume_dependency)
02390 ("volume_create", handle_volume_create)
02391 ("volume_delete", handle_volume_delete)
02392 ("volume_disable", handle_volume_disable)
02393 ("volume_enable", handle_volume_enable)
02394 ("volume_replicate", handle_volume_replicate)
02395 ("volume_replicate_range_block_size",
02396 handle_volume_replicate_range_block_size)
02397 ("volume_replicate_range", handle_volume_replicate_range)
02398 ("volume_resize", handle_volume_resize)
02399 ("volumes_accessible_by_access_group", vol_accessible_by_ag)
02400 ("volumes", handle_volumes)
02401 ("volume_raid_info", handle_volume_raid_info)
02402 ("pool_member_info", handle_pool_member_info)
02403 ("volume_raid_create", handle_volume_raid_create)
02404 ("volume_raid_create_cap_get", handle_volume_raid_create_cap_get);
02405
02406 static int process_request(lsm_plugin_ptr p, const std::string & method,
02407 Value & request, Value & response)
02408 {
02409 int rc = LSM_ERR_LIB_BUG;
02410
02411 response = Value();
02412
02413 if (dispatch.find(method) != dispatch.end()) {
02414 rc = (dispatch[method]) (p, request["params"], response);
02415 } else {
02416 rc = LSM_ERR_NO_SUPPORT;
02417 }
02418
02419 return rc;
02420 }
02421
02422 static int lsm_plugin_run(lsm_plugin_ptr p)
02423 {
02424 int rc = 0;
02425 lsm_flag flags = 0;
02426
02427 if (LSM_IS_PLUGIN(p)) {
02428 while (true) {
02429 try {
02430
02431 if (!LSM_IS_PLUGIN(p)) {
02432 syslog(LOG_USER | LOG_NOTICE, "Someone stepped on "
02433 "plugin pointer, exiting!");
02434 break;
02435 }
02436
02437 Value req = p->tp->readRequest();
02438 Value resp;
02439
02440 if (req.isValidRequest()) {
02441 std::string method = req["method"].asString();
02442 rc = process_request(p, method, req, resp);
02443
02444 if (LSM_ERR_OK == rc || LSM_ERR_JOB_STARTED == rc) {
02445 p->tp->responseSend(resp);
02446 } else {
02447 error_send(p, rc);
02448 }
02449
02450 if (method == "plugin_unregister") {
02451 flags = LSM_FLAG_GET_VALUE(req["params"]);
02452 break;
02453 }
02454 } else {
02455 syslog(LOG_USER | LOG_NOTICE, "Invalid request");
02456 break;
02457 }
02458 }
02459 catch(EOFException & eof) {
02460 break;
02461 }
02462 catch(ValueException & ve) {
02463 syslog(LOG_USER | LOG_NOTICE, "Plug-in exception: %s",
02464 ve.what());
02465 rc = 1;
02466 break;
02467 }
02468 catch(LsmException & le) {
02469 syslog(LOG_USER | LOG_NOTICE, "Plug-in exception: %s",
02470 le.what());
02471 rc = 2;
02472 break;
02473 }
02474 catch( ...) {
02475 syslog(LOG_USER | LOG_NOTICE, "Plug-in un-handled exception");
02476 rc = 3;
02477 break;
02478 }
02479 }
02480 lsm_plugin_free(p, flags);
02481 p = NULL;
02482 } else {
02483 rc = LSM_ERR_INVALID_ARGUMENT;
02484 }
02485
02486 return rc;
02487 }
02488
02489 int lsm_log_error_basic(lsm_plugin_ptr plug, lsm_error_number code,
02490 const char *msg)
02491 {
02492 if (!LSM_IS_PLUGIN(plug)) {
02493 return LSM_ERR_INVALID_ARGUMENT;
02494 }
02495
02496 lsm_error_ptr e = LSM_ERROR_CREATE_PLUGIN_MSG(code, msg);
02497 if (e) {
02498 int rc = lsm_plugin_error_log(plug, e);
02499
02500 if (LSM_ERR_OK != rc) {
02501 syslog(LOG_USER | LOG_NOTICE,
02502 "Plug-in error %d while reporting an error, code= %d, "
02503 "msg= %s",
02504 rc, code, msg);
02505 }
02506 }
02507 return (int) code;
02508 }
02509
02510 int lsm_plugin_error_log(lsm_plugin_ptr plug, lsm_error_ptr error)
02511 {
02512 if (!LSM_IS_PLUGIN(plug) || !LSM_IS_ERROR(error)) {
02513 return LSM_ERR_INVALID_ARGUMENT;
02514 }
02515
02516 if (plug->error) {
02517 lsm_error_free(plug->error);
02518 }
02519
02520 plug->error = error;
02521
02522 return LSM_ERR_OK;
02523 }
02524
02525
02526 #define STR_D(c, s) \
02527 do { \
02528 if(s) { \
02529 (c) = strdup(s); \
02530 if( !c ) {\
02531 rc = LSM_ERR_NO_MEMORY; \
02532 goto bail; \
02533 } \
02534 } \
02535 } while(0)\
02536
02537 int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme,
02538 char **user, char **server, int *port,
02539 char **path, lsm_hash ** query_params)
02540 {
02541 int rc = LSM_ERR_INVALID_ARGUMENT;
02542 xmlURIPtr u = NULL;
02543
02544 if (uri && strlen(uri) > 0) {
02545 *scheme = NULL;
02546 *user = NULL;
02547 *server = NULL;
02548 *port = -1;
02549 *path = NULL;
02550 *query_params = NULL;
02551
02552 u = xmlParseURI(uri);
02553 if (u) {
02554 STR_D(*scheme, u->scheme);
02555 STR_D(*user, u->user);
02556 STR_D(*server, u->server);
02557 STR_D(*path, u->path);
02558 *port = u->port;
02559
02560 *query_params = lsm_hash_alloc();
02561 if (*query_params) {
02562 int i;
02563 struct qparam_set *qp = NULL;
02564 qp = qparam_query_parse(u->query_raw);
02565
02566 if (qp) {
02567 for (i = 0; i < qp->n; ++i) {
02568 rc = lsm_hash_string_set(*query_params,
02569 qp->p[i].name, qp->p[i].value);
02570 if (LSM_ERR_OK != rc) {
02571 free_qparam_set(qp);
02572 goto bail;
02573 }
02574 }
02575 free_qparam_set(qp);
02576 }
02577 } else {
02578 rc = LSM_ERR_NO_MEMORY;
02579 goto bail;
02580 }
02581
02582 rc = LSM_ERR_OK;
02583 }
02584
02585 bail:
02586 if (rc != LSM_ERR_OK) {
02587 free(*scheme);
02588 *scheme = NULL;
02589 free(*user);
02590 *user = NULL;
02591 free(*server);
02592 *server = NULL;
02593 *port = -1;
02594 free(*path);
02595 *path = NULL;
02596 lsm_hash_free(*query_params);
02597 *query_params = NULL;
02598 }
02599
02600 if (u) {
02601 xmlFreeURI(u);
02602 u = NULL;
02603 }
02604 }
02605 return rc;
02606 }
02607
02608
02609 typedef int (*array_cmp) (void *item, void *cmp_data);
02610 typedef void (*free_item) (void *item);
02611
02612 #define CMP_FUNCTION(name, method, method_type) \
02613 static int name(void *i, void *d) \
02614 { \
02615 method_type *v = (method_type *)i; \
02616 char *val = (char *)d; \
02617 \
02618 if( strcmp(method(v), val) == 0 ) { \
02619 return 1; \
02620 } \
02621 return 0; \
02622 } \
02623
02624
02625 #define CMP_FREE_FUNCTION(name, method, method_type) \
02626 static void name(void *i) \
02627 { \
02628 method((method_type *)i); \
02629 } \
02630
02631 static int filter(void *a[], size_t size, array_cmp cmp, void *cmp_data,
02632 free_item fo)
02633 {
02634 int remaining = 0;
02635 size_t i = 0;
02636
02637 for (i = 0; i < size; ++i) {
02638 if (cmp(a[i], cmp_data)) {
02639 memmove(&a[remaining], &a[i], sizeof(void *));
02640 remaining += 1;
02641 } else {
02642 fo(a[i]);
02643 a[i] = NULL;
02644 }
02645 }
02646 return remaining;
02647 }
02648
02649 CMP_FUNCTION(volume_compare_id, lsm_volume_id_get, lsm_volume)
02650 CMP_FUNCTION(volume_compare_system, lsm_volume_system_id_get, lsm_volume)
02651 CMP_FUNCTION(volume_compare_pool, lsm_volume_pool_id_get, lsm_volume)
02652 CMP_FREE_FUNCTION(volume_free, lsm_volume_record_free, lsm_volume)
02653
02654 void lsm_plug_volume_search_filter(const char *search_key,
02655 const char *search_value,
02656 lsm_volume * vols[], uint32_t * count)
02657 {
02658 array_cmp cmp = NULL;
02659
02660 if (search_key) {
02661
02662 if (0 == strcmp("id", search_key)) {
02663 cmp = volume_compare_id;
02664 } else if (0 == strcmp("system_id", search_key)) {
02665 cmp = volume_compare_system;
02666 } else if (0 == strcmp("pool_id", search_key)) {
02667 cmp = volume_compare_pool;
02668 }
02669
02670 if (cmp) {
02671 *count =
02672 filter((void **) vols, *count, cmp, (void *) search_value,
02673 volume_free);
02674 }
02675 }
02676 }
02677
02678 CMP_FUNCTION(pool_compare_id, lsm_pool_id_get, lsm_pool)
02679 CMP_FUNCTION(pool_compare_system, lsm_pool_system_id_get, lsm_pool)
02680 CMP_FREE_FUNCTION(pool_free, lsm_pool_record_free, lsm_pool);
02681
02682 void lsm_plug_pool_search_filter(const char *search_key,
02683 const char *search_value,
02684 lsm_pool * pools[], uint32_t * count)
02685 {
02686 array_cmp cmp = NULL;
02687
02688 if (search_key) {
02689
02690 if (0 == strcmp("id", search_key)) {
02691 cmp = pool_compare_id;
02692 } else if (0 == strcmp("system_id", search_key)) {
02693 cmp = pool_compare_system;
02694 }
02695
02696 if (cmp) {
02697 *count =
02698 filter((void **) pools, *count, cmp, (void *) search_value,
02699 pool_free);
02700 }
02701 }
02702 }
02703
02704 CMP_FUNCTION(disk_compare_id, lsm_disk_id_get, lsm_disk)
02705 CMP_FUNCTION(disk_compare_system, lsm_disk_system_id_get, lsm_disk)
02706 CMP_FREE_FUNCTION(disk_free, lsm_disk_record_free, lsm_disk)
02707
02708 void lsm_plug_disk_search_filter(const char *search_key,
02709 const char *search_value,
02710 lsm_disk * disks[], uint32_t * count)
02711 {
02712 array_cmp cmp = NULL;
02713
02714 if (search_key) {
02715
02716 if (0 == strcmp("id", search_key)) {
02717 cmp = disk_compare_id;
02718 } else if (0 == strcmp("system_id", search_key)) {
02719 cmp = disk_compare_system;
02720 }
02721
02722 if (cmp) {
02723 *count =
02724 filter((void **) disks, *count, cmp, (void *) search_value,
02725 disk_free);
02726 }
02727 }
02728 }
02729
02730 CMP_FUNCTION(access_group_compare_id, lsm_access_group_id_get, lsm_access_group)
02731 CMP_FUNCTION(access_group_compare_system, lsm_access_group_system_id_get,
02732 lsm_access_group)
02733 CMP_FREE_FUNCTION(access_group_free, lsm_access_group_record_free,
02734 lsm_access_group);
02735
02736 void lsm_plug_access_group_search_filter(const char *search_key,
02737 const char *search_value,
02738 lsm_access_group * ag[],
02739 uint32_t * count)
02740 {
02741 array_cmp cmp = NULL;
02742
02743 if (search_key) {
02744
02745 if (0 == strcmp("id", search_key)) {
02746 cmp = access_group_compare_id;
02747 } else if (0 == strcmp("system_id", search_key)) {
02748 cmp = access_group_compare_system;
02749 }
02750
02751 if (cmp) {
02752 *count =
02753 filter((void **) ag, *count, cmp, (void *) search_value,
02754 access_group_free);
02755 }
02756 }
02757 }
02758
02759 CMP_FUNCTION(fs_compare_id, lsm_fs_id_get, lsm_fs)
02760 CMP_FUNCTION(fs_compare_system, lsm_fs_system_id_get, lsm_fs)
02761 CMP_FREE_FUNCTION(fs_free, lsm_fs_record_free, lsm_fs);
02762
02763 void lsm_plug_fs_search_filter(const char *search_key,
02764 const char *search_value,
02765 lsm_fs * fs[], uint32_t * count)
02766 {
02767 array_cmp cmp = NULL;
02768
02769 if (search_key) {
02770
02771 if (0 == strcmp("id", search_key)) {
02772 cmp = fs_compare_id;
02773 } else if (0 == strcmp("system_id", search_key)) {
02774 cmp = fs_compare_system;
02775 }
02776
02777 if (cmp) {
02778 *count =
02779 filter((void **) fs, *count, cmp, (void *) search_value,
02780 fs_free);
02781 }
02782 }
02783 }
02784
02785 CMP_FUNCTION(nfs_compare_id, lsm_nfs_export_id_get, lsm_nfs_export)
02786 CMP_FUNCTION(nfs_compare_fs_id, lsm_nfs_export_fs_id_get, lsm_nfs_export)
02787 CMP_FREE_FUNCTION(nfs_free, lsm_nfs_export_record_free, lsm_nfs_export)
02788
02789 void lsm_plug_nfs_export_search_filter(const char *search_key,
02790 const char *search_value,
02791 lsm_nfs_export * exports[],
02792 uint32_t * count)
02793 {
02794 array_cmp cmp = NULL;
02795
02796 if (search_key) {
02797
02798 if (0 == strcmp("id", search_key)) {
02799 cmp = nfs_compare_id;
02800 } else if (0 == strcmp("fs_id", search_key)) {
02801 cmp = nfs_compare_fs_id;
02802 }
02803
02804 if (cmp) {
02805 *count =
02806 filter((void **) exports, *count, cmp,
02807 (void *) search_value, nfs_free);
02808 }
02809 }
02810 }
02811
02812 CMP_FUNCTION(tp_compare_id, lsm_target_port_id_get, lsm_target_port)
02813 CMP_FUNCTION(tp_compare_system_id, lsm_target_port_system_id_get,
02814 lsm_target_port)
02815 CMP_FREE_FUNCTION(tp_free, lsm_target_port_record_free, lsm_target_port)
02816
02817 void lsm_plug_target_port_search_filter(const char *search_key,
02818 const char *search_value,
02819 lsm_target_port * tp[],
02820 uint32_t * count)
02821 {
02822 array_cmp cmp = NULL;
02823
02824 if (search_key) {
02825
02826 if (0 == strcmp("id", search_key)) {
02827 cmp = tp_compare_id;
02828 } else if (0 == strcmp("system_id", search_key)) {
02829 cmp = tp_compare_system_id;
02830 }
02831
02832 if (cmp) {
02833 *count =
02834 filter((void **) tp, *count, cmp, (void *) search_value,
02835 tp_free);
02836 }
02837 }
02838 }