diff options
| author | Vijay Bellur <vijay@gluster.com> | 2010-08-23 03:51:21 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-08-23 02:53:16 -0700 | 
| commit | df4a7d75765b042ddbda4cbcd419743a37767ec3 (patch) | |
| tree | 4a04c3720ad869869deb3d7d42c63252b2d7772a | |
| parent | 39dc05e370286a62428a94e3e7666e2eedaea941 (diff) | |
glusterd: support for volume version and cksumv3.1.0qa8
Signed-off-by: Vijay Bellur <vijay@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1310 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1310
| -rw-r--r-- | libglusterfs/src/common-utils.c | 414 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 1 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterd1-xdr.c | 10 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterd1-xdr.h | 20 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterd1.x | 8 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 32 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 19 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 16 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 16 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 488 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 12 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 14 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 18 | 
15 files changed, 847 insertions, 223 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index eef865ec500..f3386fe2b62 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 93d62f6cbc3..54f52a5a0b1 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 c7b83b9d575..82d9830c97f 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 4125d7b1259..7b208ee5f11 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 28e6de01f82..19fa7af688b 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 7e9a82e306a..00162e913ea 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 b243e78951b..3b4b390d144 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 18b0b1aa5eb..c12a11a8fb2 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 65cf6dc8905..6490f3d526d 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 2cee89516db..ee47696da96 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 1889e5f58bd..10fb4a3af01 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 35dfa3dfba3..f0115c05b19 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 892533c40a6..1e9469ce0fd 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 cc1fb7786bd..4465ee316dd 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 2c5cb8f33ab..5196055b3e1 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;  }  | 
