summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/common-utils.c414
-rw-r--r--libglusterfs/src/common-utils.h1
-rw-r--r--rpc/xdr/src/glusterd1-xdr.c10
-rw-r--r--rpc/xdr/src/glusterd1-xdr.h20
-rw-r--r--rpc/xdr/src/glusterd1.x8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c32
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c19
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c488
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd3_1-mops.c18
15 files changed, 847 insertions, 223 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index eef865ec5..f3386fe2b 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -72,10 +72,10 @@ log_base2 (unsigned long x)
int32_t
-gf_resolve_ip6 (const char *hostname,
- uint16_t port,
- int family,
- void **dnscache,
+gf_resolve_ip6 (const char *hostname,
+ uint16_t port,
+ int family,
+ void **dnscache,
struct addrinfo **addr_info)
{
int32_t ret = 0;
@@ -189,18 +189,18 @@ gf_log_volume_file (FILE *specfp)
extern FILE *gf_log_logfile;
int lcount = 0;
char data[GF_UNIT_KB];
-
+
fseek (specfp, 0L, SEEK_SET);
-
+
fprintf (gf_log_logfile, "Given volfile:\n");
- fprintf (gf_log_logfile,
+ fprintf (gf_log_logfile,
"+---------------------------------------"
"---------------------------------------+\n");
while (fgets (data, GF_UNIT_KB, specfp) != NULL){
lcount++;
fprintf (gf_log_logfile, "%3d: %s", lcount, data);
}
- fprintf (gf_log_logfile,
+ fprintf (gf_log_logfile,
"\n+---------------------------------------"
"---------------------------------------+\n");
fflush (gf_log_logfile);
@@ -419,28 +419,28 @@ char *
gf_trim (char *string)
{
register char *s, *t;
-
+
if (string == NULL)
{
return NULL;
}
-
+
for (s = string; isspace (*s); s++)
;
-
+
if (*s == 0)
return s;
-
+
t = s + strlen (s) - 1;
while (t > s && isspace (*t))
t--;
*++t = '\0';
-
+
return s;
}
-int
-gf_strsplit (const char *str, const char *delim,
+int
+gf_strsplit (const char *str, const char *delim,
char ***tokens, int *token_count)
{
char *_running = NULL;
@@ -450,57 +450,57 @@ gf_strsplit (const char *str, const char *delim,
int count = 0;
int i = 0;
int j = 0;
-
+
if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL)
{
return -1;
}
-
+
_running = gf_strdup (str);
if (_running == NULL)
{
return -1;
}
running = _running;
-
+
while ((token = strsep (&running, delim)) != NULL)
{
if (token[0] != '\0')
count++;
}
GF_FREE (_running);
-
+
_running = gf_strdup (str);
if (_running == NULL)
{
return -1;
}
running = _running;
-
+
if ((token_list = GF_CALLOC (count, sizeof (char *),
gf_common_mt_char)) == NULL)
{
GF_FREE (_running);
return -1;
}
-
+
while ((token = strsep (&running, delim)) != NULL)
{
if (token[0] == '\0')
continue;
-
+
token_list[i] = gf_strdup (token);
if (token_list[i] == NULL)
goto free_exit;
i++;
}
-
+
GF_FREE (_running);
-
+
*tokens = token_list;
*token_count = count;
return 0;
-
+
free_exit:
GF_FREE (_running);
for (j = 0; j < i; j++)
@@ -511,7 +511,7 @@ free_exit:
return -1;
}
-int
+int
gf_strstr (const char *str, const char *delim, const char *match)
{
char *tmp = NULL;
@@ -551,41 +551,41 @@ int
gf_volume_name_validate (const char *volume_name)
{
const char *vname = NULL;
-
+
if (volume_name == NULL)
{
return -1;
}
-
+
if (!isalpha (volume_name[0]))
{
return 1;
}
-
+
for (vname = &volume_name[1]; *vname != '\0'; vname++)
{
if (!(isalnum (*vname) || *vname == '_'))
return 1;
}
-
+
return 0;
}
-int
+int
gf_string2time (const char *str, uint32_t *n)
{
unsigned long value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -598,48 +598,48 @@ gf_string2time (const char *str, uint32_t *n)
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtol (str, &tail, 0);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
- if (!((tail[0] == '\0') ||
+
+ if (!((tail[0] == '\0') ||
((tail[0] == 's') && (tail[1] == '\0')) ||
((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') && (tail[3] == '\0'))))
{
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-int
+int
gf_string2percent (const char *str, uint32_t *n)
{
unsigned long value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -652,55 +652,55 @@ gf_string2percent (const char *str, uint32_t *n)
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtol (str, &tail, 0);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
- if (!((tail[0] == '\0') ||
+
+ if (!((tail[0] == '\0') ||
((tail[0] == '%') && (tail[1] == '\0'))))
{
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-static int
+static int
_gf_string2long (const char *str, long *n, int base)
{
long value = 0;
char *tail = NULL;
int old_errno = 0;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
old_errno = errno;
errno = 0;
value = strtol (str, &tail, base);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
@@ -711,26 +711,26 @@ _gf_string2long (const char *str, long *n, int base)
/* bala: invalid integer format */
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-static int
+static int
_gf_string2ulong (const char *str, unsigned long *n, int base)
{
unsigned long value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -739,52 +739,52 @@ _gf_string2ulong (const char *str, unsigned long *n, int base)
}
if (*s == '-')
{
- /* bala: we do not support suffixed (-) sign and
+ /* bala: we do not support suffixed (-) sign and
invalid integer format */
return -1;
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
+
if (tail[0] != '\0')
{
/* bala: invalid integer format */
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-static int
+static int
_gf_string2uint (const char *str, unsigned int *n, int base)
{
unsigned long value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -793,123 +793,123 @@ _gf_string2uint (const char *str, unsigned int *n, int base)
}
if (*s == '-')
{
- /* bala: we do not support suffixed (-) sign and
+ /* bala: we do not support suffixed (-) sign and
invalid integer format */
return -1;
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
+
if (tail[0] != '\0')
{
/* bala: invalid integer format */
return -1;
}
-
+
*n = (unsigned int)value;
-
+
return 0;
}
-static int
+static int
_gf_string2double (const char *str, double *n)
{
double value = 0.0;
char *tail = NULL;
int old_errno = 0;
-
+
if (str == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
-
+
old_errno = errno;
errno = 0;
value = strtod (str, &tail);
-
+
if (errno == ERANGE || errno == EINVAL) {
return -1;
}
-
+
if (errno == 0) {
errno = old_errno;
}
-
+
if (tail[0] != '\0') {
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-static int
+static int
_gf_string2longlong (const char *str, long long *n, int base)
{
long long value = 0;
char *tail = NULL;
int old_errno = 0;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
old_errno = errno;
errno = 0;
value = strtoll (str, &tail, base);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
+
if (tail[0] != '\0')
{
/* bala: invalid integer format */
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-static int
+static int
_gf_string2ulonglong (const char *str, unsigned long long *n, int base)
{
unsigned long long value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -918,57 +918,57 @@ _gf_string2ulonglong (const char *str, unsigned long long *n, int base)
}
if (*s == '-')
{
- /* bala: we do not support suffixed (-) sign and
+ /* bala: we do not support suffixed (-) sign and
invalid integer format */
return -1;
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtoull (str, &tail, base);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
+
if (tail[0] != '\0')
{
/* bala: invalid integer format */
return -1;
}
-
+
*n = value;
-
+
return 0;
}
-int
+int
gf_string2long (const char *str, long *n)
{
return _gf_string2long (str, n, 0);
}
-int
+int
gf_string2ulong (const char *str, unsigned long *n)
{
return _gf_string2ulong (str, n, 0);
}
-int
+int
gf_string2int (const char *str, int *n)
{
return _gf_string2long (str, (long *) n, 0);
}
-int
+int
gf_string2uint (const char *str, unsigned int *n)
{
return _gf_string2uint (str, n, 0);
@@ -980,284 +980,284 @@ gf_string2double (const char *str, double *n)
return _gf_string2double (str, n);
}
-int
+int
gf_string2longlong (const char *str, long long *n)
{
return _gf_string2longlong (str, n, 0);
}
-int
+int
gf_string2ulonglong (const char *str, unsigned long long *n)
{
return _gf_string2ulonglong (str, n, 0);
}
-int
+int
gf_string2int8 (const char *str, int8_t *n)
{
long l = 0L;
int rv = 0;
-
+
rv = _gf_string2long (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= INT8_MIN && l <= INT8_MAX)
{
*n = (int8_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2int16 (const char *str, int16_t *n)
{
long l = 0L;
int rv = 0;
-
+
rv = _gf_string2long (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= INT16_MIN && l <= INT16_MAX)
{
*n = (int16_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2int32 (const char *str, int32_t *n)
{
long l = 0L;
int rv = 0;
-
+
rv = _gf_string2long (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= INT32_MIN && l <= INT32_MAX)
{
*n = (int32_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2int64 (const char *str, int64_t *n)
{
long long l = 0LL;
int rv = 0;
-
+
rv = _gf_string2longlong (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= INT64_MIN && l <= INT64_MAX)
{
*n = (int64_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint8 (const char *str, uint8_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT8_MAX)
{
*n = (uint8_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint16 (const char *str, uint16_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT16_MAX)
{
*n = (uint16_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint32 (const char *str, uint32_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT32_MAX)
{
*n = (uint32_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint64 (const char *str, uint64_t *n)
{
unsigned long long l = 0ULL;
int rv = 0;
-
+
rv = _gf_string2ulonglong (str, &l, 0);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT64_MAX)
{
*n = (uint64_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2ulong_base10 (const char *str, unsigned long *n)
{
return _gf_string2ulong (str, n, 10);
}
-int
+int
gf_string2uint_base10 (const char *str, unsigned int *n)
{
return _gf_string2uint (str, n, 10);
}
-int
+int
gf_string2uint8_base10 (const char *str, uint8_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 10);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT8_MAX)
{
*n = (uint8_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint16_base10 (const char *str, uint16_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 10);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT16_MAX)
{
*n = (uint16_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint32_base10 (const char *str, uint32_t *n)
{
unsigned long l = 0L;
int rv = 0;
-
+
rv = _gf_string2ulong (str, &l, 10);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT32_MAX)
{
*n = (uint32_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2uint64_base10 (const char *str, uint64_t *n)
{
unsigned long long l = 0ULL;
int rv = 0;
-
+
rv = _gf_string2ulonglong (str, &l, 10);
if (rv != 0)
return rv;
-
+
if (l >= 0 && l <= UINT64_MAX)
{
*n = (uint64_t) l;
return 0;
}
-
+
errno = ERANGE;
return -1;
}
-int
+int
gf_string2bytesize (const char *str, uint64_t *n)
{
uint64_t value = 0ULL;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
-
+
if (str == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
-
+
for (s = str; *s != '\0'; s++)
{
if (isspace (*s))
@@ -1266,27 +1266,27 @@ gf_string2bytesize (const char *str, uint64_t *n)
}
if (*s == '-')
{
- /* bala: we do not support suffixed (-) sign and
+ /* bala: we do not support suffixed (-) sign and
invalid integer format */
return -1;
}
break;
}
-
+
old_errno = errno;
errno = 0;
value = strtoull (str, &tail, 10);
-
+
if (errno == ERANGE || errno == EINVAL)
{
return -1;
}
-
+
if (errno == 0)
{
errno = old_errno;
}
-
+
if (tail[0] != '\0')
{
if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
@@ -1309,19 +1309,19 @@ gf_string2bytesize (const char *str, uint64_t *n)
{
value *= GF_UNIT_PB;
}
- else
+ else
{
/* bala: invalid integer format */
return -1;
}
}
-
+
*n = value;
-
+
return 0;
}
-int64_t
+int64_t
gf_str_to_long_long (const char *number)
{
int64_t unit = 1;
@@ -1360,62 +1360,62 @@ gf_str_to_long_long (const char *number)
return ret * unit;
}
-int
+int
gf_string2boolean (const char *str, gf_boolean_t *b)
{
if (str == NULL) {
return -1;
}
-
- if ((strcasecmp (str, "1") == 0) ||
- (strcasecmp (str, "on") == 0) ||
- (strcasecmp (str, "yes") == 0) ||
- (strcasecmp (str, "true") == 0) ||
+
+ if ((strcasecmp (str, "1") == 0) ||
+ (strcasecmp (str, "on") == 0) ||
+ (strcasecmp (str, "yes") == 0) ||
+ (strcasecmp (str, "true") == 0) ||
(strcasecmp (str, "enable") == 0)) {
*b = _gf_true;
return 0;
}
-
- if ((strcasecmp (str, "0") == 0) ||
- (strcasecmp (str, "off") == 0) ||
- (strcasecmp (str, "no") == 0) ||
- (strcasecmp (str, "false") == 0) ||
+
+ if ((strcasecmp (str, "0") == 0) ||
+ (strcasecmp (str, "off") == 0) ||
+ (strcasecmp (str, "no") == 0) ||
+ (strcasecmp (str, "false") == 0) ||
(strcasecmp (str, "disable") == 0)) {
*b = _gf_false;
return 0;
}
-
+
return -1;
}
-int
+int
gf_lockfd (int fd)
{
struct flock fl;
-
+
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
-
+
return fcntl (fd, F_SETLK, &fl);
}
-int
+int
gf_unlockfd (int fd)
{
struct flock fl;
-
+
fl.l_type = F_UNLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
-
+
return fcntl (fd, F_SETLK, &fl);
}
-
+
static void
compute_checksum (char *buf, size_t size, uint32_t *checksum)
{
@@ -1428,7 +1428,7 @@ compute_checksum (char *buf, size_t size, uint32_t *checksum)
checksum_buf [0] = 0xba;
checksum_buf [1] = 0xbe;
checksum_buf [2] = 0xb0;
- checksum_buf [3] = 0x0b;
+ checksum_buf [3] = 0x0b;
}
for (ret = 0; ret < (size - 4); ret += 4) {
@@ -1441,14 +1441,14 @@ compute_checksum (char *buf, size_t size, uint32_t *checksum)
for (ret = 0; ret <= (size % 4); ret++) {
checksum_buf[ret] ^= (buf[(size - 4) + ret] << ret);
}
-
+
return;
}
#define GF_CHECKSUM_BUF_SIZE 1024
int
-get_checksum_for_file (int fd, uint32_t *checksum)
+get_checksum_for_file (int fd, uint32_t *checksum)
{
int ret = -1;
char buf[GF_CHECKSUM_BUF_SIZE] = {0,};
@@ -1458,7 +1458,7 @@ get_checksum_for_file (int fd, uint32_t *checksum)
do {
ret = read (fd, &buf, GF_CHECKSUM_BUF_SIZE);
if (ret > 0)
- compute_checksum (buf, GF_CHECKSUM_BUF_SIZE,
+ compute_checksum (buf, GF_CHECKSUM_BUF_SIZE,
checksum);
} while (ret > 0);
@@ -1522,3 +1522,29 @@ out:
return ret;
}
+
+int
+get_checksum_for_path (char *path, uint32_t *checksum)
+{
+ int ret = -1;
+ int fd = -1;
+
+ GF_ASSERT (path);
+ GF_ASSERT (checksum);
+
+ fd = open (path, O_RDWR);
+
+ if (fd == -1) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ path, errno);
+ goto out;
+ }
+
+ ret = get_checksum_for_file (fd, checksum);
+
+out:
+ if (fd != -1)
+ close (fd);
+
+ return ret;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 93d62f6cb..54f52a5a0 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -329,6 +329,7 @@ int get_checksum_for_file (int fd, uint32_t *checksum);
int log_base2 (unsigned long x);
int gf_system (const char *command);
+int get_checksum_for_path (char *path, uint32_t *checksum);
#endif /* _COMMON_UTILS_H */
diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c
index c7b83b9d5..82d9830c9 100644
--- a/rpc/xdr/src/glusterd1-xdr.c
+++ b/rpc/xdr/src/glusterd1-xdr.c
@@ -73,6 +73,8 @@ xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->port))
return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->vols.vols_val, (u_int *) &objp->vols.vols_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -85,12 +87,12 @@ xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
- if (!xdr_int (xdrs, &objp->port))
- return FALSE;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
+ if (!xdr_int (xdrs, &objp->port))
+ return FALSE;
return TRUE;
}
@@ -117,12 +119,12 @@ xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp)
return FALSE;
if (!xdr_string (xdrs, &objp->hostname, ~0))
return FALSE;
- if (!xdr_int (xdrs, &objp->port))
- return FALSE;
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
return FALSE;
+ if (!xdr_int (xdrs, &objp->port))
+ return FALSE;
return TRUE;
}
diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h
index 4125d7b12..7b208ee5f 100644
--- a/rpc/xdr/src/glusterd1-xdr.h
+++ b/rpc/xdr/src/glusterd1-xdr.h
@@ -26,7 +26,7 @@
#ifndef _GLUSTERD1_H_RPCGEN
#define _GLUSTERD1_H_RPCGEN
-//#include <rpc/rpc.h>
+#include <rpc/rpc.h>
#ifdef __cplusplus
@@ -44,46 +44,50 @@ typedef enum glusterd_volume_status glusterd_volume_status;
struct gd1_mgmt_probe_req {
u_char uuid[16];
char *hostname;
- int port;
+ int port;
};
typedef struct gd1_mgmt_probe_req gd1_mgmt_probe_req;
struct gd1_mgmt_probe_rsp {
u_char uuid[16];
char *hostname;
- int port;
+ int port;
};
typedef struct gd1_mgmt_probe_rsp gd1_mgmt_probe_rsp;
struct gd1_mgmt_friend_req {
u_char uuid[16];
char *hostname;
- int port;
+ int port;
+ struct {
+ u_int vols_len;
+ char *vols_val;
+ } vols;
};
typedef struct gd1_mgmt_friend_req gd1_mgmt_friend_req;
struct gd1_mgmt_friend_rsp {
u_char uuid[16];
char *hostname;
- int port;
int op_ret;
int op_errno;
+ int port;
};
typedef struct gd1_mgmt_friend_rsp gd1_mgmt_friend_rsp;
struct gd1_mgmt_unfriend_req {
u_char uuid[16];
char *hostname;
- int port;
+ int port;
};
typedef struct gd1_mgmt_unfriend_req gd1_mgmt_unfriend_req;
struct gd1_mgmt_unfriend_rsp {
u_char uuid[16];
char *hostname;
- int port;
int op_ret;
int op_errno;
+ int port;
};
typedef struct gd1_mgmt_unfriend_rsp gd1_mgmt_unfriend_rsp;
@@ -153,7 +157,7 @@ struct gd1_mgmt_friend_update {
u_int friends_len;
char *friends_val;
} friends;
- int port;
+ int port;
};
typedef struct gd1_mgmt_friend_update gd1_mgmt_friend_update;
diff --git a/rpc/xdr/src/glusterd1.x b/rpc/xdr/src/glusterd1.x
index 28e6de01f..19fa7af68 100644
--- a/rpc/xdr/src/glusterd1.x
+++ b/rpc/xdr/src/glusterd1.x
@@ -7,16 +7,20 @@
struct gd1_mgmt_probe_req {
unsigned char uuid[16];
string hostname<>;
+ int port;
} ;
struct gd1_mgmt_probe_rsp {
unsigned char uuid[16];
string hostname<>;
+ int port;
} ;
struct gd1_mgmt_friend_req {
unsigned char uuid[16];
string hostname<>;
+ int port;
+ opaque vols<>;
} ;
struct gd1_mgmt_friend_rsp {
@@ -24,11 +28,13 @@ struct gd1_mgmt_friend_rsp {
string hostname<>;
int op_ret;
int op_errno;
+ int port;
} ;
struct gd1_mgmt_unfriend_req {
unsigned char uuid[16];
string hostname<>;
+ int port;
} ;
struct gd1_mgmt_unfriend_rsp {
@@ -36,6 +42,7 @@ struct gd1_mgmt_unfriend_rsp {
string hostname<>;
int op_ret;
int op_errno;
+ int port;
} ;
struct gd1_mgmt_cluster_lock_req {
@@ -89,6 +96,7 @@ struct gd1_mgmt_commit_op_rsp {
struct gd1_mgmt_friend_update {
unsigned char uuid[16];
opaque friends<>;
+ int port;
} ;
struct gd1_mgmt_friend_update_rsp {
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 7e9a82e30..00162e913 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -119,7 +119,8 @@ glusterd_friend_find_by_uuid (uuid_t uuid,
}
static int
-glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname, int port)
+glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
+ char *hostname, int port, dict_t *dict)
{
int ret = -1;
glusterd_peerinfo_t *peerinfo = NULL;
@@ -159,6 +160,7 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname,
if (hostname)
ctx->hostname = gf_strdup (hostname);
ctx->req = req;
+ ctx->vols = dict;
event->ctx = ctx;
@@ -176,6 +178,8 @@ out:
if (0 != ret) {
if (ctx && ctx->hostname)
GF_FREE (ctx->hostname);
+ if (ctx && ctx->vols)
+ dict_destroy (ctx->vols);
if (ctx)
GF_FREE (ctx);
}
@@ -742,7 +746,7 @@ out:
defrag->mount);
snprintf (cmd_str, 1024, "umount %s", defrag->mount);
- system (cmd_str);
+ ret = system (cmd_str);
volinfo->defrag = NULL;
LOCK_DESTROY (&defrag->lock);
GF_FREE (defrag);
@@ -1291,7 +1295,8 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_friend_req friend_req = {{0},};
- char str[50];
+ char str[50] = {0,};
+ dict_t *dict = NULL;
GF_ASSERT (req);
if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &friend_req)) {
@@ -1304,8 +1309,22 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_NORMAL,
"Received probe from uuid: %s", str);
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (friend_req.vols.vols_val,
+ friend_req.vols.vols_len,
+ &dict);
+
+ if (ret)
+ goto out;
+
ret = glusterd_handle_friend_req (req, friend_req.uuid,
- friend_req.hostname, friend_req.port);
+ friend_req.hostname, friend_req.port,
+ dict);
out:
@@ -1728,7 +1747,8 @@ glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int por
}
int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port)
+glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port,
+ int32_t op_ret)
{
gd1_mgmt_friend_rsp rsp = {{0}, };
int32_t ret = -1;
@@ -1737,7 +1757,7 @@ glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port)
GF_ASSERT (hostname);
- rsp.op_ret = 0;
+ rsp.op_ret = op_ret;
this = THIS;
GF_ASSERT (this);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index b243e7895..3b4b390d1 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -253,7 +253,7 @@ out:
return ret;
}
-static int
+int
glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo)
{
int32_t ret = -1;
@@ -800,6 +800,7 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
i++;
}
list_add_tail (&volinfo->vol_list, &priv->volumes);
+ volinfo->version++;
ret = glusterd_store_create_volume (volinfo);
@@ -811,6 +812,10 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
goto out;
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
out:
return ret;
}
@@ -942,6 +947,12 @@ glusterd_op_add_brick (gd1_mgmt_stage_op_req *req)
goto out;
}
+ volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_store_update_volume (volinfo);
if (ret)
@@ -1879,6 +1890,12 @@ glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req)
goto out;
}
+ volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_store_update_volume (volinfo);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 18b0b1aa5..c12a11a8f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -306,6 +306,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
glusterd_friend_sm_event_t *new_event = NULL;
glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
int status = 0;
+ int32_t op_ret = -1;
GF_ASSERT (ctx);
ev_ctx = ctx;
@@ -315,11 +316,18 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
uuid_copy (peerinfo->uuid, ev_ctx->uuid);
//Build comparison logic here.
+ ret = glusterd_compare_friend_data (ev_ctx->vols, &status);
+ if (ret)
+ goto out;
- if (!status)
+ if (GLUSTERD_VOL_COMP_RJT != status) {
event_type = GD_FRIEND_EVENT_LOCAL_ACC;
- else
+ op_ret = 0;
+ }
+ else {
event_type = GD_FRIEND_EVENT_LOCAL_RJT;
+ op_ret = -1;
+ }
ret = glusterd_friend_sm_new_event (event_type, &new_event);
@@ -344,7 +352,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
glusterd_friend_sm_inject_event (new_event);
ret = glusterd_xfer_friend_add_resp (ev_ctx->req, ev_ctx->hostname,
- ev_ctx->port);
+ ev_ctx->port, op_ret);
out:
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
@@ -408,7 +416,7 @@ glusterd_sm_t glusterd_state_req_rcvd [] = {
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_ACC
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
+ {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCV_FRIEND_REQ
{GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
{GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
index 65cf6dc89..6490f3d52 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.h
@@ -124,6 +124,7 @@ typedef struct glusterd_friend_req_ctx_ {
char *hostname;
rpcsvc_request_t *req;
int port;
+ dict_t *vols;
} glusterd_friend_req_ctx_t;
typedef glusterd_friend_req_ctx_t glusterd_friend_update_ctx_t;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 2cee89516..ee47696da 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -134,9 +134,9 @@ glusterd_store_create_brick (glusterd_volinfo_t *volinfo,
snprintf (buf, sizeof(buf), "hostname=%s\n", brickinfo->hostname);
- write (fd, buf, strlen(buf));
+ ret = write (fd, buf, strlen(buf));
snprintf (buf, sizeof(buf), "path=%s\n", brickinfo->path);
- write (fd, buf, strlen(buf));
+ ret = write (fd, buf, strlen(buf));
ret = 0;
@@ -293,18 +293,24 @@ glusterd_store_create_volume (glusterd_volinfo_t *volinfo)
if (ret)
goto out;
- snprintf (buf, sizeof (buf), "%d", volinfo->status);
+/* snprintf (buf, sizeof (buf), "%d", volinfo->port);
ret = glusterd_store_save_value (volinfo->shandle,
GLUSTERD_STORE_KEY_VOL_PORT, buf);
if (ret)
goto out;
-
+*/
snprintf (buf, sizeof (buf), "%d", volinfo->sub_count);
ret = glusterd_store_save_value (volinfo->shandle,
GLUSTERD_STORE_KEY_VOL_SUB_COUNT, buf);
if (ret)
goto out;
+ snprintf (buf, sizeof (buf), "%d", volinfo->version);
+ ret = glusterd_store_save_value (volinfo->shandle,
+ GLUSTERD_STORE_KEY_VOL_VERSION, buf);
+ if (ret)
+ goto out;
+
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
ret = glusterd_store_create_brick (volinfo, brickinfo);
if (ret)
@@ -328,7 +334,7 @@ int32_t
glusterd_store_delete_volume (glusterd_volinfo_t *volinfo)
{
char pathname[PATH_MAX] = {0,};
- int32_t ret = -1;
+ int32_t ret = 0;
glusterd_conf_t *priv = NULL;
DIR *dir = NULL;
struct dirent *entry = NULL;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index 1889e5f58..10fb4a3af 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -46,6 +46,7 @@
#define GLUSTERD_STORE_KEY_VOL_PORT "port"
#define GLUSTERD_STORE_KEY_VOL_SUB_COUNT "sub_count"
#define GLUSTERD_STORE_KEY_VOL_BRICK "brick"
+#define GLUSTERD_STORE_KEY_VOL_VERSION "version"
#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname"
#define GLUSTERD_STORE_KEY_BRICK_PATH "path"
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 35dfa3dfb..f0115c05b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -927,3 +927,491 @@ glusterd_is_cli_op_req (int32_t op)
return _gf_false;
}
+
+
+int
+glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
+{
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ char path[PATH_MAX] = {0,};
+ char cksum_path[PATH_MAX] = {0,};
+ char filepath[PATH_MAX] = {0,};
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+ int fd = -1;
+ uint32_t cksum = 0;
+ char buf[4096] = {0,};
+
+ GF_ASSERT (volinfo);
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+
+ snprintf (cksum_path, sizeof (cksum_path), "%s/%s",
+ path, GLUSTERD_CKSUM_FILE);
+
+ fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT, 0644);
+
+ if (-1 == fd) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ cksum_path, errno);
+ ret = -1;
+ goto out;
+ }
+
+
+ dir = opendir (path);
+
+ glusterd_for_each_entry (entry, dir);
+
+/* while (entry) {
+
+ snprintf (filepath, sizeof (filepath), "%s/%s", path,
+ entry->d_name);
+
+ if (!strcmp (entry->d_name, "bricks") ||
+ !strcmp (entry->d_name, "run")) {
+ glusterd_for_each_entry (entry, dir);
+ continue;
+ }
+
+ ret = get_checksum_for_path (filepath, &cksum);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get checksum"
+ " for path: %s", filepath);
+ goto out;
+ }
+
+ snprintf (buf, sizeof (buf), "%s=%u\n", entry->d_name, cksum);
+ ret = write (fd, buf, strlen (buf));
+
+ if (ret <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ glusterd_for_each_entry (entry, dir);
+ }
+*/
+
+ snprintf (filepath, sizeof (filepath), "%s/%s", path,
+ GLUSTERD_VOLUME_INFO_FILE);
+
+ ret = get_checksum_for_path (filepath, &cksum);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get checksum"
+ " for path: %s", filepath);
+ goto out;
+ }
+
+ snprintf (buf, sizeof (buf), "%s=%u\n", "info", cksum);
+ ret = write (fd, buf, strlen (buf));
+
+ if (ret <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = get_checksum_for_file (fd, &cksum);
+
+ if (ret)
+ goto out;
+
+ volinfo->cksum = cksum;
+
+out:
+ if (fd > 0)
+ close (fd);
+
+ if (dir)
+ closedir (dir);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+
+ return ret;
+}
+
+int32_t
+glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
+ dict_t *dict, int32_t count)
+{
+ int32_t ret = -1;
+ char key[512] = {0,};
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t i = 1;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (volinfo);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_set_str (dict, key, volinfo->volname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.type", count);
+ ret = dict_set_int32 (dict, key, volinfo->type);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick_count", count);
+ ret = dict_set_int32 (dict, key, volinfo->brick_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_set_int32 (dict, key, volinfo->version);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.status", count);
+ ret = dict_set_int32 (dict, key, volinfo->status);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.sub_count", count);
+ ret = dict_set_int32 (dict, key, volinfo->sub_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_set_int64 (dict, key, volinfo->cksum);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
+ count, i);
+ ret = dict_set_str (dict, key, brickinfo->hostname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.path",
+ count, i);
+ ret = dict_set_str (dict, key, brickinfo->path);
+ if (ret)
+ goto out;
+
+ i++;
+ }
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+
+ return ret;
+}
+
+int32_t
+glusterd_build_volume_dict (dict_t **vols)
+{
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int32_t count = 0;
+
+ priv = THIS->private;
+
+ dict = dict_new ();
+
+ if (!dict)
+ goto out;
+
+ list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+ count++;
+ ret = glusterd_add_volume_to_dict (volinfo, dict, count);
+ if (ret)
+ goto out;
+ }
+
+
+ ret = dict_set_int32 (dict, "count", count);
+ if (ret)
+ goto out;
+
+ *vols = dict;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ if (ret)
+ dict_destroy (dict);
+
+ return ret;
+}
+
+int32_t
+glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status)
+{
+
+ int32_t ret = -1;
+ char key[512] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ uint32_t cksum = 0;
+ int32_t version = 0;
+
+ GF_ASSERT (vols);
+ GF_ASSERT (status);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_get_str (vols, key, &volname);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
+ ret = 0;
+ goto out;
+ }
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_get_int32 (vols, key, &version);
+ if (ret)
+ goto out;
+
+ if (version != volinfo->version) {
+ //Mismatch detected
+ ret = 0;
+ gf_log ("", GF_LOG_ERROR, "Version of volume %s differ."
+ "local version = %d, remote version = %d",
+ volinfo->volname, volinfo->version, version);
+ *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
+ goto out;
+ }
+
+ //Now, versions are same, compare cksums.
+ //
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_get_uint32 (vols, key, &cksum);
+ if (ret)
+ goto out;
+
+ if (cksum != volinfo->cksum) {
+ ret = 0;
+ gf_log ("", GF_LOG_ERROR, "Cksums of volume %s differ."
+ " local cksum = %d, remote cksum = %d",
+ volinfo->volname, volinfo->cksum, cksum);
+ *status = GLUSTERD_VOL_COMP_RJT;
+ goto out;
+ }
+
+ *status = GLUSTERD_VOL_COMP_SCS;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
+ ret, *status);
+ return ret;
+}
+
+int32_t
+glusterd_import_friend_volume (dict_t *vols, int count)
+{
+
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ char key[512] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_brickinfo_t *tmp = NULL;
+ int new_volinfo = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_get_str (vols, key, &volname);
+ if (ret)
+ goto out;
+
+ priv = THIS->private;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ ret = glusterd_volinfo_new (&volinfo);
+ if (ret)
+ goto out;
+ strncpy (volinfo->volname, volname, sizeof (volinfo->volname));
+ new_volinfo = 1;
+ }
+
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.type", count);
+ ret = dict_get_int32 (vols, key, &volinfo->type);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick_count", count);
+ ret = dict_get_int32 (vols, key, &volinfo->brick_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_get_int32 (vols, key, &volinfo->version);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.status", count);
+ ret = dict_get_int32 (vols, key, (int32_t *)&volinfo->status);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.sub_count", count);
+ ret = dict_get_int32 (vols, key, &volinfo->sub_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_get_uint32 (vols, key, &volinfo->cksum);
+ if (ret)
+ goto out;
+
+ list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
+ brick_list) {
+ ret = glusterd_brickinfo_delete (brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ while (i <= volinfo->brick_count) {
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
+ count, i);
+ ret = dict_get_str (vols, key, &hostname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.path",
+ count, i);
+ ret = dict_get_str (vols, key, &path);
+ if (ret)
+ goto out;
+
+ ret = glusterd_brickinfo_new (&brickinfo);
+ if (ret)
+ goto out;
+
+ strcpy (brickinfo->path, path);
+ strcpy (brickinfo->hostname, hostname);
+
+ list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
+
+ i++;
+ }
+
+ if (new_volinfo) {
+ list_add_tail (&volinfo->vol_list, &priv->volumes);
+ ret = glusterd_store_create_volume (volinfo);
+ } else {
+ ret = glusterd_store_update_volume (volinfo);
+ }
+
+ ret = glusterd_volume_create_generate_volfiles (volinfo);
+ if (ret)
+ goto out;
+
+ //volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d", ret);
+ return ret;
+}
+
+
+int32_t
+glusterd_import_friend_volumes (dict_t *vols)
+{
+ int32_t ret = -1;
+ int32_t count = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+
+ ret = dict_get_int32 (vols, "count", &count);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+ ret = glusterd_import_friend_volume (vols, i);
+ if (ret)
+ goto out;
+
+ i++;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_compare_friend_data (dict_t *vols, int32_t *status)
+{
+ int32_t ret = -1;
+ int32_t count = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+ GF_ASSERT (status);
+
+ ret = dict_get_int32 (vols, "count", &count);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+ ret = glusterd_compare_friend_volume (vols, i, status);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_VOL_COMP_RJT == *status) {
+ ret = 0;
+ goto out;
+ }
+
+ i++;
+ }
+
+ if (GLUSTERD_VOL_COMP_UPDATE_REQ == *status) {
+ ret = glusterd_import_friend_volumes (vols);
+ if (ret)
+ goto out;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
+ ret, *status);
+
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 892533c40..1e9469ce0 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -117,4 +117,16 @@ glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t **brickinfo);
int32_t
glusterd_is_local_addr (char *hostname);
+
+int32_t
+glusterd_build_volume_dict (dict_t **vols);
+
+int32_t
+glusterd_compare_friend_data (dict_t *vols, int32_t *status);
+
+int
+glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo);
+
+int
+glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index cc1fb7786..4465ee316 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -127,6 +127,9 @@ struct glusterd_volinfo_ {
uint64_t rebalance_data;
uint64_t lookedup_files;
glusterd_defrag_info_t *defrag;
+
+ int version;
+ uint32_t cksum;
};
typedef struct glusterd_volinfo_ glusterd_volinfo_t;
@@ -135,6 +138,13 @@ enum glusterd_op_ret {
GLUSTERD_CONNECTION_AWAITED = 100,
};
+enum glusterd_vol_comp_status_ {
+ GLUSTERD_VOL_COMP_NONE = 0,
+ GLUSTERD_VOL_COMP_SCS = 1,
+ GLUSTERD_VOL_COMP_UPDATE_REQ,
+ GLUSTERD_VOL_COMP_RJT,
+};
+
#define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd"
#define GLUSTERD_DEFAULT_PORT 6969
#define GLUSTERD_INFO_FILE "glusterd.info"
@@ -142,6 +152,7 @@ enum glusterd_op_ret {
#define GLUSTERD_PEER_DIR_PREFIX "peers"
#define GLUSTERD_VOLUME_INFO_FILE "info"
#define GLUSTERD_BRICK_INFO_DIR "bricks"
+#define GLUSTERD_CKSUM_FILE "cksum"
/*All definitions related to replace brick */
#define RB_PUMP_START_CMD "trusted.glusterfs.pump.start"
@@ -173,7 +184,8 @@ int
glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port);
int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port);
+glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname,
+ int port, int32_t op_ret);
int
glusterd_friend_find (uuid_t uuid, char *hostname,
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index 2c5cb8f33..5196055b3 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -639,6 +639,7 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,
glusterd_conf_t *priv = NULL;
glusterd_friend_sm_event_t *event = NULL;
glusterd_friend_req_ctx_t *ctx = NULL;
+ dict_t *vols = NULL;
if (!frame || !this || !data) {
@@ -655,15 +656,32 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,
peerinfo = event->peerinfo;
+ ret = glusterd_build_volume_dict (&vols);
+ if (ret)
+ goto out;
+
uuid_copy (req.uuid, priv->uuid);
req.hostname = gf_strdup (peerinfo->hostname);
req.port = peerinfo->port;
+
+ ret = dict_allocate_and_serialize (vols, &req.vols.vols_val,
+ (size_t *)&req.vols.vols_len);
+ if (ret)
+ goto out;
+
ret = glusterd_submit_request (peerinfo, &req, frame, priv->mgmt,
GD_MGMT_FRIEND_ADD,
NULL, gd_xdr_from_mgmt_friend_req,
this, glusterd3_1_friend_add_cbk);
+
out:
+ if (req.vols.vols_val)
+ GF_FREE (req.vols.vols_val);
+
+ if (vols)
+ dict_destroy (vols);
+
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}