00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "libstoragemgmt/libstoragemgmt.h"
00020 #include "libstoragemgmt/libstoragemgmt_error.h"
00021 #include "libstoragemgmt/libstoragemgmt_plug_interface.h"
00022 #include "libstoragemgmt/libstoragemgmt_types.h"
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <dirent.h>
00026 #include <libxml/uri.h>
00027
00028 #include "lsm_datatypes.hpp"
00029 #include "lsm_convert.hpp"
00030
00031 #define COUNT_OF(x) \
00032 ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
00033
00034 static const char *const POOL_SEARCH_KEYS[] = { "id", "system_id" };
00035
00036 #define POOL_SEARCH_KEYS_COUNT COUNT_OF(POOL_SEARCH_KEYS)
00037
00038 static const char *const VOLUME_SEARCH_KEYS[] =
00039 { "id", "system_id", "pool_id" };
00040 #define VOLUME_SEARCH_KEYS_COUNT COUNT_OF(VOLUME_SEARCH_KEYS)
00041
00042 static const char *const DISK_SEARCH_KEYS[] = { "id", "system_id" };
00043
00044 #define DISK_SEARCH_KEYS_COUNT COUNT_OF(DISK_SEARCH_KEYS)
00045
00046 static const char *const FS_SEARCH_KEYS[] = { "id", "system_id", "pool_id" };
00047
00048 #define FS_SEARCH_KEYS_COUNT COUNT_OF(FS_SEARCH_KEYS)
00049
00050 static const char *const NFS_EXPORT_SEARCH_KEYS[] = { "id", "fs_id" };
00051
00052 #define NFS_EXPORT_SEARCH_KEYS_COUNT COUNT_OF(NFS_EXPORT_SEARCH_KEYS)
00053
00054 static const char *const ACCESS_GROUP_SEARCH_KEYS[] = { "id", "system_id" };
00055
00056 #define ACCESS_GROUP_SEARCH_KEYS_COUNT COUNT_OF(ACCESS_GROUP_SEARCH_KEYS)
00057
00058 static const char *const TARGET_PORT_SEARCH_KEYS[] = { "id", "system_id" };
00059
00060 #define TARGET_PORT_SEARCH_KEYS_COUNT COUNT_OF(TARGET_PORT_SEARCH_KEYS)
00061
00065 #define CONN_SETUP(c) do { \
00066 if(!LSM_IS_CONNECT(c)) { \
00067 return LSM_ERR_INVALID_ARGUMENT;\
00068 } \
00069 lsm_error_free(c->error); \
00070 c->error = NULL; \
00071 } while (0)
00072
00073 static int check_search_key(const char *search_key,
00074 const char *const supported_keys[],
00075 size_t supported_keys_count)
00076 {
00077 size_t i = 0;
00078 for (i = 0; i < supported_keys_count; ++i) {
00079 if (0 == strcmp(search_key, supported_keys[i])) {
00080 return 1;
00081 }
00082 }
00083 return 0;
00084 }
00085
00086 int lsm_initiator_id_verify(const char *init_id,
00087 lsm_access_group_init_type * init_type)
00088 {
00089 int rc = LSM_ERR_INVALID_ARGUMENT;
00090
00091 if (init_id != NULL && strlen(init_id) > 3) {
00092
00093 switch (*init_type) {
00094 case (LSM_ACCESS_GROUP_INIT_TYPE_UNKNOWN):
00095 if (0 == iqn_validate(init_id)) {
00096 *init_type = LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN;
00097 rc = LSM_ERR_OK;
00098 }
00099 if (0 == wwpn_validate(init_id)) {
00100 *init_type = LSM_ACCESS_GROUP_INIT_TYPE_WWPN;
00101 rc = LSM_ERR_OK;
00102 }
00103 break;
00104 case (LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN):
00105 if (0 == iqn_validate(init_id)) {
00106 *init_type = LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN;
00107 rc = LSM_ERR_OK;
00108 }
00109 break;
00110 case (LSM_ACCESS_GROUP_INIT_TYPE_WWPN):
00111 if (0 == wwpn_validate(init_id)) {
00112 *init_type = LSM_ACCESS_GROUP_INIT_TYPE_WWPN;
00113 rc = LSM_ERR_OK;
00114 }
00115 break;
00116 default:
00117 break;
00118 }
00119 }
00120 return rc;
00121 }
00122
00123 int lsm_volume_vpd83_verify(const char *vpd83)
00124 {
00125 int rc = LSM_ERR_INVALID_ARGUMENT;
00126 size_t i;
00127 size_t vpd83_len;
00128
00129 if (vpd83) {
00130 vpd83_len = strlen(vpd83);
00131 if ((vpd83_len == 32 && vpd83[0] == '6') ||
00132 (vpd83_len == 16 && vpd83[0] == '2') ||
00133 (vpd83_len == 16 && vpd83[0] == '3') ||
00134 (vpd83_len == 16 && vpd83[0] == '5')) {
00135 for (i = 0; i < vpd83_len; ++i) {
00136 char v = vpd83[i];
00137
00138 if (!((v >= 48 && v <= 57) || (v >= 97 && v <= 102))) {
00139 return rc;
00140 }
00141 }
00142 rc = LSM_ERR_OK;
00143 }
00144 }
00145 return rc;
00146 }
00147
00148 static int verify_initiator_id(const char *id,
00149 lsm_access_group_init_type t, Value & initiator)
00150 {
00151 initiator = Value(id);
00152
00153 if (t == LSM_ACCESS_GROUP_INIT_TYPE_WWPN) {
00154 char *wwpn = wwpn_convert(id);
00155 if (wwpn) {
00156 initiator = Value(wwpn);
00157 free(wwpn);
00158 wwpn = NULL;
00159 } else {
00160 return LSM_ERR_INVALID_ARGUMENT;
00161 }
00162 } else if (t == LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN) {
00163 if (iqn_validate(id)) {
00164 return LSM_ERR_INVALID_ARGUMENT;
00165 }
00166 }
00167 return LSM_ERR_OK;
00168 }
00169
00173 #define CHECK_STR(x) ( !(x) || !strlen(x) )
00174
00180 #define CHECK_RP(x) (!(x) || *(x) != NULL)
00181
00182 int lsm_connect_password(const char *uri, const char *password,
00183 lsm_connect ** conn, uint32_t timeout,
00184 lsm_error_ptr * e, lsm_flag flags)
00185 {
00186 int rc = LSM_ERR_OK;
00187 lsm_connect *c = NULL;
00188
00189
00190 if (CHECK_STR(uri) || CHECK_RP(conn) || !timeout || CHECK_RP(e) ||
00191 LSM_FLAG_UNUSED_CHECK(flags)) {
00192 return LSM_ERR_INVALID_ARGUMENT;
00193 }
00194
00195 c = connection_get();
00196 if (c) {
00197 c->uri = xmlParseURI(uri);
00198 if (c->uri && c->uri->scheme) {
00199 c->raw_uri = strdup(uri);
00200 if (c->raw_uri) {
00201 rc = driver_load(c, c->uri->scheme, password, timeout, e,
00202 1, flags);
00203 if (rc == LSM_ERR_OK) {
00204 *conn = (lsm_connect *) c;
00205 }
00206 } else {
00207 rc = LSM_ERR_NO_MEMORY;
00208 }
00209 } else {
00210 rc = LSM_ERR_INVALID_ARGUMENT;
00211 }
00212
00213
00214 if (rc != LSM_ERR_OK) {
00215 connection_free(c);
00216 }
00217 } else {
00218 rc = LSM_ERR_NO_MEMORY;
00219 }
00220 return rc;
00221 }
00222
00223 static int lsm_error_log(lsm_connect * c, lsm_error_ptr error)
00224 {
00225 if (!LSM_IS_CONNECT(c) || !LSM_IS_ERROR(error)) {
00226 return LSM_ERR_INVALID_ARGUMENT;
00227 }
00228
00229 if (c->error) {
00230 lsm_error_free(c->error);
00231 c->error = NULL;
00232 }
00233
00234 c->error = error;
00235 return LSM_ERR_OK;
00236 }
00237
00238 static lsm_error_number log_exception(lsm_connect * c,
00239 lsm_error_number error,
00240 const char *message,
00241 const char *exception_msg)
00242 {
00243 lsm_error_ptr err = lsm_error_create(error, message,
00244 exception_msg, NULL,
00245 NULL, 0);
00246 if (err) {
00247 lsm_error_log(c, err);
00248 }
00249 return error;
00250 }
00251
00252 static int rpc(lsm_connect * c, const char *method,
00253 const Value & parameters, Value & response) throw()
00254 {
00255 try {
00256 response = c->tp->rpc(method, parameters);
00257 } catch(const ValueException & ve) {
00258 return log_exception(c, LSM_ERR_TRANSPORT_SERIALIZATION,
00259 "Serialization error", ve.what());
00260 }
00261 catch(const LsmException & le) {
00262 return log_exception(c, (lsm_error_number) le.error_code,
00263 le.what(), NULL);
00264 }
00265 catch(const EOFException & eof) {
00266 return log_exception(c, LSM_ERR_TRANSPORT_COMMUNICATION,
00267 "Plug-in died", "Check syslog");
00268 }
00269 catch( ...) {
00270 return log_exception(c, LSM_ERR_LIB_BUG, "Unexpected exception",
00271 "Unknown exception");
00272 }
00273 return LSM_ERR_OK;
00274 }
00275
00276 static int job_check(lsm_connect * c, int rc, Value & response, char **job)
00277 {
00278 try {
00279 if (LSM_ERR_OK == rc) {
00280
00281 if (Value::string_t == response.valueType()) {
00282 *job = strdup(response.asString().c_str());
00283
00284 if (*job) {
00285 rc = LSM_ERR_JOB_STARTED;
00286 } else {
00287 rc = LSM_ERR_NO_MEMORY;
00288 }
00289 } else {
00290 *job = NULL;
00291 }
00292 }
00293 }
00294 catch(const ValueException & ve) {
00295 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Wrong type", ve.what());
00296 }
00297 return rc;
00298 }
00299
00300 static int get_access_groups(lsm_connect * c, int rc, Value & response,
00301 lsm_access_group ** groups[], uint32_t * count)
00302 {
00303 try {
00304 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
00305 rc = value_array_to_access_groups(response, groups, count);
00306 }
00307 }
00308 catch(const ValueException & ve) {
00309 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00310 }
00311 return rc;
00312 }
00313
00314 static int add_search_params(std::map < std::string, Value > &p,
00315 const char *k, const char *v,
00316 const char *const supported_keys[],
00317 size_t supported_keys_count)
00318 {
00319 if (k) {
00320 if (v) {
00321 if (!check_search_key(k, supported_keys, supported_keys_count)) {
00322 return LSM_ERR_UNSUPPORTED_SEARCH_KEY;
00323 }
00324 } else {
00325 return LSM_ERR_INVALID_ARGUMENT;
00326 }
00327 }
00328 p["search_key"] = Value(k);
00329 p["search_value"] = Value(v);
00330 return LSM_ERR_OK;
00331 }
00332
00333 int lsm_connect_close(lsm_connect * c, lsm_flag flags)
00334 {
00335 CONN_SETUP(c);
00336
00337 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00338 return LSM_ERR_INVALID_ARGUMENT;
00339 }
00340
00341 std::map < std::string, Value > p;
00342 p["flags"] = Value(flags);
00343 Value parameters(p);
00344 Value response;
00345
00346
00347 int rc = rpc(c, "plugin_unregister", parameters, response);
00348
00349
00350 connection_free(c);
00351 return rc;
00352 }
00353
00354 static Value _create_flag_param(lsm_flag flags)
00355 {
00356 std::map < std::string, Value > p;
00357 p["flags"] = Value(flags);
00358 return Value(p);
00359 }
00360
00361 int lsm_plugin_info_get(lsm_connect * c, char **desc,
00362 char **version, lsm_flag flags)
00363 {
00364 int rc = LSM_ERR_OK;
00365 CONN_SETUP(c);
00366
00367 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00368 return LSM_ERR_INVALID_ARGUMENT;
00369 }
00370
00371 if (CHECK_RP(desc) || CHECK_RP(version)) {
00372 return LSM_ERR_INVALID_ARGUMENT;
00373 }
00374
00375 try {
00376
00377 Value parameters = _create_flag_param(flags);
00378 Value response;
00379
00380 rc = rpc(c, "plugin_info", parameters, response);
00381
00382 if (rc == LSM_ERR_OK) {
00383 std::vector < Value > j = response.asArray();
00384 *desc = strdup(j[0].asC_str());
00385 *version = strdup(j[1].asC_str());
00386
00387 if (!*desc || !*version) {
00388 rc = LSM_ERR_NO_MEMORY;
00389 free(*desc);
00390 free(*version);
00391 }
00392 }
00393 }
00394 catch(const ValueException & ve) {
00395 free(*desc);
00396 *desc = NULL;
00397 free(*version);
00398 *version = NULL;
00399 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00400 }
00401
00402 return rc;
00403 }
00404
00405 int lsm_available_plugins_list(const char *sep,
00406 lsm_string_list ** plugins, lsm_flag flags)
00407 {
00408 int rc = LSM_ERR_OK;
00409 DIR *dirp = NULL;
00410 struct dirent *dp = NULL;
00411 lsm_connect *c = NULL;
00412 lsm_error_ptr e = NULL;
00413 char *desc = NULL;
00414 char *version = NULL;
00415 char *s = NULL;
00416 const char *uds_dir = uds_path();
00417 lsm_string_list *plugin_list = NULL;
00418
00419 if (CHECK_STR(sep) || CHECK_RP(plugins)
00420 || LSM_FLAG_UNUSED_CHECK(flags)) {
00421 return LSM_ERR_INVALID_ARGUMENT;
00422 }
00423
00424 plugin_list = lsm_string_list_alloc(0);
00425 if (!plugin_list) {
00426 return LSM_ERR_NO_MEMORY;
00427 }
00428
00429 dirp = opendir(uds_dir);
00430 if (dirp) {
00431 for (;;) {
00432 dp = readdir(dirp);
00433 if (NULL == dp) {
00434 break;
00435 }
00436
00437 if (DT_SOCK == dp->d_type) {
00438 c = connection_get();
00439 if (c) {
00440 rc = driver_load(c, dp->d_name, NULL, 30000, &e, 0, 0);
00441 if (LSM_ERR_OK == rc) {
00442
00443 rc = lsm_plugin_info_get(c, &desc, &version, 0);
00444 if (LSM_ERR_OK == rc) {
00445 int format =
00446 asprintf(&s, "%s%s%s", desc, sep, version);
00447 free(desc);
00448 desc = NULL;
00449 free(version);
00450 version = NULL;
00451
00452 if (-1 == format) {
00453 rc = LSM_ERR_NO_MEMORY;
00454 break;
00455 }
00456
00457 rc = lsm_string_list_append(plugin_list, s);
00458 free(s);
00459 s = NULL;
00460 if (LSM_ERR_OK != rc) {
00461 break;
00462 }
00463
00464 }
00465 } else {
00466 break;
00467 }
00468
00469 connection_free(c);
00470 c = NULL;
00471 }
00472 }
00473 }
00474
00475 if (e) {
00476 lsm_error_free(e);
00477 e = NULL;
00478 }
00479
00480 if (c) {
00481 connection_free(c);
00482 c = NULL;
00483 }
00484
00485
00486 if (-1 == closedir(dirp)) {
00487
00488 rc = LSM_ERR_LIB_BUG;
00489 }
00490
00491 } else {
00492
00493 rc = LSM_ERR_LIB_BUG;
00494 }
00495
00496 if (LSM_ERR_OK == rc) {
00497 *plugins = plugin_list;
00498 } else {
00499 lsm_string_list_free(plugin_list);
00500 plugin_list = NULL;
00501 }
00502
00503 return rc;
00504 }
00505
00506 int lsm_connect_timeout_set(lsm_connect * c, uint32_t timeout, lsm_flag flags)
00507 {
00508 CONN_SETUP(c);
00509
00510 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00511 return LSM_ERR_INVALID_ARGUMENT;
00512 }
00513
00514 std::map < std::string, Value > p;
00515 p["ms"] = Value(timeout);
00516 p["flags"] = Value(flags);
00517 Value parameters(p);
00518 Value response;
00519
00520
00521 return rpc(c, "time_out_set", parameters, response);
00522 }
00523
00524 int lsm_connect_timeout_get(lsm_connect * c, uint32_t * timeout, lsm_flag flags)
00525 {
00526 int rc = LSM_ERR_OK;
00527 CONN_SETUP(c);
00528
00529 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00530 return LSM_ERR_INVALID_ARGUMENT;
00531 }
00532
00533 try {
00534
00535 Value parameters = _create_flag_param(flags);
00536 Value response;
00537
00538 rc = rpc(c, "time_out_get", parameters, response);
00539 if (rc == LSM_ERR_OK) {
00540 *timeout = response.asUint32_t();
00541 }
00542 }
00543 catch(const ValueException & ve) {
00544 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00545 }
00546 return rc;
00547 }
00548
00549 static int job_status(lsm_connect * c, const char *job,
00550 lsm_job_status * status, uint8_t * percentComplete,
00551 Value & returned_value, lsm_flag flags)
00552 {
00553 int rc = LSM_ERR_OK;
00554 CONN_SETUP(c);
00555
00556 if (!job || !status || !percentComplete) {
00557 return LSM_ERR_INVALID_ARGUMENT;
00558 }
00559
00560 try {
00561 std::map < std::string, Value > p;
00562 p["job_id"] = Value(job);
00563 p["flags"] = Value(flags);
00564 Value parameters(p);
00565 Value response;
00566
00567 rc = rpc(c, "job_status", parameters, response);
00568 if (LSM_ERR_OK == rc) {
00569
00570 std::vector < Value > j = response.asArray();
00571 *status = (lsm_job_status) j[0].asInt32_t();
00572 *percentComplete = (uint8_t) j[1].asUint32_t();
00573
00574 returned_value = j[2];
00575 }
00576 }
00577 catch(const ValueException & ve) {
00578 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00579 }
00580 return rc;
00581 }
00582
00583 int lsm_job_status_get(lsm_connect * c, const char *job_id,
00584 lsm_job_status * status, uint8_t * percentComplete,
00585 lsm_flag flags)
00586 {
00587 CONN_SETUP(c);
00588
00589 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00590 return LSM_ERR_INVALID_ARGUMENT;
00591 }
00592
00593 Value rv;
00594 return job_status(c, job_id, status, percentComplete, rv, flags);
00595 }
00596
00597 int lsm_job_status_pool_get(lsm_connect * c,
00598 const char *job, lsm_job_status * status,
00599 uint8_t * percentComplete, lsm_pool ** pool,
00600 lsm_flag flags)
00601 {
00602 Value rv;
00603 int rc = LSM_ERR_OK;
00604
00605 CONN_SETUP(c);
00606
00607 if (CHECK_RP(pool) || LSM_FLAG_UNUSED_CHECK(flags)) {
00608 return LSM_ERR_INVALID_ARGUMENT;
00609 }
00610
00611 try {
00612
00613 rc = job_status(c, job, status, percentComplete, rv, flags);
00614
00615 if (LSM_ERR_OK == rc) {
00616 if (Value::object_t == rv.valueType()) {
00617 *pool = value_to_pool(rv);
00618 if (!(*pool)) {
00619 rc = LSM_ERR_NO_MEMORY;
00620 }
00621 } else {
00622 *pool = NULL;
00623 }
00624 }
00625 }
00626 catch(const ValueException & ve) {
00627 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00628 }
00629 return rc;
00630 }
00631
00632 int lsm_job_status_volume_get(lsm_connect * c, const char *job,
00633 lsm_job_status * status,
00634 uint8_t * percentComplete, lsm_volume ** vol,
00635 lsm_flag flags)
00636 {
00637 Value rv;
00638 int rc = LSM_ERR_OK;
00639
00640 CONN_SETUP(c);
00641
00642 if (CHECK_RP(vol) || LSM_FLAG_UNUSED_CHECK(flags)) {
00643 return LSM_ERR_INVALID_ARGUMENT;
00644 }
00645
00646 try {
00647
00648 rc = job_status(c, job, status, percentComplete, rv, flags);
00649
00650 if (LSM_ERR_OK == rc) {
00651 if (Value::object_t == rv.valueType()) {
00652 *vol = value_to_volume(rv);
00653 if (!(*vol)) {
00654 rc = LSM_ERR_NO_MEMORY;
00655 }
00656 } else {
00657 *vol = NULL;
00658 }
00659 }
00660 }
00661 catch(const ValueException & ve) {
00662 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00663 }
00664 return rc;
00665 }
00666
00667 int lsm_job_status_fs_get(lsm_connect * c, const char *job,
00668 lsm_job_status * status,
00669 uint8_t * percentComplete, lsm_fs ** fs,
00670 lsm_flag flags)
00671 {
00672 int rc = LSM_ERR_OK;
00673 Value rv;
00674
00675 if (CHECK_RP(fs) || LSM_FLAG_UNUSED_CHECK(flags)) {
00676 return LSM_ERR_INVALID_ARGUMENT;
00677 }
00678
00679 try {
00680
00681 rc = job_status(c, job, status, percentComplete, rv, flags);
00682
00683 if (LSM_ERR_OK == rc) {
00684 if (Value::object_t == rv.valueType()) {
00685 *fs = value_to_fs(rv);
00686 if (!(*fs)) {
00687 rc = LSM_ERR_NO_MEMORY;
00688 }
00689 } else {
00690 *fs = NULL;
00691 }
00692 }
00693 }
00694 catch(const ValueException & ve) {
00695 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00696 }
00697 return rc;
00698 }
00699
00700 int lsm_job_status_ss_get(lsm_connect * c, const char *job,
00701 lsm_job_status * status,
00702 uint8_t * percentComplete, lsm_fs_ss ** ss,
00703 lsm_flag flags)
00704 {
00705 int rc = LSM_ERR_OK;
00706 Value rv;
00707
00708 if (CHECK_RP(ss) || LSM_FLAG_UNUSED_CHECK(flags)) {
00709 return LSM_ERR_INVALID_ARGUMENT;
00710 }
00711
00712 try {
00713
00714 rc = job_status(c, job, status, percentComplete, rv, flags);
00715
00716 if (LSM_ERR_OK == rc) {
00717 if (Value::object_t == rv.valueType()) {
00718 *ss = value_to_ss(rv);
00719 if (!(*ss)) {
00720 rc = LSM_ERR_NO_MEMORY;
00721 }
00722 } else {
00723 *ss = NULL;
00724 }
00725 }
00726 }
00727 catch(const ValueException & ve) {
00728 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00729 }
00730 return rc;
00731 }
00732
00733 int lsm_job_free(lsm_connect * c, char **job, lsm_flag flags)
00734 {
00735 CONN_SETUP(c);
00736
00737 if (job == NULL || strlen(*job) < 1 || LSM_FLAG_UNUSED_CHECK(flags)) {
00738 return LSM_ERR_INVALID_ARGUMENT;
00739 }
00740
00741 std::map < std::string, Value > p;
00742 p["job_id"] = Value(*job);
00743 p["flags"] = Value(flags);
00744 Value parameters(p);
00745 Value response;
00746
00747 int rc = rpc(c, "job_free", parameters, response);
00748
00749 if (LSM_ERR_OK == rc) {
00750
00751 free(*job);
00752 *job = NULL;
00753 }
00754 return rc;
00755 }
00756
00757 int lsm_capabilities(lsm_connect * c, lsm_system * system,
00758 lsm_storage_capabilities ** cap, lsm_flag flags)
00759 {
00760 int rc = LSM_ERR_OK;
00761 CONN_SETUP(c);
00762
00763 if (!LSM_IS_SYSTEM(system) || CHECK_RP(cap) ||
00764 LSM_FLAG_UNUSED_CHECK(flags)) {
00765 return LSM_ERR_INVALID_ARGUMENT;
00766 }
00767
00768 std::map < std::string, Value > p;
00769
00770 p["system"] = system_to_value(system);
00771 p["flags"] = Value(flags);
00772
00773 Value parameters(p);
00774 Value response;
00775
00776 try {
00777 rc = rpc(c, "capabilities", parameters, response);
00778
00779 if (LSM_ERR_OK == rc && Value::object_t == response.valueType()) {
00780 *cap = value_to_capabilities(response);
00781 if (!(*cap)) {
00782 rc = LSM_ERR_NO_MEMORY;
00783 }
00784 }
00785 }
00786 catch(const ValueException & ve) {
00787 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00788 }
00789
00790 return rc;
00791 }
00792
00793 int lsm_pool_list(lsm_connect * c, char *search_key, char *search_value,
00794 lsm_pool ** poolArray[], uint32_t * count, lsm_flag flags)
00795 {
00796 int rc = LSM_ERR_OK;
00797 CONN_SETUP(c);
00798
00799 if (!poolArray || !count || CHECK_RP(poolArray)) {
00800 return LSM_ERR_INVALID_ARGUMENT;
00801 }
00802
00803 *count = 0;
00804 *poolArray = NULL;
00805
00806 try {
00807 std::map < std::string, Value > p;
00808
00809 rc = add_search_params(p, search_key, search_value,
00810 POOL_SEARCH_KEYS, POOL_SEARCH_KEYS_COUNT);
00811 if (LSM_ERR_OK != rc) {
00812 return rc;
00813 }
00814
00815 p["flags"] = Value(flags);
00816 Value parameters(p);
00817 Value response;
00818
00819 rc = rpc(c, "pools", parameters, response);
00820 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
00821 std::vector < Value > pools = response.asArray();
00822
00823 *count = pools.size();
00824
00825 if (pools.size()) {
00826 *poolArray = lsm_pool_record_array_alloc(pools.size());
00827
00828 for (size_t i = 0; i < pools.size(); ++i) {
00829 (*poolArray)[i] = value_to_pool(pools[i]);
00830 if (!(*poolArray)[i]) {
00831 rc = LSM_ERR_NO_MEMORY;
00832 goto error;
00833 }
00834 }
00835 }
00836 }
00837 }
00838 catch(const ValueException & ve) {
00839 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00840 goto error;
00841 }
00842
00843 out:
00844 return rc;
00845
00846 error:
00847 if (*poolArray && *count) {
00848 lsm_pool_record_array_free(*poolArray, *count);
00849 *poolArray = NULL;
00850 *count = 0;
00851 }
00852 goto out;
00853 }
00854
00855 int lsm_pool_member_info(lsm_connect * c, lsm_pool * pool,
00856 lsm_volume_raid_type * raid_type,
00857 lsm_pool_member_type * member_type,
00858 lsm_string_list ** member_ids, lsm_flag flags)
00859 {
00860 if (LSM_FLAG_UNUSED_CHECK(flags)) {
00861 return LSM_ERR_INVALID_ARGUMENT;
00862 }
00863
00864 int rc = LSM_ERR_OK;
00865 CONN_SETUP(c);
00866
00867 if (!LSM_IS_POOL(pool)) {
00868 return LSM_ERR_INVALID_ARGUMENT;
00869 }
00870
00871 if (!raid_type || !member_type || !member_ids) {
00872 return LSM_ERR_INVALID_ARGUMENT;
00873 }
00874
00875 std::map < std::string, Value > p;
00876 p["pool"] = pool_to_value(pool);
00877 p["flags"] = Value(flags);
00878 Value parameters(p);
00879 try {
00880
00881 Value response;
00882
00883 rc = rpc(c, "pool_member_info", parameters, response);
00884 if (LSM_ERR_OK == rc) {
00885 std::vector < Value > j = response.asArray();
00886 *raid_type = (lsm_volume_raid_type) j[0].asInt32_t();
00887 *member_type = (lsm_pool_member_type) j[1].asInt32_t();
00888 *member_ids = NULL;
00889 if (Value::array_t == j[2].valueType()) {
00890 if (j[2].asArray().size()) {
00891 *member_ids = value_to_string_list(j[2]);
00892 if (*member_ids == NULL) {
00893 return LSM_ERR_NO_MEMORY;
00894 } else if (lsm_string_list_size(*member_ids) !=
00895 j[2].asArray().size()) {
00896
00897 lsm_string_list_free(*member_ids);
00898 return LSM_ERR_NO_MEMORY;
00899 }
00900 }
00901 } else {
00902 rc = log_exception(c, LSM_ERR_PLUGIN_BUG,
00903 "member_ids data is not an array",
00904 "member_ids data is not an array");
00905 }
00906 }
00907 }
00908 catch(const ValueException & ve) {
00909 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00910 }
00911 return rc;
00912
00913 }
00914
00915 int lsm_target_port_list(lsm_connect * c, const char *search_key,
00916 const char *search_value,
00917 lsm_target_port ** target_ports[],
00918 uint32_t * count, lsm_flag flags)
00919 {
00920 int rc = LSM_ERR_OK;
00921 CONN_SETUP(c);
00922
00923 if (!target_ports || !count || CHECK_RP(target_ports)) {
00924 return LSM_ERR_INVALID_ARGUMENT;
00925 }
00926
00927 try {
00928 std::map < std::string, Value > p;
00929
00930 rc = add_search_params(p, search_key, search_value,
00931 TARGET_PORT_SEARCH_KEYS,
00932 TARGET_PORT_SEARCH_KEYS_COUNT);
00933 if (LSM_ERR_OK != rc) {
00934 return rc;
00935 }
00936
00937 p["flags"] = Value(flags);
00938 Value parameters(p);
00939 Value response;
00940
00941 rc = rpc(c, "target_ports", parameters, response);
00942 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
00943 std::vector < Value > tp = response.asArray();
00944
00945 *count = tp.size();
00946
00947 if (tp.size()) {
00948 *target_ports = lsm_target_port_record_array_alloc(tp.size());
00949
00950 for (size_t i = 0; i < tp.size(); ++i) {
00951 (*target_ports)[i] = value_to_target_port(tp[i]);
00952 if (!((*target_ports)[i])) {
00953 rc = LSM_ERR_NO_MEMORY;
00954 goto error;
00955 }
00956 }
00957 }
00958 }
00959 }
00960 catch(const ValueException & ve) {
00961 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
00962 goto error;
00963 }
00964 out:
00965 return rc;
00966
00967 error:
00968 if (*target_ports && *count) {
00969 lsm_target_port_record_array_free(*target_ports, *count);
00970 *target_ports = NULL;
00971 *count = 0;
00972 }
00973 goto out;
00974 }
00975
00976 static int get_volume_array(lsm_connect * c, int rc, Value & response,
00977 lsm_volume ** volumes[], uint32_t * count)
00978 {
00979 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
00980 try {
00981 rc = value_array_to_volumes(response, volumes, count);
00982 }
00983 catch(const ValueException & ve) {
00984 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Wrong type", ve.what());
00985 }
00986 }
00987 return rc;
00988 }
00989
00990
00991 int lsm_volume_list(lsm_connect * c, const char *search_key,
00992 const char *search_value, lsm_volume ** volumes[],
00993 uint32_t * count, lsm_flag flags)
00994 {
00995 CONN_SETUP(c);
00996
00997 if (!volumes || !count || CHECK_RP(volumes)) {
00998 return LSM_ERR_INVALID_ARGUMENT;
00999 }
01000
01001 std::map < std::string, Value > p;
01002 p["flags"] = Value(flags);
01003
01004 int rc = add_search_params(p, search_key, search_value, VOLUME_SEARCH_KEYS,
01005 VOLUME_SEARCH_KEYS_COUNT);
01006 if (LSM_ERR_OK != rc) {
01007 return rc;
01008 }
01009
01010 Value parameters(p);
01011 Value response;
01012
01013 rc = rpc(c, "volumes", parameters, response);
01014 return get_volume_array(c, rc, response, volumes, count);
01015 }
01016
01017 static int get_disk_array(lsm_connect * c, int rc, Value & response,
01018 lsm_disk ** disks[], uint32_t * count)
01019 {
01020 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
01021 rc = value_array_to_disks(response, disks, count);
01022
01023 if (LSM_ERR_OK != rc) {
01024 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", NULL);
01025 }
01026 }
01027
01028 return rc;
01029 }
01030
01031 int lsm_disk_list(lsm_connect * c, const char *search_key,
01032 const char *search_value,
01033 lsm_disk ** disks[], uint32_t * count, lsm_flag flags)
01034 {
01035 CONN_SETUP(c);
01036
01037 if (CHECK_RP(disks) || !count) {
01038 return LSM_ERR_INVALID_ARGUMENT;
01039 }
01040
01041 std::map < std::string, Value > p;
01042 p["flags"] = Value(flags);
01043
01044 int rc = add_search_params(p, search_key, search_value, DISK_SEARCH_KEYS,
01045 DISK_SEARCH_KEYS_COUNT);
01046 if (LSM_ERR_OK != rc) {
01047 return rc;
01048 }
01049
01050 Value parameters(p);
01051 Value response;
01052
01053 rc = rpc(c, "disks", parameters, response);
01054 return get_disk_array(c, rc, response, disks, count);
01055 }
01056
01057 typedef void *(*convert) (Value & v);
01058
01059 static void *parse_job_response(lsm_connect * c, Value response, int &rc,
01060 char **job, convert conv)
01061 {
01062 void *val = NULL;
01063 *job = NULL;
01064
01065 try {
01066
01067 if (Value::array_t == response.valueType()) {
01068 std::vector < Value > r = response.asArray();
01069 if (Value::string_t == r[0].valueType()) {
01070 *job = strdup((r[0].asString()).c_str());
01071 if (!(*job)) {
01072 rc = LSM_ERR_NO_MEMORY;
01073 goto error;
01074 }
01075
01076 rc = LSM_ERR_JOB_STARTED;
01077 }
01078 if (Value::object_t == r[1].valueType()) {
01079 val = conv(r[1]);
01080 if (!val) {
01081 rc = LSM_ERR_NO_MEMORY;
01082 goto error;
01083 }
01084 }
01085 }
01086 }
01087 catch(const ValueException & ve) {
01088 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01089 goto error;
01090 }
01091
01092 out:
01093 return val;
01094
01095 error:
01096 free(*job);
01097 *job = NULL;
01098 goto out;
01099 }
01100
01101 int lsm_volume_create(lsm_connect * c, lsm_pool * pool,
01102 const char *volumeName, uint64_t size,
01103 lsm_volume_provision_type provisioning,
01104 lsm_volume ** newVolume, char **job, lsm_flag flags)
01105 {
01106 CONN_SETUP(c);
01107
01108 if (!LSM_IS_POOL(pool)) {
01109 return LSM_ERR_INVALID_ARGUMENT;
01110 }
01111
01112 if (CHECK_STR(volumeName) || !size || CHECK_RP(newVolume) ||
01113 CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
01114 return LSM_ERR_INVALID_ARGUMENT;
01115 }
01116
01117 std::map < std::string, Value > p;
01118 p["pool"] = pool_to_value(pool);
01119 p["volume_name"] = Value(volumeName);
01120 p["size_bytes"] = Value(size);
01121 p["provisioning"] = Value((int32_t) provisioning);
01122 p["flags"] = Value(flags);
01123
01124 Value parameters(p);
01125 Value response;
01126
01127 int rc = rpc(c, "volume_create", parameters, response);
01128 if (LSM_ERR_OK == rc) {
01129 *newVolume =
01130 (lsm_volume *) parse_job_response(c, response, rc, job,
01131 (convert) value_to_volume);
01132 }
01133 return rc;
01134 }
01135
01136 int lsm_volume_resize(lsm_connect * c, lsm_volume * volume,
01137 uint64_t newSize, lsm_volume ** resizedVolume,
01138 char **job, lsm_flag flags)
01139 {
01140 CONN_SETUP(c);
01141
01142 if (!LSM_IS_VOL(volume) || !newSize || CHECK_RP(resizedVolume) ||
01143 CHECK_RP(job) || newSize == 0 || LSM_FLAG_UNUSED_CHECK(flags)) {
01144 return LSM_ERR_INVALID_ARGUMENT;
01145 }
01146
01147 if ((newSize / volume->block_size) == volume->number_of_blocks) {
01148 return LSM_ERR_NO_STATE_CHANGE;
01149 }
01150
01151 std::map < std::string, Value > p;
01152 p["volume"] = volume_to_value(volume);
01153 p["new_size_bytes"] = Value(newSize);
01154 p["flags"] = Value(flags);
01155
01156 Value parameters(p);
01157 Value response;
01158
01159 int rc = rpc(c, "volume_resize", parameters, response);
01160 if (LSM_ERR_OK == rc) {
01161 *resizedVolume =
01162 (lsm_volume *) parse_job_response(c, response, rc, job,
01163 (convert) value_to_volume);
01164 }
01165 return rc;
01166 }
01167
01168 int lsm_volume_replicate(lsm_connect * c, lsm_pool * pool,
01169 lsm_replication_type repType,
01170 lsm_volume * volumeSrc, const char *name,
01171 lsm_volume ** newReplicant, char **job, lsm_flag flags)
01172 {
01173 CONN_SETUP(c);
01174
01175 if ((pool && !LSM_IS_POOL(pool)) || !LSM_IS_VOL(volumeSrc)) {
01176 return LSM_ERR_INVALID_ARGUMENT;
01177 }
01178
01179 if (CHECK_STR(name) || CHECK_RP(newReplicant) || CHECK_RP(job) ||
01180 LSM_FLAG_UNUSED_CHECK(flags)) {
01181 return LSM_ERR_INVALID_ARGUMENT;
01182 }
01183
01184 std::map < std::string, Value > p;
01185 p["pool"] = pool_to_value(pool);
01186 p["rep_type"] = Value((int32_t) repType);
01187 p["volume_src"] = volume_to_value(volumeSrc);
01188 p["name"] = Value(name);
01189 p["flags"] = Value(flags);
01190
01191 Value parameters(p);
01192 Value response;
01193
01194 int rc = rpc(c, "volume_replicate", parameters, response);
01195 if (LSM_ERR_OK == rc) {
01196 *newReplicant =
01197 (lsm_volume *) parse_job_response(c, response, rc, job,
01198 (convert) value_to_volume);
01199 }
01200 return rc;
01201
01202 }
01203
01204 int lsm_volume_replicate_range_block_size(lsm_connect * c,
01205 lsm_system * system,
01206 uint32_t * bs, lsm_flag flags)
01207 {
01208 int rc = LSM_ERR_OK;
01209 CONN_SETUP(c);
01210
01211 if (!bs || LSM_FLAG_UNUSED_CHECK(flags) || !LSM_IS_SYSTEM(system)) {
01212 return LSM_ERR_INVALID_ARGUMENT;
01213 }
01214
01215 try {
01216 std::map < std::string, Value > p;
01217 p["system"] = system_to_value(system);
01218 p["flags"] = Value(flags);
01219 Value parameters(p);
01220 Value response;
01221
01222 rc = rpc(c, "volume_replicate_range_block_size", parameters, response);
01223 if (LSM_ERR_OK == rc) {
01224 if (Value::numeric_t == response.valueType()) {
01225 *bs = response.asUint32_t();
01226 }
01227 }
01228 }
01229 catch(const ValueException & ve) {
01230 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01231 }
01232 return rc;
01233 }
01234
01235
01236 int lsm_volume_replicate_range(lsm_connect * c,
01237 lsm_replication_type repType,
01238 lsm_volume * source,
01239 lsm_volume * dest,
01240 lsm_block_range ** ranges,
01241 uint32_t num_ranges, char **job, lsm_flag flags)
01242 {
01243 CONN_SETUP(c);
01244
01245 if (!LSM_IS_VOL(source) || !LSM_IS_VOL(dest)) {
01246 return LSM_ERR_INVALID_ARGUMENT;
01247 }
01248
01249 if (!ranges || !num_ranges || CHECK_RP(job) ||
01250 LSM_FLAG_UNUSED_CHECK(flags)) {
01251 return LSM_ERR_INVALID_ARGUMENT;
01252 }
01253
01254 std::map < std::string, Value > p;
01255 p["rep_type"] = Value((int32_t) repType);
01256 p["volume_src"] = volume_to_value(source);
01257 p["volume_dest"] = volume_to_value(dest);
01258 p["ranges"] = block_range_list_to_value(ranges, num_ranges);
01259 p["flags"] = Value(flags);
01260
01261 Value parameters(p);
01262 Value response;
01263
01264 int rc = rpc(c, "volume_replicate_range", parameters, response);
01265 return job_check(c, rc, response, job);
01266 }
01267
01268 static Value _create_volume_flag_param(lsm_volume * volume, lsm_flag flags)
01269 {
01270 std::map < std::string, Value > p;
01271 p["volume"] = volume_to_value(volume);
01272 p["flags"] = Value(flags);
01273
01274 return Value(p);
01275 }
01276
01277 int lsm_volume_delete(lsm_connect * c, lsm_volume * volume, char **job,
01278 lsm_flag flags)
01279 {
01280 int rc = LSM_ERR_OK;
01281 CONN_SETUP(c);
01282
01283 if (!LSM_IS_VOL(volume)) {
01284 return LSM_ERR_INVALID_ARGUMENT;
01285 }
01286
01287 if (CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
01288 return LSM_ERR_INVALID_ARGUMENT;
01289 }
01290
01291 try {
01292
01293 Value parameters = _create_volume_flag_param(volume, flags);
01294 Value response;
01295
01296 rc = rpc(c, "volume_delete", parameters, response);
01297 rc = job_check(c, rc, response, job);
01298 }
01299 catch(const ValueException & ve) {
01300 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01301 }
01302 return rc;
01303
01304 }
01305
01306 int lsm_volume_raid_info(lsm_connect * c, lsm_volume * volume,
01307 lsm_volume_raid_type * raid_type,
01308 uint32_t * strip_size, uint32_t * disk_count,
01309 uint32_t * min_io_size, uint32_t * opt_io_size,
01310 lsm_flag flags)
01311 {
01312 if (LSM_FLAG_UNUSED_CHECK(flags)) {
01313 return LSM_ERR_INVALID_ARGUMENT;
01314 }
01315
01316 int rc = LSM_ERR_OK;
01317 CONN_SETUP(c);
01318
01319 if (!LSM_IS_VOL(volume)) {
01320 return LSM_ERR_INVALID_ARGUMENT;
01321 }
01322
01323 if (!raid_type || !strip_size || !disk_count || !min_io_size ||
01324 !opt_io_size) {
01325 return LSM_ERR_INVALID_ARGUMENT;
01326 }
01327
01328 try {
01329
01330 Value parameters = _create_volume_flag_param(volume, flags);
01331 Value response;
01332
01333 rc = rpc(c, "volume_raid_info", parameters, response);
01334 if (LSM_ERR_OK == rc) {
01335
01336 std::vector < Value > j = response.asArray();
01337 *raid_type = (lsm_volume_raid_type) j[0].asInt32_t();
01338 *strip_size = j[1].asUint32_t();
01339 *disk_count = j[2].asUint32_t();
01340 *min_io_size = j[3].asUint32_t();
01341 *opt_io_size = j[4].asUint32_t();
01342 }
01343 }
01344 catch(const ValueException & ve) {
01345 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01346 }
01347 return rc;
01348
01349 }
01350
01351 int lsm_iscsi_chap_auth(lsm_connect * c, const char *init_id,
01352 const char *username, const char *password,
01353 const char *out_user, const char *out_password,
01354 lsm_flag flags)
01355 {
01356 CONN_SETUP(c);
01357
01358 if (iqn_validate(init_id) || LSM_FLAG_UNUSED_CHECK(flags)) {
01359 return LSM_ERR_INVALID_ARGUMENT;
01360 }
01361
01362 std::map < std::string, Value > p;
01363 p["init_id"] = Value(init_id);
01364 p["in_user"] = Value(username);
01365 p["in_password"] = Value(password);
01366 p["out_user"] = Value(out_user);
01367 p["out_password"] = Value(out_password);
01368 p["flags"] = Value(flags);
01369
01370
01371 Value parameters(p);
01372 Value response;
01373
01374 return rpc(c, "iscsi_chap_auth", parameters, response);
01375 }
01376
01377 static int online_offline(lsm_connect * c, lsm_volume * v,
01378 const char *operation, lsm_flag flags)
01379 {
01380 CONN_SETUP(c);
01381
01382 if (!LSM_IS_VOL(v)) {
01383 return LSM_ERR_INVALID_ARGUMENT;
01384 }
01385
01386 if (LSM_FLAG_UNUSED_CHECK(flags)) {
01387 return LSM_ERR_INVALID_ARGUMENT;
01388 }
01389
01390 std::map < std::string, Value > p;
01391 p["volume"] = volume_to_value(v);
01392 p["flags"] = Value(flags);
01393
01394 Value parameters(p);
01395 Value response;
01396 return rpc(c, operation, parameters, response);
01397 }
01398
01399 int lsm_volume_enable(lsm_connect * c, lsm_volume * volume, lsm_flag flags)
01400 {
01401 return online_offline(c, volume, "volume_enable", flags);
01402 }
01403
01404 int lsm_volume_disable(lsm_connect * c, lsm_volume * volume, lsm_flag flags)
01405 {
01406 return online_offline(c, volume, "volume_disable", flags);
01407 }
01408
01409 int lsm_access_group_list(lsm_connect * c, const char *search_key,
01410 const char *search_value,
01411 lsm_access_group ** groups[],
01412 uint32_t * groupCount, lsm_flag flags)
01413 {
01414 CONN_SETUP(c);
01415
01416 if (!groups || !groupCount) {
01417 return LSM_ERR_INVALID_ARGUMENT;
01418 }
01419
01420 std::map < std::string, Value > p;
01421
01422 int rc = add_search_params(p, search_key, search_value,
01423 ACCESS_GROUP_SEARCH_KEYS,
01424 ACCESS_GROUP_SEARCH_KEYS_COUNT);
01425 if (LSM_ERR_OK != rc) {
01426 return rc;
01427 }
01428
01429 p["flags"] = Value(flags);
01430 Value parameters(p);
01431 Value response;
01432
01433 rc = rpc(c, "access_groups", parameters, response);
01434 return get_access_groups(c, rc, response, groups, groupCount);
01435 }
01436
01437 int lsm_access_group_create(lsm_connect * c, const char *name,
01438 const char *init_id,
01439 lsm_access_group_init_type init_type,
01440 lsm_system * system,
01441 lsm_access_group ** access_group, lsm_flag flags)
01442 {
01443 CONN_SETUP(c);
01444
01445 if (!LSM_IS_SYSTEM(system) || CHECK_STR(name) || CHECK_STR(init_id) ||
01446 CHECK_RP(access_group) || LSM_FLAG_UNUSED_CHECK(flags)) {
01447 return LSM_ERR_INVALID_ARGUMENT;
01448 }
01449
01450 Value id;
01451
01452 if (LSM_ERR_OK != verify_initiator_id(init_id, init_type, id)) {
01453 return LSM_ERR_INVALID_ARGUMENT;
01454 }
01455
01456 std::map < std::string, Value > p;
01457 p["name"] = Value(name);
01458 p["init_id"] = id;
01459 p["init_type"] = Value((int32_t) init_type);
01460 p["system"] = system_to_value(system);
01461 p["flags"] = Value(flags);
01462
01463 Value parameters(p);
01464 Value response;
01465
01466 *access_group = NULL;
01467
01468 int rc = rpc(c, "access_group_create", parameters, response);
01469 try {
01470 if (LSM_ERR_OK == rc) {
01471
01472 if (Value::object_t == response.valueType()) {
01473 *access_group = value_to_access_group(response);
01474 if (!(*access_group)) {
01475 rc = LSM_ERR_NO_MEMORY;
01476 }
01477 }
01478 }
01479 }
01480 catch(const ValueException & ve) {
01481 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01482 }
01483 return rc;
01484 }
01485
01486 int lsm_access_group_delete(lsm_connect * c,
01487 lsm_access_group * access_group, lsm_flag flags)
01488 {
01489 CONN_SETUP(c);
01490
01491 if (!LSM_IS_ACCESS_GROUP(access_group) || LSM_FLAG_UNUSED_CHECK(flags)) {
01492 return LSM_ERR_INVALID_ARGUMENT;
01493 }
01494
01495 std::map < std::string, Value > p;
01496 p["access_group"] = access_group_to_value(access_group);
01497 p["flags"] = Value(flags);
01498
01499 Value parameters(p);
01500 Value response;
01501
01502 return rpc(c, "access_group_delete", parameters, response);
01503 }
01504
01505 static int _lsm_ag_add_delete(lsm_connect * c,
01506 lsm_access_group * access_group,
01507 const char *init_id,
01508 lsm_access_group_init_type init_type,
01509 lsm_access_group ** updated_access_group,
01510 lsm_flag flags, const char *message)
01511 {
01512 CONN_SETUP(c);
01513
01514 if (!LSM_IS_ACCESS_GROUP(access_group) || CHECK_STR(init_id) ||
01515 LSM_FLAG_UNUSED_CHECK(flags) || CHECK_RP(updated_access_group)) {
01516 return LSM_ERR_INVALID_ARGUMENT;
01517 }
01518
01519 Value id;
01520
01521 if (LSM_ERR_OK != verify_initiator_id(init_id, init_type, id)) {
01522 return LSM_ERR_INVALID_ARGUMENT;
01523 }
01524
01525 std::map < std::string, Value > p;
01526 p["access_group"] = access_group_to_value(access_group);
01527 p["init_id"] = id;
01528 p["init_type"] = Value((int32_t) init_type);
01529 p["flags"] = Value(flags);
01530
01531 Value parameters(p);
01532 Value response;
01533
01534 int rc = rpc(c, message, parameters, response);
01535 try {
01536 if (LSM_ERR_OK == rc) {
01537
01538 if (Value::object_t == response.valueType()) {
01539 *updated_access_group = value_to_access_group(response);
01540 if (!(*updated_access_group)) {
01541 rc = LSM_ERR_NO_MEMORY;
01542 }
01543 }
01544 }
01545 }
01546 catch(const ValueException & ve) {
01547 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01548 }
01549
01550 return rc;
01551 }
01552
01553 int lsm_access_group_initiator_add(lsm_connect * c,
01554 lsm_access_group * access_group,
01555 const char *init_id,
01556 lsm_access_group_init_type init_type,
01557 lsm_access_group **
01558 updated_access_group, lsm_flag flags)
01559 {
01560 return _lsm_ag_add_delete(c, access_group, init_id, init_type,
01561 updated_access_group, flags,
01562 "access_group_initiator_add");
01563 }
01564
01565 int lsm_access_group_initiator_delete(lsm_connect * c,
01566 lsm_access_group * access_group,
01567 const char *init_id,
01568 lsm_access_group_init_type init_type,
01569 lsm_access_group **
01570 updated_access_group, lsm_flag flags)
01571 {
01572 return _lsm_ag_add_delete(c, access_group, init_id, init_type,
01573 updated_access_group, flags,
01574 "access_group_initiator_delete");
01575 }
01576
01577 int lsm_volume_mask(lsm_connect * c, lsm_access_group * access_group,
01578 lsm_volume * volume, lsm_flag flags)
01579 {
01580 CONN_SETUP(c);
01581
01582 if (!LSM_IS_ACCESS_GROUP(access_group) || !LSM_IS_VOL(volume) ||
01583 LSM_FLAG_UNUSED_CHECK(flags)) {
01584 return LSM_ERR_INVALID_ARGUMENT;
01585 }
01586
01587 std::map < std::string, Value > p;
01588 p["access_group"] = access_group_to_value(access_group);
01589 p["volume"] = volume_to_value(volume);
01590 p["flags"] = Value(flags);
01591
01592 Value parameters(p);
01593 Value response;
01594
01595 return rpc(c, "volume_mask", parameters, response);
01596 }
01597
01598
01599 int lsm_volume_unmask(lsm_connect * c, lsm_access_group * group,
01600 lsm_volume * volume, lsm_flag flags)
01601 {
01602 CONN_SETUP(c);
01603
01604 if (!LSM_IS_ACCESS_GROUP(group) || !LSM_IS_VOL(volume) ||
01605 LSM_FLAG_UNUSED_CHECK(flags)) {
01606 return LSM_ERR_INVALID_ARGUMENT;
01607 }
01608
01609 std::map < std::string, Value > p;
01610 p["access_group"] = access_group_to_value(group);
01611 p["volume"] = volume_to_value(volume);
01612 p["flags"] = Value(flags);
01613
01614 Value parameters(p);
01615 Value response;
01616
01617 return rpc(c, "volume_unmask", parameters, response);
01618 }
01619
01620 int lsm_volumes_accessible_by_access_group(lsm_connect * c,
01621 lsm_access_group * group,
01622 lsm_volume ** volumes[],
01623 uint32_t * count, lsm_flag flags)
01624 {
01625 int rc = LSM_ERR_OK;
01626 CONN_SETUP(c);
01627
01628 if (!LSM_IS_ACCESS_GROUP(group) ||
01629 !volumes || !count || LSM_FLAG_UNUSED_CHECK(flags)) {
01630 return LSM_ERR_INVALID_ARGUMENT;
01631 }
01632
01633 try {
01634 std::map < std::string, Value > p;
01635 p["access_group"] = access_group_to_value(group);
01636 p["flags"] = Value(flags);
01637
01638 Value parameters(p);
01639 Value response;
01640
01641 rc = rpc(c, "volumes_accessible_by_access_group", parameters, response);
01642 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
01643 std::vector < Value > vol = response.asArray();
01644
01645 *count = vol.size();
01646
01647 if (vol.size()) {
01648 *volumes = lsm_volume_record_array_alloc(vol.size());
01649
01650 if (*volumes) {
01651 for (size_t i = 0; i < vol.size(); ++i) {
01652 (*volumes)[i] = value_to_volume(vol[i]);
01653 if (!((*volumes)[i])) {
01654 rc = LSM_ERR_NO_MEMORY;
01655 goto error;
01656 }
01657 }
01658 } else {
01659 rc = LSM_ERR_NO_MEMORY;
01660 }
01661 }
01662 }
01663 }
01664 catch(const ValueException & ve) {
01665 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01666 goto error;
01667
01668 }
01669
01670 out:
01671 return rc;
01672
01673 error:
01674 if (*volumes && *count) {
01675 lsm_volume_record_array_free(*volumes, *count);
01676 *volumes = NULL;
01677 *count = 0;
01678 }
01679 goto out;
01680 }
01681
01682 int lsm_access_groups_granted_to_volume(lsm_connect * c,
01683 lsm_volume * volume,
01684 lsm_access_group ** groups[],
01685 uint32_t * groupCount, lsm_flag flags)
01686 {
01687 CONN_SETUP(c);
01688
01689 if (!LSM_IS_VOL(volume)) {
01690 return LSM_ERR_INVALID_ARGUMENT;
01691 }
01692
01693 if (!groups || !groupCount || LSM_FLAG_UNUSED_CHECK(flags)) {
01694 return LSM_ERR_INVALID_ARGUMENT;
01695 }
01696
01697 std::map < std::string, Value > p;
01698 p["volume"] = volume_to_value(volume);
01699 p["flags"] = Value(flags);
01700
01701 Value parameters(p);
01702 Value response;
01703
01704 int rc = rpc(c, "access_groups_granted_to_volume", parameters, response);
01705 return get_access_groups(c, rc, response, groups, groupCount);
01706 }
01707
01708 static int _retrieve_bool(int rc, Value & response, uint8_t * yes)
01709 {
01710 int rc_out = rc;
01711
01712 *yes = 0;
01713
01714 if (LSM_ERR_OK == rc) {
01715
01716 if (Value::boolean_t == response.valueType()) {
01717 if (response.asBool()) {
01718 *yes = 1;
01719 }
01720 } else {
01721 rc_out = LSM_ERR_PLUGIN_BUG;
01722 }
01723 }
01724 return rc_out;
01725 }
01726
01727 int lsm_volume_child_dependency(lsm_connect * c, lsm_volume * volume,
01728 uint8_t * yes, lsm_flag flags)
01729 {
01730 int rc = LSM_ERR_OK;
01731 CONN_SETUP(c);
01732
01733 if (!LSM_IS_VOL(volume)) {
01734 return LSM_ERR_INVALID_ARGUMENT;
01735 }
01736
01737 if (!yes || LSM_FLAG_UNUSED_CHECK(flags)) {
01738 return LSM_ERR_INVALID_ARGUMENT;
01739 }
01740
01741 try {
01742
01743 Value parameters = _create_volume_flag_param(volume, flags);
01744 Value response;
01745
01746 rc = rpc(c, "volume_child_dependency", parameters, response);
01747 rc = _retrieve_bool(rc, response, yes);
01748 }
01749 catch(const ValueException & ve) {
01750 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01751 }
01752 return rc;
01753 }
01754
01755 int lsm_volume_child_dependency_delete(lsm_connect * c,
01756 lsm_volume * volume, char **job,
01757 lsm_flag flags)
01758 {
01759 CONN_SETUP(c);
01760
01761 if (!LSM_IS_VOL(volume) || CHECK_RP(job)
01762 || LSM_FLAG_UNUSED_CHECK(flags)) {
01763 return LSM_ERR_INVALID_ARGUMENT;
01764 }
01765
01766 Value parameters = _create_volume_flag_param(volume, flags);
01767 Value response;
01768
01769 int rc = rpc(c, "volume_child_dependency_rm", parameters, response);
01770 return job_check(c, rc, response, job);
01771 }
01772
01773 int lsm_system_list(lsm_connect * c, lsm_system ** systems[],
01774 uint32_t * systemCount, lsm_flag flags)
01775 {
01776 int rc = LSM_ERR_OK;
01777 CONN_SETUP(c);
01778
01779 if (!systems || !systemCount) {
01780 return LSM_ERR_INVALID_ARGUMENT;
01781 }
01782
01783 try {
01784 std::map < std::string, Value > p;
01785 p["flags"] = Value(flags);
01786 Value parameters(p);
01787 Value response;
01788
01789 rc = rpc(c, "systems", parameters, response);
01790 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
01791 std::vector < Value > sys = response.asArray();
01792
01793 *systemCount = sys.size();
01794
01795 if (sys.size()) {
01796 *systems = lsm_system_record_array_alloc(sys.size());
01797
01798 if (*systems) {
01799 for (size_t i = 0; i < sys.size(); ++i) {
01800 (*systems)[i] = value_to_system(sys[i]);
01801 if (!(*systems)[i]) {
01802 rc = LSM_ERR_NO_MEMORY;
01803 goto error;
01804 }
01805 }
01806 } else {
01807 rc = LSM_ERR_NO_MEMORY;
01808 }
01809 }
01810 }
01811 }
01812 catch(const ValueException & ve) {
01813 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01814 goto error;
01815
01816 }
01817 out:
01818 return rc;
01819
01820 error:
01821 if (*systems) {
01822 lsm_system_record_array_free(*systems, *systemCount);
01823 *systems = NULL;
01824 *systemCount = 0;
01825 }
01826 goto out;
01827 }
01828
01829 int lsm_fs_list(lsm_connect * c, const char *search_key,
01830 const char *search_value, lsm_fs ** fs[],
01831 uint32_t * fsCount, lsm_flag flags)
01832 {
01833 int rc = LSM_ERR_OK;
01834 CONN_SETUP(c);
01835
01836 if (!fs || !fsCount) {
01837 return LSM_ERR_INVALID_ARGUMENT;
01838 }
01839
01840 try {
01841 std::map < std::string, Value > p;
01842
01843 int rc = add_search_params(p, search_key, search_value, FS_SEARCH_KEYS,
01844 FS_SEARCH_KEYS_COUNT);
01845 if (LSM_ERR_OK != rc) {
01846 return rc;
01847 }
01848
01849 p["flags"] = Value(flags);
01850 Value parameters(p);
01851 Value response;
01852
01853 rc = rpc(c, "fs", parameters, response);
01854 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
01855 std::vector < Value > sys = response.asArray();
01856
01857 *fsCount = sys.size();
01858
01859 if (sys.size()) {
01860 *fs = lsm_fs_record_array_alloc(sys.size());
01861
01862 if (*fs) {
01863 for (size_t i = 0; i < sys.size(); ++i) {
01864 (*fs)[i] = value_to_fs(sys[i]);
01865 if (!((*fs)[i])) {
01866 rc = LSM_ERR_NO_MEMORY;
01867 goto error;
01868 }
01869 }
01870 } else {
01871 rc = LSM_ERR_NO_MEMORY;
01872 }
01873 }
01874 }
01875 }
01876 catch(const ValueException & ve) {
01877 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
01878 goto error;
01879
01880 }
01881 out:
01882 return rc;
01883
01884 error:
01885 if (*fs && *fsCount) {
01886 lsm_fs_record_array_free(*fs, *fsCount);
01887 *fs = NULL;
01888 *fsCount = 0;
01889 }
01890 goto out;
01891 }
01892
01893 int lsm_fs_create(lsm_connect * c, lsm_pool * pool, const char *name,
01894 uint64_t size_bytes, lsm_fs ** fs, char **job, lsm_flag flags)
01895 {
01896 CONN_SETUP(c);
01897
01898 if (!LSM_IS_POOL(pool)) {
01899 return LSM_ERR_INVALID_ARGUMENT;
01900 }
01901
01902 if (CHECK_STR(name) || !size_bytes || CHECK_RP(fs) || CHECK_RP(job)
01903 || LSM_FLAG_UNUSED_CHECK(flags)) {
01904 return LSM_ERR_INVALID_ARGUMENT;
01905 }
01906
01907 std::map < std::string, Value > p;
01908 p["pool"] = pool_to_value(pool);
01909 p["name"] = Value(name);
01910 p["size_bytes"] = Value(size_bytes);
01911 p["flags"] = Value(flags);
01912
01913 Value parameters(p);
01914 Value response;
01915
01916 int rc = rpc(c, "fs_create", parameters, response);
01917 if (LSM_ERR_OK == rc) {
01918 *fs = (lsm_fs *) parse_job_response(c, response, rc, job,
01919 (convert) value_to_fs);
01920 }
01921 return rc;
01922 }
01923
01924 static Value _create_fs_flag_param(lsm_fs * fs, lsm_flag flags)
01925 {
01926 std::map < std::string, Value > p;
01927 p["fs"] = fs_to_value(fs);
01928 p["flags"] = Value(flags);
01929 return Value(p);
01930 }
01931
01932 int lsm_fs_delete(lsm_connect * c, lsm_fs * fs, char **job, lsm_flag flags)
01933 {
01934 CONN_SETUP(c);
01935
01936 if (!LSM_IS_FS(fs) || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
01937 return LSM_ERR_INVALID_ARGUMENT;
01938 }
01939
01940 Value parameters = _create_fs_flag_param(fs, flags);
01941 Value response;
01942
01943 int rc = rpc(c, "fs_delete", parameters, response);
01944 return job_check(c, rc, response, job);
01945 }
01946
01947
01948 int lsm_fs_resize(lsm_connect * c, lsm_fs * fs,
01949 uint64_t new_size_bytes, lsm_fs ** rfs,
01950 char **job, lsm_flag flags)
01951 {
01952 CONN_SETUP(c);
01953
01954 if (!LSM_IS_FS(fs) || !new_size_bytes || CHECK_RP(rfs) || CHECK_RP(job)
01955 || LSM_FLAG_UNUSED_CHECK(flags)) {
01956 return LSM_ERR_INVALID_ARGUMENT;
01957 }
01958
01959 std::map < std::string, Value > p;
01960 p["fs"] = fs_to_value(fs);
01961 p["new_size_bytes"] = Value(new_size_bytes);
01962 p["flags"] = Value(flags);
01963
01964 Value parameters(p);
01965 Value response;
01966
01967 int rc = rpc(c, "fs_resize", parameters, response);
01968 if (LSM_ERR_OK == rc) {
01969 *rfs = (lsm_fs *) parse_job_response(c, response, rc, job,
01970 (convert) value_to_fs);
01971 }
01972 return rc;
01973 }
01974
01975 int lsm_fs_clone(lsm_connect * c, lsm_fs * src_fs,
01976 const char *name, lsm_fs_ss * optional_ss,
01977 lsm_fs ** cloned_fs, char **job, lsm_flag flags)
01978 {
01979 CONN_SETUP(c);
01980
01981 if (!LSM_IS_FS(src_fs) || CHECK_STR(name) || CHECK_RP(cloned_fs) ||
01982 CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
01983 return LSM_ERR_INVALID_ARGUMENT;
01984 }
01985
01986 std::map < std::string, Value > p;
01987 p["src_fs"] = fs_to_value(src_fs);
01988 p["dest_fs_name"] = Value(name);
01989 p["snapshot"] = ss_to_value(optional_ss);
01990 p["flags"] = Value(flags);
01991
01992 Value parameters(p);
01993 Value response;
01994
01995 int rc = rpc(c, "fs_clone", parameters, response);
01996 if (LSM_ERR_OK == rc) {
01997 *cloned_fs = (lsm_fs *) parse_job_response(c, response, rc, job,
01998 (convert) value_to_fs);
01999 }
02000 return rc;
02001 }
02002
02003 int lsm_fs_file_clone(lsm_connect * c, lsm_fs * fs,
02004 const char *src_file_name,
02005 const char *dest_file_name, lsm_fs_ss * snapshot,
02006 char **job, lsm_flag flags)
02007 {
02008 CONN_SETUP(c);
02009
02010 if (!LSM_IS_FS(fs) || CHECK_STR(src_file_name)
02011 || CHECK_STR(dest_file_name)
02012 || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
02013 return LSM_ERR_INVALID_ARGUMENT;
02014 }
02015
02016 std::map < std::string, Value > p;
02017 p["fs"] = fs_to_value(fs);
02018 p["src_file_name"] = Value(src_file_name);
02019 p["dest_file_name"] = Value(dest_file_name);
02020 p["snapshot"] = ss_to_value(snapshot);
02021 p["flags"] = Value(flags);
02022
02023 Value parameters(p);
02024 Value response;
02025
02026 int rc = rpc(c, "fs_file_clone", parameters, response);
02027 return job_check(c, rc, response, job);
02028 }
02029
02030 static Value _create_fs_file_flag_params(lsm_fs * fs,
02031 lsm_string_list * files,
02032 lsm_flag flags)
02033 {
02034 std::map < std::string, Value > p;
02035 p["fs"] = fs_to_value(fs);
02036 p["files"] = string_list_to_value(files);
02037 p["flags"] = Value(flags);
02038 return Value(p);
02039 }
02040
02041 int lsm_fs_child_dependency(lsm_connect * c, lsm_fs * fs,
02042 lsm_string_list * files, uint8_t * yes,
02043 lsm_flag flags)
02044 {
02045 int rc = LSM_ERR_OK;
02046 CONN_SETUP(c);
02047
02048 if (!LSM_IS_FS(fs)) {
02049 return LSM_ERR_INVALID_ARGUMENT;
02050 }
02051
02052 if (files) {
02053 if (!LSM_IS_STRING_LIST(files)) {
02054 return LSM_ERR_INVALID_ARGUMENT;
02055 }
02056 }
02057
02058 if (!yes || LSM_FLAG_UNUSED_CHECK(flags)) {
02059 return LSM_ERR_INVALID_ARGUMENT;
02060 }
02061
02062 try {
02063
02064 Value parameters = _create_fs_file_flag_params(fs, files, flags);
02065 Value response;
02066
02067 rc = rpc(c, "fs_child_dependency", parameters, response);
02068 rc = _retrieve_bool(rc, response, yes);
02069 }
02070 catch(const ValueException & ve) {
02071 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02072 }
02073 return rc;
02074 }
02075
02076 int lsm_fs_child_dependency_delete(lsm_connect * c, lsm_fs * fs,
02077 lsm_string_list * files, char **job,
02078 lsm_flag flags)
02079 {
02080 CONN_SETUP(c);
02081
02082 if (!LSM_IS_FS(fs)) {
02083 return LSM_ERR_INVALID_ARGUMENT;
02084 }
02085
02086 if (files) {
02087 if (!LSM_IS_STRING_LIST(files)) {
02088 return LSM_ERR_INVALID_ARGUMENT;
02089 }
02090 }
02091
02092 if (CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
02093 return LSM_ERR_INVALID_ARGUMENT;
02094 }
02095
02096 Value parameters = _create_fs_file_flag_params(fs, files, flags);
02097 Value response;
02098
02099 int rc = rpc(c, "fs_child_dependency_rm", parameters, response);
02100 return job_check(c, rc, response, job);
02101 }
02102
02103 int lsm_fs_ss_list(lsm_connect * c, lsm_fs * fs, lsm_fs_ss ** ss[],
02104 uint32_t * ssCount, lsm_flag flags)
02105 {
02106 int rc = LSM_ERR_OK;
02107 CONN_SETUP(c);
02108
02109 if (!LSM_IS_FS(fs)) {
02110 return LSM_ERR_INVALID_ARGUMENT;
02111 }
02112
02113 if (CHECK_RP(ss) || !ssCount) {
02114 return LSM_ERR_INVALID_ARGUMENT;
02115 }
02116
02117 Value parameters = _create_fs_flag_param(fs, flags);
02118 Value response;
02119
02120 try {
02121 rc = rpc(c, "fs_snapshots", parameters, response);
02122 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
02123 std::vector < Value > sys = response.asArray();
02124
02125 *ssCount = sys.size();
02126
02127 if (sys.size()) {
02128 *ss = lsm_fs_ss_record_array_alloc(sys.size());
02129
02130 if (*ss) {
02131 for (size_t i = 0; i < sys.size(); ++i) {
02132 (*ss)[i] = value_to_ss(sys[i]);
02133 if (!((*ss)[i])) {
02134 rc = LSM_ERR_NO_MEMORY;
02135 goto error;
02136 }
02137 }
02138 } else {
02139 rc = LSM_ERR_NO_MEMORY;
02140 }
02141 }
02142 }
02143 }
02144 catch(const ValueException & ve) {
02145 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02146 goto error;
02147 }
02148 out:
02149 return rc;
02150
02151 error:
02152 if (*ss && *ssCount) {
02153 lsm_fs_ss_record_array_free(*ss, *ssCount);
02154 *ss = NULL;
02155 *ssCount = 0;
02156 }
02157
02158 goto out;
02159 }
02160
02161 int lsm_fs_ss_create(lsm_connect * c, lsm_fs * fs, const char *name,
02162 lsm_fs_ss ** snapshot, char **job, lsm_flag flags)
02163 {
02164 CONN_SETUP(c);
02165
02166 if (!LSM_IS_FS(fs)) {
02167 return LSM_ERR_INVALID_ARGUMENT;
02168 }
02169
02170 if (CHECK_STR(name) || CHECK_RP(snapshot) || CHECK_RP(job)
02171 || LSM_FLAG_UNUSED_CHECK(flags)) {
02172 return LSM_ERR_INVALID_ARGUMENT;
02173 }
02174
02175 std::map < std::string, Value > p;
02176 p["fs"] = fs_to_value(fs);
02177 p["snapshot_name"] = Value(name);
02178 p["flags"] = Value(flags);
02179
02180 Value parameters(p);
02181 Value response;
02182
02183 int rc = rpc(c, "fs_snapshot_create", parameters, response);
02184 if (LSM_ERR_OK == rc) {
02185 *snapshot = (lsm_fs_ss *) parse_job_response(c, response, rc, job,
02186 (convert)
02187 value_to_ss);
02188 }
02189 return rc;
02190 }
02191
02192 int lsm_fs_ss_delete(lsm_connect * c, lsm_fs * fs, lsm_fs_ss * ss,
02193 char **job, lsm_flag flags)
02194 {
02195 CONN_SETUP(c);
02196
02197 if (!LSM_IS_FS(fs)) {
02198 return LSM_ERR_INVALID_ARGUMENT;
02199 }
02200
02201 if (!LSM_IS_SS(ss)) {
02202 return LSM_ERR_INVALID_ARGUMENT;
02203 }
02204
02205 if (CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
02206 return LSM_ERR_INVALID_ARGUMENT;
02207 }
02208
02209 std::map < std::string, Value > p;
02210 p["fs"] = fs_to_value(fs);
02211 p["snapshot"] = ss_to_value(ss);
02212 p["flags"] = Value(flags);
02213
02214 Value parameters(p);
02215 Value response;
02216
02217 int rc = rpc(c, "fs_snapshot_delete", parameters, response);
02218 return job_check(c, rc, response, job);
02219 }
02220
02221 int lsm_fs_ss_restore(lsm_connect * c, lsm_fs * fs, lsm_fs_ss * ss,
02222 lsm_string_list * files,
02223 lsm_string_list * restore_files,
02224 int all_files, char **job, lsm_flag flags)
02225 {
02226 CONN_SETUP(c);
02227
02228 if (!LSM_IS_FS(fs)) {
02229 return LSM_ERR_INVALID_ARGUMENT;
02230 }
02231
02232 if (!LSM_IS_SS(ss)) {
02233 return LSM_ERR_INVALID_ARGUMENT;
02234 }
02235
02236 if (files) {
02237 if (!LSM_IS_STRING_LIST(files)) {
02238 return LSM_ERR_INVALID_ARGUMENT;
02239 }
02240 }
02241
02242 if (restore_files) {
02243 if (!LSM_IS_STRING_LIST(restore_files)) {
02244 return LSM_ERR_INVALID_ARGUMENT;
02245 }
02246 }
02247
02248 if (CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags)) {
02249 return LSM_ERR_INVALID_ARGUMENT;
02250 }
02251
02252 std::map < std::string, Value > p;
02253 p["fs"] = fs_to_value(fs);
02254 p["snapshot"] = ss_to_value(ss);
02255 p["files"] = string_list_to_value(files);
02256 p["restore_files"] = string_list_to_value(restore_files);
02257 p["all_files"] = Value((all_files) ? true : false);
02258 p["flags"] = Value(flags);
02259
02260 Value parameters(p);
02261 Value response;
02262
02263 int rc = rpc(c, "fs_snapshot_restore", parameters, response);
02264 return job_check(c, rc, response, job);
02265
02266 }
02267
02268 int lsm_nfs_list(lsm_connect * c, const char *search_key,
02269 const char *search_value, lsm_nfs_export ** exports[],
02270 uint32_t * count, lsm_flag flags)
02271 {
02272 int rc = LSM_ERR_OK;
02273 CONN_SETUP(c);
02274
02275 if (CHECK_RP(exports) || !count) {
02276 return LSM_ERR_INVALID_ARGUMENT;
02277 }
02278
02279 *count = 0;
02280 *exports = NULL;
02281
02282 try {
02283 std::map < std::string, Value > p;
02284
02285 rc = add_search_params(p, search_key, search_value,
02286 NFS_EXPORT_SEARCH_KEYS,
02287 NFS_EXPORT_SEARCH_KEYS_COUNT);
02288 if (LSM_ERR_OK != rc) {
02289 return rc;
02290 }
02291
02292 p["flags"] = Value(flags);
02293 Value parameters(p);
02294 Value response;
02295
02296 rc = rpc(c, "exports", parameters, response);
02297 if (LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
02298 std::vector < Value > exps = response.asArray();
02299
02300 *count = exps.size();
02301
02302 if (*count) {
02303 *exports = lsm_nfs_export_record_array_alloc(*count);
02304
02305 if (*exports) {
02306 for (size_t i = 0; i < *count; ++i) {
02307 (*exports)[i] = value_to_nfs_export(exps[i]);
02308 if (!((*exports)[i])) {
02309 rc = LSM_ERR_NO_MEMORY;
02310 goto error;
02311 }
02312 }
02313 } else {
02314 rc = LSM_ERR_NO_MEMORY;
02315 }
02316 }
02317 }
02318 }
02319 catch(const ValueException & ve) {
02320 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02321 goto error;
02322 }
02323 out:
02324 return rc;
02325
02326 error:
02327 if (*exports && *count) {
02328 lsm_nfs_export_record_array_free(*exports, *count);
02329 *exports = NULL;
02330 *count = 0;
02331 }
02332 goto out;
02333 }
02334
02335 int lsm_nfs_export_fs(lsm_connect * c,
02336 const char *fs_id,
02337 const char *export_path,
02338 lsm_string_list * root_list,
02339 lsm_string_list * rw_list,
02340 lsm_string_list * ro_list,
02341 uint64_t anon_uid,
02342 uint64_t anon_gid,
02343 const char *auth_type,
02344 const char *options,
02345 lsm_nfs_export ** exported, lsm_flag flags)
02346 {
02347 CONN_SETUP(c);
02348
02349 if (root_list) {
02350 if (!LSM_IS_STRING_LIST(root_list)) {
02351 return LSM_ERR_INVALID_ARGUMENT;
02352 }
02353 }
02354
02355 if (rw_list) {
02356 if (!LSM_IS_STRING_LIST(rw_list)) {
02357 return LSM_ERR_INVALID_ARGUMENT;
02358 }
02359 }
02360
02361 if (ro_list) {
02362 if (!LSM_IS_STRING_LIST(ro_list)) {
02363 return LSM_ERR_INVALID_ARGUMENT;
02364 }
02365 }
02366
02367 if (CHECK_STR(fs_id) || CHECK_RP(exported)
02368 || !(root_list || rw_list || ro_list)
02369 || LSM_FLAG_UNUSED_CHECK(flags)) {
02370 return LSM_ERR_INVALID_ARGUMENT;
02371 }
02372
02373 std::map < std::string, Value > p;
02374
02375 p["fs_id"] = Value(fs_id);
02376 p["export_path"] = Value(export_path);
02377 p["root_list"] = string_list_to_value(root_list);
02378 p["rw_list"] = string_list_to_value(rw_list);
02379 p["ro_list"] = string_list_to_value(ro_list);
02380 p["anon_uid"] = Value(anon_uid);
02381 p["anon_gid"] = Value(anon_gid);
02382 p["auth_type"] = Value(auth_type);
02383 p["options"] = Value(options);
02384 p["flags"] = Value(flags);
02385
02386 Value parameters(p);
02387 Value response;
02388
02389 int rc = rpc(c, "export_fs", parameters, response);
02390 try {
02391 if (LSM_ERR_OK == rc && Value::object_t == response.valueType()) {
02392 *exported = value_to_nfs_export(response);
02393 if (!(*exported)) {
02394 rc = LSM_ERR_NO_MEMORY;
02395 }
02396 }
02397 }
02398 catch(const ValueException & ve) {
02399 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02400 }
02401 return rc;
02402 }
02403
02404 int lsm_nfs_export_delete(lsm_connect * c, lsm_nfs_export * e, lsm_flag flags)
02405 {
02406 CONN_SETUP(c);
02407
02408 if (!LSM_IS_NFS_EXPORT(e) || LSM_FLAG_UNUSED_CHECK(flags)) {
02409 return LSM_ERR_INVALID_ARGUMENT;
02410 }
02411
02412 std::map < std::string, Value > p;
02413 p["export"] = nfs_export_to_value(e);
02414 p["flags"] = Value(flags);
02415
02416 Value parameters(p);
02417 Value response;
02418
02419 int rc = rpc(c, "export_remove", parameters, response);
02420 return rc;
02421 }
02422
02423 int lsm_volume_raid_create_cap_get(lsm_connect * c, lsm_system * system,
02424 uint32_t ** supported_raid_types,
02425 uint32_t * supported_raid_type_count,
02426 uint32_t ** supported_strip_sizes,
02427 uint32_t * supported_strip_size_count,
02428 lsm_flag flags)
02429 {
02430 CONN_SETUP(c);
02431
02432 if (!supported_raid_types || !supported_raid_type_count ||
02433 !supported_strip_sizes || !supported_strip_size_count) {
02434 return LSM_ERR_INVALID_ARGUMENT;
02435 }
02436
02437 *supported_raid_types = NULL;
02438
02439 std::map < std::string, Value > p;
02440 p["system"] = system_to_value(system);
02441 p["flags"] = Value(flags);
02442
02443 Value parameters(p);
02444 Value response;
02445
02446 int rc = rpc(c, "volume_raid_create_cap_get", parameters, response);
02447 try {
02448 std::vector < Value > j = response.asArray();
02449
02450 rc = values_to_uint32_array(j[0], supported_raid_types,
02451 supported_raid_type_count);
02452
02453 if (rc != LSM_ERR_OK) {
02454 goto error;
02455 }
02456
02457 rc = values_to_uint32_array(j[1], supported_strip_sizes,
02458 supported_strip_size_count);
02459 if (rc != LSM_ERR_OK) {
02460 goto error;
02461 }
02462 }
02463 catch(const ValueException & ve) {
02464 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02465 }
02466
02467 out:
02468 return rc;
02469
02470 error:
02471 free(*supported_raid_types);
02472 *supported_raid_types = NULL;
02473 *supported_raid_type_count = 0;
02474 *supported_strip_sizes = NULL;
02475 *supported_strip_size_count = 0;
02476 goto out;
02477 }
02478
02479 int lsm_volume_raid_create(lsm_connect * c, const char *name,
02480 lsm_volume_raid_type raid_type,
02481 lsm_disk * disks[], uint32_t disk_count,
02482 uint32_t strip_size, lsm_volume ** new_volume,
02483 lsm_flag flags)
02484 {
02485 CONN_SETUP(c);
02486
02487 if (disk_count == 0) {
02488 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02489 "Require at least one disks", NULL);
02490 }
02491
02492 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID1 && disk_count != 2) {
02493 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02494 "RAID 1 only allows two disks", NULL);
02495 }
02496
02497 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID5 && disk_count < 3) {
02498 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02499 "RAID 5 require 3 or more disks", NULL);
02500 }
02501
02502 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID6 && disk_count < 4) {
02503 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02504 "RAID 5 require 4 or more disks", NULL);
02505 }
02506
02507 if (disk_count % 2) {
02508 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID10 && disk_count < 4) {
02509 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02510 "RAID 10 require even disks count and 4 "
02511 "or more disks",
02512 NULL);
02513 }
02514 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID50 && disk_count < 6) {
02515 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02516 "RAID 50 require even disks count and 6 or "
02517 "more disks",
02518 NULL);
02519 }
02520 if (raid_type == LSM_VOLUME_RAID_TYPE_RAID60 && disk_count < 8) {
02521 return log_exception(c, LSM_ERR_INVALID_ARGUMENT,
02522 "RAID 60 require even disks count and 8 or "
02523 "more disks",
02524 NULL);
02525 }
02526 }
02527
02528 if (CHECK_RP(new_volume)) {
02529 return LSM_ERR_INVALID_ARGUMENT;
02530 }
02531
02532 std::map < std::string, Value > p;
02533 p["name"] = Value(name);
02534 p["raid_type"] = Value((int32_t) raid_type);
02535 p["strip_size"] = Value((int32_t) strip_size);
02536 p["flags"] = Value(flags);
02537 std::vector < Value > disks_value;
02538 disks_value.reserve(disk_count);
02539 for (uint32_t i = 0; i < disk_count; i++) {
02540 disks_value.push_back(disk_to_value(disks[i]));
02541 }
02542 p["disks"] = disks_value;
02543
02544 Value parameters(p);
02545 Value response;
02546
02547 int rc = rpc(c, "volume_raid_create", parameters, response);
02548 try {
02549 if (LSM_ERR_OK == rc) {
02550 *new_volume = value_to_volume(response);
02551 if (!(*new_volume)) {
02552 rc = LSM_ERR_NO_MEMORY;
02553 }
02554 }
02555 }
02556 catch(const ValueException & ve) {
02557 rc = log_exception(c, LSM_ERR_PLUGIN_BUG, "Unexpected type", ve.what());
02558 }
02559 return rc;
02560 }