From df4a7d75765b042ddbda4cbcd419743a37767ec3 Mon Sep 17 00:00:00 2001 From: Vijay Bellur Date: Mon, 23 Aug 2010 03:51:21 +0000 Subject: glusterd: support for volume version and cksum Signed-off-by: Vijay Bellur Signed-off-by: Anand V. Avati BUG: 1310 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1310 --- libglusterfs/src/common-utils.c | 414 ++++++++++++----------- libglusterfs/src/common-utils.h | 1 + rpc/xdr/src/glusterd1-xdr.c | 10 +- rpc/xdr/src/glusterd1-xdr.h | 20 +- rpc/xdr/src/glusterd1.x | 8 + xlators/mgmt/glusterd/src/glusterd-handler.c | 32 +- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 19 +- xlators/mgmt/glusterd/src/glusterd-sm.c | 16 +- xlators/mgmt/glusterd/src/glusterd-sm.h | 1 + xlators/mgmt/glusterd/src/glusterd-store.c | 16 +- xlators/mgmt/glusterd/src/glusterd-store.h | 1 + xlators/mgmt/glusterd/src/glusterd-utils.c | 488 +++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-utils.h | 12 + xlators/mgmt/glusterd/src/glusterd.h | 14 +- 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 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 +#include #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; } -- cgit