File: | xlators/cluster/dht/src/dht-rebalance.c |
Location: | line 982, column 13 |
Description: | Access to field 'sock_file' results in a dereference of a null pointer (loaded from variable 'cmd_args') |
1 | /* | |||
2 | Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> | |||
3 | This file is part of GlusterFS. | |||
4 | ||||
5 | This file is licensed to you under your choice of the GNU Lesser | |||
6 | General Public License, version 3 or any later version (LGPLv3 or | |||
7 | later), or the GNU General Public License, version 2 (GPLv2), in all | |||
8 | cases as published by the Free Software Foundation. | |||
9 | */ | |||
10 | ||||
11 | ||||
12 | #ifndef _CONFIG_H | |||
13 | #define _CONFIG_H | |||
14 | #include "config.h" | |||
15 | #endif | |||
16 | ||||
17 | #include "dht-common.h" | |||
18 | #include "xlator.h" | |||
19 | #include <fnmatch.h> | |||
20 | ||||
21 | #define GF_DISK_SECTOR_SIZE512 512 | |||
22 | #define DHT_REBALANCE_PID4242 4242 /* Change it if required */ | |||
23 | #define DHT_REBALANCE_BLKSIZE(128 * 1024) (128 * 1024) | |||
24 | ||||
25 | static int | |||
26 | dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count, | |||
27 | int32_t size, off_t offset, struct iobref *iobref) | |||
28 | { | |||
29 | int i = 0; | |||
30 | int ret = -1; | |||
31 | int start_idx = 0; | |||
32 | int tmp_offset = 0; | |||
33 | int write_needed = 0; | |||
34 | int buf_len = 0; | |||
35 | int size_pending = 0; | |||
36 | char *buf = NULL((void*)0); | |||
37 | ||||
38 | /* loop through each vector */ | |||
39 | for (i = 0; i < count; i++) { | |||
40 | buf = vec[i].iov_base; | |||
41 | buf_len = vec[i].iov_len; | |||
42 | ||||
43 | for (start_idx = 0; (start_idx + GF_DISK_SECTOR_SIZE512) <= buf_len; | |||
44 | start_idx += GF_DISK_SECTOR_SIZE512) { | |||
45 | ||||
46 | if (mem_0filled (buf + start_idx, GF_DISK_SECTOR_SIZE512) != 0) { | |||
47 | write_needed = 1; | |||
48 | continue; | |||
49 | } | |||
50 | ||||
51 | if (write_needed) { | |||
52 | ret = syncop_write (to, fd, (buf + tmp_offset), | |||
53 | (start_idx - tmp_offset), | |||
54 | (offset + tmp_offset), | |||
55 | iobref, 0); | |||
56 | /* 'path' will be logged in calling function */ | |||
57 | if (ret < 0) { | |||
58 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 60, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0) | |||
59 | "failed to write (%s)",do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 60, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0) | |||
60 | strerror (errno))do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 60, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0); | |||
61 | goto out; | |||
62 | } | |||
63 | ||||
64 | write_needed = 0; | |||
65 | } | |||
66 | tmp_offset = start_idx + GF_DISK_SECTOR_SIZE512; | |||
67 | } | |||
68 | ||||
69 | if ((start_idx < buf_len) || write_needed) { | |||
70 | /* This means, last chunk is not yet written.. write it */ | |||
71 | ret = syncop_write (to, fd, (buf + tmp_offset), | |||
72 | (buf_len - tmp_offset), | |||
73 | (offset + tmp_offset), iobref, 0); | |||
74 | if (ret < 0) { | |||
75 | /* 'path' will be logged in calling function */ | |||
76 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 78, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0) | |||
77 | "failed to write (%s)",do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 78, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0) | |||
78 | strerror (errno))do { do { if (0) printf ("failed to write (%s)", strerror ((* __errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 78, GF_LOG_WARNING , "failed to write (%s)", strerror ((*__errno_location ()))); } while (0); | |||
79 | goto out; | |||
80 | } | |||
81 | } | |||
82 | ||||
83 | size_pending = (size - buf_len); | |||
84 | if (!size_pending) | |||
85 | break; | |||
86 | } | |||
87 | ||||
88 | ret = size; | |||
89 | out: | |||
90 | return ret; | |||
91 | ||||
92 | } | |||
93 | ||||
94 | int32_t | |||
95 | gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs, | |||
96 | struct iatt *stbuf) | |||
97 | { | |||
98 | int32_t ret = -1; | |||
99 | xlator_t *cached_subvol = NULL((void*)0); | |||
100 | xlator_t *hashed_subvol = NULL((void*)0); | |||
101 | xlator_t *linkto_subvol = NULL((void*)0); | |||
102 | data_t *data = NULL((void*)0); | |||
103 | struct iatt iatt = {0,}; | |||
104 | int32_t op_errno = 0; | |||
105 | dht_conf_t *conf = NULL((void*)0); | |||
106 | ||||
107 | GF_VALIDATE_OR_GOTO ("defrag", loc, out)do { if (!loc) { (*__errno_location ()) = 22; do { do { if (0 ) printf ("invalid argument: " "loc"); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c", __FUNCTION__, 107, GF_LOG_ERROR , "invalid argument: " "loc"); } while (0); goto out; } } while (0); | |||
108 | GF_VALIDATE_OR_GOTO ("defrag", loc->name, out)do { if (!loc->name) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "loc->name"); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c", __FUNCTION__ , 108, GF_LOG_ERROR, "invalid argument: " "loc->name"); } while (0); goto out; } } while (0); | |||
109 | GF_VALIDATE_OR_GOTO ("defrag", stbuf, out)do { if (!stbuf) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "stbuf"); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c", __FUNCTION__, 109, GF_LOG_ERROR , "invalid argument: " "stbuf"); } while (0); goto out; } } while (0); | |||
110 | GF_VALIDATE_OR_GOTO ("defrag", this, out)do { if (!this) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c", __FUNCTION__, 110, GF_LOG_ERROR , "invalid argument: " "this"); } while (0); goto out; } } while (0); | |||
111 | GF_VALIDATE_OR_GOTO ("defrag", xattrs, out)do { if (!xattrs) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "xattrs"); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c", __FUNCTION__, 111, GF_LOG_ERROR , "invalid argument: " "xattrs"); } while (0); goto out; } } while (0); | |||
112 | GF_VALIDATE_OR_GOTO ("defrag", this->private, out)do { if (!this->private) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "this->private" ); } while (0); _gf_log_callingfn ("defrag", "dht-rebalance.c" , __FUNCTION__, 112, GF_LOG_ERROR, "invalid argument: " "this->private" ); } while (0); goto out; } } while (0); | |||
113 | ||||
114 | conf = this->private; | |||
115 | ||||
116 | if (uuid_is_null (loc->pargfid)) { | |||
117 | gf_log ("", GF_LOG_ERROR, "loc->pargfid is NULL for "do { do { if (0) printf ("loc->pargfid is NULL for " "%s", loc->path); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__ , 118, GF_LOG_ERROR, "loc->pargfid is NULL for " "%s", loc ->path); } while (0) | |||
118 | "%s", loc->path)do { do { if (0) printf ("loc->pargfid is NULL for " "%s", loc->path); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__ , 118, GF_LOG_ERROR, "loc->pargfid is NULL for " "%s", loc ->path); } while (0); | |||
119 | goto out; | |||
120 | } | |||
121 | ||||
122 | if (uuid_is_null (loc->gfid)) { | |||
123 | gf_log ("", GF_LOG_ERROR, "loc->gfid is NULL for "do { do { if (0) printf ("loc->gfid is NULL for " "%s", loc ->path); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__ , 124, GF_LOG_ERROR, "loc->gfid is NULL for " "%s", loc-> path); } while (0) | |||
124 | "%s", loc->path)do { do { if (0) printf ("loc->gfid is NULL for " "%s", loc ->path); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__ , 124, GF_LOG_ERROR, "loc->gfid is NULL for " "%s", loc-> path); } while (0); | |||
125 | goto out; | |||
126 | } | |||
127 | ||||
128 | cached_subvol = dht_subvol_get_cached (this, loc->inode); | |||
129 | if (!cached_subvol) { | |||
130 | gf_log (this->name, GF_LOG_ERROR, "Failed to get cached subvol"do { do { if (0) printf ("Failed to get cached subvol" " for %s on %s" , loc->name, this->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 131, GF_LOG_ERROR, "Failed to get cached subvol" " for %s on %s", loc->name, this->name); } while (0) | |||
131 | " for %s on %s", loc->name, this->name)do { do { if (0) printf ("Failed to get cached subvol" " for %s on %s" , loc->name, this->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 131, GF_LOG_ERROR, "Failed to get cached subvol" " for %s on %s", loc->name, this->name); } while (0); | |||
132 | goto out; | |||
133 | } | |||
134 | ||||
135 | hashed_subvol = dht_subvol_get_hashed (this, loc); | |||
136 | if (!hashed_subvol) { | |||
137 | gf_log (this->name, GF_LOG_ERROR, "Failed to get hashed subvol"do { do { if (0) printf ("Failed to get hashed subvol" " for %s on %s" , loc->name, this->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 138, GF_LOG_ERROR, "Failed to get hashed subvol" " for %s on %s", loc->name, this->name); } while (0) | |||
138 | " for %s on %s", loc->name, this->name)do { do { if (0) printf ("Failed to get hashed subvol" " for %s on %s" , loc->name, this->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 138, GF_LOG_ERROR, "Failed to get hashed subvol" " for %s on %s", loc->name, this->name); } while (0); | |||
139 | goto out; | |||
140 | } | |||
141 | ||||
142 | gf_log (this->name, GF_LOG_INFO, "Attempting to migrate hardlink %s "do { do { if (0) printf ("Attempting to migrate hardlink %s " "with gfid %s from %s -> %s", loc->name, uuid_utoa (loc ->gfid), cached_subvol->name, hashed_subvol->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 144, GF_LOG_INFO, "Attempting to migrate hardlink %s " "with gfid %s from %s -> %s" , loc->name, uuid_utoa (loc->gfid), cached_subvol->name , hashed_subvol->name); } while (0) | |||
143 | "with gfid %s from %s -> %s", loc->name, uuid_utoa (loc->gfid),do { do { if (0) printf ("Attempting to migrate hardlink %s " "with gfid %s from %s -> %s", loc->name, uuid_utoa (loc ->gfid), cached_subvol->name, hashed_subvol->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 144, GF_LOG_INFO, "Attempting to migrate hardlink %s " "with gfid %s from %s -> %s" , loc->name, uuid_utoa (loc->gfid), cached_subvol->name , hashed_subvol->name); } while (0) | |||
144 | cached_subvol->name, hashed_subvol->name)do { do { if (0) printf ("Attempting to migrate hardlink %s " "with gfid %s from %s -> %s", loc->name, uuid_utoa (loc ->gfid), cached_subvol->name, hashed_subvol->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 144, GF_LOG_INFO, "Attempting to migrate hardlink %s " "with gfid %s from %s -> %s" , loc->name, uuid_utoa (loc->gfid), cached_subvol->name , hashed_subvol->name); } while (0); | |||
145 | data = dict_get (xattrs, conf->link_xattr_name); | |||
146 | /* set linkto on cached -> hashed if not present, else link it */ | |||
147 | if (!data) { | |||
148 | ret = dict_set_str (xattrs, conf->link_xattr_name, | |||
149 | hashed_subvol->name); | |||
150 | if (ret) { | |||
151 | gf_log (this->name, GF_LOG_ERROR, "Failed to set "do { do { if (0) printf ("Failed to set " "linkto xattr in dict for %s" , loc->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 152, GF_LOG_ERROR, "Failed to set " "linkto xattr in dict for %s" , loc->name); } while (0) | |||
152 | "linkto xattr in dict for %s", loc->name)do { do { if (0) printf ("Failed to set " "linkto xattr in dict for %s" , loc->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 152, GF_LOG_ERROR, "Failed to set " "linkto xattr in dict for %s" , loc->name); } while (0); | |||
153 | goto out; | |||
154 | } | |||
155 | ||||
156 | ret = syncop_setxattr (cached_subvol, loc, xattrs, 0); | |||
157 | if (ret) { | |||
158 | gf_log (this->name, GF_LOG_ERROR, "Linkto setxattr "do { do { if (0) printf ("Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 160, GF_LOG_ERROR, "Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0) | |||
159 | "failed %s -> %s (%s)", cached_subvol->name,do { do { if (0) printf ("Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 160, GF_LOG_ERROR, "Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0) | |||
160 | loc->name, strerror (errno))do { do { if (0) printf ("Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 160, GF_LOG_ERROR, "Linkto setxattr " "failed %s -> %s (%s)" , cached_subvol->name, loc->name, strerror ((*__errno_location ()))); } while (0); | |||
161 | goto out; | |||
162 | } | |||
163 | goto out; | |||
164 | } else { | |||
165 | linkto_subvol = dht_linkfile_subvol (this, NULL((void*)0), NULL((void*)0), xattrs); | |||
166 | if (!linkto_subvol) { | |||
167 | gf_log (this->name, GF_LOG_ERROR, "Failed to get "do { do { if (0) printf ("Failed to get " "linkto subvol for %s" , loc->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 168, GF_LOG_ERROR, "Failed to get " "linkto subvol for %s" , loc->name); } while (0) | |||
168 | "linkto subvol for %s", loc->name)do { do { if (0) printf ("Failed to get " "linkto subvol for %s" , loc->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 168, GF_LOG_ERROR, "Failed to get " "linkto subvol for %s" , loc->name); } while (0); | |||
169 | } else { | |||
170 | hashed_subvol = linkto_subvol; | |||
171 | } | |||
172 | ||||
173 | ret = syncop_link (hashed_subvol, loc, loc); | |||
174 | if (ret) { | |||
175 | op_errno = errno(*__errno_location ()); | |||
176 | gf_log (this->name, GF_LOG_ERROR, "link of %s -> %s"do { do { if (0) printf ("link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 179, GF_LOG_ERROR, "link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0) | |||
177 | " failed on subvol %s (%s)", loc->name,do { do { if (0) printf ("link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 179, GF_LOG_ERROR, "link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0) | |||
178 | uuid_utoa(loc->gfid),do { do { if (0) printf ("link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 179, GF_LOG_ERROR, "link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0) | |||
179 | hashed_subvol->name, strerror (op_errno))do { do { if (0) printf ("link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 179, GF_LOG_ERROR, "link of %s -> %s" " failed on subvol %s (%s)" , loc->name, uuid_utoa(loc->gfid), hashed_subvol->name , strerror (op_errno)); } while (0); | |||
180 | if (op_errno != EEXIST17) | |||
181 | goto out; | |||
182 | } | |||
183 | } | |||
184 | ret = syncop_lookup (hashed_subvol, loc, NULL((void*)0), &iatt, NULL((void*)0), NULL((void*)0)); | |||
185 | if (ret) { | |||
186 | gf_log (this->name, GF_LOG_ERROR, "Failed lookup %s on %s (%s)"do { do { if (0) printf ("Failed lookup %s on %s (%s)" , loc-> name, hashed_subvol->name, strerror ((*__errno_location () ))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 187, GF_LOG_ERROR, "Failed lookup %s on %s (%s)" , loc-> name, hashed_subvol->name, strerror ((*__errno_location () ))); } while (0) | |||
187 | , loc->name, hashed_subvol->name, strerror (errno))do { do { if (0) printf ("Failed lookup %s on %s (%s)" , loc-> name, hashed_subvol->name, strerror ((*__errno_location () ))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 187, GF_LOG_ERROR, "Failed lookup %s on %s (%s)" , loc-> name, hashed_subvol->name, strerror ((*__errno_location () ))); } while (0); | |||
188 | goto out; | |||
189 | } | |||
190 | ||||
191 | if (iatt.ia_nlink == stbuf->ia_nlink) { | |||
192 | ret = dht_migrate_file (this, loc, cached_subvol, hashed_subvol, | |||
193 | GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS); | |||
194 | if (ret) | |||
195 | goto out; | |||
196 | } | |||
197 | ret = 0; | |||
198 | out: | |||
199 | return ret; | |||
200 | } | |||
201 | ||||
202 | ||||
203 | static inline int | |||
204 | __is_file_migratable (xlator_t *this, loc_t *loc, | |||
205 | struct iatt *stbuf, dict_t *xattrs, int flags) | |||
206 | { | |||
207 | int ret = -1; | |||
208 | ||||
209 | if (IA_ISDIR (stbuf->ia_type)(stbuf->ia_type == IA_IFDIR)) { | |||
210 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: migrate-file called on directory" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 211, GF_LOG_WARNING, "%s: migrate-file called on directory" , loc->path); } while (0) | |||
211 | "%s: migrate-file called on directory", loc->path)do { do { if (0) printf ("%s: migrate-file called on directory" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 211, GF_LOG_WARNING, "%s: migrate-file called on directory" , loc->path); } while (0); | |||
212 | ret = -1; | |||
213 | goto out; | |||
214 | } | |||
215 | ||||
216 | if (flags == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS) { | |||
217 | ret = 0; | |||
218 | goto out; | |||
219 | } | |||
220 | if (stbuf->ia_nlink > 1) { | |||
221 | /* support for decomission */ | |||
222 | if (flags == GF_DHT_MIGRATE_HARDLINK) { | |||
223 | ret = gf_defrag_handle_hardlink (this, loc, | |||
224 | xattrs, stbuf); | |||
225 | if (ret) { | |||
226 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to migrate file with link" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 228, GF_LOG_WARNING, "%s: failed to migrate file with link" , loc->path); } while (0) | |||
227 | "%s: failed to migrate file with link",do { do { if (0) printf ("%s: failed to migrate file with link" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 228, GF_LOG_WARNING, "%s: failed to migrate file with link" , loc->path); } while (0) | |||
228 | loc->path)do { do { if (0) printf ("%s: failed to migrate file with link" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 228, GF_LOG_WARNING, "%s: failed to migrate file with link" , loc->path); } while (0); | |||
229 | } | |||
230 | } else { | |||
231 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: file has hardlinks", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 232, GF_LOG_WARNING, "%s: file has hardlinks", loc->path ); } while (0) | |||
232 | "%s: file has hardlinks", loc->path)do { do { if (0) printf ("%s: file has hardlinks", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 232, GF_LOG_WARNING, "%s: file has hardlinks", loc->path ); } while (0); | |||
233 | } | |||
234 | ret = ENOTSUP95; | |||
235 | goto out; | |||
236 | } | |||
237 | ||||
238 | ret = 0; | |||
239 | ||||
240 | out: | |||
241 | return ret; | |||
242 | } | |||
243 | ||||
244 | static inline int | |||
245 | __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf, | |||
246 | dict_t *dict, fd_t **dst_fd) | |||
247 | { | |||
248 | xlator_t *this = NULL((void*)0); | |||
249 | int ret = -1; | |||
250 | fd_t *fd = NULL((void*)0); | |||
251 | struct iatt new_stbuf = {0,}; | |||
252 | dht_conf_t *conf = NULL((void*)0); | |||
253 | ||||
254 | this = THIS(*__glusterfs_this_location()); | |||
255 | conf = this->private; | |||
256 | ||||
257 | ret = dict_set_static_bin (dict, "gfid-req", stbuf->ia_gfid, 16); | |||
258 | if (ret) { | |||
259 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 260, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0) | |||
260 | "%s: failed to set gfid in dict for create", loc->path)do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 260, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0); | |||
261 | goto out; | |||
262 | } | |||
263 | ||||
264 | ret = dict_set_str (dict, conf->link_xattr_name, from->name); | |||
265 | if (ret) { | |||
266 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 267, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0) | |||
267 | "%s: failed to set gfid in dict for create", loc->path)do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 267, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0); | |||
268 | goto out; | |||
269 | } | |||
270 | ||||
271 | fd = fd_create (loc->inode, DHT_REBALANCE_PID4242); | |||
272 | if (!fd) { | |||
273 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: fd create failed (destination) (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 275 , GF_LOG_ERROR, "%s: fd create failed (destination) (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0) | |||
274 | "%s: fd create failed (destination) (%s)",do { do { if (0) printf ("%s: fd create failed (destination) (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 275 , GF_LOG_ERROR, "%s: fd create failed (destination) (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0) | |||
275 | loc->path, strerror (errno))do { do { if (0) printf ("%s: fd create failed (destination) (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 275 , GF_LOG_ERROR, "%s: fd create failed (destination) (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); | |||
276 | ret = -1; | |||
277 | goto out; | |||
278 | } | |||
279 | ||||
280 | ret = syncop_lookup (to, loc, NULL((void*)0), &new_stbuf, NULL((void*)0), NULL((void*)0)); | |||
281 | if (!ret) { | |||
282 | /* File exits in the destination, check if gfid matches */ | |||
283 | if (uuid_compare (stbuf->ia_gfid, new_stbuf.ia_gfid) != 0) { | |||
284 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("file %s exits in %s with different gfid" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 286, GF_LOG_ERROR, "file %s exits in %s with different gfid" , loc->path, to->name); } while (0) | |||
285 | "file %s exits in %s with different gfid",do { do { if (0) printf ("file %s exits in %s with different gfid" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 286, GF_LOG_ERROR, "file %s exits in %s with different gfid" , loc->path, to->name); } while (0) | |||
286 | loc->path, to->name)do { do { if (0) printf ("file %s exits in %s with different gfid" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 286, GF_LOG_ERROR, "file %s exits in %s with different gfid" , loc->path, to->name); } while (0); | |||
287 | fd_unref (fd); | |||
288 | goto out; | |||
289 | } | |||
290 | } | |||
291 | if ((ret == -1) && (errno(*__errno_location ()) != ENOENT2)) { | |||
292 | /* File exists in destination, but not accessible */ | |||
293 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to lookup file (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c", __FUNCTION__, 295, GF_LOG_WARNING, "%s: failed to lookup file (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
294 | "%s: failed to lookup file (%s)",do { do { if (0) printf ("%s: failed to lookup file (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c", __FUNCTION__, 295, GF_LOG_WARNING, "%s: failed to lookup file (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
295 | loc->path, strerror (errno))do { do { if (0) printf ("%s: failed to lookup file (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c", __FUNCTION__, 295, GF_LOG_WARNING, "%s: failed to lookup file (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); | |||
296 | goto out; | |||
297 | } | |||
298 | ||||
299 | /* Create the destination with LINKFILE mode, and linkto xattr, | |||
300 | if the linkfile already exists, it will just open the file */ | |||
301 | ret = syncop_create (to, loc, O_RDWR02, DHT_LINKFILE_MODE(01000), fd, | |||
302 | dict); | |||
303 | if (ret < 0) { | |||
304 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to create %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 306, GF_LOG_ERROR, "failed to create %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
305 | "failed to create %s on %s (%s)",do { do { if (0) printf ("failed to create %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 306, GF_LOG_ERROR, "failed to create %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
306 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("failed to create %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 306, GF_LOG_ERROR, "failed to create %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0); | |||
307 | goto out; | |||
308 | } | |||
309 | ||||
310 | ret = syncop_ftruncate (to, fd, stbuf->ia_size); | |||
311 | if (ret < 0) | |||
312 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("ftruncate failed for %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 314, GF_LOG_ERROR, "ftruncate failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
313 | "ftruncate failed for %s on %s (%s)",do { do { if (0) printf ("ftruncate failed for %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 314, GF_LOG_ERROR, "ftruncate failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
314 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("ftruncate failed for %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 314, GF_LOG_ERROR, "ftruncate failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); | |||
315 | ||||
316 | ret = syncop_fsetattr (to, fd, stbuf, | |||
317 | (GF_SET_ATTR_UID0x2 | GF_SET_ATTR_GID0x4), | |||
318 | NULL((void*)0), NULL((void*)0)); | |||
319 | if (ret < 0) | |||
320 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("chown failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 322, GF_LOG_ERROR, "chown failed for %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
321 | "chown failed for %s on %s (%s)",do { do { if (0) printf ("chown failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 322, GF_LOG_ERROR, "chown failed for %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
322 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("chown failed for %s on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 322, GF_LOG_ERROR, "chown failed for %s on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0); | |||
323 | ||||
324 | if (dst_fd) | |||
325 | *dst_fd = fd; | |||
326 | ||||
327 | /* success */ | |||
328 | ret = 0; | |||
329 | ||||
330 | out: | |||
331 | return ret; | |||
332 | } | |||
333 | ||||
334 | static inline int | |||
335 | __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc, | |||
336 | struct iatt *stbuf, int flag) | |||
337 | { | |||
338 | struct statvfs src_statfs = {0,}; | |||
339 | struct statvfs dst_statfs = {0,}; | |||
340 | int ret = -1; | |||
341 | xlator_t *this = NULL((void*)0); | |||
342 | ||||
343 | this = THIS(*__glusterfs_this_location()); | |||
344 | ||||
345 | ret = syncop_statfs (from, loc, &src_statfs); | |||
346 | if (ret) { | |||
347 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 349, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
348 | "failed to get statfs of %s on %s (%s)",do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 349, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
349 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 349, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
350 | goto out; | |||
351 | } | |||
352 | ||||
353 | ret = syncop_statfs (to, loc, &dst_statfs); | |||
354 | if (ret) { | |||
355 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 357, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)", loc->path, to->name, strerror ((*__errno_location ())) ); } while (0) | |||
356 | "failed to get statfs of %s on %s (%s)",do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 357, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)", loc->path, to->name, strerror ((*__errno_location ())) ); } while (0) | |||
357 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("failed to get statfs of %s on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 357, GF_LOG_ERROR, "failed to get statfs of %s on %s (%s)", loc->path, to->name, strerror ((*__errno_location ())) ); } while (0); | |||
358 | goto out; | |||
359 | } | |||
360 | ||||
361 | /* if force option is given, do not check for space @ dst. | |||
362 | * Check only if space is avail for the file */ | |||
363 | if (flag != GF_DHT_MIGRATE_DATA) | |||
364 | goto check_avail_space; | |||
365 | ||||
366 | if (((dst_statfs.f_bavail * | |||
367 | dst_statfs.f_bsize) / GF_DISK_SECTOR_SIZE512) < | |||
368 | (((src_statfs.f_bavail * src_statfs.f_bsize) / | |||
369 | GF_DISK_SECTOR_SIZE512) - stbuf->ia_blocks)) { | |||
370 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 374, GF_LOG_WARNING , "data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)", from->name, to->name, loc-> path); } while (0) | |||
371 | "data movement attempted from node (%s) with"do { do { if (0) printf ("data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 374, GF_LOG_WARNING , "data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)", from->name, to->name, loc-> path); } while (0) | |||
372 | " higher disk space to a node (%s) with "do { do { if (0) printf ("data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 374, GF_LOG_WARNING , "data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)", from->name, to->name, loc-> path); } while (0) | |||
373 | "lesser disk space (%s)", from->name,do { do { if (0) printf ("data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 374, GF_LOG_WARNING , "data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)", from->name, to->name, loc-> path); } while (0) | |||
374 | to->name, loc->path)do { do { if (0) printf ("data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 374, GF_LOG_WARNING , "data movement attempted from node (%s) with" " higher disk space to a node (%s) with " "lesser disk space (%s)", from->name, to->name, loc-> path); } while (0); | |||
375 | ||||
376 | /* this is not a 'failure', but we don't want to | |||
377 | consider this as 'success' too :-/ */ | |||
378 | ret = 1; | |||
379 | goto out; | |||
380 | } | |||
381 | ||||
382 | check_avail_space: | |||
383 | if (((dst_statfs.f_bavail * dst_statfs.f_bsize) / | |||
384 | GF_DISK_SECTOR_SIZE512) < stbuf->ia_blocks) { | |||
385 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 388, GF_LOG_ERROR , "data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s", from->name, to->name, loc->path); } while (0) | |||
386 | "data movement attempted from node (%s) with "do { do { if (0) printf ("data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 388, GF_LOG_ERROR , "data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s", from->name, to->name, loc->path); } while (0) | |||
387 | "to node (%s) which does not have required free space"do { do { if (0) printf ("data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 388, GF_LOG_ERROR , "data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s", from->name, to->name, loc->path); } while (0) | |||
388 | " for %s", from->name, to->name, loc->path)do { do { if (0) printf ("data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s" , from->name, to->name, loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 388, GF_LOG_ERROR , "data movement attempted from node (%s) with " "to node (%s) which does not have required free space" " for %s", from->name, to->name, loc->path); } while (0); | |||
389 | ret = 1; | |||
390 | goto out; | |||
391 | } | |||
392 | ||||
393 | ret = 0; | |||
394 | out: | |||
395 | return ret; | |||
396 | } | |||
397 | ||||
398 | static inline int | |||
399 | __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst, | |||
400 | uint64_t ia_size, int hole_exists) | |||
401 | { | |||
402 | int ret = 0; | |||
403 | int count = 0; | |||
404 | off_t offset = 0; | |||
405 | struct iovec *vector = NULL((void*)0); | |||
406 | struct iobref *iobref = NULL((void*)0); | |||
407 | uint64_t total = 0; | |||
408 | size_t read_size = 0; | |||
409 | ||||
410 | /* if file size is '0', no need to enter this loop */ | |||
411 | while (total < ia_size) { | |||
412 | read_size = (((ia_size - total) > DHT_REBALANCE_BLKSIZE(128 * 1024)) ? | |||
413 | DHT_REBALANCE_BLKSIZE(128 * 1024) : (ia_size - total)); | |||
414 | ret = syncop_readv (from, src, read_size, | |||
415 | offset, 0, &vector, &count, &iobref); | |||
416 | if (!ret || (ret < 0)) { | |||
417 | break; | |||
418 | } | |||
419 | ||||
420 | if (hole_exists) | |||
421 | ret = dht_write_with_holes (to, dst, vector, count, | |||
422 | ret, offset, iobref); | |||
423 | else | |||
424 | ret = syncop_writev (to, dst, vector, count, | |||
425 | offset, iobref, 0); | |||
426 | if (ret < 0) { | |||
427 | break; | |||
428 | } | |||
429 | offset += ret; | |||
430 | total += ret; | |||
431 | ||||
432 | GF_FREE (vector)__gf_free (vector); | |||
433 | if (iobref) | |||
434 | iobref_unref (iobref); | |||
435 | iobref = NULL((void*)0); | |||
436 | vector = NULL((void*)0); | |||
437 | } | |||
438 | if (iobref) | |||
439 | iobref_unref (iobref); | |||
440 | GF_FREE (vector)__gf_free (vector); | |||
441 | ||||
442 | if (ret >= 0) | |||
443 | ret = 0; | |||
444 | ||||
445 | return ret; | |||
446 | } | |||
447 | ||||
448 | ||||
449 | static inline int | |||
450 | __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc, | |||
451 | struct iatt *stbuf, fd_t **src_fd) | |||
452 | { | |||
453 | int ret = 0; | |||
454 | fd_t *fd = NULL((void*)0); | |||
455 | dict_t *dict = NULL((void*)0); | |||
456 | xlator_t *this = NULL((void*)0); | |||
457 | struct iatt iatt = {0,}; | |||
458 | dht_conf_t *conf = NULL((void*)0); | |||
459 | ||||
460 | this = THIS(*__glusterfs_this_location()); | |||
461 | conf = this->private; | |||
462 | ||||
463 | fd = fd_create (loc->inode, DHT_REBALANCE_PID4242); | |||
464 | if (!fd) { | |||
465 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: fd create failed (source)", loc ->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 466, GF_LOG_ERROR, "%s: fd create failed (source)" , loc->path); } while (0) | |||
466 | "%s: fd create failed (source)", loc->path)do { do { if (0) printf ("%s: fd create failed (source)", loc ->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 466, GF_LOG_ERROR, "%s: fd create failed (source)" , loc->path); } while (0); | |||
467 | ret = -1; | |||
468 | goto out; | |||
469 | } | |||
470 | ||||
471 | ret = syncop_open (from, loc, O_RDWR02, fd); | |||
472 | if (ret == -1) { | |||
473 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to open file %s on %s (%s)", loc->path, from->name, strerror ((*__errno_location () ))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 475, GF_LOG_ERROR, "failed to open file %s on %s (%s)", loc ->path, from->name, strerror ((*__errno_location ()))); } while (0) | |||
474 | "failed to open file %s on %s (%s)",do { do { if (0) printf ("failed to open file %s on %s (%s)", loc->path, from->name, strerror ((*__errno_location () ))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 475, GF_LOG_ERROR, "failed to open file %s on %s (%s)", loc ->path, from->name, strerror ((*__errno_location ()))); } while (0) | |||
475 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to open file %s on %s (%s)", loc->path, from->name, strerror ((*__errno_location () ))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 475, GF_LOG_ERROR, "failed to open file %s on %s (%s)", loc ->path, from->name, strerror ((*__errno_location ()))); } while (0); | |||
476 | goto out; | |||
477 | } | |||
478 | ||||
479 | ret = -1; | |||
480 | dict = dict_new (); | |||
481 | if (!dict) | |||
482 | goto out; | |||
483 | ||||
484 | ret = dict_set_str (dict, conf->link_xattr_name, to->name); | |||
485 | if (ret) { | |||
486 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 488, GF_LOG_ERROR, "failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0) | |||
487 | "failed to set xattr in dict for %s (linkto:%s)",do { do { if (0) printf ("failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 488, GF_LOG_ERROR, "failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0) | |||
488 | loc->path, to->name)do { do { if (0) printf ("failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 488, GF_LOG_ERROR, "failed to set xattr in dict for %s (linkto:%s)" , loc->path, to->name); } while (0); | |||
489 | goto out; | |||
490 | } | |||
491 | ||||
492 | /* Once the migration starts, the source should have 'linkto' key set | |||
493 | to show which is the target, so other clients can work around it */ | |||
494 | ret = syncop_setxattr (from, loc, dict, 0); | |||
495 | if (ret) { | |||
496 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 498, GF_LOG_ERROR, "failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
497 | "failed to set xattr on %s in %s (%s)",do { do { if (0) printf ("failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 498, GF_LOG_ERROR, "failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
498 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 498, GF_LOG_ERROR, "failed to set xattr on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
499 | goto out; | |||
500 | } | |||
501 | ||||
502 | /* mode should be (+S+T) to indicate migration is in progress */ | |||
503 | iatt.ia_prot = stbuf->ia_prot; | |||
504 | iatt.ia_type = stbuf->ia_type; | |||
505 | iatt.ia_prot.sticky = 1; | |||
506 | iatt.ia_prot.sgid = 1; | |||
507 | ||||
508 | ret = syncop_setattr (from, loc, &iatt, GF_SET_ATTR_MODE0x1, NULL((void*)0), NULL((void*)0)); | |||
509 | if (ret) { | |||
510 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 512, GF_LOG_ERROR, "failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
511 | "failed to set mode on %s in %s (%s)",do { do { if (0) printf ("failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 512, GF_LOG_ERROR, "failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
512 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 512, GF_LOG_ERROR, "failed to set mode on %s in %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
513 | goto out; | |||
514 | } | |||
515 | ||||
516 | if (src_fd) | |||
517 | *src_fd = fd; | |||
518 | ||||
519 | /* success */ | |||
520 | ret = 0; | |||
521 | out: | |||
522 | if (dict) | |||
523 | dict_unref (dict); | |||
524 | ||||
525 | return ret; | |||
526 | } | |||
527 | ||||
528 | int | |||
529 | migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc, | |||
530 | struct iatt *buf) | |||
531 | { | |||
532 | int ret = -1; | |||
533 | dict_t *rsp_dict = NULL((void*)0); | |||
534 | dict_t *dict = NULL((void*)0); | |||
535 | char *link = NULL((void*)0); | |||
536 | struct iatt stbuf = {0,}; | |||
537 | dht_conf_t *conf = this->private; | |||
538 | ||||
539 | dict = dict_new (); | |||
540 | if (!dict) | |||
541 | goto out; | |||
542 | ||||
543 | ret = dict_set_int32 (dict, conf->link_xattr_name, 256); | |||
544 | if (ret) { | |||
545 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to set 'linkto' key in dict" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 546, GF_LOG_ERROR, "%s: failed to set 'linkto' key in dict" , loc->path); } while (0) | |||
546 | "%s: failed to set 'linkto' key in dict", loc->path)do { do { if (0) printf ("%s: failed to set 'linkto' key in dict" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 546, GF_LOG_ERROR, "%s: failed to set 'linkto' key in dict" , loc->path); } while (0); | |||
547 | goto out; | |||
548 | } | |||
549 | ||||
550 | /* check in the destination if the file is link file */ | |||
551 | ret = syncop_lookup (to, loc, dict, &stbuf, &rsp_dict, NULL((void*)0)); | |||
552 | if ((ret == -1) && (errno(*__errno_location ()) != ENOENT2)) { | |||
553 | gf_log (this->name, GF_LOG_WARNING, "%s: lookup failed (%s)",do { do { if (0) printf ("%s: lookup failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 554, GF_LOG_WARNING , "%s: lookup failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0) | |||
554 | loc->path, strerror (errno))do { do { if (0) printf ("%s: lookup failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 554, GF_LOG_WARNING , "%s: lookup failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0); | |||
555 | goto out; | |||
556 | } | |||
557 | ||||
558 | /* we no more require this key */ | |||
559 | dict_del (dict, conf->link_xattr_name); | |||
560 | ||||
561 | /* file exists in target node, only if it is 'linkfile' its valid, | |||
562 | otherwise, error out */ | |||
563 | if (!ret) { | |||
564 | if (!check_is_linkfile (loc->inode, &stbuf, rsp_dict,( ((st_mode_from_ia ((&stbuf)->ia_prot, (&stbuf)-> ia_type) & ~0170000) == (01000)) && dict_get (rsp_dict , conf->link_xattr_name)) | |||
565 | conf->link_xattr_name)( ((st_mode_from_ia ((&stbuf)->ia_prot, (&stbuf)-> ia_type) & ~0170000) == (01000)) && dict_get (rsp_dict , conf->link_xattr_name))) { | |||
566 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: file exists in destination", loc ->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 567, GF_LOG_WARNING, "%s: file exists in destination" , loc->path); } while (0) | |||
567 | "%s: file exists in destination", loc->path)do { do { if (0) printf ("%s: file exists in destination", loc ->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 567, GF_LOG_WARNING, "%s: file exists in destination" , loc->path); } while (0); | |||
568 | ret = -1; | |||
569 | goto out; | |||
570 | } | |||
571 | ||||
572 | /* as file is linkfile, delete it */ | |||
573 | ret = syncop_unlink (to, loc); | |||
574 | if (ret) { | |||
575 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to delete the linkfile (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 577 , GF_LOG_WARNING, "%s: failed to delete the linkfile (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0) | |||
576 | "%s: failed to delete the linkfile (%s)",do { do { if (0) printf ("%s: failed to delete the linkfile (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 577 , GF_LOG_WARNING, "%s: failed to delete the linkfile (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0) | |||
577 | loc->path, strerror (errno))do { do { if (0) printf ("%s: failed to delete the linkfile (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 577 , GF_LOG_WARNING, "%s: failed to delete the linkfile (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); | |||
578 | goto out; | |||
579 | } | |||
580 | } | |||
581 | ||||
582 | /* Set the gfid of the source file in dict */ | |||
583 | ret = dict_set_static_bin (dict, "gfid-req", buf->ia_gfid, 16); | |||
584 | if (ret) { | |||
585 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 586, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0) | |||
586 | "%s: failed to set gfid in dict for create", loc->path)do { do { if (0) printf ("%s: failed to set gfid in dict for create" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 586, GF_LOG_ERROR, "%s: failed to set gfid in dict for create" , loc->path); } while (0); | |||
587 | goto out; | |||
588 | } | |||
589 | ||||
590 | /* Create the file in target */ | |||
591 | if (IA_ISLNK (buf->ia_type)(buf->ia_type == IA_IFLNK)) { | |||
592 | /* Handle symlinks separately */ | |||
593 | ret = syncop_readlink (from, loc, &link, buf->ia_size); | |||
594 | if (ret < 0) { | |||
595 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: readlink on symlink failed (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 597 , GF_LOG_WARNING, "%s: readlink on symlink failed (%s)", loc-> path, strerror ((*__errno_location ()))); } while (0) | |||
596 | "%s: readlink on symlink failed (%s)",do { do { if (0) printf ("%s: readlink on symlink failed (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 597 , GF_LOG_WARNING, "%s: readlink on symlink failed (%s)", loc-> path, strerror ((*__errno_location ()))); } while (0) | |||
597 | loc->path, strerror (errno))do { do { if (0) printf ("%s: readlink on symlink failed (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 597 , GF_LOG_WARNING, "%s: readlink on symlink failed (%s)", loc-> path, strerror ((*__errno_location ()))); } while (0); | |||
598 | goto out; | |||
599 | } | |||
600 | ||||
601 | ret = syncop_symlink (to, loc, link, dict); | |||
602 | if (ret) { | |||
603 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: creating symlink failed (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 605, GF_LOG_WARNING , "%s: creating symlink failed (%s)", loc->path, strerror ( (*__errno_location ()))); } while (0) | |||
604 | "%s: creating symlink failed (%s)",do { do { if (0) printf ("%s: creating symlink failed (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 605, GF_LOG_WARNING , "%s: creating symlink failed (%s)", loc->path, strerror ( (*__errno_location ()))); } while (0) | |||
605 | loc->path, strerror (errno))do { do { if (0) printf ("%s: creating symlink failed (%s)", loc ->path, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 605, GF_LOG_WARNING , "%s: creating symlink failed (%s)", loc->path, strerror ( (*__errno_location ()))); } while (0); | |||
606 | goto out; | |||
607 | } | |||
608 | ||||
609 | goto done; | |||
610 | } | |||
611 | ||||
612 | ret = syncop_mknod (to, loc, st_mode_from_ia (buf->ia_prot, | |||
613 | buf->ia_type), | |||
614 | makedev (ia_major (buf->ia_rdev),gnu_dev_makedev (ia_major (buf->ia_rdev), ia_minor (buf-> ia_rdev)) | |||
615 | ia_minor (buf->ia_rdev))gnu_dev_makedev (ia_major (buf->ia_rdev), ia_minor (buf-> ia_rdev)), dict); | |||
616 | if (ret) { | |||
617 | gf_log (this->name, GF_LOG_WARNING, "%s: mknod failed (%s)",do { do { if (0) printf ("%s: mknod failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 618, GF_LOG_WARNING , "%s: mknod failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0) | |||
618 | loc->path, strerror (errno))do { do { if (0) printf ("%s: mknod failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 618, GF_LOG_WARNING , "%s: mknod failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0); | |||
619 | goto out; | |||
620 | } | |||
621 | ||||
622 | done: | |||
623 | ret = syncop_unlink (from, loc); | |||
624 | if (ret) | |||
625 | gf_log (this->name, GF_LOG_WARNING, "%s: unlink failed (%s)",do { do { if (0) printf ("%s: unlink failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 626, GF_LOG_WARNING , "%s: unlink failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0) | |||
626 | loc->path, strerror (errno))do { do { if (0) printf ("%s: unlink failed (%s)", loc->path , strerror ((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 626, GF_LOG_WARNING , "%s: unlink failed (%s)", loc->path, strerror ((*__errno_location ()))); } while (0); | |||
627 | ||||
628 | out: | |||
629 | if (dict) | |||
630 | dict_unref (dict); | |||
631 | ||||
632 | if (rsp_dict) | |||
633 | dict_unref (rsp_dict); | |||
634 | ||||
635 | return ret; | |||
636 | } | |||
637 | ||||
638 | /* | |||
639 | return values: | |||
640 | ||||
641 | -1 : failure | |||
642 | 0 : successfully migrated data | |||
643 | 1 : not a failure, but we can't migrate data as of now | |||
644 | */ | |||
645 | int | |||
646 | dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to, | |||
647 | int flag) | |||
648 | { | |||
649 | int ret = -1; | |||
650 | struct iatt new_stbuf = {0,}; | |||
651 | struct iatt stbuf = {0,}; | |||
652 | struct iatt empty_iatt = {0,}; | |||
653 | ia_prot_t src_ia_prot = {0,}; | |||
654 | fd_t *src_fd = NULL((void*)0); | |||
655 | fd_t *dst_fd = NULL((void*)0); | |||
656 | dict_t *dict = NULL((void*)0); | |||
657 | dict_t *xattr = NULL((void*)0); | |||
658 | dict_t *xattr_rsp = NULL((void*)0); | |||
659 | int file_has_holes = 0; | |||
660 | dht_conf_t *conf = this->private; | |||
661 | ||||
662 | gf_log (this->name, GF_LOG_INFO, "%s: attempting to move from %s to %s",do { do { if (0) printf ("%s: attempting to move from %s to %s" , loc->path, from->name, to->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 663, GF_LOG_INFO , "%s: attempting to move from %s to %s", loc->path, from-> name, to->name); } while (0) | |||
663 | loc->path, from->name, to->name)do { do { if (0) printf ("%s: attempting to move from %s to %s" , loc->path, from->name, to->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 663, GF_LOG_INFO , "%s: attempting to move from %s to %s", loc->path, from-> name, to->name); } while (0); | |||
664 | ||||
665 | dict = dict_new (); | |||
666 | if (!dict) | |||
667 | goto out; | |||
668 | ||||
669 | ret = dict_set_int32 (dict, conf->link_xattr_name, 256); | |||
670 | if (ret) { | |||
671 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to set 'linkto' key in dict" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 672, GF_LOG_ERROR, "%s: failed to set 'linkto' key in dict" , loc->path); } while (0) | |||
672 | "%s: failed to set 'linkto' key in dict", loc->path)do { do { if (0) printf ("%s: failed to set 'linkto' key in dict" , loc->path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 672, GF_LOG_ERROR, "%s: failed to set 'linkto' key in dict" , loc->path); } while (0); | |||
673 | goto out; | |||
674 | } | |||
675 | ||||
676 | /* Phase 1 - Data migration is in progress from now on */ | |||
677 | ret = syncop_lookup (from, loc, dict, &stbuf, &xattr_rsp, NULL((void*)0)); | |||
678 | if (ret) { | |||
679 | gf_log (this->name, GF_LOG_ERROR, "%s: lookup failed on %s (%s)",do { do { if (0) printf ("%s: lookup failed on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 680, GF_LOG_ERROR, "%s: lookup failed on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0) | |||
680 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: lookup failed on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 680, GF_LOG_ERROR, "%s: lookup failed on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0); | |||
681 | goto out; | |||
682 | } | |||
683 | ||||
684 | /* we no more require this key */ | |||
685 | dict_del (dict, conf->link_xattr_name); | |||
686 | ||||
687 | /* preserve source mode, so set the same to the destination */ | |||
688 | src_ia_prot = stbuf.ia_prot; | |||
689 | ||||
690 | /* Check if file can be migrated */ | |||
691 | ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag); | |||
692 | if (ret) | |||
693 | goto out; | |||
694 | ||||
695 | /* Take care of the special files */ | |||
696 | if (!IA_ISREG (stbuf.ia_type)(stbuf.ia_type == IA_IFREG)) { | |||
697 | /* Special files */ | |||
698 | ret = migrate_special_files (this, from, to, loc, &stbuf); | |||
699 | goto out; | |||
700 | } | |||
701 | ||||
702 | /* create the destination, with required modes/xattr */ | |||
703 | ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf, | |||
704 | dict, &dst_fd); | |||
705 | if (ret) | |||
706 | goto out; | |||
707 | ||||
708 | ret = __dht_check_free_space (to, from, loc, &stbuf, flag); | |||
709 | if (ret) { | |||
710 | goto out; | |||
711 | } | |||
712 | ||||
713 | /* Open the source, and also update mode/xattr */ | |||
714 | ret = __dht_rebalance_open_src_file (from, to, loc, &stbuf, &src_fd); | |||
715 | if (ret) { | |||
716 | gf_log (this->name, GF_LOG_ERROR, "failed to open %s on %s",do { do { if (0) printf ("failed to open %s on %s", loc->path , from->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 717, GF_LOG_ERROR, "failed to open %s on %s", loc->path, from->name); } while (0) | |||
717 | loc->path, from->name)do { do { if (0) printf ("failed to open %s on %s", loc->path , from->name); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 717, GF_LOG_ERROR, "failed to open %s on %s", loc->path, from->name); } while (0); | |||
718 | goto out; | |||
719 | } | |||
720 | ||||
721 | ret = syncop_fstat (from, src_fd, &stbuf); | |||
722 | if (ret) { | |||
723 | gf_log (this->name, GF_LOG_ERROR, "failed to lookup %s on %s (%s)",do { do { if (0) printf ("failed to lookup %s on %s (%s)", loc ->path, from->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 724, GF_LOG_ERROR, "failed to lookup %s on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0) | |||
724 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to lookup %s on %s (%s)", loc ->path, from->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 724, GF_LOG_ERROR, "failed to lookup %s on %s (%s)", loc-> path, from->name, strerror ((*__errno_location ()))); } while (0); | |||
725 | goto out; | |||
726 | } | |||
727 | ||||
728 | /* Try to preserve 'holes' while migrating data */ | |||
729 | if (stbuf.ia_size > (stbuf.ia_blocks * GF_DISK_SECTOR_SIZE512)) | |||
730 | file_has_holes = 1; | |||
731 | ||||
732 | /* All I/O happens in this function */ | |||
733 | ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd, | |||
734 | stbuf.ia_size, file_has_holes); | |||
735 | if (ret) { | |||
736 | gf_log (this->name, GF_LOG_ERROR, "%s: failed to migrate data",do { do { if (0) printf ("%s: failed to migrate data", loc-> path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 737, GF_LOG_ERROR, "%s: failed to migrate data" , loc->path); } while (0) | |||
737 | loc->path)do { do { if (0) printf ("%s: failed to migrate data", loc-> path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 737, GF_LOG_ERROR, "%s: failed to migrate data" , loc->path); } while (0); | |||
738 | /* reset the destination back to 0 */ | |||
739 | ret = syncop_ftruncate (to, dst_fd, 0); | |||
740 | if (ret) { | |||
741 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 743 , GF_LOG_ERROR, "%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
742 | "%s: failed to reset target size back to 0 (%s)",do { do { if (0) printf ("%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 743 , GF_LOG_ERROR, "%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
743 | loc->path, strerror (errno))do { do { if (0) printf ("%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 743 , GF_LOG_ERROR, "%s: failed to reset target size back to 0 (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); | |||
744 | } | |||
745 | ||||
746 | ret = -1; | |||
747 | goto out; | |||
748 | } | |||
749 | ||||
750 | /* TODO: move all xattr related operations to fd based operations */ | |||
751 | ret = syncop_listxattr (from, loc, &xattr); | |||
752 | if (ret == -1) | |||
753 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 755, GF_LOG_WARNING, "%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
754 | "%s: failed to get xattr from %s (%s)",do { do { if (0) printf ("%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 755, GF_LOG_WARNING, "%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
755 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 755, GF_LOG_WARNING, "%s: failed to get xattr from %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
756 | ||||
757 | ret = syncop_setxattr (to, loc, xattr, 0); | |||
758 | if (ret == -1) | |||
759 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to set xattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 761, GF_LOG_WARNING, "%s: failed to set xattr on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
760 | "%s: failed to set xattr on %s (%s)",do { do { if (0) printf ("%s: failed to set xattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 761, GF_LOG_WARNING, "%s: failed to set xattr on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
761 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("%s: failed to set xattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 761, GF_LOG_WARNING, "%s: failed to set xattr on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); | |||
762 | ||||
763 | /* TODO: Sync the locks */ | |||
764 | ||||
765 | ret = syncop_fsync (to, dst_fd, 0); | |||
766 | if (ret) | |||
767 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to fsync on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 769, GF_LOG_WARNING, "%s: failed to fsync on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
768 | "%s: failed to fsync on %s (%s)",do { do { if (0) printf ("%s: failed to fsync on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 769, GF_LOG_WARNING, "%s: failed to fsync on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0) | |||
769 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("%s: failed to fsync on %s (%s)", loc ->path, to->name, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 769, GF_LOG_WARNING, "%s: failed to fsync on %s (%s)", loc-> path, to->name, strerror ((*__errno_location ()))); } while (0); | |||
770 | ||||
771 | ||||
772 | /* Phase 2 - Data-Migration Complete, Housekeeping updates pending */ | |||
773 | ||||
774 | ret = syncop_fstat (from, src_fd, &new_stbuf); | |||
775 | if (ret < 0) { | |||
776 | /* Failed to get the stat info */ | |||
777 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 779, GF_LOG_ERROR, "failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
778 | "failed to fstat file %s on %s (%s)",do { do { if (0) printf ("failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 779, GF_LOG_ERROR, "failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
779 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 779, GF_LOG_ERROR, "failed to fstat file %s on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
780 | goto out; | |||
781 | } | |||
782 | ||||
783 | /* source would have both sticky bit and sgid bit set, reset it to 0, | |||
784 | and set the source permission on destination, if it was not set | |||
785 | prior to setting rebalance-modes in source */ | |||
786 | if (!src_ia_prot.sticky) | |||
787 | new_stbuf.ia_prot.sticky = 0; | |||
788 | ||||
789 | if (!src_ia_prot.sgid) | |||
790 | new_stbuf.ia_prot.sgid = 0; | |||
791 | ||||
792 | /* TODO: if the source actually had sticky bit, or sgid bit set, | |||
793 | we are not handling it */ | |||
794 | ||||
795 | ret = syncop_fsetattr (to, dst_fd, &new_stbuf, | |||
796 | (GF_SET_ATTR_UID0x2 | GF_SET_ATTR_GID0x4 | | |||
797 | GF_SET_ATTR_MODE0x1), NULL((void*)0), NULL((void*)0)); | |||
798 | if (ret) { | |||
799 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 801, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
800 | "%s: failed to perform setattr on %s (%s)",do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 801, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
801 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 801, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); | |||
802 | goto out; | |||
803 | } | |||
804 | ||||
805 | /* Because 'futimes' is not portable */ | |||
806 | ret = syncop_setattr (to, loc, &new_stbuf, | |||
807 | (GF_SET_ATTR_MTIME0x20 | GF_SET_ATTR_ATIME0x10), | |||
808 | NULL((void*)0), NULL((void*)0)); | |||
809 | if (ret) { | |||
810 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 812, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
811 | "%s: failed to perform setattr on %s (%s)",do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 812, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
812 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 812, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); | |||
813 | } | |||
814 | ||||
815 | /* Make the source as a linkfile first before deleting it */ | |||
816 | empty_iatt.ia_prot.sticky = 1; | |||
817 | ret = syncop_fsetattr (from, src_fd, &empty_iatt, | |||
818 | GF_SET_ATTR_MODE0x1, NULL((void*)0), NULL((void*)0)); | |||
819 | if (ret) { | |||
820 | gf_log (this->name, GF_LOG_WARNING, \do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 822, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
821 | "%s: failed to perform setattr on %s (%s)",do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 822, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
822 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 822, GF_LOG_WARNING, "%s: failed to perform setattr on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
823 | goto out; | |||
824 | } | |||
825 | ||||
826 | /* Do a stat and check the gfid before unlink */ | |||
827 | ret = syncop_stat (from, loc, &empty_iatt); | |||
828 | if (ret) { | |||
829 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 831, GF_LOG_WARNING, "%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
830 | "%s: failed to do a stat on %s (%s)",do { do { if (0) printf ("%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 831, GF_LOG_WARNING, "%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
831 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 831, GF_LOG_WARNING, "%s: failed to do a stat on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
832 | goto out; | |||
833 | } | |||
834 | ||||
835 | if (uuid_compare (empty_iatt.ia_gfid, loc->gfid) == 0) { | |||
836 | /* take out the source from namespace */ | |||
837 | ret = syncop_unlink (from, loc); | |||
838 | if (ret) { | |||
839 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 841, GF_LOG_WARNING, "%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
840 | "%s: failed to perform unlink on %s (%s)",do { do { if (0) printf ("%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 841, GF_LOG_WARNING, "%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
841 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 841, GF_LOG_WARNING, "%s: failed to perform unlink on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
842 | goto out; | |||
843 | } | |||
844 | } | |||
845 | ||||
846 | /* Free up the data blocks on the source node, as the whole | |||
847 | file is migrated */ | |||
848 | ret = syncop_ftruncate (from, src_fd, 0); | |||
849 | if (ret) { | |||
850 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 852, GF_LOG_WARNING, "%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
851 | "%s: failed to perform truncate on %s (%s)",do { do { if (0) printf ("%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 852, GF_LOG_WARNING, "%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0) | |||
852 | loc->path, from->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 852, GF_LOG_WARNING, "%s: failed to perform truncate on %s (%s)" , loc->path, from->name, strerror ((*__errno_location ( )))); } while (0); | |||
853 | } | |||
854 | ||||
855 | /* remove the 'linkto' xattr from the destination */ | |||
856 | ret = syncop_fremovexattr (to, dst_fd, conf->link_xattr_name); | |||
857 | if (ret) { | |||
858 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 860, GF_LOG_WARNING, "%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
859 | "%s: failed to perform removexattr on %s (%s)",do { do { if (0) printf ("%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 860, GF_LOG_WARNING, "%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0) | |||
860 | loc->path, to->name, strerror (errno))do { do { if (0) printf ("%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 860, GF_LOG_WARNING, "%s: failed to perform removexattr on %s (%s)" , loc->path, to->name, strerror ((*__errno_location ()) )); } while (0); | |||
861 | } | |||
862 | ||||
863 | ret = syncop_lookup (this, loc, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
864 | if (ret) { | |||
865 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 867 , GF_LOG_DEBUG, "%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
866 | "%s: failed to lookup the file on subvolumes (%s)",do { do { if (0) printf ("%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 867 , GF_LOG_DEBUG, "%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0) | |||
867 | loc->path, strerror (errno))do { do { if (0) printf ("%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 867 , GF_LOG_DEBUG, "%s: failed to lookup the file on subvolumes (%s)" , loc->path, strerror ((*__errno_location ()))); } while ( 0); | |||
868 | } | |||
869 | ||||
870 | gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("completed migration of %s from subvolume %s to %s" , loc->path, from->name, to->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 872, GF_LOG_INFO , "completed migration of %s from subvolume %s to %s", loc-> path, from->name, to->name); } while (0) | |||
871 | "completed migration of %s from subvolume %s to %s",do { do { if (0) printf ("completed migration of %s from subvolume %s to %s" , loc->path, from->name, to->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 872, GF_LOG_INFO , "completed migration of %s from subvolume %s to %s", loc-> path, from->name, to->name); } while (0) | |||
872 | loc->path, from->name, to->name)do { do { if (0) printf ("completed migration of %s from subvolume %s to %s" , loc->path, from->name, to->name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 872, GF_LOG_INFO , "completed migration of %s from subvolume %s to %s", loc-> path, from->name, to->name); } while (0); | |||
873 | ||||
874 | ret = 0; | |||
875 | out: | |||
876 | if (dict) | |||
877 | dict_unref (dict); | |||
878 | ||||
879 | if (xattr) | |||
880 | dict_unref (xattr); | |||
881 | if (xattr_rsp) | |||
882 | dict_unref (xattr_rsp); | |||
883 | ||||
884 | if (dst_fd) | |||
885 | syncop_close (dst_fd); | |||
886 | if (src_fd) | |||
887 | syncop_close (src_fd); | |||
888 | ||||
889 | return ret; | |||
890 | } | |||
891 | ||||
892 | static int | |||
893 | rebalance_task (void *data) | |||
894 | { | |||
895 | int ret = -1; | |||
896 | dht_local_t *local = NULL((void*)0); | |||
897 | call_frame_t *frame = NULL((void*)0); | |||
898 | ||||
899 | frame = data; | |||
900 | ||||
901 | local = frame->local; | |||
902 | ||||
903 | /* This function is 'synchrounous', hence if it returns, | |||
904 | we are done with the task */ | |||
905 | ret = dht_migrate_file (THIS(*__glusterfs_this_location()), &local->loc, local->rebalance.from_subvol, | |||
906 | local->rebalance.target_node, local->flags); | |||
907 | ||||
908 | return ret; | |||
909 | } | |||
910 | ||||
911 | static int | |||
912 | rebalance_task_completion (int op_ret, call_frame_t *sync_frame, void *data) | |||
913 | { | |||
914 | int ret = -1; | |||
915 | uint64_t layout_int = 0; | |||
916 | dht_layout_t *layout = 0; | |||
917 | xlator_t *this = NULL((void*)0); | |||
918 | dht_local_t *local = NULL((void*)0); | |||
919 | int32_t op_errno = EINVAL22; | |||
920 | ||||
921 | this = THIS(*__glusterfs_this_location()); | |||
922 | local = sync_frame->local; | |||
923 | ||||
924 | if (!op_ret) { | |||
925 | /* Make sure we have valid 'layout' in inode ctx | |||
926 | after the operation */ | |||
927 | ret = inode_ctx_del (local->loc.inode, this, &layout_int)inode_ctx_del2(local->loc.inode,this,&layout_int,0); | |||
928 | if (!ret && layout_int) { | |||
929 | layout = (dht_layout_t *)(long)layout_int; | |||
930 | dht_layout_unref (this, layout); | |||
931 | } | |||
932 | ||||
933 | ret = dht_layout_preset (this, local->rebalance.target_node, | |||
934 | local->loc.inode); | |||
935 | if (ret) | |||
936 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to set inode ctx", local ->loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 937, GF_LOG_WARNING, "%s: failed to set inode ctx" , local->loc.path); } while (0) | |||
937 | "%s: failed to set inode ctx", local->loc.path)do { do { if (0) printf ("%s: failed to set inode ctx", local ->loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 937, GF_LOG_WARNING, "%s: failed to set inode ctx" , local->loc.path); } while (0); | |||
938 | } | |||
939 | ||||
940 | if (op_ret == -1) { | |||
941 | /* Failure of migration process, mostly due to write process. | |||
942 | as we can't preserve the exact errno, lets say there was | |||
943 | no space to migrate-data | |||
944 | */ | |||
945 | op_errno = ENOSPC28; | |||
946 | } | |||
947 | ||||
948 | if (op_ret == 1) { | |||
949 | /* migration didn't happen, but is not a failure, let the user | |||
950 | understand that he doesn't have permission to migrate the | |||
951 | file. | |||
952 | */ | |||
953 | op_ret = -1; | |||
954 | op_errno = EPERM1; | |||
955 | } | |||
956 | ||||
957 | DHT_STACK_UNWIND (setxattr, sync_frame, op_ret, op_errno, NULL)do { dht_local_t *__local = ((void*)0); xlator_t *__xl = ((void *)0); if (sync_frame) { __xl = sync_frame->this; __local = sync_frame->local; sync_frame->local = ((void*)0); } do { fop_setxattr_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!sync_frame ) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ( "stack", "dht-rebalance.c", __FUNCTION__, 957, GF_LOG_CRITICAL , "!frame"); } while (0); break; } fn = (fop_setxattr_cbk_t ) sync_frame->ret; _parent = sync_frame->parent; pthread_spin_lock (&sync_frame->root->stack_lock); { _parent->ref_count --; } pthread_spin_unlock (&sync_frame->root->stack_lock ); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location ()) = _parent->this; sync_frame->complete = _gf_true; sync_frame ->unwind_from = __FUNCTION__; if (sync_frame->this-> ctx->measure_latency) gf_latency_end (sync_frame); fn (_parent , sync_frame->cookie, _parent->this, op_ret, op_errno, ( (void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); dht_local_wipe (__xl, __local); } while (0); | |||
958 | return 0; | |||
959 | } | |||
960 | ||||
961 | int | |||
962 | dht_start_rebalance_task (xlator_t *this, call_frame_t *frame) | |||
963 | { | |||
964 | int ret = -1; | |||
965 | ||||
966 | ret = synctask_new (this->ctx->env, rebalance_task, | |||
967 | rebalance_task_completion, | |||
968 | frame, frame); | |||
969 | return ret; | |||
970 | } | |||
971 | ||||
972 | int | |||
973 | gf_listener_stop (xlator_t *this) | |||
974 | { | |||
975 | glusterfs_ctx_t *ctx = NULL((void*)0); | |||
976 | cmd_args_t *cmd_args = NULL((void*)0); | |||
977 | int ret = 0; | |||
978 | ||||
979 | ctx = this->ctx; | |||
980 | GF_ASSERT (ctx)do { if (!(ctx)) { do { do { if (0) printf ("Assertion failed: " "ctx"); } while (0); _gf_log_callingfn ("", "dht-rebalance.c" , __FUNCTION__, 980, GF_LOG_ERROR, "Assertion failed: " "ctx" ); } while (0); } } while (0); | |||
981 | cmd_args = &ctx->cmd_args; | |||
982 | if (cmd_args->sock_file) { | |||
| ||||
983 | ret = unlink (cmd_args->sock_file); | |||
984 | if (ret && (ENOENT2 == errno(*__errno_location ()))) { | |||
985 | ret = 0; | |||
986 | } | |||
987 | } | |||
988 | ||||
989 | if (ret) { | |||
990 | gf_log (this->name, GF_LOG_ERROR, "Failed to unlink listener "do { do { if (0) printf ("Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 992, GF_LOG_ERROR, "Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0) | |||
991 | "socket %s, error: %s", cmd_args->sock_file,do { do { if (0) printf ("Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 992, GF_LOG_ERROR, "Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0) | |||
992 | strerror (errno))do { do { if (0) printf ("Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 992, GF_LOG_ERROR, "Failed to unlink listener " "socket %s, error: %s" , cmd_args->sock_file, strerror ((*__errno_location ()))); } while (0); | |||
993 | } | |||
994 | return ret; | |||
995 | } | |||
996 | ||||
997 | void | |||
998 | dht_build_root_inode (xlator_t *this, inode_t **inode) | |||
999 | { | |||
1000 | inode_table_t *itable = NULL((void*)0); | |||
1001 | uuid_t root_gfid = {0, }; | |||
1002 | ||||
1003 | itable = inode_table_new (0, this); | |||
1004 | if (!itable) | |||
1005 | return; | |||
1006 | ||||
1007 | root_gfid[15] = 1; | |||
1008 | *inode = inode_find (itable, root_gfid); | |||
1009 | } | |||
1010 | ||||
1011 | void | |||
1012 | dht_build_root_loc (inode_t *inode, loc_t *loc) | |||
1013 | { | |||
1014 | loc->path = "/"; | |||
1015 | loc->inode = inode; | |||
1016 | loc->inode->ia_type = IA_IFDIR; | |||
1017 | memset (loc->gfid, 0, 16); | |||
1018 | loc->gfid[15] = 1; | |||
1019 | } | |||
1020 | ||||
1021 | ||||
1022 | /* return values: 1 -> error, bug ignore and continue | |||
1023 | 0 -> proceed | |||
1024 | -1 -> error, handle it */ | |||
1025 | int32_t | |||
1026 | gf_defrag_handle_migrate_error (int32_t op_errno, gf_defrag_info_t *defrag) | |||
1027 | { | |||
1028 | /* if errno is not ENOSPC or ENOTCONN, we can still continue | |||
1029 | with rebalance process */ | |||
1030 | if ((errno(*__errno_location ()) != ENOSPC28) || (errno(*__errno_location ()) != ENOTCONN107)) | |||
1031 | return 1; | |||
1032 | ||||
1033 | if (errno(*__errno_location ()) == ENOTCONN107) { | |||
1034 | /* Most probably mount point went missing (mostly due | |||
1035 | to a brick down), say rebalance failure to user, | |||
1036 | let him restart it if everything is fine */ | |||
1037 | defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; | |||
1038 | return -1; | |||
1039 | } | |||
1040 | ||||
1041 | if (errno(*__errno_location ()) == ENOSPC28) { | |||
1042 | /* rebalance process itself failed, may be | |||
1043 | remote brick went down, or write failed due to | |||
1044 | disk full etc etc.. */ | |||
1045 | defrag->defrag_status = GF_DEFRAG_STATUS_FAILED; | |||
1046 | return -1; | |||
1047 | } | |||
1048 | ||||
1049 | return 0; | |||
1050 | } | |||
1051 | ||||
1052 | static gf_boolean_t | |||
1053 | gf_defrag_pattern_match (gf_defrag_info_t *defrag, char *name, uint64_t size) | |||
1054 | { | |||
1055 | gf_defrag_pattern_list_t *trav = NULL((void*)0); | |||
1056 | gf_boolean_t match = _gf_false; | |||
1057 | gf_boolean_t ret = _gf_false; | |||
1058 | ||||
1059 | GF_VALIDATE_OR_GOTO ("dht", defrag, out)do { if (!defrag) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "defrag"); } while (0); _gf_log_callingfn ("dht", "dht-rebalance.c", __FUNCTION__, 1059, GF_LOG_ERROR, "invalid argument: " "defrag"); } while (0); goto out; } } while (0); | |||
1060 | ||||
1061 | trav = defrag->defrag_pattern; | |||
1062 | while (trav) { | |||
1063 | if (!fnmatch (trav->path_pattern, name, FNM_NOESCAPE(1 << 1))) { | |||
1064 | match = _gf_true; | |||
1065 | break; | |||
1066 | } | |||
1067 | trav = trav->next; | |||
1068 | } | |||
1069 | ||||
1070 | if ((match == _gf_true) && (size >= trav->size)) | |||
1071 | ret = _gf_true; | |||
1072 | ||||
1073 | out: | |||
1074 | return ret; | |||
1075 | } | |||
1076 | ||||
1077 | /* We do a depth first traversal of directories. But before we move into | |||
1078 | * subdirs, we complete the data migration of those directories whose layouts | |||
1079 | * have been fixed | |||
1080 | */ | |||
1081 | ||||
1082 | int | |||
1083 | gf_defrag_migrate_data (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, | |||
1084 | dict_t *migrate_data) | |||
1085 | { | |||
1086 | int ret = -1; | |||
1087 | loc_t entry_loc = {0,}; | |||
1088 | fd_t *fd = NULL((void*)0); | |||
1089 | gf_dirent_t entries; | |||
1090 | gf_dirent_t *tmp = NULL((void*)0); | |||
1091 | gf_dirent_t *entry = NULL((void*)0); | |||
1092 | gf_boolean_t free_entries = _gf_false; | |||
1093 | off_t offset = 0; | |||
1094 | dict_t *dict = NULL((void*)0); | |||
1095 | struct iatt iatt = {0,}; | |||
1096 | int32_t op_errno = 0; | |||
1097 | char *uuid_str = NULL((void*)0); | |||
1098 | uuid_t node_uuid = {0,}; | |||
1099 | int readdir_operrno = 0; | |||
1100 | struct timeval dir_start = {0,}; | |||
1101 | struct timeval end = {0,}; | |||
1102 | double elapsed = {0,}; | |||
1103 | struct timeval start = {0,}; | |||
1104 | ||||
1105 | gf_log (this->name, GF_LOG_INFO, "migrate data called on %s",do { do { if (0) printf ("migrate data called on %s", loc-> path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1106, GF_LOG_INFO, "migrate data called on %s" , loc->path); } while (0) | |||
1106 | loc->path)do { do { if (0) printf ("migrate data called on %s", loc-> path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1106, GF_LOG_INFO, "migrate data called on %s" , loc->path); } while (0); | |||
1107 | gettimeofday (&dir_start, NULL((void*)0)); | |||
1108 | ||||
1109 | fd = fd_create (loc->inode, defrag->pid); | |||
1110 | if (!fd) { | |||
1111 | gf_log (this->name, GF_LOG_ERROR, "Failed to create fd")do { do { if (0) printf ("Failed to create fd"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1111 , GF_LOG_ERROR, "Failed to create fd"); } while (0); | |||
1112 | goto out; | |||
1113 | } | |||
1114 | ||||
1115 | ret = syncop_opendir (this, loc, fd); | |||
1116 | if (ret) { | |||
1117 | gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s",do { do { if (0) printf ("Failed to open dir %s", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1118, GF_LOG_ERROR, "Failed to open dir %s", loc->path); } while (0) | |||
1118 | loc->path)do { do { if (0) printf ("Failed to open dir %s", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1118, GF_LOG_ERROR, "Failed to open dir %s", loc->path); } while (0); | |||
1119 | goto out; | |||
1120 | } | |||
1121 | ||||
1122 | INIT_LIST_HEAD (&entries.list)do { (&entries.list)->next = (&entries.list)->prev = &entries.list; } while (0); | |||
1123 | ||||
1124 | while ((ret = syncop_readdirp (this, fd, 131072, offset, NULL((void*)0), | |||
1125 | &entries)) != 0) { | |||
1126 | ||||
1127 | if (ret < 0) { | |||
1128 | ||||
1129 | gf_log (this->name, GF_LOG_ERROR, "Readdir returned %s."do { do { if (0) printf ("Readdir returned %s." " Aborting migrate-data" , strerror(readdir_operrno)); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 1131, GF_LOG_ERROR, "Readdir returned %s." " Aborting migrate-data", strerror(readdir_operrno)); } while (0) | |||
1130 | " Aborting migrate-data",do { do { if (0) printf ("Readdir returned %s." " Aborting migrate-data" , strerror(readdir_operrno)); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 1131, GF_LOG_ERROR, "Readdir returned %s." " Aborting migrate-data", strerror(readdir_operrno)); } while (0) | |||
1131 | strerror(readdir_operrno))do { do { if (0) printf ("Readdir returned %s." " Aborting migrate-data" , strerror(readdir_operrno)); } while (0); _gf_log (this-> name, "dht-rebalance.c", __FUNCTION__, 1131, GF_LOG_ERROR, "Readdir returned %s." " Aborting migrate-data", strerror(readdir_operrno)); } while (0); | |||
1132 | goto out; | |||
1133 | } | |||
1134 | ||||
1135 | /* Need to keep track of ENOENT errno, that means, there is no | |||
1136 | need to send more readdirp() */ | |||
1137 | readdir_operrno = errno(*__errno_location ()); | |||
1138 | ||||
1139 | if (list_empty (&entries.list)) | |||
1140 | break; | |||
1141 | ||||
1142 | free_entries = _gf_true; | |||
1143 | ||||
1144 | list_for_each_entry_safe (entry, tmp, &entries.list, list)for (entry = ((typeof(*entry) *)((char *)((&entries.list) ->next)-(unsigned long)(&((typeof(*entry) *)0)->list ))), tmp = ((typeof(*entry) *)((char *)(entry->list.next)- (unsigned long)(&((typeof(*entry) *)0)->list))); & entry->list != (&entries.list); entry = tmp, tmp = ((typeof (*tmp) *)((char *)(tmp->list.next)-(unsigned long)(&(( typeof(*tmp) *)0)->list)))) { | |||
1145 | if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { | |||
1146 | ret = 1; | |||
1147 | goto out; | |||
1148 | } | |||
1149 | ||||
1150 | offset = entry->d_off; | |||
1151 | ||||
1152 | if (!strcmp (entry->d_name, ".") || | |||
1153 | !strcmp (entry->d_name, "..")) | |||
1154 | continue; | |||
1155 | ||||
1156 | if (IA_ISDIR (entry->d_stat.ia_type)(entry->d_stat.ia_type == IA_IFDIR)) | |||
1157 | continue; | |||
1158 | ||||
1159 | defrag->num_files_lookedup++; | |||
1160 | if (defrag->stats == _gf_true) { | |||
1161 | gettimeofday (&start, NULL((void*)0)); | |||
1162 | } | |||
1163 | if (defrag->defrag_pattern && | |||
1164 | (gf_defrag_pattern_match (defrag, entry->d_name, | |||
1165 | entry->d_stat.ia_size) | |||
1166 | == _gf_false)) { | |||
1167 | continue; | |||
1168 | } | |||
1169 | loc_wipe (&entry_loc); | |||
1170 | ret =dht_build_child_loc (this, &entry_loc, loc, | |||
1171 | entry->d_name); | |||
1172 | if (ret) { | |||
1173 | gf_log (this->name, GF_LOG_ERROR, "Child loc"do { do { if (0) printf ("Child loc" " build failed"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1174, GF_LOG_ERROR, "Child loc" " build failed"); } while ( 0) | |||
1174 | " build failed")do { do { if (0) printf ("Child loc" " build failed"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1174, GF_LOG_ERROR, "Child loc" " build failed"); } while ( 0); | |||
1175 | goto out; | |||
1176 | } | |||
1177 | ||||
1178 | if (uuid_is_null (entry->d_stat.ia_gfid)) { | |||
1179 | gf_log (this->name, GF_LOG_ERROR, "%s/%s"do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1181, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1180 | " gfid not present", loc->path,do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1181, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1181 | entry->d_name)do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1181, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0); | |||
1182 | continue; | |||
1183 | } | |||
1184 | ||||
1185 | uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid); | |||
1186 | ||||
1187 | if (uuid_is_null (loc->gfid)) { | |||
1188 | gf_log (this->name, GF_LOG_ERROR, "%s/%s"do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1190, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1189 | " gfid not present", loc->path,do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1190, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1190 | entry->d_name)do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1190, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0); | |||
1191 | continue; | |||
1192 | } | |||
1193 | ||||
1194 | uuid_copy (entry_loc.pargfid, loc->gfid); | |||
1195 | ||||
1196 | entry_loc.inode->ia_type = entry->d_stat.ia_type; | |||
1197 | ||||
1198 | ret = syncop_lookup (this, &entry_loc, NULL((void*)0), &iatt, | |||
1199 | NULL((void*)0), NULL((void*)0)); | |||
1200 | if (ret) { | |||
1201 | gf_log (this->name, GF_LOG_ERROR, "%s"do { do { if (0) printf ("%s" " lookup failed", entry_loc.path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1202, GF_LOG_ERROR, "%s" " lookup failed", entry_loc.path); } while (0) | |||
1202 | " lookup failed", entry_loc.path)do { do { if (0) printf ("%s" " lookup failed", entry_loc.path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1202, GF_LOG_ERROR, "%s" " lookup failed", entry_loc.path); } while (0); | |||
1203 | continue; | |||
1204 | } | |||
1205 | ||||
1206 | ret = syncop_getxattr (this, &entry_loc, &dict, | |||
1207 | GF_XATTR_NODE_UUID_KEY"trusted.glusterfs.node-uuid"); | |||
1208 | if(ret < 0) { | |||
1209 | gf_log (this->name, GF_LOG_ERROR, "Failed to "do { do { if (0) printf ("Failed to " "get node-uuid for %s", entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1210, GF_LOG_ERROR, "Failed to " "get node-uuid for %s" , entry_loc.path); } while (0) | |||
1210 | "get node-uuid for %s", entry_loc.path)do { do { if (0) printf ("Failed to " "get node-uuid for %s", entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1210, GF_LOG_ERROR, "Failed to " "get node-uuid for %s" , entry_loc.path); } while (0); | |||
1211 | continue; | |||
1212 | } | |||
1213 | ||||
1214 | ret = dict_get_str (dict, GF_XATTR_NODE_UUID_KEY"trusted.glusterfs.node-uuid", | |||
1215 | &uuid_str); | |||
1216 | if(ret < 0) { | |||
1217 | gf_log (this->name, GF_LOG_ERROR, "Failed to "do { do { if (0) printf ("Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1219, GF_LOG_ERROR, "Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0) | |||
1218 | "get node-uuid from dict for %s",do { do { if (0) printf ("Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1219, GF_LOG_ERROR, "Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0) | |||
1219 | entry_loc.path)do { do { if (0) printf ("Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1219, GF_LOG_ERROR, "Failed to " "get node-uuid from dict for %s" , entry_loc.path); } while (0); | |||
1220 | continue; | |||
1221 | } | |||
1222 | ||||
1223 | if (uuid_parse (uuid_str, node_uuid)) { | |||
1224 | gf_log (this->name, GF_LOG_ERROR, "uuid_parse "do { do { if (0) printf ("uuid_parse " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1225, GF_LOG_ERROR, "uuid_parse " "failed for %s" , entry_loc.path); } while (0) | |||
1225 | "failed for %s", entry_loc.path)do { do { if (0) printf ("uuid_parse " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1225, GF_LOG_ERROR, "uuid_parse " "failed for %s" , entry_loc.path); } while (0); | |||
1226 | continue; | |||
1227 | } | |||
1228 | ||||
1229 | /* if file belongs to different node, skip migration | |||
1230 | * the other node will take responsibility of migration | |||
1231 | */ | |||
1232 | if (uuid_compare (node_uuid, defrag->node_uuid)) { | |||
1233 | gf_log (this->name, GF_LOG_TRACE, "%s does not"do { do { if (0) printf ("%s does not" "belong to this node", entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1234, GF_LOG_TRACE, "%s does not" "belong to this node" , entry_loc.path); } while (0) | |||
1234 | "belong to this node", entry_loc.path)do { do { if (0) printf ("%s does not" "belong to this node", entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1234, GF_LOG_TRACE, "%s does not" "belong to this node" , entry_loc.path); } while (0); | |||
1235 | continue; | |||
1236 | } | |||
1237 | ||||
1238 | uuid_str = NULL((void*)0); | |||
1239 | ||||
1240 | dict_del (dict, GF_XATTR_NODE_UUID_KEY"trusted.glusterfs.node-uuid"); | |||
1241 | ||||
1242 | ||||
1243 | /* if distribute is present, it will honor this key. | |||
1244 | * -1 is returned if distribute is not present or file | |||
1245 | * doesn't have a link-file. If file has link-file, the | |||
1246 | * path of link-file will be the value, and also that | |||
1247 | * guarantees that file has to be mostly migrated */ | |||
1248 | ||||
1249 | ret = syncop_getxattr (this, &entry_loc, &dict, | |||
1250 | GF_XATTR_LINKINFO_KEY"trusted.distribute.linkinfo"); | |||
1251 | if (ret < 0) { | |||
1252 | gf_log (this->name, GF_LOG_TRACE, "failed to "do { do { if (0) printf ("failed to " "get link-to key for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1254, GF_LOG_TRACE, "failed to " "get link-to key for %s" , entry_loc.path); } while (0) | |||
1253 | "get link-to key for %s",do { do { if (0) printf ("failed to " "get link-to key for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1254, GF_LOG_TRACE, "failed to " "get link-to key for %s" , entry_loc.path); } while (0) | |||
1254 | entry_loc.path)do { do { if (0) printf ("failed to " "get link-to key for %s" , entry_loc.path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1254, GF_LOG_TRACE, "failed to " "get link-to key for %s" , entry_loc.path); } while (0); | |||
1255 | continue; | |||
1256 | } | |||
1257 | ||||
1258 | ret = syncop_setxattr (this, &entry_loc, migrate_data, | |||
1259 | 0); | |||
1260 | if (ret) { | |||
1261 | gf_log (this->name, GF_LOG_ERROR, "migrate-data"do { do { if (0) printf ("migrate-data" " failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1262, GF_LOG_ERROR, "migrate-data" " failed for %s" , entry_loc.path); } while (0) | |||
1262 | " failed for %s", entry_loc.path)do { do { if (0) printf ("migrate-data" " failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1262, GF_LOG_ERROR, "migrate-data" " failed for %s" , entry_loc.path); } while (0); | |||
1263 | defrag->total_failures +=1; | |||
1264 | } | |||
1265 | ||||
1266 | if (ret == -1) { | |||
1267 | op_errno = errno(*__errno_location ()); | |||
1268 | ret = gf_defrag_handle_migrate_error (op_errno, | |||
1269 | defrag); | |||
1270 | ||||
1271 | if (!ret) | |||
1272 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("migrate-data on %s failed: %s", entry_loc .path, strerror (op_errno)); } while (0); _gf_log (this->name , "dht-rebalance.c", __FUNCTION__, 1275, GF_LOG_DEBUG, "migrate-data on %s failed: %s" , entry_loc.path, strerror (op_errno)); } while (0) | |||
1273 | "migrate-data on %s failed: %s",do { do { if (0) printf ("migrate-data on %s failed: %s", entry_loc .path, strerror (op_errno)); } while (0); _gf_log (this->name , "dht-rebalance.c", __FUNCTION__, 1275, GF_LOG_DEBUG, "migrate-data on %s failed: %s" , entry_loc.path, strerror (op_errno)); } while (0) | |||
1274 | entry_loc.path,do { do { if (0) printf ("migrate-data on %s failed: %s", entry_loc .path, strerror (op_errno)); } while (0); _gf_log (this->name , "dht-rebalance.c", __FUNCTION__, 1275, GF_LOG_DEBUG, "migrate-data on %s failed: %s" , entry_loc.path, strerror (op_errno)); } while (0) | |||
1275 | strerror (op_errno))do { do { if (0) printf ("migrate-data on %s failed: %s", entry_loc .path, strerror (op_errno)); } while (0); _gf_log (this->name , "dht-rebalance.c", __FUNCTION__, 1275, GF_LOG_DEBUG, "migrate-data on %s failed: %s" , entry_loc.path, strerror (op_errno)); } while (0); | |||
1276 | else if (ret == 1) | |||
1277 | continue; | |||
1278 | else if (ret == -1) | |||
1279 | goto out; | |||
1280 | } | |||
1281 | ||||
1282 | LOCK (&defrag->lock)pthread_spin_lock (&defrag->lock); | |||
1283 | { | |||
1284 | defrag->total_files += 1; | |||
1285 | defrag->total_data += iatt.ia_size; | |||
1286 | } | |||
1287 | UNLOCK (&defrag->lock)pthread_spin_unlock (&defrag->lock); | |||
1288 | if (defrag->stats == _gf_true) { | |||
1289 | gettimeofday (&end, NULL((void*)0)); | |||
1290 | elapsed = (end.tv_sec - start.tv_sec) * 1e6 + | |||
1291 | (end.tv_usec - start.tv_usec); | |||
1292 | gf_log (this->name, GF_LOG_INFO, "Migration of "do { do { if (0) printf ("Migration of " "file:%s size:%""ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size, elapsed /1e6); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1295, GF_LOG_INFO, "Migration of " "file:%s size:%" "ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size , elapsed/1e6); } while (0) | |||
1293 | "file:%s size:%"PRIu64" bytes took %.2f"do { do { if (0) printf ("Migration of " "file:%s size:%""ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size, elapsed /1e6); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1295, GF_LOG_INFO, "Migration of " "file:%s size:%" "ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size , elapsed/1e6); } while (0) | |||
1294 | "secs", entry_loc.path, iatt.ia_size,do { do { if (0) printf ("Migration of " "file:%s size:%""ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size, elapsed /1e6); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1295, GF_LOG_INFO, "Migration of " "file:%s size:%" "ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size , elapsed/1e6); } while (0) | |||
1295 | elapsed/1e6)do { do { if (0) printf ("Migration of " "file:%s size:%""ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size, elapsed /1e6); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1295, GF_LOG_INFO, "Migration of " "file:%s size:%" "ll" "u"" bytes took %.2f" "secs", entry_loc.path, iatt.ia_size , elapsed/1e6); } while (0); | |||
1296 | } | |||
1297 | } | |||
1298 | ||||
1299 | gf_dirent_free (&entries); | |||
1300 | free_entries = _gf_false; | |||
1301 | INIT_LIST_HEAD (&entries.list)do { (&entries.list)->next = (&entries.list)->prev = &entries.list; } while (0); | |||
1302 | ||||
1303 | if (readdir_operrno == ENOENT2) | |||
1304 | break; | |||
1305 | } | |||
1306 | ||||
1307 | gettimeofday (&end, NULL((void*)0)); | |||
1308 | elapsed = (end.tv_sec - dir_start.tv_sec) * 1e6 + | |||
1309 | (end.tv_usec - dir_start.tv_usec); | |||
1310 | gf_log (this->name, GF_LOG_INFO, "Migration operation on dir %s took "do { do { if (0) printf ("Migration operation on dir %s took " "%.2f secs", loc->path, elapsed/1e6); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1311, GF_LOG_INFO , "Migration operation on dir %s took " "%.2f secs", loc-> path, elapsed/1e6); } while (0) | |||
1311 | "%.2f secs", loc->path, elapsed/1e6)do { do { if (0) printf ("Migration operation on dir %s took " "%.2f secs", loc->path, elapsed/1e6); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1311, GF_LOG_INFO , "Migration operation on dir %s took " "%.2f secs", loc-> path, elapsed/1e6); } while (0); | |||
1312 | ret = 0; | |||
1313 | out: | |||
1314 | if (free_entries) | |||
1315 | gf_dirent_free (&entries); | |||
1316 | ||||
1317 | loc_wipe (&entry_loc); | |||
1318 | ||||
1319 | if (dict) | |||
1320 | dict_unref(dict); | |||
1321 | ||||
1322 | if (fd) | |||
1323 | fd_unref (fd); | |||
1324 | return ret; | |||
1325 | ||||
1326 | } | |||
1327 | ||||
1328 | ||||
1329 | int | |||
1330 | gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, | |||
1331 | dict_t *fix_layout, dict_t *migrate_data) | |||
1332 | { | |||
1333 | int ret = -1; | |||
1334 | loc_t entry_loc = {0,}; | |||
1335 | fd_t *fd = NULL((void*)0); | |||
1336 | gf_dirent_t entries; | |||
1337 | gf_dirent_t *tmp = NULL((void*)0); | |||
1338 | gf_dirent_t *entry = NULL((void*)0); | |||
1339 | gf_boolean_t free_entries = _gf_false; | |||
1340 | dict_t *dict = NULL((void*)0); | |||
1341 | off_t offset = 0; | |||
1342 | struct iatt iatt = {0,}; | |||
1343 | int readdirp_errno = 0; | |||
1344 | ||||
1345 | ret = syncop_lookup (this, loc, NULL((void*)0), &iatt, NULL((void*)0), NULL((void*)0)); | |||
1346 | if (ret) { | |||
1347 | gf_log (this->name, GF_LOG_ERROR, "Lookup failed on %s",do { do { if (0) printf ("Lookup failed on %s", loc->path) ; } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1348, GF_LOG_ERROR, "Lookup failed on %s", loc->path); } while (0) | |||
1348 | loc->path)do { do { if (0) printf ("Lookup failed on %s", loc->path) ; } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1348, GF_LOG_ERROR, "Lookup failed on %s", loc->path); } while (0); | |||
1349 | goto out; | |||
1350 | } | |||
1351 | ||||
1352 | if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { | |||
1353 | ret = gf_defrag_migrate_data (this, defrag, loc, migrate_data); | |||
1354 | if (ret) | |||
1355 | goto out; | |||
1356 | } | |||
1357 | ||||
1358 | gf_log (this->name, GF_LOG_TRACE, "fix layout called on %s", loc->path)do { do { if (0) printf ("fix layout called on %s", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1358, GF_LOG_TRACE, "fix layout called on %s", loc->path ); } while (0); | |||
1359 | ||||
1360 | fd = fd_create (loc->inode, defrag->pid); | |||
1361 | if (!fd) { | |||
1362 | gf_log (this->name, GF_LOG_ERROR, "Failed to create fd")do { do { if (0) printf ("Failed to create fd"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1362 , GF_LOG_ERROR, "Failed to create fd"); } while (0); | |||
1363 | ret = -1; | |||
1364 | goto out; | |||
1365 | } | |||
1366 | ||||
1367 | ret = syncop_opendir (this, loc, fd); | |||
1368 | if (ret) { | |||
1369 | gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s",do { do { if (0) printf ("Failed to open dir %s", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1370, GF_LOG_ERROR, "Failed to open dir %s", loc->path); } while (0) | |||
1370 | loc->path)do { do { if (0) printf ("Failed to open dir %s", loc->path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1370, GF_LOG_ERROR, "Failed to open dir %s", loc->path); } while (0); | |||
1371 | ret = -1; | |||
1372 | goto out; | |||
1373 | } | |||
1374 | ||||
1375 | INIT_LIST_HEAD (&entries.list)do { (&entries.list)->next = (&entries.list)->prev = &entries.list; } while (0); | |||
1376 | while ((ret = syncop_readdirp (this, fd, 131072, offset, NULL((void*)0), | |||
1377 | &entries)) != 0) | |||
1378 | { | |||
1379 | ||||
1380 | if (ret < 0) { | |||
1381 | gf_log (this->name, GF_LOG_ERROR, "Readdir returned %s"do { do { if (0) printf ("Readdir returned %s" ". Aborting fix-layout" ,strerror((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 1382, GF_LOG_ERROR , "Readdir returned %s" ". Aborting fix-layout",strerror((*__errno_location ()))); } while (0) | |||
1382 | ". Aborting fix-layout",strerror(errno))do { do { if (0) printf ("Readdir returned %s" ". Aborting fix-layout" ,strerror((*__errno_location ()))); } while (0); _gf_log (this ->name, "dht-rebalance.c", __FUNCTION__, 1382, GF_LOG_ERROR , "Readdir returned %s" ". Aborting fix-layout",strerror((*__errno_location ()))); } while (0); | |||
1383 | goto out; | |||
1384 | } | |||
1385 | ||||
1386 | /* Need to keep track of ENOENT errno, that means, there is no | |||
1387 | need to send more readdirp() */ | |||
1388 | readdirp_errno = errno(*__errno_location ()); | |||
1389 | ||||
1390 | if (list_empty (&entries.list)) | |||
1391 | break; | |||
1392 | ||||
1393 | free_entries = _gf_true; | |||
1394 | ||||
1395 | list_for_each_entry_safe (entry, tmp, &entries.list, list)for (entry = ((typeof(*entry) *)((char *)((&entries.list) ->next)-(unsigned long)(&((typeof(*entry) *)0)->list ))), tmp = ((typeof(*entry) *)((char *)(entry->list.next)- (unsigned long)(&((typeof(*entry) *)0)->list))); & entry->list != (&entries.list); entry = tmp, tmp = ((typeof (*tmp) *)((char *)(tmp->list.next)-(unsigned long)(&(( typeof(*tmp) *)0)->list)))) { | |||
1396 | if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { | |||
1397 | ret = 1; | |||
1398 | goto out; | |||
1399 | } | |||
1400 | ||||
1401 | offset = entry->d_off; | |||
1402 | ||||
1403 | if (!strcmp (entry->d_name, ".") || | |||
1404 | !strcmp (entry->d_name, "..")) | |||
1405 | continue; | |||
1406 | ||||
1407 | if (!IA_ISDIR (entry->d_stat.ia_type)(entry->d_stat.ia_type == IA_IFDIR)) | |||
1408 | continue; | |||
1409 | ||||
1410 | loc_wipe (&entry_loc); | |||
1411 | ret =dht_build_child_loc (this, &entry_loc, loc, | |||
1412 | entry->d_name); | |||
1413 | if (ret) { | |||
1414 | gf_log (this->name, GF_LOG_ERROR, "Child loc"do { do { if (0) printf ("Child loc" " build failed"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1415, GF_LOG_ERROR, "Child loc" " build failed"); } while ( 0) | |||
1415 | " build failed")do { do { if (0) printf ("Child loc" " build failed"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1415, GF_LOG_ERROR, "Child loc" " build failed"); } while ( 0); | |||
1416 | goto out; | |||
1417 | } | |||
1418 | ||||
1419 | if (uuid_is_null (entry->d_stat.ia_gfid)) { | |||
1420 | gf_log (this->name, GF_LOG_ERROR, "%s/%s"do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1422, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1421 | " gfid not present", loc->path,do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1422, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1422 | entry->d_name)do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1422, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0); | |||
1423 | continue; | |||
1424 | } | |||
1425 | ||||
1426 | entry_loc.inode->ia_type = entry->d_stat.ia_type; | |||
1427 | ||||
1428 | uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid); | |||
1429 | if (uuid_is_null (loc->gfid)) { | |||
1430 | gf_log (this->name, GF_LOG_ERROR, "%s/%s"do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1432, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1431 | " gfid not present", loc->path,do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1432, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0) | |||
1432 | entry->d_name)do { do { if (0) printf ("%s/%s" " gfid not present", loc-> path, entry->d_name); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1432, GF_LOG_ERROR, "%s/%s" " gfid not present", loc->path, entry->d_name); } while (0); | |||
1433 | continue; | |||
1434 | } | |||
1435 | ||||
1436 | uuid_copy (entry_loc.pargfid, loc->gfid); | |||
1437 | ||||
1438 | ret = syncop_lookup (this, &entry_loc, NULL((void*)0), &iatt, | |||
1439 | NULL((void*)0), NULL((void*)0)); | |||
1440 | if (ret) { | |||
1441 | gf_log (this->name, GF_LOG_ERROR, "%s"do { do { if (0) printf ("%s" " lookup failed", entry_loc.path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1442, GF_LOG_ERROR, "%s" " lookup failed", entry_loc.path); } while (0) | |||
1442 | " lookup failed", entry_loc.path)do { do { if (0) printf ("%s" " lookup failed", entry_loc.path ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1442, GF_LOG_ERROR, "%s" " lookup failed", entry_loc.path); } while (0); | |||
1443 | continue; | |||
1444 | } | |||
1445 | ||||
1446 | ret = syncop_setxattr (this, &entry_loc, fix_layout, | |||
1447 | 0); | |||
1448 | if (ret) { | |||
1449 | gf_log (this->name, GF_LOG_ERROR, "Setxattr "do { do { if (0) printf ("Setxattr " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1450, GF_LOG_ERROR, "Setxattr " "failed for %s" , entry_loc.path); } while (0) | |||
1450 | "failed for %s", entry_loc.path)do { do { if (0) printf ("Setxattr " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1450, GF_LOG_ERROR, "Setxattr " "failed for %s" , entry_loc.path); } while (0); | |||
1451 | defrag->defrag_status = | |||
1452 | GF_DEFRAG_STATUS_FAILED; | |||
1453 | defrag->total_failures ++; | |||
1454 | goto out; | |||
1455 | } | |||
1456 | ret = gf_defrag_fix_layout (this, defrag, &entry_loc, | |||
1457 | fix_layout, migrate_data); | |||
1458 | ||||
1459 | if (ret) { | |||
1460 | gf_log (this->name, GF_LOG_ERROR, "Fix layout "do { do { if (0) printf ("Fix layout " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1461, GF_LOG_ERROR, "Fix layout " "failed for %s" , entry_loc.path); } while (0) | |||
1461 | "failed for %s", entry_loc.path)do { do { if (0) printf ("Fix layout " "failed for %s", entry_loc .path); } while (0); _gf_log (this->name, "dht-rebalance.c" , __FUNCTION__, 1461, GF_LOG_ERROR, "Fix layout " "failed for %s" , entry_loc.path); } while (0); | |||
1462 | defrag->total_failures++; | |||
1463 | goto out; | |||
1464 | } | |||
1465 | ||||
1466 | } | |||
1467 | gf_dirent_free (&entries); | |||
1468 | free_entries = _gf_false; | |||
1469 | INIT_LIST_HEAD (&entries.list)do { (&entries.list)->next = (&entries.list)->prev = &entries.list; } while (0); | |||
1470 | if (readdirp_errno == ENOENT2) | |||
1471 | break; | |||
1472 | } | |||
1473 | ||||
1474 | ret = 0; | |||
1475 | out: | |||
1476 | if (free_entries) | |||
1477 | gf_dirent_free (&entries); | |||
1478 | ||||
1479 | loc_wipe (&entry_loc); | |||
1480 | ||||
1481 | if (dict) | |||
1482 | dict_unref(dict); | |||
1483 | ||||
1484 | if (fd) | |||
1485 | fd_unref (fd); | |||
1486 | ||||
1487 | return ret; | |||
1488 | ||||
1489 | } | |||
1490 | ||||
1491 | ||||
1492 | int | |||
1493 | gf_defrag_start_crawl (void *data) | |||
1494 | { | |||
1495 | xlator_t *this = NULL((void*)0); | |||
1496 | dht_conf_t *conf = NULL((void*)0); | |||
1497 | gf_defrag_info_t *defrag = NULL((void*)0); | |||
1498 | int ret = -1; | |||
1499 | loc_t loc = {0,}; | |||
1500 | struct iatt iatt = {0,}; | |||
1501 | struct iatt parent = {0,}; | |||
1502 | dict_t *fix_layout = NULL((void*)0); | |||
1503 | dict_t *migrate_data = NULL((void*)0); | |||
1504 | dict_t *status = NULL((void*)0); | |||
1505 | glusterfs_ctx_t *ctx = NULL((void*)0); | |||
1506 | ||||
1507 | this = data; | |||
1508 | if (!this) | |||
1509 | goto out; | |||
1510 | ||||
1511 | ctx = this->ctx; | |||
1512 | if (!ctx) | |||
1513 | goto out; | |||
1514 | ||||
1515 | conf = this->private; | |||
1516 | if (!conf) | |||
1517 | goto out; | |||
1518 | ||||
1519 | defrag = conf->defrag; | |||
1520 | if (!defrag) | |||
1521 | goto out; | |||
1522 | ||||
1523 | gettimeofday (&defrag->start_time, NULL((void*)0)); | |||
1524 | dht_build_root_inode (this, &defrag->root_inode); | |||
1525 | if (!defrag->root_inode) | |||
1526 | goto out; | |||
1527 | ||||
1528 | dht_build_root_loc (defrag->root_inode, &loc); | |||
1529 | ||||
1530 | /* fix-layout on '/' first */ | |||
1531 | ||||
1532 | ret = syncop_lookup (this, &loc, NULL((void*)0), &iatt, NULL((void*)0), &parent); | |||
1533 | ||||
1534 | if (ret) { | |||
1535 | gf_log (this->name, GF_LOG_ERROR, "look up on / failed")do { do { if (0) printf ("look up on / failed"); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1535 , GF_LOG_ERROR, "look up on / failed"); } while (0); | |||
1536 | goto out; | |||
1537 | } | |||
1538 | ||||
1539 | fix_layout = dict_new (); | |||
1540 | if (!fix_layout) { | |||
1541 | ret = -1; | |||
1542 | goto out; | |||
1543 | } | |||
1544 | ||||
1545 | ret = dict_set_str (fix_layout, GF_XATTR_FIX_LAYOUT_KEY"distribute.fix.layout", "yes"); | |||
1546 | if (ret) { | |||
1547 | gf_log (this->name, GF_LOG_ERROR, "Failed to set dict str")do { do { if (0) printf ("Failed to set dict str"); } while ( 0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__, 1547 , GF_LOG_ERROR, "Failed to set dict str"); } while (0); | |||
1548 | goto out; | |||
1549 | } | |||
1550 | ||||
1551 | ret = syncop_setxattr (this, &loc, fix_layout, 0); | |||
1552 | if (ret) { | |||
1553 | gf_log (this->name, GF_LOG_ERROR, "fix layout on %s failed",do { do { if (0) printf ("fix layout on %s failed", loc.path) ; } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1554, GF_LOG_ERROR, "fix layout on %s failed", loc.path); } while (0) | |||
1554 | loc.path)do { do { if (0) printf ("fix layout on %s failed", loc.path) ; } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1554, GF_LOG_ERROR, "fix layout on %s failed", loc.path); } while (0); | |||
1555 | defrag->total_failures++; | |||
1556 | goto out; | |||
1557 | } | |||
1558 | ||||
1559 | if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { | |||
1560 | migrate_data = dict_new (); | |||
1561 | if (!migrate_data) { | |||
1562 | ret = -1; | |||
1563 | goto out; | |||
1564 | } | |||
1565 | if (defrag->cmd == GF_DEFRAG_CMD_START_FORCE) | |||
1566 | ret = dict_set_str (migrate_data, | |||
1567 | "distribute.migrate-data", "force"); | |||
1568 | else | |||
1569 | ret = dict_set_str (migrate_data, | |||
1570 | "distribute.migrate-data", | |||
1571 | "non-force"); | |||
1572 | if (ret) | |||
1573 | goto out; | |||
1574 | } | |||
1575 | ret = gf_defrag_fix_layout (this, defrag, &loc, fix_layout, | |||
1576 | migrate_data); | |||
1577 | if ((defrag->defrag_status != GF_DEFRAG_STATUS_STOPPED) && | |||
1578 | (defrag->defrag_status != GF_DEFRAG_STATUS_FAILED)) { | |||
1579 | defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE; | |||
1580 | } | |||
1581 | ||||
1582 | ||||
1583 | ||||
1584 | out: | |||
1585 | LOCK (&defrag->lock)pthread_spin_lock (&defrag->lock); | |||
1586 | { | |||
1587 | status = dict_new (); | |||
1588 | gf_defrag_status_get (defrag, status); | |||
1589 | if (ctx->notify) | |||
1590 | ctx->notify (GF_EN_DEFRAG_STATUS, status); | |||
1591 | if (status) | |||
1592 | dict_unref (status); | |||
1593 | defrag->is_exiting = 1; | |||
1594 | } | |||
1595 | UNLOCK (&defrag->lock)pthread_spin_unlock (&defrag->lock); | |||
1596 | ||||
1597 | if (defrag) { | |||
1598 | GF_FREE (defrag)__gf_free (defrag); | |||
1599 | conf->defrag = NULL((void*)0); | |||
1600 | } | |||
1601 | ||||
1602 | return ret; | |||
1603 | } | |||
1604 | ||||
1605 | ||||
1606 | static int | |||
1607 | gf_defrag_done (int ret, call_frame_t *sync_frame, void *data) | |||
1608 | { | |||
1609 | gf_listener_stop (sync_frame->this); | |||
| ||||
1610 | ||||
1611 | STACK_DESTROY (sync_frame->root); | |||
1612 | kill (getpid(), SIGTERM15); | |||
1613 | return 0; | |||
1614 | } | |||
1615 | ||||
1616 | void * | |||
1617 | gf_defrag_start (void *data) | |||
1618 | { | |||
1619 | int ret = -1; | |||
1620 | call_frame_t *frame = NULL((void*)0); | |||
1621 | dht_conf_t *conf = NULL((void*)0); | |||
1622 | gf_defrag_info_t *defrag = NULL((void*)0); | |||
1623 | xlator_t *this = NULL((void*)0); | |||
1624 | ||||
1625 | this = data; | |||
1626 | conf = this->private; | |||
1627 | if (!conf) | |||
1628 | goto out; | |||
1629 | ||||
1630 | defrag = conf->defrag; | |||
1631 | if (!defrag) | |||
1632 | goto out; | |||
1633 | ||||
1634 | frame = create_frame (this, this->ctx->pool); | |||
1635 | if (!frame) | |||
1636 | goto out; | |||
1637 | ||||
1638 | frame->root->pid = GF_CLIENT_PID_DEFRAG; | |||
1639 | ||||
1640 | defrag->pid = frame->root->pid; | |||
1641 | ||||
1642 | defrag->defrag_status = GF_DEFRAG_STATUS_STARTED; | |||
1643 | ||||
1644 | ret = synctask_new (this->ctx->env, gf_defrag_start_crawl, | |||
1645 | gf_defrag_done, frame, this); | |||
1646 | ||||
1647 | if (ret) | |||
1648 | gf_log (this->name, GF_LOG_ERROR, "Could not create"do { do { if (0) printf ("Could not create" " task for rebalance" ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1649, GF_LOG_ERROR, "Could not create" " task for rebalance" ); } while (0) | |||
1649 | " task for rebalance")do { do { if (0) printf ("Could not create" " task for rebalance" ); } while (0); _gf_log (this->name, "dht-rebalance.c", __FUNCTION__ , 1649, GF_LOG_ERROR, "Could not create" " task for rebalance" ); } while (0); | |||
1650 | out: | |||
1651 | return NULL((void*)0); | |||
1652 | } | |||
1653 | ||||
1654 | int | |||
1655 | gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict) | |||
1656 | { | |||
1657 | int ret = 0; | |||
1658 | uint64_t files = 0; | |||
1659 | uint64_t size = 0; | |||
1660 | uint64_t lookup = 0; | |||
1661 | uint64_t failures = 0; | |||
1662 | char *status = ""; | |||
1663 | double elapsed = 0; | |||
1664 | struct timeval end = {0,}; | |||
1665 | ||||
1666 | ||||
1667 | if (!defrag) | |||
1668 | goto out; | |||
1669 | ||||
1670 | ret = 0; | |||
1671 | if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED) | |||
1672 | goto out; | |||
1673 | ||||
1674 | files = defrag->total_files; | |||
1675 | size = defrag->total_data; | |||
1676 | lookup = defrag->num_files_lookedup; | |||
1677 | failures = defrag->total_failures; | |||
1678 | ||||
1679 | gettimeofday (&end, NULL((void*)0)); | |||
1680 | ||||
1681 | elapsed = end.tv_sec - defrag->start_time.tv_sec; | |||
1682 | ||||
1683 | if (!dict) | |||
1684 | goto log; | |||
1685 | ||||
1686 | ret = dict_set_uint64 (dict, "files", files); | |||
1687 | if (ret) | |||
1688 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set file count"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1689, GF_LOG_WARNING, "failed to set file count" ); } while (0) | |||
1689 | "failed to set file count")do { do { if (0) printf ("failed to set file count"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1689, GF_LOG_WARNING, "failed to set file count" ); } while (0); | |||
1690 | ||||
1691 | ret = dict_set_uint64 (dict, "size", size); | |||
1692 | if (ret) | |||
1693 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set size of xfer"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1694, GF_LOG_WARNING, "failed to set size of xfer" ); } while (0) | |||
1694 | "failed to set size of xfer")do { do { if (0) printf ("failed to set size of xfer"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1694, GF_LOG_WARNING, "failed to set size of xfer" ); } while (0); | |||
1695 | ||||
1696 | ret = dict_set_uint64 (dict, "lookups", lookup); | |||
1697 | if (ret) | |||
1698 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set lookedup file count") ; } while (0); _gf_log ((*__glusterfs_this_location())->name , "dht-rebalance.c", __FUNCTION__, 1699, GF_LOG_WARNING, "failed to set lookedup file count" ); } while (0) | |||
1699 | "failed to set lookedup file count")do { do { if (0) printf ("failed to set lookedup file count") ; } while (0); _gf_log ((*__glusterfs_this_location())->name , "dht-rebalance.c", __FUNCTION__, 1699, GF_LOG_WARNING, "failed to set lookedup file count" ); } while (0); | |||
1700 | ||||
1701 | ret = dict_set_int32 (dict, "status", defrag->defrag_status); | |||
1702 | if (ret) | |||
1703 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set status"); } while (0) ; _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1704, GF_LOG_WARNING, "failed to set status") ; } while (0) | |||
1704 | "failed to set status")do { do { if (0) printf ("failed to set status"); } while (0) ; _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1704, GF_LOG_WARNING, "failed to set status") ; } while (0); | |||
1705 | if (elapsed) { | |||
1706 | ret = dict_set_double (dict, "run-time", elapsed); | |||
1707 | if (ret) | |||
1708 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set run-time"); } while ( 0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1709, GF_LOG_WARNING, "failed to set run-time" ); } while (0) | |||
1709 | "failed to set run-time")do { do { if (0) printf ("failed to set run-time"); } while ( 0); _gf_log ((*__glusterfs_this_location())->name, "dht-rebalance.c" , __FUNCTION__, 1709, GF_LOG_WARNING, "failed to set run-time" ); } while (0); | |||
1710 | } | |||
1711 | ||||
1712 | ret = dict_set_uint64 (dict, "failures", failures); | |||
1713 | log: | |||
1714 | switch (defrag->defrag_status) { | |||
1715 | case GF_DEFRAG_STATUS_NOT_STARTED: | |||
1716 | status = "not started"; | |||
1717 | break; | |||
1718 | case GF_DEFRAG_STATUS_STARTED: | |||
1719 | status = "in progress"; | |||
1720 | break; | |||
1721 | case GF_DEFRAG_STATUS_STOPPED: | |||
1722 | status = "stopped"; | |||
1723 | break; | |||
1724 | case GF_DEFRAG_STATUS_COMPLETE: | |||
1725 | status = "completed"; | |||
1726 | break; | |||
1727 | case GF_DEFRAG_STATUS_FAILED: | |||
1728 | status = "failed"; | |||
1729 | break; | |||
1730 | } | |||
1731 | ||||
1732 | gf_log (THIS->name, GF_LOG_INFO, "Rebalance is %s. Time taken is %.2f "do { do { if (0) printf ("Rebalance is %s. Time taken is %.2f " "secs", status, elapsed); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 1733, GF_LOG_INFO , "Rebalance is %s. Time taken is %.2f " "secs", status, elapsed ); } while (0) | |||
1733 | "secs", status, elapsed)do { do { if (0) printf ("Rebalance is %s. Time taken is %.2f " "secs", status, elapsed); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 1733, GF_LOG_INFO , "Rebalance is %s. Time taken is %.2f " "secs", status, elapsed ); } while (0); | |||
1734 | gf_log (THIS->name, GF_LOG_INFO, "Files migrated: %"PRIu64", size: %"do { do { if (0) printf ("Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %""ll" "u"", failures: %""ll" "u", files , size, lookup, failures); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 1736, GF_LOG_INFO , "Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %" "ll" "u"", failures: %""ll" "u", files, size, lookup, failures ); } while (0) | |||
1735 | PRIu64", lookups: %"PRIu64", failures: %"PRIu64, files, size,do { do { if (0) printf ("Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %""ll" "u"", failures: %""ll" "u", files , size, lookup, failures); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 1736, GF_LOG_INFO , "Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %" "ll" "u"", failures: %""ll" "u", files, size, lookup, failures ); } while (0) | |||
1736 | lookup, failures)do { do { if (0) printf ("Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %""ll" "u"", failures: %""ll" "u", files , size, lookup, failures); } while (0); _gf_log ((*__glusterfs_this_location ())->name, "dht-rebalance.c", __FUNCTION__, 1736, GF_LOG_INFO , "Files migrated: %""ll" "u"", size: %" "ll" "u"", lookups: %" "ll" "u"", failures: %""ll" "u", files, size, lookup, failures ); } while (0); | |||
1737 | ||||
1738 | ||||
1739 | out: | |||
1740 | return 0; | |||
1741 | } | |||
1742 | ||||
1743 | int | |||
1744 | gf_defrag_stop (gf_defrag_info_t *defrag, dict_t *output) | |||
1745 | { | |||
1746 | /* TODO: set a variable 'stop_defrag' here, it should be checked | |||
1747 | in defrag loop */ | |||
1748 | int ret = -1; | |||
1749 | GF_ASSERT (defrag)do { if (!(defrag)) { do { do { if (0) printf ("Assertion failed: " "defrag"); } while (0); _gf_log_callingfn ("", "dht-rebalance.c" , __FUNCTION__, 1749, GF_LOG_ERROR, "Assertion failed: " "defrag" ); } while (0); } } while (0); | |||
1750 | ||||
1751 | if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED) { | |||
1752 | goto out; | |||
1753 | } | |||
1754 | ||||
1755 | gf_log ("", GF_LOG_INFO, "Received stop command on rebalance")do { do { if (0) printf ("Received stop command on rebalance" ); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__, 1755, GF_LOG_INFO, "Received stop command on rebalance"); } while (0); | |||
1756 | defrag->defrag_status = GF_DEFRAG_STATUS_STOPPED; | |||
1757 | ||||
1758 | if (output) | |||
1759 | gf_defrag_status_get (defrag, output); | |||
1760 | ret = 0; | |||
1761 | out: | |||
1762 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "dht-rebalance.c", __FUNCTION__, 1762, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||
1763 | return ret; | |||
1764 | } |