Bug Summary

File:xlators/mgmt/glusterd/src/glusterd-brick-ops.c
Location:line 1267, column 33
Description:Access to field 'name' results in a dereference of a null pointer (loaded from variable 'this')

Annotated Source Code

1/*
2 Copyright (c) 2011-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#ifndef _CONFIG_H
11#define _CONFIG_H
12#include "config.h"
13#endif
14
15#include "common-utils.h"
16#include "cli1-xdr.h"
17#include "xdr-generic.h"
18#include "glusterd.h"
19#include "glusterd-op-sm.h"
20#include "glusterd-store.h"
21#include "glusterd-utils.h"
22#include "glusterd-volgen.h"
23#include "run.h"
24#include <sys/signal.h>
25
26/* misc */
27
28/* In this function, we decide, based on the 'count' of the brick,
29 where to add it in the current volume. 'count' tells us already
30 how many of the given bricks are added. other argument are self-
31 descriptive. */
32int
33add_brick_at_right_order (glusterd_brickinfo_t *brickinfo,
34 glusterd_volinfo_t *volinfo, int count,
35 int32_t stripe_cnt, int32_t replica_cnt)
36{
37 int idx = 0;
38 int i = 0;
39 int sub_cnt = 0;
40 glusterd_brickinfo_t *brick = NULL((void*)0);
41
42 /* The complexity of the function is in deciding at which index
43 to add new brick. Even though it can be defined with a complex
44 single formula for all volume, it is seperated out to make it
45 more readable */
46 if (stripe_cnt) {
47 /* common formula when 'stripe_count' is set */
48 /* idx = ((count / ((stripe_cnt * volinfo->replica_count) -
49 volinfo->dist_leaf_count)) * volinfo->dist_leaf_count) +
50 (count + volinfo->dist_leaf_count);
51 */
52
53 sub_cnt = volinfo->dist_leaf_count;
54
55 idx = ((count / ((stripe_cnt * volinfo->replica_count) -
56 sub_cnt)) * sub_cnt) +
57 (count + sub_cnt);
58
59 goto insert_brick;
60 }
61
62 /* replica count is set */
63 /* common formula when 'replica_count' is set */
64 /* idx = ((count / (replica_cnt - existing_replica_count)) *
65 existing_replica_count) +
66 (count + existing_replica_count);
67 */
68
69 sub_cnt = volinfo->replica_count;
70 idx = (count / (replica_cnt - sub_cnt) * sub_cnt) +
71 (count + sub_cnt);
72
73insert_brick:
74 i = 0;
75 list_for_each_entry (brick, &volinfo->bricks, brick_list)for (brick = ((typeof(*brick) *)((char *)((&volinfo->bricks
)->next)-(unsigned long)(&((typeof(*brick) *)0)->brick_list
))); &brick->brick_list != (&volinfo->bricks); brick
= ((typeof(*brick) *)((char *)(brick->brick_list.next)-(unsigned
long)(&((typeof(*brick) *)0)->brick_list))))
{
76 i++;
77 if (i < idx)
78 continue;
79 gf_log (THIS->name, GF_LOG_DEBUG, "brick:%s index=%d, count=%d",do { do { if (0) printf ("brick:%s index=%d, count=%d", brick
->path, idx, count); } while (0); _gf_log ((*__glusterfs_this_location
())->name, "glusterd-brick-ops.c", __FUNCTION__, 80, GF_LOG_DEBUG
, "brick:%s index=%d, count=%d", brick->path, idx, count);
} while (0)
80 brick->path, idx, count)do { do { if (0) printf ("brick:%s index=%d, count=%d", brick
->path, idx, count); } while (0); _gf_log ((*__glusterfs_this_location
())->name, "glusterd-brick-ops.c", __FUNCTION__, 80, GF_LOG_DEBUG
, "brick:%s index=%d, count=%d", brick->path, idx, count);
} while (0)
;
81
82 list_add (&brickinfo->brick_list, &brick->brick_list);
83 break;
84 }
85
86 return 0;
87}
88
89
90static int
91gd_addbr_validate_stripe_count (glusterd_volinfo_t *volinfo, int stripe_count,
92 int total_bricks, int *type, char *err_str,
93 size_t err_len)
94{
95 int ret = -1;
96
97 switch (volinfo->type) {
98 case GF_CLUSTER_TYPE_NONE:
99 if ((volinfo->brick_count * stripe_count) == total_bricks) {
100 /* Change the volume type */
101 *type = GF_CLUSTER_TYPE_STRIPE;
102 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 104, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
)
103 "Changing the type of volume %s from "do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 104, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
)
104 "'distribute' to 'stripe'", volinfo->volname)do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 104, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'stripe'", volinfo->volname); } while (0
)
;
105 ret = 0;
106 goto out;
107 } else {
108 snprintf (err_str, err_len, "Incorrect number of "
109 "bricks (%d) supplied for stripe count (%d).",
110 (total_bricks - volinfo->brick_count),
111 stripe_count);
112 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 112, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
113 goto out;
114 }
115 break;
116 case GF_CLUSTER_TYPE_REPLICATE:
117 if (!(total_bricks % (volinfo->replica_count * stripe_count))) {
118 /* Change the volume type */
119 *type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
120 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"glusterd-brick-ops.c", __FUNCTION__, 123, GF_LOG_INFO, "Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0)
121 "Changing the type of volume %s from "do { do { if (0) printf ("Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"glusterd-brick-ops.c", __FUNCTION__, 123, GF_LOG_INFO, "Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0)
122 "'replicate' to 'replicate-stripe'",do { do { if (0) printf ("Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"glusterd-brick-ops.c", __FUNCTION__, 123, GF_LOG_INFO, "Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0)
123 volinfo->volname)do { do { if (0) printf ("Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"glusterd-brick-ops.c", __FUNCTION__, 123, GF_LOG_INFO, "Changing the type of volume %s from "
"'replicate' to 'replicate-stripe'", volinfo->volname); }
while (0)
;
124 ret = 0;
125 goto out;
126 } else {
127 snprintf (err_str, err_len, "Incorrect number of "
128 "bricks (%d) supplied for changing volume's "
129 "stripe count to %d, need at least %d bricks",
130 (total_bricks - volinfo->brick_count),
131 stripe_count,
132 (volinfo->replica_count * stripe_count));
133 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 133, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
134 goto out;
135 }
136 break;
137 case GF_CLUSTER_TYPE_STRIPE:
138 case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
139 if (stripe_count < volinfo->stripe_count) {
140 snprintf (err_str, err_len,
141 "Incorrect stripe count (%d) supplied. "
142 "Volume already has stripe count (%d)",
143 stripe_count, volinfo->stripe_count);
144 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 144, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
145 goto out;
146 }
147 if (stripe_count == volinfo->stripe_count) {
148 if (!(total_bricks % volinfo->dist_leaf_count)) {
149 /* its same as the one which exists */
150 ret = 1;
151 goto out;
152 }
153 }
154 if (stripe_count > volinfo->stripe_count) {
155 /* We have to make sure before and after 'add-brick',
156 the number or subvolumes for distribute will remain
157 same, when stripe count is given */
158 if ((volinfo->brick_count * (stripe_count *
159 volinfo->replica_count)) ==
160 (total_bricks * volinfo->dist_leaf_count)) {
161 /* Change the dist_leaf_count */
162 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the stripe count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->stripe_count, stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 166, GF_LOG_INFO, "Changing the stripe count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
stripe_count, stripe_count); } while (0)
163 "Changing the stripe count of "do { do { if (0) printf ("Changing the stripe count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->stripe_count, stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 166, GF_LOG_INFO, "Changing the stripe count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
stripe_count, stripe_count); } while (0)
164 "volume %s from %d to %d",do { do { if (0) printf ("Changing the stripe count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->stripe_count, stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 166, GF_LOG_INFO, "Changing the stripe count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
stripe_count, stripe_count); } while (0)
165 volinfo->volname,do { do { if (0) printf ("Changing the stripe count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->stripe_count, stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 166, GF_LOG_INFO, "Changing the stripe count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
stripe_count, stripe_count); } while (0)
166 volinfo->stripe_count, stripe_count)do { do { if (0) printf ("Changing the stripe count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->stripe_count, stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 166, GF_LOG_INFO, "Changing the stripe count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
stripe_count, stripe_count); } while (0)
;
167 ret = 0;
168 goto out;
169 }
170 }
171 break;
172 }
173
174out:
175 return ret;
176}
177
178static int
179gd_addbr_validate_replica_count (glusterd_volinfo_t *volinfo, int replica_count,
180 int total_bricks, int *type, char *err_str,
181 int err_len)
182{
183 int ret = -1;
184
185 /* replica count is set */
186 switch (volinfo->type) {
187 case GF_CLUSTER_TYPE_NONE:
188 if ((volinfo->brick_count * replica_count) == total_bricks) {
189 /* Change the volume type */
190 *type = GF_CLUSTER_TYPE_REPLICATE;
191 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 193, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0)
192 "Changing the type of volume %s from "do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 193, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0)
193 "'distribute' to 'replica'", volinfo->volname)do { do { if (0) printf ("Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 193, GF_LOG_INFO, "Changing the type of volume %s from "
"'distribute' to 'replica'", volinfo->volname); } while (
0)
;
194 ret = 0;
195 goto out;
196
197 } else {
198 snprintf (err_str, err_len, "Incorrect number of "
199 "bricks (%d) supplied for replica count (%d).",
200 (total_bricks - volinfo->brick_count),
201 replica_count);
202 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 202, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
203 goto out;
204 }
205 break;
206 case GF_CLUSTER_TYPE_STRIPE:
207 if (!(total_bricks % (volinfo->dist_leaf_count * replica_count))) {
208 /* Change the volume type */
209 *type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
210 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 213, GF_LOG_INFO, "Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0)
211 "Changing the type of volume %s from "do { do { if (0) printf ("Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 213, GF_LOG_INFO, "Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0)
212 "'stripe' to 'replicate-stripe'",do { do { if (0) printf ("Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 213, GF_LOG_INFO, "Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0)
213 volinfo->volname)do { do { if (0) printf ("Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 213, GF_LOG_INFO, "Changing the type of volume %s from "
"'stripe' to 'replicate-stripe'", volinfo->volname); } while
(0)
;
214 ret = 0;
215 goto out;
216 } else {
217 snprintf (err_str, err_len, "Incorrect number of "
218 "bricks (%d) supplied for changing volume's "
219 "replica count to %d, need at least %d "
220 "bricks",
221 (total_bricks - volinfo->brick_count),
222 replica_count, (volinfo->dist_leaf_count *
223 replica_count));
224 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 224, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
225 goto out;
226 }
227 break;
228 case GF_CLUSTER_TYPE_REPLICATE:
229 case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
230 if (replica_count < volinfo->replica_count) {
231 snprintf (err_str, err_len,
232 "Incorrect replica count (%d) supplied. "
233 "Volume already has (%d)",
234 replica_count, volinfo->replica_count);
235 gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 235, GF_LOG_ERROR, "%s", err_str); } while (0
)
;
236 goto out;
237 }
238 if (replica_count == volinfo->replica_count) {
239 if (!(total_bricks % volinfo->dist_leaf_count)) {
240 ret = 1;
241 goto out;
242 }
243 }
244 if (replica_count > volinfo->replica_count) {
245 /* We have to make sure before and after 'add-brick',
246 the number or subvolumes for distribute will remain
247 same, when replica count is given */
248 if ((total_bricks * volinfo->dist_leaf_count) ==
249 (volinfo->brick_count * (replica_count *
250 volinfo->stripe_count))) {
251 /* Change the dist_leaf_count */
252 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("Changing the replica count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->replica_count, replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 256, GF_LOG_INFO, "Changing the replica count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
replica_count, replica_count); } while (0)
253 "Changing the replica count of "do { do { if (0) printf ("Changing the replica count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->replica_count, replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 256, GF_LOG_INFO, "Changing the replica count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
replica_count, replica_count); } while (0)
254 "volume %s from %d to %d",do { do { if (0) printf ("Changing the replica count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->replica_count, replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 256, GF_LOG_INFO, "Changing the replica count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
replica_count, replica_count); } while (0)
255 volinfo->volname, volinfo->replica_count,do { do { if (0) printf ("Changing the replica count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->replica_count, replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 256, GF_LOG_INFO, "Changing the replica count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
replica_count, replica_count); } while (0)
256 replica_count)do { do { if (0) printf ("Changing the replica count of " "volume %s from %d to %d"
, volinfo->volname, volinfo->replica_count, replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 256, GF_LOG_INFO, "Changing the replica count of "
"volume %s from %d to %d", volinfo->volname, volinfo->
replica_count, replica_count); } while (0)
;
257 ret = 0;
258 goto out;
259 }
260 }
261 break;
262 }
263out:
264 return ret;
265}
266
267static int
268gd_rmbr_validate_replica_count (glusterd_volinfo_t *volinfo,
269 int32_t replica_count,
270 int32_t brick_count, char *err_str,
271 size_t err_len)
272{
273 int ret = -1;
274 int replica_nodes = 0;
275
276 switch (volinfo->type) {
277 case GF_CLUSTER_TYPE_NONE:
278 case GF_CLUSTER_TYPE_STRIPE:
279 snprintf (err_str, err_len,
280 "replica count (%d) option given for non replicate "
281 "volume %s", replica_count, volinfo->volname);
282 gf_log (THIS->name, GF_LOG_WARNING, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 282, GF_LOG_WARNING, "%s", err_str); } while (
0)
;
283 goto out;
284
285 case GF_CLUSTER_TYPE_REPLICATE:
286 case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
287 /* in remove brick, you can only reduce the replica count */
288 if (replica_count > volinfo->replica_count) {
289 snprintf (err_str, err_len,
290 "given replica count (%d) option is more "
291 "than volume %s's replica count (%d)",
292 replica_count, volinfo->volname,
293 volinfo->replica_count);
294 gf_log (THIS->name, GF_LOG_WARNING, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 294, GF_LOG_WARNING, "%s", err_str); } while (
0)
;
295 goto out;
296 }
297 if (replica_count == volinfo->replica_count) {
298 /* This means the 'replica N' option on CLI was
299 redundant. Check if the total number of bricks given
300 for removal is same as 'dist_leaf_count' */
301 if (brick_count % volinfo->dist_leaf_count) {
302 snprintf (err_str, err_len,
303 "number of bricks provided (%d) is "
304 "not valid. need at least %d "
305 "(or %dxN)", brick_count,
306 volinfo->dist_leaf_count,
307 volinfo->dist_leaf_count);
308 gf_log (THIS->name, GF_LOG_WARNING, "%s",do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 309, GF_LOG_WARNING, "%s", err_str); } while (
0)
309 err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 309, GF_LOG_WARNING, "%s", err_str); } while (
0)
;
310 goto out;
311 }
312 ret = 1;
313 goto out;
314 }
315
316 replica_nodes = ((volinfo->brick_count /
317 volinfo->replica_count) *
318 (volinfo->replica_count - replica_count));
319
320 if (brick_count % replica_nodes) {
321 snprintf (err_str, err_len,
322 "need %d(xN) bricks for reducing replica "
323 "count of the volume from %d to %d",
324 replica_nodes, volinfo->replica_count,
325 replica_count);
326 goto out;
327 }
328 break;
329 }
330
331 ret = 0;
332out:
333 return ret;
334}
335
336/* Handler functions */
337int
338__glusterd_handle_add_brick (rpcsvc_request_t *req)
339{
340 int32_t ret = -1;
341 gf_cli_req cli_req = {{0,}};
342 dict_t *dict = NULL((void*)0);
343 char *bricks = NULL((void*)0);
344 char *volname = NULL((void*)0);
345 int brick_count = 0;
346 void *cli_rsp = NULL((void*)0);
347 char err_str[2048] = {0,};
348 gf_cli_rsp rsp = {0,};
349 glusterd_volinfo_t *volinfo = NULL((void*)0);
350 xlator_t *this = NULL((void*)0);
351 int total_bricks = 0;
352 int32_t replica_count = 0;
353 int32_t stripe_count = 0;
354 int type = 0;
355
356 this = THIS(*__glusterfs_this_location());
357 GF_ASSERT(this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 357, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
358
359 GF_ASSERT (req)do { if (!(req)) { do { do { if (0) printf ("Assertion failed: "
"req"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 359, GF_LOG_ERROR, "Assertion failed: " "req"
); } while (0); } } while (0)
;
360
361 ret = xdr_to_generic (req->msg[0], &cli_req,
362 (xdrproc_t)xdr_gf_cli_req);
363 if (ret < 0) {
364 //failed to decode msg;
365 req->rpc_err = GARBAGE_ARGS;
366 snprintf (err_str, sizeof (err_str), "Garbage args received");
367 goto out;
368 }
369
370 gf_log (this->name, GF_LOG_INFO, "Received add brick req")do { do { if (0) printf ("Received add brick req"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 370, GF_LOG_INFO, "Received add brick req"); } while (0)
;
371
372 if (cli_req.dict.dict_len) {
373 /* Unserialize the dictionary */
374 dict = dict_new ();
375
376 ret = dict_unserialize (cli_req.dict.dict_val,
377 cli_req.dict.dict_len,
378 &dict);
379 if (ret < 0) {
380 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 382, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
381 "failed to "do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 382, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
382 "unserialize req-buffer to dictionary")do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 382, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
;
383 snprintf (err_str, sizeof (err_str), "Unable to decode "
384 "the command");
385 goto out;
386 }
387 }
388
389 ret = dict_get_str (dict, "volname", &volname);
390
391 if (ret) {
392 snprintf (err_str, sizeof (err_str), "Unable to get volume "
393 "name");
394 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 394, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
395 goto out;
396 }
397
398 if (!(ret = glusterd_check_volume_exists (volname))) {
399 ret = -1;
400 snprintf (err_str, sizeof (err_str), "Volume %s does not exist",
401 volname);
402 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 402, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
403 goto out;
404 }
405
406 ret = dict_get_int32 (dict, "count", &brick_count);
407 if (ret) {
408 snprintf (err_str, sizeof (err_str), "Unable to get volume "
409 "brick count");
410 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 410, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
411 goto out;
412 }
413
414 ret = dict_get_int32 (dict, "replica-count", &replica_count);
415 if (!ret) {
416 gf_log (this->name, GF_LOG_INFO, "replica-count is %d",do { do { if (0) printf ("replica-count is %d", replica_count
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 417, GF_LOG_INFO, "replica-count is %d", replica_count
); } while (0)
417 replica_count)do { do { if (0) printf ("replica-count is %d", replica_count
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 417, GF_LOG_INFO, "replica-count is %d", replica_count
); } while (0)
;
418 }
419
420 ret = dict_get_int32 (dict, "stripe-count", &stripe_count);
421 if (!ret) {
422 gf_log (this->name, GF_LOG_INFO, "stripe-count is %d",do { do { if (0) printf ("stripe-count is %d", stripe_count);
} while (0); _gf_log (this->name, "glusterd-brick-ops.c",
__FUNCTION__, 423, GF_LOG_INFO, "stripe-count is %d", stripe_count
); } while (0)
423 stripe_count)do { do { if (0) printf ("stripe-count is %d", stripe_count);
} while (0); _gf_log (this->name, "glusterd-brick-ops.c",
__FUNCTION__, 423, GF_LOG_INFO, "stripe-count is %d", stripe_count
); } while (0)
;
424 }
425
426 if (!dict_get (dict, "force")) {
427 gf_log (this->name, GF_LOG_ERROR, "Failed to get flag")do { do { if (0) printf ("Failed to get flag"); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 427, GF_LOG_ERROR
, "Failed to get flag"); } while (0)
;
428 goto out;
429 }
430
431 ret = glusterd_volinfo_find (volname, &volinfo);
432 if (ret) {
433 snprintf (err_str, sizeof (err_str), "Unable to get volinfo "
434 "for volume name %s", volname);
435 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 435, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
436 goto out;
437
438 }
439
440 total_bricks = volinfo->brick_count + brick_count;
441
442 if (!stripe_count && !replica_count) {
443 if (volinfo->type == GF_CLUSTER_TYPE_NONE)
444 goto brick_val;
445
446 if ((volinfo->brick_count < volinfo->dist_leaf_count) &&
447 (total_bricks <= volinfo->dist_leaf_count))
448 goto brick_val;
449
450 if ((brick_count % volinfo->dist_leaf_count) != 0) {
451 snprintf (err_str, sizeof (err_str), "Incorrect number "
452 "of bricks supplied %d with count %d",
453 brick_count, volinfo->dist_leaf_count);
454 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 454, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
455 ret = -1;
456 goto out;
457 }
458 goto brick_val;
459 /* done with validation.. below section is if stripe|replica
460 count is given */
461 }
462
463 /* These bricks needs to be added one per a replica or stripe volume */
464 if (stripe_count) {
465 ret = gd_addbr_validate_stripe_count (volinfo, stripe_count,
466 total_bricks, &type,
467 err_str,
468 sizeof (err_str));
469 if (ret == -1) {
470 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 470, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
471 goto out;
472 }
473
474 /* if stripe count is same as earlier, set it back to 0 */
475 if (ret == 1)
476 stripe_count = 0;
477
478 ret = dict_set_int32 (dict, "stripe-count", stripe_count);
479 if (ret) {
480 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set the stripe-count in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 481, GF_LOG_ERROR, "failed to set the stripe-count in dict"
); } while (0)
481 "failed to set the stripe-count in dict")do { do { if (0) printf ("failed to set the stripe-count in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 481, GF_LOG_ERROR, "failed to set the stripe-count in dict"
); } while (0)
;
482 goto out;
483 }
484 goto brick_val;
485 }
486
487 ret = gd_addbr_validate_replica_count (volinfo, replica_count,
488 total_bricks,
489 &type, err_str,
490 sizeof (err_str));
491 if (ret == -1) {
492 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 492, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
493 goto out;
494 }
495
496 /* if replica count is same as earlier, set it back to 0 */
497 if (ret == 1)
498 replica_count = 0;
499
500 ret = dict_set_int32 (dict, "replica-count", replica_count);
501 if (ret) {
502 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set the replica-count in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 503, GF_LOG_ERROR, "failed to set the replica-count in dict"
); } while (0)
503 "failed to set the replica-count in dict")do { do { if (0) printf ("failed to set the replica-count in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 503, GF_LOG_ERROR, "failed to set the replica-count in dict"
); } while (0)
;
504 goto out;
505 }
506
507brick_val:
508 ret = dict_get_str (dict, "bricks", &bricks);
509 if (ret) {
510 snprintf (err_str, sizeof (err_str), "Unable to get volume "
511 "bricks");
512 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 512, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
513 goto out;
514 }
515
516 if (type != volinfo->type) {
517 ret = dict_set_int32 (dict, "type", type);
518 if (ret)
519 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to set the new type in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 520, GF_LOG_ERROR, "failed to set the new type in dict"
); } while (0)
520 "failed to set the new type in dict")do { do { if (0) printf ("failed to set the new type in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 520, GF_LOG_ERROR, "failed to set the new type in dict"
); } while (0)
;
521 }
522
523 ret = glusterd_op_begin_synctask (req, GD_OP_ADD_BRICK, dict);
524
525out:
526 if (ret) {
527 rsp.op_ret = -1;
528 rsp.op_errno = 0;
529 if (err_str[0] == '\0')
530 snprintf (err_str, sizeof (err_str), "Operation failed");
531 rsp.op_errstr = err_str;
532 cli_rsp = &rsp;
533 glusterd_to_cli (req, cli_rsp, NULL((void*)0), 0, NULL((void*)0),
534 (xdrproc_t)xdr_gf_cli_rsp, dict);
535 ret = 0; //sent error to cli, prevent second reply
536 }
537
538 free (cli_req.dict.dict_val); //its malloced by xdr
539
540 return ret;
541}
542
543int
544glusterd_handle_add_brick (rpcsvc_request_t *req)
545{
546 return glusterd_big_locked_handler (req, __glusterd_handle_add_brick);
547}
548
549int
550__glusterd_handle_remove_brick (rpcsvc_request_t *req)
551{
552 int32_t ret = -1;
553 gf_cli_req cli_req = {{0,}};
554 dict_t *dict = NULL((void*)0);
555 int32_t count = 0;
556 char *brick = NULL((void*)0);
557 char key[256] = {0,};
558 char *brick_list = NULL((void*)0);
559 int i = 1;
560 glusterd_volinfo_t *volinfo = NULL((void*)0);
561 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
562 int32_t pos = 0;
563 int32_t sub_volume = 0;
564 int32_t sub_volume_start = 0;
565 int32_t sub_volume_end = 0;
566 glusterd_brickinfo_t *tmp = NULL((void*)0);
567 char err_str[2048] = {0};
568 gf_cli_rsp rsp = {0,};
569 void *cli_rsp = NULL((void*)0);
570 char vol_type[256] = {0,};
571 int32_t replica_count = 0;
572 int32_t brick_index = 0;
573 int32_t tmp_brick_idx = 0;
574 int found = 0;
575 int diff_count = 0;
576 char *volname = 0;
577 xlator_t *this = NULL((void*)0);
578
579 GF_ASSERT (req)do { if (!(req)) { do { do { if (0) printf ("Assertion failed: "
"req"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 579, GF_LOG_ERROR, "Assertion failed: " "req"
); } while (0); } } while (0)
;
580 this = THIS(*__glusterfs_this_location());
581 GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 581, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
582
583 ret = xdr_to_generic (req->msg[0], &cli_req,
584 (xdrproc_t)xdr_gf_cli_req);
585 if (ret < 0) {
586 //failed to decode msg;
587 req->rpc_err = GARBAGE_ARGS;
588 snprintf (err_str, sizeof (err_str), "Received garbage args");
589 goto out;
590 }
591
592
593 gf_log (this->name, GF_LOG_INFO, "Received rem brick req")do { do { if (0) printf ("Received rem brick req"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 593, GF_LOG_INFO, "Received rem brick req"); } while (0)
;
594
595 if (cli_req.dict.dict_len) {
596 /* Unserialize the dictionary */
597 dict = dict_new ();
598
599 ret = dict_unserialize (cli_req.dict.dict_val,
600 cli_req.dict.dict_len,
601 &dict);
602 if (ret < 0) {
603 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 605, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
604 "failed to "do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 605, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
605 "unserialize req-buffer to dictionary")do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 605, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"
); } while (0)
;
606 snprintf (err_str, sizeof (err_str), "Unable to decode "
607 "the command");
608 goto out;
609 }
610 }
611
612 ret = dict_get_str (dict, "volname", &volname);
613 if (ret) {
614 snprintf (err_str, sizeof (err_str), "Unable to get volume "
615 "name");
616 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 616, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
617 goto out;
618 }
619
620 ret = dict_get_int32 (dict, "count", &count);
621 if (ret) {
622 snprintf (err_str, sizeof (err_str), "Unable to get brick "
623 "count");
624 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 624, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
625 goto out;
626 }
627
628 ret = glusterd_volinfo_find (volname, &volinfo);
629 if (ret) {
630 snprintf (err_str, sizeof (err_str),"Volume %s does not exist",
631 volname);
632 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 632, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
633 goto out;
634 }
635
636 ret = dict_get_int32 (dict, "replica-count", &replica_count);
637 if (!ret) {
638 gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("request to change replica-count to %d"
, replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 639, GF_LOG_INFO, "request to change replica-count to %d"
, replica_count); } while (0)
639 "request to change replica-count to %d", replica_count)do { do { if (0) printf ("request to change replica-count to %d"
, replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 639, GF_LOG_INFO, "request to change replica-count to %d"
, replica_count); } while (0)
;
640 ret = gd_rmbr_validate_replica_count (volinfo, replica_count,
641 count, err_str,
642 sizeof (err_str));
643 if (ret < 0) {
644 /* logging and error msg are done in above function
645 itself */
646 goto out;
647 }
648 dict_del (dict, "replica-count");
649 if (ret) {
650 replica_count = 0;
651 } else {
652 ret = dict_set_int32 (dict, "replica-count",
653 replica_count);
654 if (ret) {
655 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to set the replica_count " "in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 657, GF_LOG_WARNING, "failed to set the replica_count "
"in dict"); } while (0)
656 "failed to set the replica_count "do { do { if (0) printf ("failed to set the replica_count " "in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 657, GF_LOG_WARNING, "failed to set the replica_count "
"in dict"); } while (0)
657 "in dict")do { do { if (0) printf ("failed to set the replica_count " "in dict"
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 657, GF_LOG_WARNING, "failed to set the replica_count "
"in dict"); } while (0)
;
658 goto out;
659 }
660 }
661 }
662
663 /* 'vol_type' is used for giving the meaning full error msg for user */
664 if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
665 strcpy (vol_type, "replica");
666 } else if (volinfo->type == GF_CLUSTER_TYPE_STRIPE) {
667 strcpy (vol_type, "stripe");
668 } else if (volinfo->type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) {
669 strcpy (vol_type, "stripe-replicate");
670 } else {
671 strcpy (vol_type, "distribute");
672 }
673
674 /* Do not allow remove-brick if the volume is plain stripe */
675 if ((volinfo->type == GF_CLUSTER_TYPE_STRIPE) &&
676 (volinfo->brick_count == volinfo->stripe_count)) {
677 snprintf (err_str, sizeof (err_str),
678 "Removing brick from a plain stripe is not allowed");
679 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 679, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
680 ret = -1;
681 goto out;
682 }
683
684 if (!replica_count &&
685 (volinfo->type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) &&
686 (volinfo->brick_count == volinfo->dist_leaf_count)) {
687 snprintf (err_str, sizeof(err_str),
688 "Removing bricks from stripe-replicate"
689 " configuration is not allowed without reducing "
690 "replica or stripe count explicitly.");
691 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 691, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
692 ret = -1;
693 goto out;
694 }
695
696 if (!replica_count &&
697 (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) &&
698 (volinfo->brick_count == volinfo->dist_leaf_count)) {
699 snprintf (err_str, sizeof (err_str),
700 "Removing bricks from replicate configuration "
701 "is not allowed without reducing replica count "
702 "explicitly.");
703 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 703, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
704 ret = -1;
705 goto out;
706 }
707
708 /* Do not allow remove-brick if the bricks given is less than
709 the replica count or stripe count */
710 if (!replica_count && (volinfo->type != GF_CLUSTER_TYPE_NONE)) {
711 if (volinfo->dist_leaf_count &&
712 (count % volinfo->dist_leaf_count)) {
713 snprintf (err_str, sizeof (err_str), "Remove brick "
714 "incorrect brick count of %d for %s %d",
715 count, vol_type, volinfo->dist_leaf_count);
716 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 716, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
717 ret = -1;
718 goto out;
719 }
720 }
721
722 brick_list = GF_MALLOC (120000 * sizeof(*brick_list),gf_common_mt_char)__gf_malloc (120000 * sizeof(*brick_list), gf_common_mt_char);
723
724 if (!brick_list) {
725 ret = -1;
726 goto out;
727 }
728
729 strcpy (brick_list, " ");
730 while ( i <= count) {
731 snprintf (key, sizeof (key), "brick%d", i);
732 ret = dict_get_str (dict, key, &brick);
733 if (ret) {
734 snprintf (err_str, sizeof (err_str), "Unable to get %s",
735 key);
736 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 736, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
737 goto out;
738 }
739 gf_log (this->name, GF_LOG_DEBUG, "Remove brick count %d brick:"do { do { if (0) printf ("Remove brick count %d brick:" " %s"
, i, brick); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 740, GF_LOG_DEBUG, "Remove brick count %d brick:"
" %s", i, brick); } while (0)
740 " %s", i, brick)do { do { if (0) printf ("Remove brick count %d brick:" " %s"
, i, brick); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 740, GF_LOG_DEBUG, "Remove brick count %d brick:"
" %s", i, brick); } while (0)
;
741
742 ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo,
743 &brickinfo);
744 if (ret) {
745 snprintf (err_str, sizeof (err_str), "Incorrect brick "
746 "%s for volume %s", brick, volname);
747 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 747, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
748 goto out;
749 }
750 strcat(brick_list, brick);
751 strcat(brick_list, " ");
752
753 i++;
754 if ((volinfo->type == GF_CLUSTER_TYPE_NONE) ||
755 (volinfo->brick_count <= volinfo->dist_leaf_count))
756 continue;
757
758 if (replica_count) {
759 /* do the validation of bricks here */
760 /* -2 because i++ is already done, and i starts with 1,
761 instead of 0 */
762 diff_count = (volinfo->replica_count - replica_count);
763 brick_index = (((i -2) / diff_count) * volinfo->replica_count);
764 tmp_brick_idx = 0;
765 found = 0;
766 list_for_each_entry (tmp, &volinfo->bricks, brick_list)for (tmp = ((typeof(*tmp) *)((char *)((&volinfo->bricks
)->next)-(unsigned long)(&((typeof(*tmp) *)0)->brick_list
))); &tmp->brick_list != (&volinfo->bricks); tmp
= ((typeof(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned
long)(&((typeof(*tmp) *)0)->brick_list))))
{
767 tmp_brick_idx++;
768 gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("validate brick %s:%s (%d %d %d)", tmp
->hostname, tmp->path, tmp_brick_idx, brick_index, volinfo
->replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 771, GF_LOG_TRACE, "validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
769 "validate brick %s:%s (%d %d %d)",do { do { if (0) printf ("validate brick %s:%s (%d %d %d)", tmp
->hostname, tmp->path, tmp_brick_idx, brick_index, volinfo
->replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 771, GF_LOG_TRACE, "validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
770 tmp->hostname, tmp->path, tmp_brick_idx,do { do { if (0) printf ("validate brick %s:%s (%d %d %d)", tmp
->hostname, tmp->path, tmp_brick_idx, brick_index, volinfo
->replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 771, GF_LOG_TRACE, "validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
771 brick_index, volinfo->replica_count)do { do { if (0) printf ("validate brick %s:%s (%d %d %d)", tmp
->hostname, tmp->path, tmp_brick_idx, brick_index, volinfo
->replica_count); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 771, GF_LOG_TRACE, "validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
;
772 if (tmp_brick_idx <= brick_index)
773 continue;
774 if (tmp_brick_idx >
775 (brick_index + volinfo->replica_count))
776 break;
777 if ((!strcmp (tmp->hostname,brickinfo->hostname)) &&
778 !strcmp (tmp->path, brickinfo->path)) {
779 found = 1;
780 break;
781 }
782 }
783 if (found)
784 continue;
785
786 snprintf (err_str, sizeof (err_str), "Bricks are from "
787 "same subvol");
788 gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0); _gf_log (this->name
, "glusterd-brick-ops.c", __FUNCTION__, 791, GF_LOG_INFO, "failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
789 "failed to validate brick %s:%s (%d %d %d)",do { do { if (0) printf ("failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0); _gf_log (this->name
, "glusterd-brick-ops.c", __FUNCTION__, 791, GF_LOG_INFO, "failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
790 tmp->hostname, tmp->path, tmp_brick_idx,do { do { if (0) printf ("failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0); _gf_log (this->name
, "glusterd-brick-ops.c", __FUNCTION__, 791, GF_LOG_INFO, "failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
791 brick_index, volinfo->replica_count)do { do { if (0) printf ("failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0); _gf_log (this->name
, "glusterd-brick-ops.c", __FUNCTION__, 791, GF_LOG_INFO, "failed to validate brick %s:%s (%d %d %d)"
, tmp->hostname, tmp->path, tmp_brick_idx, brick_index,
volinfo->replica_count); } while (0)
;
792 ret = -1;
793 /* brick order is not valid */
794 goto out;
795 }
796
797 pos = 0;
798 list_for_each_entry (tmp, &volinfo->bricks, brick_list)for (tmp = ((typeof(*tmp) *)((char *)((&volinfo->bricks
)->next)-(unsigned long)(&((typeof(*tmp) *)0)->brick_list
))); &tmp->brick_list != (&volinfo->bricks); tmp
= ((typeof(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned
long)(&((typeof(*tmp) *)0)->brick_list))))
{
799
800 if (strcmp (tmp->hostname,brickinfo->hostname) ||
801 strcmp (tmp->path, brickinfo->path)) {
802 pos++;
803 continue;
804 }
805
806 gf_log (this->name, GF_LOG_DEBUG, LOGSTR_FOUND_BRICK,do { do { if (0) printf ("Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 808, GF_LOG_DEBUG, "Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0)
807 brickinfo->hostname, brickinfo->path,do { do { if (0) printf ("Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 808, GF_LOG_DEBUG, "Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0)
808 volinfo->volname)do { do { if (0) printf ("Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 808, GF_LOG_DEBUG, "Found brick %s:%s in volume %s", brickinfo
->hostname, brickinfo->path, volinfo->volname); } while
(0)
;
809 if (!sub_volume && (volinfo->dist_leaf_count > 1)) {
810 sub_volume = (pos / volinfo->dist_leaf_count) + 1;
811 sub_volume_start = (volinfo->dist_leaf_count *
812 (sub_volume - 1));
813 sub_volume_end = (volinfo->dist_leaf_count *
814 sub_volume) - 1;
815 } else {
816 if (pos < sub_volume_start ||
817 pos >sub_volume_end) {
818 ret = -1;
819 snprintf (err_str, sizeof (err_str),
820 "Bricks not from same subvol "
821 "for %s", vol_type);
822 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 823, GF_LOG_ERROR
, "%s", err_str); } while (0)
823 "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 823, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
824 goto out;
825 }
826 }
827 break;
828 }
829 }
830
831 ret = glusterd_op_begin_synctask (req, GD_OP_REMOVE_BRICK, dict);
832
833out:
834 if (ret) {
835 rsp.op_ret = -1;
836 rsp.op_errno = 0;
837 if (err_str[0] == '\0')
838 snprintf (err_str, sizeof (err_str),
839 "Operation failed");
840 gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 840, GF_LOG_ERROR
, "%s", err_str); } while (0)
;
841 rsp.op_errstr = err_str;
842 cli_rsp = &rsp;
843 glusterd_to_cli (req, cli_rsp, NULL((void*)0), 0, NULL((void*)0),
844 (xdrproc_t)xdr_gf_cli_rsp, dict);
845
846 ret = 0; //sent error to cli, prevent second reply
847
848 }
849
850 GF_FREE (brick_list)__gf_free (brick_list);
851 free (cli_req.dict.dict_val); //its malloced by xdr
852
853 return ret;
854}
855
856int
857glusterd_handle_remove_brick (rpcsvc_request_t *req)
858{
859 return glusterd_big_locked_handler (req,
860 __glusterd_handle_remove_brick);
861}
862
863/* op-sm */
864
865int
866glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count,
867 char *bricks, dict_t *dict)
868{
869 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
870 char *brick = NULL((void*)0);
871 int32_t i = 1;
872 char *brick_list = NULL((void*)0);
873 char *free_ptr1 = NULL((void*)0);
874 char *free_ptr2 = NULL((void*)0);
875 char *saveptr = NULL((void*)0);
876 int32_t ret = -1;
877 int32_t stripe_count = 0;
878 int32_t replica_count = 0;
879 int32_t type = 0;
880
881 GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: "
"volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 881, GF_LOG_ERROR, "Assertion failed: " "volinfo"
); } while (0); } } while (0)
;
882
883 if (bricks) {
884 brick_list = gf_strdup (bricks);
885 free_ptr1 = brick_list;
886 }
887
888 if (count)
889 brick = strtok_r (brick_list+1, " \n", &saveptr);
890
891 if (dict) {
892 ret = dict_get_int32 (dict, "stripe-count", &stripe_count);
893 if (!ret)
894 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("stripe-count is set %d", stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 895, GF_LOG_INFO, "stripe-count is set %d"
, stripe_count); } while (0)
895 "stripe-count is set %d", stripe_count)do { do { if (0) printf ("stripe-count is set %d", stripe_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 895, GF_LOG_INFO, "stripe-count is set %d"
, stripe_count); } while (0)
;
896
897 ret = dict_get_int32 (dict, "replica-count", &replica_count);
898 if (!ret)
899 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("replica-count is set %d", replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 900, GF_LOG_INFO, "replica-count is set %d"
, replica_count); } while (0)
900 "replica-count is set %d", replica_count)do { do { if (0) printf ("replica-count is set %d", replica_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 900, GF_LOG_INFO, "replica-count is set %d"
, replica_count); } while (0)
;
901 ret = dict_get_int32 (dict, "type", &type);
902 if (!ret)
903 gf_log (THIS->name, GF_LOG_INFO,do { do { if (0) printf ("type is set %d, need to change it",
type); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 904, GF_LOG_INFO,
"type is set %d, need to change it", type); } while (0)
904 "type is set %d, need to change it", type)do { do { if (0) printf ("type is set %d, need to change it",
type); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 904, GF_LOG_INFO,
"type is set %d, need to change it", type); } while (0)
;
905 }
906
907 while ( i <= count) {
908 ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
909 if (ret)
910 goto out;
911
912 ret = glusterd_resolve_brick (brickinfo);
913 if (ret)
914 goto out;
915 if (stripe_count || replica_count) {
916 add_brick_at_right_order (brickinfo, volinfo, (i - 1),
917 stripe_count, replica_count);
918 } else {
919 list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
920 }
921 brick = strtok_r (NULL((void*)0), " \n", &saveptr);
922 i++;
923 volinfo->brick_count++;
924
925 }
926
927
928 /* Gets changed only if the options are given in add-brick cli */
929 if (type)
930 volinfo->type = type;
931 if (replica_count) {
932 volinfo->replica_count = replica_count;
933 }
934 if (stripe_count) {
935 volinfo->stripe_count = stripe_count;
936 }
937 volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
938
939 /* backward compatibility */
940 volinfo->sub_count = ((volinfo->dist_leaf_count == 1) ? 0:
941 volinfo->dist_leaf_count);
942
943 volinfo->subvol_count = (volinfo->brick_count /
944 volinfo->dist_leaf_count);
945
946 ret = glusterd_create_volfiles_and_notify_services (volinfo);
947 if (ret)
948 goto out;
949
950 ret = 0;
951 if (GLUSTERD_STATUS_STARTED != volinfo->status)
952 goto out;
953
954 brick_list = gf_strdup (bricks);
955 free_ptr2 = brick_list;
956 i = 1;
957
958 if (count)
959 brick = strtok_r (brick_list+1, " \n", &saveptr);
960
961 while (i <= count) {
962
963 ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
964 &brickinfo);
965 if (ret)
966 goto out;
967
968 ret = glusterd_brick_start (volinfo, brickinfo,
969 _gf_true);
970 if (ret)
971 goto out;
972 i++;
973 brick = strtok_r (NULL((void*)0), " \n", &saveptr);
974 }
975
976out:
977 GF_FREE (free_ptr1)__gf_free (free_ptr1);
978 GF_FREE (free_ptr2)__gf_free (free_ptr2);
979
980 gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log
("", "glusterd-brick-ops.c", __FUNCTION__, 980, GF_LOG_DEBUG
, "Returning %d", ret); } while (0)
;
981 return ret;
982}
983
984
985int
986glusterd_op_perform_remove_brick (glusterd_volinfo_t *volinfo, char *brick,
987 int force, int *need_migrate)
988{
989 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
990 int32_t ret = -1;
991 glusterd_conf_t *priv = NULL((void*)0);
992
993 GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: "
"volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 993, GF_LOG_ERROR, "Assertion failed: " "volinfo"
); } while (0); } } while (0)
;
994 GF_ASSERT (brick)do { if (!(brick)) { do { do { if (0) printf ("Assertion failed: "
"brick"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 994, GF_LOG_ERROR, "Assertion failed: " "brick"
); } while (0); } } while (0)
;
995
996 priv = THIS(*__glusterfs_this_location())->private;
997 GF_ASSERT (priv)do { if (!(priv)) { do { do { if (0) printf ("Assertion failed: "
"priv"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 997, GF_LOG_ERROR, "Assertion failed: " "priv"
); } while (0); } } while (0)
;
998
999 ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
1000 &brickinfo);
1001 if (ret)
1002 goto out;
1003
1004 ret = glusterd_resolve_brick (brickinfo);
1005 if (ret)
1006 goto out;
1007
1008 glusterd_volinfo_reset_defrag_stats (volinfo);
1009
1010 if (!uuid_compare (brickinfo->uuid, MY_UUID(__glusterd_uuid()))) {
1011 /* Only if the brick is in this glusterd, do the rebalance */
1012 if (need_migrate)
1013 *need_migrate = 1;
1014 }
1015
1016 if (force) {
1017 ret = glusterd_brick_stop (volinfo, brickinfo,
1018 _gf_true);
1019 if (ret) {
1020 gf_log (THIS->name, GF_LOG_ERROR, "Unable to stop "do { do { if (0) printf ("Unable to stop " "glusterfs, ret: %d"
, ret); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1021, GF_LOG_ERROR
, "Unable to stop " "glusterfs, ret: %d", ret); } while (0)
1021 "glusterfs, ret: %d", ret)do { do { if (0) printf ("Unable to stop " "glusterfs, ret: %d"
, ret); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1021, GF_LOG_ERROR
, "Unable to stop " "glusterfs, ret: %d", ret); } while (0)
;
1022 }
1023 goto out;
1024 }
1025
1026 brickinfo->decommissioned = 1;
1027 ret = 0;
1028out:
1029 gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log
("", "glusterd-brick-ops.c", __FUNCTION__, 1029, GF_LOG_DEBUG
, "Returning %d", ret); } while (0)
;
1030 return ret;
1031}
1032
1033int
1034glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
1035{
1036 int ret = 0;
1037 char *volname = NULL((void*)0);
1038 int count = 0;
1039 int i = 0;
1040 char *bricks = NULL((void*)0);
1041 char *brick_list = NULL((void*)0);
1042 char *saveptr = NULL((void*)0);
1043 char *free_ptr = NULL((void*)0);
1044 char *brick = NULL((void*)0);
1045 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
1046 glusterd_volinfo_t *volinfo = NULL((void*)0);
1047 glusterd_conf_t *priv = NULL((void*)0);
1048 char msg[2048] = {0,};
1049 gf_boolean_t brick_alloc = _gf_false;
1050 char *all_bricks = NULL((void*)0);
1051 char *str_ret = NULL((void*)0);
1052 gf_boolean_t is_force = _gf_false;
1053
1054 priv = THIS(*__glusterfs_this_location())->private;
1055 if (!priv)
1056 goto out;
1057
1058 ret = dict_get_str (dict, "volname", &volname);
1059 if (ret) {
1060 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to get volume name"); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1061, GF_LOG_ERROR, "Unable to get volume name"
); } while (0)
1061 "Unable to get volume name")do { do { if (0) printf ("Unable to get volume name"); } while
(0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1061, GF_LOG_ERROR, "Unable to get volume name"
); } while (0)
;
1062 goto out;
1063 }
1064
1065 ret = glusterd_volinfo_find (volname, &volinfo);
1066 if (ret) {
1067 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to find volume: %s", volname
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1068, GF_LOG_ERROR, "Unable to find volume: %s"
, volname); } while (0)
1068 "Unable to find volume: %s", volname)do { do { if (0) printf ("Unable to find volume: %s", volname
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1068, GF_LOG_ERROR, "Unable to find volume: %s"
, volname); } while (0)
;
1069 goto out;
1070 }
1071
1072 if (volinfo->backend == GD_VOL_BK_BD) {
1073 snprintf (msg, sizeof (msg), "Add brick is not supported for "
1074 "Block backend volume %s.", volname);
1075 gf_log (THIS->name, GF_LOG_ERROR, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log ((*
__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1075, GF_LOG_ERROR, "%s", msg); } while (0)
;
1076 *op_errstr = gf_strdup (msg);
1077 ret = -1;
1078 goto out;
1079 }
1080
1081 ret = glusterd_validate_volume_id (dict, volinfo);
1082 if (ret)
1083 goto out;
1084
1085 if (glusterd_is_rb_ongoing (volinfo)) {
1086 snprintf (msg, sizeof (msg), "Replace brick is in progress on "
1087 "volume %s. Please retry after replace-brick "
1088 "operation is committed or aborted", volname);
1089 gf_log (THIS->name, GF_LOG_ERROR, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log ((*
__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1089, GF_LOG_ERROR, "%s", msg); } while (0)
;
1090 *op_errstr = gf_strdup (msg);
1091 ret = -1;
1092 goto out;
1093 }
1094
1095 if (glusterd_is_defrag_on(volinfo)) {
1096 snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
1097 "progress. Please retry after completion", volname);
1098 gf_log (THIS->name, GF_LOG_ERROR, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log ((*
__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1098, GF_LOG_ERROR, "%s", msg); } while (0)
;
1099 *op_errstr = gf_strdup (msg);
1100 ret = -1;
1101 goto out;
1102 }
1103 ret = dict_get_int32 (dict, "count", &count);
1104 if (ret) {
1105 gf_log ("", GF_LOG_ERROR, "Unable to get count")do { do { if (0) printf ("Unable to get count"); } while (0);
_gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1105, GF_LOG_ERROR
, "Unable to get count"); } while (0)
;
1106 goto out;
1107 }
1108
1109 ret = dict_get_str (dict, "bricks", &bricks);
1110 if (ret) {
1111 gf_log (THIS->name, GF_LOG_ERROR, "Unable to get bricks")do { do { if (0) printf ("Unable to get bricks"); } while (0)
; _gf_log ((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1111, GF_LOG_ERROR, "Unable to get bricks"); }
while (0)
;
1112 goto out;
1113 }
1114
1115 is_force = dict_get_str_boolean (dict, "force", _gf_false);
1116
1117 if (bricks) {
1118 brick_list = gf_strdup (bricks);
1119 all_bricks = gf_strdup (bricks);
1120 free_ptr = brick_list;
1121 }
1122
1123 if (count)
1124 brick = strtok_r (brick_list+1, " \n", &saveptr);
1125
1126
1127 while ( i < count) {
1128 if (!glusterd_store_is_valid_brickpath (volname, brick) ||
1129 !glusterd_is_valid_volfpath (volname, brick)) {
1130 snprintf (msg, sizeof (msg), "brick path %s is "
1131 "too long", brick);
1132 gf_log (THIS->name, GF_LOG_ERROR, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log ((*
__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1132, GF_LOG_ERROR, "%s", msg); } while (0)
;
1133 *op_errstr = gf_strdup (msg);
1134
1135 ret = -1;
1136 goto out;
1137
1138 }
1139
1140 ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
1141 if (ret) {
1142 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Add-brick: Unable" " to get brickinfo"
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1144, GF_LOG_ERROR, "Add-brick: Unable"
" to get brickinfo"); } while (0)
1143 "Add-brick: Unable"do { do { if (0) printf ("Add-brick: Unable" " to get brickinfo"
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1144, GF_LOG_ERROR, "Add-brick: Unable"
" to get brickinfo"); } while (0)
1144 " to get brickinfo")do { do { if (0) printf ("Add-brick: Unable" " to get brickinfo"
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1144, GF_LOG_ERROR, "Add-brick: Unable"
" to get brickinfo"); } while (0)
;
1145 goto out;
1146 }
1147 brick_alloc = _gf_true;
1148
1149 ret = glusterd_new_brick_validate (brick, brickinfo, msg,
1150 sizeof (msg));
1151 if (ret) {
1152 *op_errstr = gf_strdup (msg);
1153 ret = -1;
1154 goto out;
1155 }
1156
1157 if (!uuid_compare (brickinfo->uuid, MY_UUID(__glusterd_uuid()))) {
1158 ret = glusterd_validate_and_create_brickpath (brickinfo,
1159 volinfo->volume_id,
1160 op_errstr, is_force);
1161 if (ret)
1162 goto out;
1163 }
1164
1165 glusterd_brickinfo_delete (brickinfo);
1166 brick_alloc = _gf_false;
1167 brickinfo = NULL((void*)0);
1168 brick = strtok_r (NULL((void*)0), " \n", &saveptr);
1169 i++;
1170 }
1171
1172out:
1173 GF_FREE (free_ptr)__gf_free (free_ptr);
1174 if (brick_alloc && brickinfo)
1175 glusterd_brickinfo_delete (brickinfo);
1176 GF_FREE (str_ret)__gf_free (str_ret);
1177 GF_FREE (all_bricks)__gf_free (all_bricks);
1178
1179 gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log
((*__glusterfs_this_location())->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1179, GF_LOG_DEBUG, "Returning %d", ret); } while
(0)
;
1180
1181 return ret;
1182}
1183
1184int
1185glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)
1186{
1187 int ret = -1;
1188 char *volname = NULL((void*)0);
1189 glusterd_volinfo_t *volinfo = NULL((void*)0);
1190 char *errstr = NULL((void*)0);
1191 int32_t brick_count = 0;
1192 char msg[2048] = {0,};
1193 int32_t flag = 0;
1194 gf1_op_commands cmd = GF_OP_CMD_NONE;
1195 char *task_id_str = NULL((void*)0);
1196 xlator_t *this = NULL((void*)0);
1197
1198 this = THIS(*__glusterfs_this_location());
1
Value assigned to 'this'
1199 GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 1199, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
2
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'this' is null
1200
1201 ret = dict_get_str (dict, "volname", &volname);
1202 if (ret) {
3
Assuming 'ret' is 0
4
Taking false branch
1203 gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name")do { do { if (0) printf ("Unable to get volume name"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1203, GF_LOG_ERROR, "Unable to get volume name"); } while (
0)
;
1204 goto out;
1205 }
1206
1207 ret = glusterd_volinfo_find (volname, &volinfo);
1208
1209 if (ret) {
5
Assuming 'ret' is 0
6
Taking false branch
1210 gf_log (this->name, GF_LOG_ERROR, "Volume %s does not exist", volname)do { do { if (0) printf ("Volume %s does not exist", volname)
; } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1210, GF_LOG_ERROR, "Volume %s does not exist"
, volname); } while (0)
;
1211 goto out;
1212 }
1213
1214 ret = glusterd_validate_volume_id (dict, volinfo);
1215 if (ret)
7
Assuming 'ret' is 0
8
Taking false branch
1216 goto out;
1217
1218 if (glusterd_is_rb_ongoing (volinfo)) {
9
Taking false branch
1219 snprintf (msg, sizeof (msg), "Replace brick is in progress on "
1220 "volume %s. Please retry after replace-brick "
1221 "operation is committed or aborted", volname);
1222 gf_log (this->name, GF_LOG_ERROR, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log (this
->name, "glusterd-brick-ops.c", __FUNCTION__, 1222, GF_LOG_ERROR
, "%s", msg); } while (0)
;
1223 *op_errstr = gf_strdup (msg);
1224 ret = -1;
1225 goto out;
1226 }
1227
1228 ret = dict_get_int32 (dict, "command", &flag);
1229 if (ret) {
10
Assuming 'ret' is 0
11
Taking false branch
1230 gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count")do { do { if (0) printf ("Unable to get brick count"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1230, GF_LOG_ERROR, "Unable to get brick count"); } while (
0)
;
1231 goto out;
1232 }
1233 cmd = flag;
1234
1235 ret = -1;
1236 switch (cmd) {
12
Control jumps to 'case GF_OP_CMD_START:' at line 1245
1237 case GF_OP_CMD_NONE:
1238 errstr = gf_strdup ("no remove-brick command issued");
1239 goto out;
1240
1241 case GF_OP_CMD_STATUS:
1242 ret = 0;
1243 goto out;
1244
1245 case GF_OP_CMD_START:
1246 {
1247 if (GLUSTERD_STATUS_STARTED != volinfo->status) {
13
Taking false branch
1248 snprintf (msg, sizeof (msg), "Volume %s needs to be "
1249 "started before remove-brick (you can use "
1250 "'force' or 'commit' to override this "
1251 "behavior)", volinfo->volname);
1252 errstr = gf_strdup (msg);
1253 gf_log (this->name, GF_LOG_ERROR, "%s", errstr)do { do { if (0) printf ("%s", errstr); } while (0); _gf_log (
this->name, "glusterd-brick-ops.c", __FUNCTION__, 1253, GF_LOG_ERROR
, "%s", errstr); } while (0)
;
1254 goto out;
1255 }
1256 if (glusterd_is_defrag_on(volinfo)) {
14
Taking false branch
1257 errstr = gf_strdup("Rebalance is in progress. Please "
1258 "retry after completion");
1259 gf_log (this->name, GF_LOG_ERROR, "%s", errstr)do { do { if (0) printf ("%s", errstr); } while (0); _gf_log (
this->name, "glusterd-brick-ops.c", __FUNCTION__, 1259, GF_LOG_ERROR
, "%s", errstr); } while (0)
;
1260 goto out;
1261 }
1262
1263 if (is_origin_glusterd ()) {
15
Taking true branch
1264 ret = glusterd_generate_and_set_task_id
1265 (dict, GF_REMOVE_BRICK_TID_KEY"remove-brick-id");
1266 if (ret) {
16
Assuming 'ret' is not equal to 0
17
Taking true branch
1267 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Failed to generate task-id"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1268, GF_LOG_ERROR, "Failed to generate task-id"); } while (
0)
18
Within the expansion of the macro 'gf_log':
a
Access to field 'name' results in a dereference of a null pointer (loaded from variable 'this')
1268 "Failed to generate task-id")do { do { if (0) printf ("Failed to generate task-id"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1268, GF_LOG_ERROR, "Failed to generate task-id"); } while (
0)
;
1269 goto out;
1270 }
1271 } else {
1272 ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY"remove-brick-id",
1273 &task_id_str);
1274 if (ret) {
1275 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("Missing remove-brick-id"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1276, GF_LOG_WARNING, "Missing remove-brick-id"); } while (
0)
1276 "Missing remove-brick-id")do { do { if (0) printf ("Missing remove-brick-id"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1276, GF_LOG_WARNING, "Missing remove-brick-id"); } while (
0)
;
1277 ret = 0;
1278 }
1279 }
1280 break;
1281 }
1282
1283 case GF_OP_CMD_STOP:
1284 ret = 0;
1285 break;
1286
1287 case GF_OP_CMD_COMMIT:
1288 if (volinfo->decommission_in_progress) {
1289 errstr = gf_strdup ("use 'force' option as migration "
1290 "is in progress");
1291 goto out;
1292 }
1293 break;
1294
1295 case GF_OP_CMD_COMMIT_FORCE:
1296 break;
1297 }
1298
1299 ret = dict_get_int32 (dict, "count", &brick_count);
1300 if (ret) {
1301 gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count")do { do { if (0) printf ("Unable to get brick count"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1301, GF_LOG_ERROR, "Unable to get brick count"); } while (
0)
;
1302 goto out;
1303 }
1304
1305 ret = 0;
1306 if (volinfo->brick_count == brick_count) {
1307 errstr = gf_strdup ("Deleting all the bricks of the "
1308 "volume is not allowed");
1309 ret = -1;
1310 goto out;
1311 }
1312
1313out:
1314 gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log
(this->name, "glusterd-brick-ops.c", __FUNCTION__, 1314, GF_LOG_DEBUG
, "Returning %d", ret); } while (0)
;
1315 if (ret && errstr) {
1316 if (op_errstr)
1317 *op_errstr = errstr;
1318 }
1319
1320 return ret;
1321}
1322
1323int
1324glusterd_remove_brick_migrate_cbk (glusterd_volinfo_t *volinfo,
1325 gf_defrag_status_t status)
1326{
1327 int ret = 0;
1328
1329#if 0 /* TODO: enable this behavior once cluster-wide awareness comes for
1330 defrag cbk function */
1331 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
1332 glusterd_brickinfo_t *tmp = NULL((void*)0);
1333
1334 switch (status) {
1335 case GF_DEFRAG_STATUS_PAUSED:
1336 case GF_DEFRAG_STATUS_FAILED:
1337 /* No changes required in the volume file.
1338 everything should remain as is */
1339 break;
1340 case GF_DEFRAG_STATUS_STOPPED:
1341 /* Fall back to the old volume file */
1342 list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, brick_list)for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo
->bricks)->next)-(unsigned long)(&((typeof(*brickinfo
) *)0)->brick_list))), tmp = ((typeof(*brickinfo) *)((char
*)(brickinfo->brick_list.next)-(unsigned long)(&((typeof
(*brickinfo) *)0)->brick_list))); &brickinfo->brick_list
!= (&volinfo->bricks); brickinfo = tmp, tmp = ((typeof
(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned long)(&
((typeof(*tmp) *)0)->brick_list))))
{
1343 if (!brickinfo->decommissioned)
1344 continue;
1345 brickinfo->decommissioned = 0;
1346 }
1347 break;
1348
1349 case GF_DEFRAG_STATUS_COMPLETE:
1350 /* Done with the task, you can remove the brick from the
1351 volume file */
1352 list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, brick_list)for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo
->bricks)->next)-(unsigned long)(&((typeof(*brickinfo
) *)0)->brick_list))), tmp = ((typeof(*brickinfo) *)((char
*)(brickinfo->brick_list.next)-(unsigned long)(&((typeof
(*brickinfo) *)0)->brick_list))); &brickinfo->brick_list
!= (&volinfo->bricks); brickinfo = tmp, tmp = ((typeof
(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned long)(&
((typeof(*tmp) *)0)->brick_list))))
{
1353 if (!brickinfo->decommissioned)
1354 continue;
1355 gf_log (THIS->name, GF_LOG_INFO, "removing the brick %s",do { do { if (0) printf ("removing the brick %s", brickinfo->
path); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1356, GF_LOG_INFO
, "removing the brick %s", brickinfo->path); } while (0)
1356 brickinfo->path)do { do { if (0) printf ("removing the brick %s", brickinfo->
path); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1356, GF_LOG_INFO
, "removing the brick %s", brickinfo->path); } while (0)
;
1357 brickinfo->decommissioned = 0;
1358 if (GLUSTERD_STATUS_STARTED == volinfo->status) {
1359 /*TODO: use the 'atomic' flavour of brick_stop*/
1360 ret = glusterd_brick_stop (volinfo, brickinfo);
1361 if (ret) {
1362 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to stop glusterfs (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1363, GF_LOG_ERROR, "Unable to stop glusterfs (%d)"
, ret); } while (0)
1363 "Unable to stop glusterfs (%d)", ret)do { do { if (0) printf ("Unable to stop glusterfs (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1363, GF_LOG_ERROR, "Unable to stop glusterfs (%d)"
, ret); } while (0)
;
1364 }
1365 }
1366 glusterd_delete_brick (volinfo, brickinfo);
1367 }
1368 break;
1369
1370 default:
1371 GF_ASSERT (!"cbk function called with wrong status")do { if (!(!"cbk function called with wrong status")) { do { do
{ if (0) printf ("Assertion failed: " "!\"cbk function called with wrong status\""
); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 1371, GF_LOG_ERROR, "Assertion failed: " "!\"cbk function called with wrong status\""
); } while (0); } } while (0)
;
1372 break;
1373 }
1374
1375 ret = glusterd_create_volfiles_and_notify_services (volinfo);
1376 if (ret)
1377 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to write volume files (%d)",
ret); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1378, GF_LOG_ERROR
, "Unable to write volume files (%d)", ret); } while (0)
1378 "Unable to write volume files (%d)", ret)do { do { if (0) printf ("Unable to write volume files (%d)",
ret); } while (0); _gf_log ((*__glusterfs_this_location())->
name, "glusterd-brick-ops.c", __FUNCTION__, 1378, GF_LOG_ERROR
, "Unable to write volume files (%d)", ret); } while (0)
;
1379
1380 ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
1381 if (ret)
1382 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to store volume info (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1383, GF_LOG_ERROR, "Unable to store volume info (%d)"
, ret); } while (0)
1383 "Unable to store volume info (%d)", ret)do { do { if (0) printf ("Unable to store volume info (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1383, GF_LOG_ERROR, "Unable to store volume info (%d)"
, ret); } while (0)
;
1384
1385
1386 if (GLUSTERD_STATUS_STARTED == volinfo->status) {
1387 ret = glusterd_check_generate_start_nfs ();
1388 if (ret)
1389 gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("Unable to start nfs process (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1390, GF_LOG_ERROR, "Unable to start nfs process (%d)"
, ret); } while (0)
1390 "Unable to start nfs process (%d)", ret)do { do { if (0) printf ("Unable to start nfs process (%d)", ret
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "glusterd-brick-ops.c", __FUNCTION__, 1390, GF_LOG_ERROR, "Unable to start nfs process (%d)"
, ret); } while (0)
;
1391 }
1392
1393#endif
1394
1395 volinfo->decommission_in_progress = 0;
1396 return ret;
1397}
1398
1399
1400int
1401glusterd_op_add_brick (dict_t *dict, char **op_errstr)
1402{
1403 int ret = 0;
1404 char *volname = NULL((void*)0);
1405 glusterd_conf_t *priv = NULL((void*)0);
1406 glusterd_volinfo_t *volinfo = NULL((void*)0);
1407 xlator_t *this = NULL((void*)0);
1408 char *bricks = NULL((void*)0);
1409 int32_t count = 0;
1410
1411 this = THIS(*__glusterfs_this_location());
1412 GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 1412, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
1413
1414 priv = this->private;
1415 GF_ASSERT (priv)do { if (!(priv)) { do { do { if (0) printf ("Assertion failed: "
"priv"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 1415, GF_LOG_ERROR, "Assertion failed: " "priv"
); } while (0); } } while (0)
;
1416
1417 ret = dict_get_str (dict, "volname", &volname);
1418
1419 if (ret) {
1420 gf_log ("", GF_LOG_ERROR, "Unable to get volume name")do { do { if (0) printf ("Unable to get volume name"); } while
(0); _gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1420
, GF_LOG_ERROR, "Unable to get volume name"); } while (0)
;
1421 goto out;
1422 }
1423
1424 ret = glusterd_volinfo_find (volname, &volinfo);
1425
1426 if (ret) {
1427 gf_log ("", GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while
(0); _gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1427
, GF_LOG_ERROR, "Unable to allocate memory"); } while (0)
;
1428 goto out;
1429 }
1430
1431 ret = dict_get_int32 (dict, "count", &count);
1432 if (ret) {
1433 gf_log ("", GF_LOG_ERROR, "Unable to get count")do { do { if (0) printf ("Unable to get count"); } while (0);
_gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1433, GF_LOG_ERROR
, "Unable to get count"); } while (0)
;
1434 goto out;
1435 }
1436
1437
1438 ret = dict_get_str (dict, "bricks", &bricks);
1439 if (ret) {
1440 gf_log ("", GF_LOG_ERROR, "Unable to get bricks")do { do { if (0) printf ("Unable to get bricks"); } while (0)
; _gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1440, GF_LOG_ERROR
, "Unable to get bricks"); } while (0)
;
1441 goto out;
1442 }
1443
1444 ret = glusterd_op_perform_add_bricks (volinfo, count, bricks, dict);
1445 if (ret) {
1446 gf_log ("", GF_LOG_ERROR, "Unable to add bricks")do { do { if (0) printf ("Unable to add bricks"); } while (0)
; _gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1446, GF_LOG_ERROR
, "Unable to add bricks"); } while (0)
;
1447 goto out;
1448 }
1449
1450 /* Need to reset the defrag/rebalance status accordingly */
1451 switch (volinfo->rebal.defrag_status) {
1452 case GF_DEFRAG_STATUS_FAILED:
1453 case GF_DEFRAG_STATUS_COMPLETE:
1454 volinfo->rebal.defrag_status = 0;
1455 default:
1456 break;
1457 }
1458
1459 ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
1460 if (ret)
1461 goto out;
1462
1463 if (GLUSTERD_STATUS_STARTED == volinfo->status)
1464 ret = glusterd_nodesvcs_handle_graph_change (volinfo);
1465
1466out:
1467 return ret;
1468}
1469
1470int
1471glusterd_op_remove_brick (dict_t *dict, char **op_errstr)
1472{
1473 int ret = -1;
1474 char *volname = NULL((void*)0);
1475 glusterd_volinfo_t *volinfo = NULL((void*)0);
1476 char *brick = NULL((void*)0);
1477 int32_t count = 0;
1478 int32_t i = 1;
1479 char key[256] = {0,};
1480 int32_t flag = 0;
1481 char err_str[4096] = {0,};
1482 int need_rebalance = 0;
1483 int force = 0;
1484 gf1_op_commands cmd = 0;
1485 int32_t replica_count = 0;
1486 glusterd_brickinfo_t *brickinfo = NULL((void*)0);
1487 glusterd_brickinfo_t *tmp = NULL((void*)0);
1488 char *task_id_str = NULL((void*)0);
1489 xlator_t *this = NULL((void*)0);
1490
1491 this = THIS(*__glusterfs_this_location());
1492 GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "glusterd-brick-ops.c"
, __FUNCTION__, 1492, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
1493
1494 ret = dict_get_str (dict, "volname", &volname);
1495
1496 if (ret) {
1497 gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name")do { do { if (0) printf ("Unable to get volume name"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1497, GF_LOG_ERROR, "Unable to get volume name"); } while (
0)
;
1498 goto out;
1499 }
1500
1501 ret = glusterd_volinfo_find (volname, &volinfo);
1502 if (ret) {
1503 gf_log (this->name, GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1503, GF_LOG_ERROR, "Unable to allocate memory"); } while (
0)
;
1504 goto out;
1505 }
1506
1507 ret = dict_get_int32 (dict, "command", &flag);
1508 if (ret) {
1509 gf_log (this->name, GF_LOG_ERROR, "Unable to get command")do { do { if (0) printf ("Unable to get command"); } while (0
); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1509, GF_LOG_ERROR, "Unable to get command"); } while (0)
;
1510 goto out;
1511 }
1512 cmd = flag;
1513
1514 /* Set task-id, if available, in ctx dict for operations other than
1515 * start
1516 */
1517 if (is_origin_glusterd () && (cmd != GF_OP_CMD_START)) {
1518 if (!uuid_is_null (volinfo->rebal.rebalance_id)) {
1519 ret = glusterd_copy_uuid_to_dict
1520 (volinfo->rebal.rebalance_id, dict,
1521 GF_REMOVE_BRICK_TID_KEY"remove-brick-id");
1522 if (ret) {
1523 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Failed to set remove-brick-id"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1524, GF_LOG_ERROR, "Failed to set remove-brick-id"); } while
(0)
1524 "Failed to set remove-brick-id")do { do { if (0) printf ("Failed to set remove-brick-id"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1524, GF_LOG_ERROR, "Failed to set remove-brick-id"); } while
(0)
;
1525 goto out;
1526 }
1527 }
1528 }
1529
1530 /* Clear task-id on commmitting/stopping of remove-brick operation */
1531 if ((cmd != GF_OP_CMD_START) || (cmd != GF_OP_CMD_STATUS))
1532 uuid_clear (volinfo->rebal.rebalance_id);
1533
1534 ret = -1;
1535 switch (cmd) {
1536 case GF_OP_CMD_NONE:
1537 goto out;
1538
1539 case GF_OP_CMD_STATUS:
1540 ret = 0;
1541 goto out;
1542
1543 case GF_OP_CMD_STOP:
1544 {
1545 /* Fall back to the old volume file */
1546 list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo
->bricks)->next)-(unsigned long)(&((typeof(*brickinfo
) *)0)->brick_list))), tmp = ((typeof(*brickinfo) *)((char
*)(brickinfo->brick_list.next)-(unsigned long)(&((typeof
(*brickinfo) *)0)->brick_list))); &brickinfo->brick_list
!= (&volinfo->bricks); brickinfo = tmp, tmp = ((typeof
(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned long)(&
((typeof(*tmp) *)0)->brick_list))))
1547 brick_list)for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo
->bricks)->next)-(unsigned long)(&((typeof(*brickinfo
) *)0)->brick_list))), tmp = ((typeof(*brickinfo) *)((char
*)(brickinfo->brick_list.next)-(unsigned long)(&((typeof
(*brickinfo) *)0)->brick_list))); &brickinfo->brick_list
!= (&volinfo->bricks); brickinfo = tmp, tmp = ((typeof
(*tmp) *)((char *)(tmp->brick_list.next)-(unsigned long)(&
((typeof(*tmp) *)0)->brick_list))))
{
1548 if (!brickinfo->decommissioned)
1549 continue;
1550 brickinfo->decommissioned = 0;
1551 }
1552 ret = glusterd_create_volfiles_and_notify_services (volinfo);
1553 if (ret) {
1554 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to create volfiles"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1555, GF_LOG_WARNING, "failed to create volfiles"); } while
(0)
1555 "failed to create volfiles")do { do { if (0) printf ("failed to create volfiles"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1555, GF_LOG_WARNING, "failed to create volfiles"); } while
(0)
;
1556 goto out;
1557 }
1558
1559 ret = glusterd_store_volinfo (volinfo,
1560 GLUSTERD_VOLINFO_VER_AC_INCREMENT);
1561 if (ret) {
1562 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to store volinfo"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1563, GF_LOG_WARNING, "failed to store volinfo"); } while (
0)
1563 "failed to store volinfo")do { do { if (0) printf ("failed to store volinfo"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1563, GF_LOG_WARNING, "failed to store volinfo"); } while (
0)
;
1564 goto out;
1565 }
1566
1567 ret = 0;
1568 goto out;
1569 }
1570
1571 case GF_OP_CMD_START:
1572 ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY"remove-brick-id", &task_id_str);
1573 if (ret) {
1574 gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("Missing remove-brick-id"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1575, GF_LOG_DEBUG, "Missing remove-brick-id"); } while (0)
1575 "Missing remove-brick-id")do { do { if (0) printf ("Missing remove-brick-id"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1575, GF_LOG_DEBUG, "Missing remove-brick-id"); } while (0)
;
1576 ret = 0;
1577 } else {
1578 uuid_parse (task_id_str, volinfo->rebal.rebalance_id) ;
1579 }
1580 force = 0;
1581 break;
1582
1583 case GF_OP_CMD_COMMIT:
1584 force = 1;
1585 break;
1586
1587 case GF_OP_CMD_COMMIT_FORCE:
1588
1589 if (volinfo->decommission_in_progress) {
1590 if (volinfo->rebal.defrag) {
1591 LOCK (&volinfo->rebal.defrag->lock)pthread_spin_lock (&volinfo->rebal.defrag->lock);
1592 /* Fake 'rebalance-complete' so the graph change
1593 happens right away */
1594 volinfo->rebal.defrag_status =
1595 GF_DEFRAG_STATUS_COMPLETE;
1596
1597 UNLOCK (&volinfo->rebal.defrag->lock)pthread_spin_unlock (&volinfo->rebal.defrag->lock);
1598 }
1599 /* Graph change happens in rebalance _cbk function,
1600 no need to do anything here */
1601 /* TODO: '_cbk' function is not doing anything for now */
1602 }
1603
1604 ret = 0;
1605 force = 1;
1606 break;
1607 }
1608
1609 ret = dict_get_int32 (dict, "count", &count);
1610 if (ret) {
1611 gf_log ("", GF_LOG_ERROR, "Unable to get count")do { do { if (0) printf ("Unable to get count"); } while (0);
_gf_log ("", "glusterd-brick-ops.c", __FUNCTION__, 1611, GF_LOG_ERROR
, "Unable to get count"); } while (0)
;
1612 goto out;
1613 }
1614
1615
1616 while ( i <= count) {
1617 snprintf (key, 256, "brick%d", i);
1618 ret = dict_get_str (dict, key, &brick);
1619 if (ret) {
1620 gf_log (this->name, GF_LOG_ERROR, "Unable to get %s",do { do { if (0) printf ("Unable to get %s", key); } while (0
); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1621, GF_LOG_ERROR, "Unable to get %s", key); } while (0)
1621 key)do { do { if (0) printf ("Unable to get %s", key); } while (0
); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1621, GF_LOG_ERROR, "Unable to get %s", key); } while (0)
;
1622 goto out;
1623 }
1624
1625 ret = glusterd_op_perform_remove_brick (volinfo, brick, force,
1626 &need_rebalance);
1627 if (ret)
1628 goto out;
1629 i++;
1630 }
1631 ret = dict_get_int32 (dict, "replica-count", &replica_count);
1632 if (!ret) {
1633 gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1636, GF_LOG_INFO, "changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0)
1634 "changing replica count %d to %d on volume %s",do { do { if (0) printf ("changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1636, GF_LOG_INFO, "changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0)
1635 volinfo->replica_count, replica_count,do { do { if (0) printf ("changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1636, GF_LOG_INFO, "changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0)
1636 volinfo->volname)do { do { if (0) printf ("changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0); _gf_log (this->name, "glusterd-brick-ops.c"
, __FUNCTION__, 1636, GF_LOG_INFO, "changing replica count %d to %d on volume %s"
, volinfo->replica_count, replica_count, volinfo->volname
); } while (0)
;
1637 volinfo->replica_count = replica_count;
1638 volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
1639 volinfo->subvol_count = (volinfo->brick_count /
1640 volinfo->dist_leaf_count);
1641
1642 if (replica_count == 1) {
1643 if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
1644 volinfo->type = GF_CLUSTER_TYPE_NONE;
1645 /* backward compatibility */
1646 volinfo->sub_count = 0;
1647 } else {
1648 volinfo->type = GF_CLUSTER_TYPE_STRIPE;
1649 /* backward compatibility */
1650 volinfo->sub_count = volinfo->dist_leaf_count;
1651 }
1652 }
1653 }
1654
1655 ret = glusterd_create_volfiles_and_notify_services (volinfo);
1656 if (ret) {
1657 gf_log (this->name, GF_LOG_WARNING, "failed to create volfiles")do { do { if (0) printf ("failed to create volfiles"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1657, GF_LOG_WARNING, "failed to create volfiles"); } while
(0)
;
1658 goto out;
1659 }
1660
1661 ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
1662 if (ret) {
1663 gf_log (this->name, GF_LOG_WARNING, "failed to store volinfo")do { do { if (0) printf ("failed to store volinfo"); } while (
0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1663, GF_LOG_WARNING, "failed to store volinfo"); } while (
0)
;
1664 goto out;
1665 }
1666
1667 /* Need to reset the defrag/rebalance status accordingly */
1668 switch (volinfo->rebal.defrag_status) {
1669 case GF_DEFRAG_STATUS_FAILED:
1670 case GF_DEFRAG_STATUS_COMPLETE:
1671 volinfo->rebal.defrag_status = 0;
1672 default:
1673 break;
1674 }
1675 if (!force && need_rebalance) {
1676 /* perform the rebalance operations */
1677 ret = glusterd_handle_defrag_start
1678 (volinfo, err_str, sizeof (err_str),
1679 GF_DEFRAG_CMD_START_FORCE,
1680 glusterd_remove_brick_migrate_cbk, GD_OP_REMOVE_BRICK);
1681
1682 if (!ret)
1683 volinfo->decommission_in_progress = 1;
1684
1685 if (ret) {
1686 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to start the rebalance"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1687, GF_LOG_ERROR, "failed to start the rebalance"); } while
(0)
1687 "failed to start the rebalance")do { do { if (0) printf ("failed to start the rebalance"); } while
(0); _gf_log (this->name, "glusterd-brick-ops.c", __FUNCTION__
, 1687, GF_LOG_ERROR, "failed to start the rebalance"); } while
(0)
;
1688 }
1689 } else {
1690 if (GLUSTERD_STATUS_STARTED == volinfo->status)
1691 ret = glusterd_nodesvcs_handle_graph_change (volinfo);
1692 }
1693
1694out:
1695 if (ret && err_str[0] && op_errstr)
1696 *op_errstr = gf_strdup (err_str);
1697
1698 return ret;
1699}