diff options
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-log-ops.c | 573 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 20 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 3 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 14 |
4 files changed, 0 insertions, 610 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-log-ops.c b/xlators/mgmt/glusterd/src/glusterd-log-ops.c index b032e902d..ec8889670 100644 --- a/xlators/mgmt/glusterd/src/glusterd-log-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-log-ops.c @@ -34,242 +34,6 @@ #include <signal.h> int -glusterd_handle_log_filename (rpcsvc_request_t *req) -{ - int32_t ret = -1; - gf_cli_req cli_req = {{0,}}; - dict_t *dict = NULL; - glusterd_op_t cli_op = GD_OP_LOG_FILENAME; - char *volname = NULL; - - GF_ASSERT (req); - - if (!xdr_to_generic (req->msg[0], &cli_req, - (xdrproc_t)xdr_gf_cli_req)) { - //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; - goto out; - } - - - if (cli_req.dict.dict_len) { - /* Unserialize the dictionary */ - dict = dict_new (); - - ret = dict_unserialize (cli_req.dict.dict_val, - cli_req.dict.dict_len, - &dict); - if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, - "failed to " - "unserialize req-buffer to dictionary"); - goto out; - } - } - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname"); - goto out; - } - - gf_log ("glusterd", GF_LOG_INFO, "Received log filename req " - "for volume %s", volname); - ret = glusterd_op_begin (req, GD_OP_LOG_FILENAME, dict); - -out: - if (ret && dict) - dict_unref (dict); - - glusterd_friend_sm (); - glusterd_op_sm (); - - if (ret) - ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, - NULL, "operation failed"); - if (cli_req.dict.dict_val) - free (cli_req.dict.dict_val); - return ret; -} - -int -glusterd_handle_log_locate (rpcsvc_request_t *req) -{ - int32_t ret = -1; - gf1_cli_log_locate_req cli_req = {0,}; - gf1_cli_log_locate_rsp rsp = {0,}; - glusterd_volinfo_t *volinfo = NULL; - glusterd_brickinfo_t *brickinfo = NULL; - char tmp_str[PATH_MAX] = {0,}; - char *tmp_brick = NULL; - uint32_t found = 0; - glusterd_brickinfo_t *tmpbrkinfo = NULL; - - GF_ASSERT (req); - - if (!xdr_to_generic (req->msg[0], &cli_req, - (xdrproc_t)xdr_gf1_cli_log_locate_req)) { - //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; - goto out; - } - - gf_log ("glusterd", GF_LOG_INFO, "Received log locate req " - "for volume %s", cli_req.volname); - - if (strchr (cli_req.brick, ':')) { - /* TODO: need to get info of only that brick and then - tell what is the exact location */ - tmp_brick = gf_strdup (cli_req.brick); - if (!tmp_brick) - goto out; - - gf_log ("", GF_LOG_DEBUG, "brick : %s", cli_req.brick); - ret = glusterd_brickinfo_from_brick (tmp_brick, &tmpbrkinfo); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, - "Cannot get brickinfo from the brick"); - goto out; - } - } - - ret = glusterd_volinfo_find (cli_req.volname, &volinfo); - if (ret) { - rsp.path = "request sent on non-existent volume"; - goto out; - } - - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - if (tmpbrkinfo) { - ret = glusterd_resolve_brick (tmpbrkinfo); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, - "cannot resolve the brick"); - goto out; - } - if (uuid_compare (tmpbrkinfo->uuid, brickinfo->uuid) || strcmp (brickinfo->path, tmpbrkinfo->path)) - continue; - } - - if (brickinfo->logfile) { - strcpy (tmp_str, brickinfo->logfile); - rsp.path = dirname (tmp_str); - found = 1; - } else { - snprintf (tmp_str, PATH_MAX, "%s/bricks/", - DEFAULT_LOG_FILE_DIRECTORY); - rsp.path = tmp_str; - found = 1; - } - break; - } - - if (!found) { - snprintf (tmp_str, PATH_MAX, "brick %s:%s does not exitst in the volume %s", - tmpbrkinfo->hostname, tmpbrkinfo->path, cli_req.volname); - rsp.path = tmp_str; - } - - ret = 0; -out: - if (tmp_brick) - GF_FREE (tmp_brick); - if (tmpbrkinfo) - glusterd_brickinfo_delete (tmpbrkinfo); - rsp.op_ret = ret; - if (!rsp.path) - rsp.path = "Operation failed"; - - ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gf1_cli_log_locate_rsp); - - if (cli_req.brick) - free (cli_req.brick); //its malloced by xdr - if (cli_req.volname) - free (cli_req.volname); //its malloced by xdr - - glusterd_friend_sm (); - glusterd_op_sm (); - - return ret; -} - -int -glusterd_handle_log_level (rpcsvc_request_t *req) -{ - int32_t ret = -1; - dict_t *dict = NULL; - gf_cli_req cli_req = {{0,}}; - glusterd_op_t cli_op = GD_OP_LOG_LEVEL; - char *loglevel = NULL; - char *xlator = NULL; - char *volname = NULL; - - GF_ASSERT(req); - - - if (!xdr_to_generic (req->msg[0], &cli_req, - (xdrproc_t)xdr_gf_cli_req)) { - gf_log ("glusterd", GF_LOG_ERROR, "Failed to decode rpc message"); - req->rpc_err = GARBAGE_ARGS; - goto out; - } - - if (cli_req.dict.dict_len) { - /* Unserialize the dictionary */ - dict = dict_new (); - - ret = dict_unserialize (cli_req.dict.dict_val, - cli_req.dict.dict_len, - &dict); - if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, - "failed to " - "unserialize req-buffer to dictionary"); - goto out; - } - } - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname"); - goto out; - } - - ret = dict_get_str (dict, "xlator", &xlator); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "failed to get xlator"); - goto out; - } - - ret = dict_get_str (dict, "loglevel", &loglevel); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "failed to get loglevel"); - goto out; - } - - gf_log ("glusterd", GF_LOG_DEBUG, "Got log level request for: Volume [%s]" - " Xlator [%s] LogLevel [\"%s\"]", volname, xlator, loglevel); - ret = glusterd_op_begin (req, cli_op, dict); - - out: - if (ret && dict) - dict_unref (dict); - - glusterd_friend_sm(); - glusterd_op_sm(); - - if (ret) - ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, NULL, - "Operation failed"); - - if (cli_req.dict.dict_val) - free (cli_req.dict.dict_val); - - return ret; -} - -int glusterd_handle_log_rotate (rpcsvc_request_t *req) { int32_t ret = -1; @@ -335,76 +99,6 @@ out: /* op-sm */ int -glusterd_op_stage_log_filename (dict_t *dict, char **op_errstr) -{ - int ret = -1; - char *volname = NULL; - gf_boolean_t exists = _gf_false; - char msg[2048] = {0}; - char *path = NULL; - char hostname[2048] = {0}; - char *brick = NULL; - glusterd_volinfo_t *volinfo = NULL; - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); - goto out; - } - - exists = glusterd_check_volume_exists (volname); - ret = glusterd_volinfo_find (volname, &volinfo); - if (!exists || ret) { - snprintf (msg, sizeof (msg), "Volume %s does not exist", - volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); - ret = -1; - goto out; - } - - ret = dict_get_str (dict, "brick", &brick); - if (ret) - goto out; - - if (strchr (brick, ':')) { - ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo, NULL, - GF_PATH_COMPLETE); - if (ret) { - snprintf (msg, sizeof (msg), "Incorrect brick %s " - "for volume %s", brick, volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); - goto out; - } - } - - ret = dict_get_str (dict, "path", &path); - if (ret) { - gf_log ("", GF_LOG_ERROR, "path not found"); - goto out; - } - - ret = gethostname (hostname, sizeof (hostname)); - if (ret) { - snprintf (msg, sizeof (msg), "Failed to get hostname, error:%s", - strerror (errno)); - gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); - goto out; - } - - ret = glusterd_brick_create_path (hostname, path, volinfo->volume_id, - 0777, op_errstr); - if (ret) - goto out; -out: - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); - - return ret; -} - -int glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr) { int ret = -1; @@ -461,200 +155,6 @@ out: return ret; } -int -glusterd_op_stage_log_level (dict_t *dict, char **op_errstr) -{ - int ret = -1; - gf_boolean_t exists = _gf_false; - dict_t *val_dict = NULL; - char *volname = NULL; - char *xlator = NULL; - char *loglevel = NULL; - glusterd_volinfo_t *volinfo = NULL; - glusterd_conf_t *priv = NULL; - xlator_t *this = NULL; - char msg[2048] = {0,}; - - GF_ASSERT (dict); - this = THIS; - GF_ASSERT (this); - priv = this->private; - GF_ASSERT(priv); - - val_dict = dict_new (); - if (!val_dict) - goto out; - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get volume name"); - goto out; - } - - /* - * check for existence of the gieven volume - */ - exists = glusterd_check_volume_exists (volname); - ret = glusterd_volinfo_find (volname, &volinfo); - if (!exists || ret) { - snprintf (msg, sizeof(msg), "Volume %s does not exist", volname); - gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); - - *op_errstr = gf_strdup(msg); - ret = -1; - goto out; - } - - ret = dict_get_str (dict, "xlator", &xlator); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get translator name"); - goto out; - } - - ret = dict_get_str (dict, "loglevel", &loglevel); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get loglevel"); - goto out; - } - - ret = 0; - - out: - if (val_dict) - dict_unref (val_dict); - - if (ret) { - if (!(*op_errstr)) { - *op_errstr = gf_strdup ("Error, Validation Failed"); - gf_log ("glusterd", GF_LOG_DEBUG, "Error, Cannot Validate option: %s", - *op_errstr); - } - } - - gf_log ("glusterd", GF_LOG_DEBUG, "Returning: %d", ret); - return ret; -} - -int -glusterd_op_log_filename (dict_t *dict) -{ - int ret = -1; - glusterd_conf_t *priv = NULL; - glusterd_volinfo_t *volinfo = NULL; - glusterd_brickinfo_t *brickinfo = NULL; - xlator_t *this = NULL; - char *volname = NULL; - char *brick = NULL; - char *path = NULL; - char logfile[PATH_MAX] = {0,}; - char exp_path[PATH_MAX] = {0,}; - struct stat stbuf = {0,}; - int valid_brick = 0; - glusterd_brickinfo_t *tmpbrkinfo = NULL; - char* new_logdir = NULL; - - this = THIS; - GF_ASSERT (this); - priv = this->private; - GF_ASSERT (priv); - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log ("", GF_LOG_ERROR, "volname not found"); - goto out; - } - - ret = dict_get_str (dict, "path", &path); - if (ret) { - gf_log ("", GF_LOG_ERROR, "path not found"); - goto out; - } - - ret = dict_get_str (dict, "brick", &brick); - if (ret) - goto out; - - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) - goto out; - - if (!strchr (brick, ':')) { - brick = NULL; - ret = stat (path, &stbuf); - if (ret || !S_ISDIR (stbuf.st_mode)) { - ret = -1; - gf_log ("", GF_LOG_ERROR, "not a directory"); - goto out; - } - new_logdir = gf_strdup (path); - if (!new_logdir) { - ret = -1; - gf_log ("", GF_LOG_ERROR, "Out of memory"); - goto out; - } - if (volinfo->logdir) - GF_FREE (volinfo->logdir); - volinfo->logdir = new_logdir; - } else { - ret = glusterd_brickinfo_from_brick (brick, &tmpbrkinfo); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, - "cannot get brickinfo from brick"); - goto out; - } - } - - - ret = -1; - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - - if (uuid_is_null (brickinfo->uuid)) { - ret = glusterd_resolve_brick (brickinfo); - if (ret) - goto out; - } - - /* check if the brickinfo belongs to the 'this' machine */ - if (uuid_compare (brickinfo->uuid, priv->uuid)) - continue; - - if (brick && strcmp (tmpbrkinfo->path,brickinfo->path)) - continue; - - valid_brick = 1; - - /* If there are more than one brick in 'this' server, its an - * extra check, but it doesn't harm functionality - */ - ret = stat (path, &stbuf); - if (ret || !S_ISDIR (stbuf.st_mode)) { - ret = -1; - gf_log ("", GF_LOG_ERROR, "not a directory"); - goto out; - } - - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path); - - snprintf (logfile, PATH_MAX, "%s/%s.log", path, exp_path); - - if (brickinfo->logfile) - GF_FREE (brickinfo->logfile); - brickinfo->logfile = gf_strdup (logfile); - ret = 0; - - /* If request was for brick, only one iteration is enough */ - if (brick) - break; - } - - if (ret && !valid_brick) - ret = 0; -out: - if (tmpbrkinfo) - glusterd_brickinfo_delete (tmpbrkinfo); - - return ret; -} int glusterd_op_log_rotate (dict_t *dict) @@ -773,76 +273,3 @@ out: return ret; } - -int -glusterd_op_log_level (dict_t *dict) -{ - int32_t ret = -1; - glusterd_volinfo_t *volinfo = NULL; - char *volname = NULL; - char *xlator = NULL; - char *loglevel = NULL; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - - this = THIS; - GF_ASSERT (this); - - priv = this->private; - GF_ASSERT (priv); - - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get volume name"); - goto out; - } - - ret = dict_get_str (dict, "xlator", &xlator); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get translator name"); - goto out; - } - - ret = dict_get_str (dict, "loglevel", &loglevel); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to get Loglevel to use"); - goto out; - } - - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Cannot find volume: %s", volname); - goto out; - } - - xlator = gf_strdup (xlator); - - ret = dict_set_dynstr (volinfo->dict, "xlator", xlator); - if (ret) - goto out; - - loglevel = gf_strdup (loglevel); - - ret = dict_set_dynstr (volinfo->dict, "loglevel", loglevel); - if (ret) - goto out; - - ret = glusterd_create_volfiles_and_notify_services (volinfo); - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "Unable to create volfile for command" - " 'log level'"); - ret = -1; - goto out; - } - - ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); - if (ret) - goto out; - - ret = 0; - - out: - gf_log ("glusterd", GF_LOG_DEBUG, "(cli log level) Returning: %d", ret); - return ret; -} - diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 61f3b70a3..225bf6791 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1504,13 +1504,11 @@ glusterd_op_build_payload (dict_t **req) case GD_OP_SET_VOLUME: case GD_OP_RESET_VOLUME: case GD_OP_REMOVE_BRICK: - case GD_OP_LOG_FILENAME: case GD_OP_LOG_ROTATE: case GD_OP_SYNC_VOLUME: case GD_OP_QUOTA: case GD_OP_GSYNC_SET: case GD_OP_PROFILE_VOLUME: - case GD_OP_LOG_LEVEL: case GD_OP_STATUS_VOLUME: case GD_OP_REBALANCE: case GD_OP_HEAL_VOLUME: @@ -2231,10 +2229,6 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, ret = glusterd_op_stage_remove_brick (dict, op_errstr); break; - case GD_OP_LOG_FILENAME: - ret = glusterd_op_stage_log_filename (dict, op_errstr); - break; - case GD_OP_LOG_ROTATE: ret = glusterd_op_stage_log_rotate (dict, op_errstr); break; @@ -2255,10 +2249,6 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, ret = glusterd_op_stage_quota (dict, op_errstr); break; - case GD_OP_LOG_LEVEL: - ret = glusterd_op_stage_log_level (dict, op_errstr); - break; - case GD_OP_STATUS_VOLUME: ret = glusterd_op_stage_status_volume (dict, op_errstr); break; @@ -2330,10 +2320,6 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr, ret = glusterd_op_remove_brick (dict, op_errstr); break; - case GD_OP_LOG_FILENAME: - ret = glusterd_op_log_filename (dict); - break; - case GD_OP_LOG_ROTATE: ret = glusterd_op_log_rotate (dict); break; @@ -2355,10 +2341,6 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr, ret = glusterd_op_quota (dict, op_errstr); break; - case GD_OP_LOG_LEVEL: - ret = glusterd_op_log_level (dict); - break; - case GD_OP_STATUS_VOLUME: ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict); break; @@ -3465,7 +3447,6 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx) case GD_OP_ADD_BRICK: case GD_OP_REMOVE_BRICK: case GD_OP_REPLACE_BRICK: - case GD_OP_LOG_FILENAME: case GD_OP_LOG_ROTATE: case GD_OP_SYNC_VOLUME: case GD_OP_SET_VOLUME: @@ -3474,7 +3455,6 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx) case GD_OP_GSYNC_SET: case GD_OP_QUOTA: case GD_OP_PROFILE_VOLUME: - case GD_OP_LOG_LEVEL: case GD_OP_STATUS_VOLUME: case GD_OP_REBALANCE: case GD_OP_HEAL_VOLUME: diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index d6ec18a3d..b22938c92 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -126,10 +126,8 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, case GD_OP_DELETE_VOLUME: case GD_OP_DEFRAG_VOLUME: case GD_OP_ADD_BRICK: - case GD_OP_LOG_FILENAME: case GD_OP_LOG_ROTATE: case GD_OP_SYNC_VOLUME: - case GD_OP_LOG_LEVEL: case GD_OP_HEAL_VOLUME: case GD_OP_STATEDUMP_VOLUME: @@ -168,7 +166,6 @@ done: case GD_OP_RENAME_VOLUME: case GD_OP_START_BRICK: case GD_OP_STOP_BRICK: - case GD_OP_LOG_LOCATE: { gf_log ("", GF_LOG_DEBUG, "not supported op %d", op); break; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index d59193e74..1ce5962bc 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -70,13 +70,10 @@ typedef enum glusterd_op_ { GD_OP_SET_VOLUME, GD_OP_RESET_VOLUME, GD_OP_SYNC_VOLUME, - GD_OP_LOG_FILENAME, - GD_OP_LOG_LOCATE, GD_OP_LOG_ROTATE, GD_OP_GSYNC_SET, GD_OP_PROFILE_VOLUME, GD_OP_QUOTA, - GD_OP_LOG_LEVEL, GD_OP_STATUS_VOLUME, GD_OP_REBALANCE, GD_OP_HEAL_VOLUME, @@ -441,10 +438,6 @@ int glusterd_handle_remove_brick (rpcsvc_request_t *req); int -glusterd_handle_log_filename (rpcsvc_request_t *req); -int -glusterd_handle_log_locate (rpcsvc_request_t *req); -int glusterd_handle_log_rotate (rpcsvc_request_t *req); int @@ -534,9 +527,6 @@ int glusterd_rpc_create (struct rpc_clnt **rpc, dict_t *options, rpc_clnt_notify_t notify_fn, void *notify_data); -int -glusterd_handle_log_level (rpcsvc_request_t *req); - /* handler functions */ int32_t glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx); @@ -559,11 +549,7 @@ int glusterd_op_stage_quota (dict_t *dict, char **op_errstr); int glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict); int glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict); -int glusterd_op_log_level (dict_t *dict); -int glusterd_op_log_filename (dict_t *dict); int glusterd_op_log_rotate (dict_t *dict); -int glusterd_op_stage_log_level (dict_t *dict, char **op_errstr); -int glusterd_op_stage_log_filename (dict_t *dict, char **op_errstr); int glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr); int glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr); int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr); |