posix/afr: handle backward compatibility for rchecksum fop

Added a volume option 'fips-mode-rchecksum' tied to op version 4.
If not set, rchecksum fop will use MD5 instead of SHA256.

updates: #230
Change-Id: Id8ea1303777e6450852c0bc25503cda341a6aec2
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
This commit is contained in:
Ravishankar N 2018-02-11 06:54:35 +05:30 committed by Amar Tumballi
parent e80c10d5e6
commit 6daa653569
11 changed files with 89 additions and 13 deletions

View File

@ -8,6 +8,7 @@
cases as published by the Free Software Foundation.
*/
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
@ -36,3 +37,9 @@ gf_rsync_strong_checksum (unsigned char *data, size_t len,
{
SHA256((const unsigned char *)data, len, sha256_md);
}
void
gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5)
{
MD5 (data, len, md5);
}

View File

@ -17,4 +17,6 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len);
void
gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
void
gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5);
#endif /* __CHECKSUM_H__ */

View File

@ -643,6 +643,7 @@ gf_resolve_path_parent
gf_rev_dns_lookup
gf_rev_dns_lookup_cached
gf_rsync_strong_checksum
gf_rsync_md5_checksum
gf_rsync_weak_checksum
gf_set_log_file_path
gf_set_log_ident

View File

@ -648,7 +648,13 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src)
if (dst->xdata)
dict_unref (dst->xdata);
dst->xdata = xdata;
memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
if (xdata && dict_get_str_boolean (xdata, "fips-mode-rchecksum",
_gf_false) == _gf_true) {
memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
} else {
memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH);
}
dst->fips_mode_rchecksum = src->fips_mode_rchecksum;
}
void

View File

@ -38,11 +38,21 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
replies[i].valid = 1;
replies[i].op_ret = op_ret;
replies[i].op_errno = op_errno;
if (xdata)
if (xdata) {
replies[i].buf_has_zeroes = dict_get_str_boolean (xdata,
"buf-has-zeroes", _gf_false);
if (strong)
memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH);
replies[i].fips_mode_rchecksum = dict_get_str_boolean (xdata,
"fips-mode-rchecksum", _gf_false);
}
if (strong) {
if (replies[i].fips_mode_rchecksum) {
memcpy (local->replies[i].checksum, strong,
SHA256_DIGEST_LENGTH);
} else {
memcpy (local->replies[i].checksum, strong,
MD5_DIGEST_LENGTH);
}
}
syncbarrier_wake (&local->barrier);
return 0;
@ -58,11 +68,13 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
afr_local_t *local = NULL;
unsigned char *wind_subvols = NULL;
gf_boolean_t checksum_match = _gf_true;
struct afr_reply *replies = NULL;
dict_t *xdata = NULL;
int i = 0;
priv = this->private;
local = frame->local;
replies = local->replies;
xdata = dict_new();
if (!xdata)
@ -83,16 +95,17 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (xdata)
dict_unref (xdata);
if (!local->replies[source].valid || local->replies[source].op_ret != 0)
if (!replies[source].valid || replies[source].op_ret != 0)
return _gf_false;
for (i = 0; i < priv->child_count; i++) {
if (i == source)
continue;
if (local->replies[i].valid) {
if (memcmp (local->replies[source].checksum,
local->replies[i].checksum,
SHA256_DIGEST_LENGTH)) {
if (replies[i].valid) {
if (memcmp (replies[source].checksum,
replies[i].checksum,
replies[source].fips_mode_rchecksum ?
SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) {
checksum_match = _gf_false;
break;
}

View File

@ -322,6 +322,7 @@ struct afr_reply {
/* For rchecksum */
uint8_t checksum[SHA256_DIGEST_LENGTH];
gf_boolean_t buf_has_zeroes;
gf_boolean_t fips_mode_rchecksum;
/* For lookup */
int8_t need_heal;
};

View File

@ -2898,6 +2898,13 @@ struct volopt_map_entry glusterd_volopt_map[] = {
},
{ .option = "health-check-timeout",
.key = "storage.health-check-timeout",
.type = NO_DOC,
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_4_0_0,
},
{ .option = "fips-mode-rchecksum",
.key = "storage.fips-mode-rchecksum",
.type = NO_DOC,
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_4_0_0,
},

View File

@ -299,7 +299,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->weak_checksum = weak_checksum;
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
}
@ -670,6 +670,7 @@ server4_post_rchecksum (gfx_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
rsp->flags = 1; /* Indicates SHA256 TYPE */
}

View File

@ -387,6 +387,9 @@ posix_reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("max-hardlinks", priv->max_hardlinks,
options, uint32, out);
GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum,
options, bool, out);
ret = 0;
out:
return ret;
@ -1076,6 +1079,9 @@ posix_init (xlator_t *this)
_private->create_directory_mask = create_directory_mask;
GF_OPTION_INIT ("max-hardlinks", _private->max_hardlinks, uint32, out);
GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum,
bool, out);
out:
if (ret) {
if (_private) {
@ -1362,5 +1368,15 @@ struct volume_options options[] = {
.description = "max number of hardlinks allowed on any one inode.\n"
"0 is unlimited, 1 prevents any hardlinking at all."
},
{
.key = {"fips-mode-rchecksum"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "off",
.op_version = {GD_OP_VERSION_4_0_0},
.flags = OPT_FLAG_SETTABLE,
.tags = {"posix"},
.description = "If enabled, posix_rchecksum uses the FIPS compliant"
"SHA256 checksum. MD5 otherwise."
},
{ .key = {NULL} }
};

View File

@ -4873,7 +4873,9 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
ssize_t bytes_read = 0;
int32_t weak_checksum = 0;
int32_t zerofillcheck = 0;
unsigned char md5_checksum[MD5_DIGEST_LENGTH] = {0};
unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0};
unsigned char *checksum = NULL;
struct posix_private *priv = NULL;
dict_t *rsp_xdata = NULL;
gf_boolean_t buf_has_zeroes = _gf_false;
@ -4942,13 +4944,31 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
}
}
weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret);
gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read,
(unsigned char *) strong_checksum);
if (priv->fips_mode_rchecksum) {
ret = dict_set_int32 (rsp_xdata, "fips-mode-rchecksum", 1);
if (ret) {
gf_msg (this->name, GF_LOG_WARNING, -ret,
P_MSG_DICT_SET_FAILED, "%s: Failed to set "
"dictionary value for key: %s",
uuid_utoa (fd->inode->gfid),
"fips-mode-rchecksum");
goto out;
}
checksum = strong_checksum;
gf_rsync_strong_checksum ((unsigned char *)buf,
(size_t) bytes_read,
(unsigned char *)checksum);
} else {
checksum = md5_checksum;
gf_rsync_md5_checksum ((unsigned char *)buf,
(size_t) bytes_read,
(unsigned char *)checksum);
}
op_ret = 0;
out:
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno,
weak_checksum, strong_checksum, rsp_xdata);
weak_checksum, checksum, rsp_xdata);
if (rsp_xdata)
dict_unref (rsp_xdata);
GF_FREE (alloc_buf);

View File

@ -243,6 +243,8 @@ struct posix_private {
mode_t create_mask;
mode_t create_directory_mask;
uint32_t max_hardlinks;
gf_boolean_t fips_mode_rchecksum;
};
typedef struct {