2
Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
3
This file is part of GlusterFS.
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.
12
#include <glusterfs/globals.h>
13
#include <glusterfs/run.h>
15
#include <glusterfs/glusterfs.h>
16
#include "glusterd-utils.h"
17
#include "glusterd-svc-mgmt.h"
18
#include "glusterd-shd-svc.h"
19
#include "glusterd-quotad-svc.h"
21
#include "glusterd-nfs-svc.h"
23
#include "glusterd-bitd-svc.h"
24
#include "glusterd-shd-svc-helper.h"
25
#include "glusterd-scrub-svc.h"
26
#include "glusterd-svc-helper.h"
27
#include <glusterfs/syscall.h>
28
#include "glusterd-snapshot-utils.h"
31
glusterd_svcs_reconfigure(glusterd_volinfo_t *volinfo)
34
xlator_t *this = THIS;
35
glusterd_conf_t *conf = NULL;
36
char *svc_name = NULL;
43
ret = glusterd_nfssvc_reconfigure();
47
svc_name = "self-heald";
49
ret = glusterd_shdsvc_reconfigure(volinfo);
54
if (conf->op_version == GD_OP_VERSION_MIN)
58
ret = glusterd_quotadsvc_reconfigure();
63
ret = glusterd_bitdsvc_reconfigure();
67
svc_name = "scrubber";
68
ret = glusterd_scrubsvc_reconfigure();
71
gf_event(EVENT_SVC_RECONFIGURE_FAILED, "svc_name=%s", svc_name);
76
glusterd_svcs_stop(glusterd_volinfo_t *volinfo)
79
glusterd_conf_t *priv = NULL;
85
ret = priv->nfs_svc.stop(&(priv->nfs_svc), SIGKILL);
89
ret = priv->quotad_svc.stop(&(priv->quotad_svc), SIGTERM);
94
ret = volinfo->shd.svc.stop(&(volinfo->shd.svc), SIGTERM);
99
ret = priv->bitd_svc.stop(&(priv->bitd_svc), SIGTERM);
103
ret = priv->scrub_svc.stop(&(priv->scrub_svc), SIGTERM);
110
glusterd_svcs_manager(glusterd_volinfo_t *volinfo)
113
glusterd_conf_t *conf = NULL;
115
conf = THIS->private;
118
if (volinfo && volinfo->is_snap_volume)
122
ret = conf->nfs_svc.manager(&(conf->nfs_svc), NULL, PROC_START_NO_WAIT);
126
if (conf->op_version == GD_OP_VERSION_MIN)
129
ret = conf->quotad_svc.manager(&(conf->quotad_svc), volinfo,
136
ret = conf->bitd_svc.manager(&(conf->bitd_svc), NULL, PROC_START_NO_WAIT);
143
ret = volinfo->shd.svc.manager(&(volinfo->shd.svc), volinfo,
151
ret = conf->scrub_svc.manager(&(conf->scrub_svc), NULL, PROC_START_NO_WAIT);
159
glusterd_svc_check_volfile_identical(char *svc_name,
160
glusterd_graph_builder_t builder,
161
gf_boolean_t *identical)
163
char orgvol[PATH_MAX] = {
167
glusterd_conf_t *conf = NULL;
168
xlator_t *this = THIS;
173
GF_ASSERT(identical);
174
conf = this->private;
176
glusterd_svc_build_volfile_path(svc_name, conf->workdir, orgvol,
179
ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name);
184
/* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */
185
tmp_fd = mkstemp(tmpvol);
187
gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
188
"Unable to create temp file"
190
tmpvol, strerror(errno));
197
ret = glusterd_create_global_volfile(builder, tmpvol, NULL);
201
ret = glusterd_check_files_identical(orgvol, tmpvol, identical);
216
glusterd_svc_check_topology_identical(char *svc_name,
217
glusterd_graph_builder_t builder,
218
gf_boolean_t *identical)
220
char orgvol[PATH_MAX] = {
224
glusterd_conf_t *conf = NULL;
225
xlator_t *this = THIS;
230
if ((!identical) || (!this->private)) {
231
gf_smsg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL);
235
conf = this->private;
236
GF_VALIDATE_OR_GOTO(this->name, conf, out);
238
/* Fetch the original volfile */
239
glusterd_svc_build_volfile_path(svc_name, conf->workdir, orgvol,
242
/* Create the temporary volfile */
243
ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name);
248
/* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */
249
tmpfd = mkstemp(tmpvol);
251
gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
252
"Unable to create temp file"
254
tmpvol, strerror(errno));
259
tmpclean = 1; /* SET the flag to unlink() tmpfile */
261
ret = glusterd_create_global_volfile(builder, tmpvol, NULL);
265
/* Compare the topology of volfiles */
266
ret = glusterd_check_topology_identical(orgvol, tmpvol, identical);
278
glusterd_volume_svc_check_volfile_identical(
279
char *svc_name, dict_t *mode_dict, glusterd_volinfo_t *volinfo,
280
glusterd_vol_graph_builder_t builder, gf_boolean_t *identical)
282
char orgvol[PATH_MAX] = {
286
xlator_t *this = THIS;
291
GF_VALIDATE_OR_GOTO(this->name, identical, out);
293
/* This builds volfile for volume level dameons */
294
glusterd_volume_svc_build_volfile_path(svc_name, volinfo, orgvol,
297
ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name);
302
/* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */
303
tmp_fd = mkstemp(tmpvol);
305
gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
306
"Unable to create temp file"
308
tmpvol, strerror(errno));
315
ret = builder(volinfo, tmpvol, mode_dict);
319
ret = glusterd_check_files_identical(orgvol, tmpvol, identical);
334
glusterd_volume_svc_check_topology_identical(
335
char *svc_name, dict_t *mode_dict, glusterd_volinfo_t *volinfo,
336
glusterd_vol_graph_builder_t builder, gf_boolean_t *identical)
338
char orgvol[PATH_MAX] = {
342
glusterd_conf_t *conf = NULL;
343
xlator_t *this = THIS;
348
if ((!identical) || (!this->private)) {
349
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL);
353
conf = this->private;
354
GF_VALIDATE_OR_GOTO(this->name, conf, out);
356
/* This builds volfile for volume level dameons */
357
glusterd_volume_svc_build_volfile_path(svc_name, volinfo, orgvol,
359
/* Create the temporary volfile */
360
ret = gf_asprintf(&tmpvol, "/tmp/g%s-XXXXXX", svc_name);
365
/* coverity[SECURE_TEMP] mkstemp uses 0600 as the mode and is safe */
366
tmpfd = mkstemp(tmpvol);
368
gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
369
"Unable to create temp file"
371
tmpvol, strerror(errno));
376
tmpclean = 1; /* SET the flag to unlink() tmpfile */
378
ret = builder(volinfo, tmpvol, mode_dict);
382
/* Compare the topology of volfiles */
383
ret = glusterd_check_topology_identical(orgvol, tmpvol, identical);
395
glusterd_is_svcproc_attachable(glusterd_svc_proc_t *svc_proc)
398
glusterd_svc_t *parent_svc = NULL;
403
if (svc_proc->status == GF_SVC_STARTING)
406
if (svc_proc->status == GF_SVC_STARTED ||
407
svc_proc->status == GF_SVC_DISCONNECTED) {
408
parent_svc = cds_list_entry(svc_proc->svcs.next, glusterd_svc_t,
410
if (parent_svc && gf_is_service_running(parent_svc->proc.pidfile, &pid))
414
if (svc_proc->status == GF_SVC_DIED || svc_proc->status == GF_SVC_STOPPING)
421
__gf_find_compatible_svc(gd_node_type daemon)
423
glusterd_svc_proc_t *svc_proc = NULL;
424
struct cds_list_head *svc_procs = NULL;
425
glusterd_conf_t *conf = NULL;
427
conf = THIS->private;
428
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
432
svc_procs = &conf->shd_procs;
437
/* Add support for other client daemons here */
441
cds_list_for_each_entry(svc_proc, svc_procs, svc_proc_list)
443
if (glusterd_is_svcproc_attachable(svc_proc))
444
return (void *)svc_proc;
446
* Logic to select one process goes here. Currently there is only one
447
* shd_proc. So selecting the first one;
455
glusterd_svcprocess_new(void)
457
glusterd_svc_proc_t *new_svcprocess = NULL;
459
new_svcprocess = GF_CALLOC(1, sizeof(*new_svcprocess),
460
gf_gld_mt_glusterd_svc_proc_t);
465
CDS_INIT_LIST_HEAD(&new_svcprocess->svc_proc_list);
466
CDS_INIT_LIST_HEAD(&new_svcprocess->svcs);
467
new_svcprocess->notify = glusterd_muxsvc_common_rpc_notify;
468
new_svcprocess->status = GF_SVC_STARTING;
469
return new_svcprocess;
473
glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc)
476
glusterd_svc_proc_t *mux_proc = NULL;
477
glusterd_conn_t *mux_conn = NULL;
478
glusterd_conf_t *conf = NULL;
479
glusterd_svc_t *parent_svc = NULL;
481
gf_boolean_t stop_daemon = _gf_false;
482
char pidfile[PATH_MAX] = {
486
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
487
GF_VALIDATE_OR_GOTO("glusterd", volinfo, out);
488
conf = THIS->private;
489
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
490
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
492
pthread_mutex_lock(&conf->attach_lock);
494
if (svc->inited && !glusterd_proc_is_running(&(svc->proc))) {
495
/* This is the case when shd process was abnormally killed */
496
pthread_mutex_unlock(&conf->attach_lock);
497
glusterd_shd_svcproc_cleanup(&volinfo->shd);
498
pthread_mutex_lock(&conf->attach_lock);
502
glusterd_svc_build_shd_pidfile(volinfo, pidfile, sizeof(pidfile));
503
ret = snprintf(svc->proc.name, sizeof(svc->proc.name), "%s",
508
ret = snprintf(svc->proc.pidfile, sizeof(svc->proc.pidfile), "%s",
513
if (gf_is_service_running(pidfile, &pid)) {
514
/* Just connect is required, but we don't know what happens
515
* during the disconnect. So better to reattach.
517
mux_proc = __gf_find_compatible_svc_from_pid(GD_NODE_SHD, pid);
521
if (pid != -1 && sys_access(pidfile, R_OK) == 0) {
522
/* stale pid file, stop and unlink it. This has to be
523
* done outside the attach_lock.
525
stop_daemon = _gf_true;
527
mux_proc = __gf_find_compatible_svc(GD_NODE_SHD);
530
/* Take first entry from the process */
531
parent_svc = cds_list_entry(mux_proc->svcs.next, glusterd_svc_t,
533
mux_conn = &parent_svc->conn;
535
volinfo->shd.attached = _gf_true;
537
mux_proc = glusterd_svcprocess_new();
542
cds_list_add_tail(&mux_proc->svc_proc_list, &conf->shd_procs);
544
svc->svc_proc = mux_proc;
545
cds_list_del_init(&svc->mux_svc);
546
cds_list_add_tail(&svc->mux_svc, &mux_proc->svcs);
547
ret = glusterd_shdsvc_init(volinfo, mux_conn, mux_proc);
549
pthread_mutex_unlock(&conf->attach_lock);
550
gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_FAILED_INIT_SHDSVC,
551
"Failed to init shd "
555
gf_msg_debug(THIS->name, 0, "shd service initialized");
556
svc->inited = _gf_true;
561
pthread_mutex_unlock(&conf->attach_lock);
564
glusterd_proc_stop(&svc->proc, SIGTERM, PROC_STOP_FORCE);
571
__gf_find_compatible_svc_from_pid(gd_node_type daemon, pid_t pid)
573
glusterd_svc_proc_t *svc_proc = NULL;
574
struct cds_list_head *svc_procs = NULL;
575
glusterd_svc_t *svc = NULL;
577
glusterd_conf_t *conf = NULL;
579
conf = THIS->private;
585
svc_procs = &conf->shd_procs;
590
/* Add support for other client daemons here */
594
cds_list_for_each_entry(svc_proc, svc_procs, svc_proc_list)
596
cds_list_for_each_entry(svc, &svc_proc->svcs, mux_svc)
598
if (gf_is_service_running(svc->proc.pidfile, &mux_pid)) {
599
if (mux_pid == pid &&
600
glusterd_is_svcproc_attachable(svc_proc)) {
602
* inefficient loop, but at the moment, there is only
614
my_callback(struct rpc_req *req, struct iovec *iov, int count, void *v_frame)
616
call_frame_t *frame = v_frame;
617
xlator_t *this = NULL;
618
glusterd_conf_t *conf = NULL;
620
GF_VALIDATE_OR_GOTO("glusterd", frame, out);
622
GF_VALIDATE_OR_GOTO("glusterd", this, out);
623
conf = this->private;
624
GF_VALIDATE_OR_GOTO(this->name, conf, out);
626
if (GF_ATOMIC_DEC(conf->blockers) == 0) {
627
synccond_broadcast(&conf->cond_blockers);
630
STACK_DESTROY(frame->root);
636
glusterd_svc_attach_cbk(struct rpc_req *req, struct iovec *iov, int count,
639
call_frame_t *frame = v_frame;
640
glusterd_volinfo_t *volinfo = NULL;
641
glusterd_shdsvc_t *shd = NULL;
642
glusterd_svc_t *svc = frame->cookie;
643
glusterd_conf_t *conf = NULL;
644
int *flag = (int *)frame->local;
645
xlator_t *this = THIS;
647
gf_getspec_rsp rsp = {
651
conf = this->private;
652
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
653
GF_VALIDATE_OR_GOTO("glusterd", frame, out);
654
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
657
frame->cookie = NULL;
659
if (!strcmp(svc->name, "glustershd")) {
660
/* Get volinfo->shd from svc object */
661
shd = cds_list_entry(svc, glusterd_shdsvc_t, svc);
663
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_SHD_OBJ_GET_FAIL,
664
"Failed to get shd object "
669
/* Get volinfo from shd */
670
volinfo = cds_list_entry(shd, glusterd_volinfo_t, shd);
672
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
673
"Failed to get volinfo from "
680
gf_msg(frame->this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL,
686
ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
688
gf_msg(frame->this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL,
689
"XDR decoding error");
694
if (rsp.op_ret == 0) {
695
svc->online = _gf_true;
696
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_SVC_ATTACH_FAIL,
697
"svc %s of volume %s attached successfully to pid %d", svc->name,
698
volinfo->volname, glusterd_proc_get_pid(&svc->proc));
700
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL,
701
"svc %s of volume %s failed to attach to pid %d", svc->name,
702
volinfo->volname, glusterd_proc_get_pid(&svc->proc));
703
if (!strcmp(svc->name, "glustershd")) {
704
glusterd_shd_svcproc_cleanup(&volinfo->shd);
713
glusterd_volinfo_unref(volinfo);
715
if (GF_ATOMIC_DEC(conf->blockers) == 0) {
716
synccond_broadcast(&conf->cond_blockers);
718
STACK_DESTROY(frame->root);
723
build_volfile_path(char *volume_id, char *path, size_t path_len,
724
char *trusted_str, dict_t *dict);
727
__glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
728
struct rpc_clnt *rpc, char *volfile_id,
732
struct iobuf *iobuf = NULL;
733
struct iobref *iobref = NULL;
737
char path[PATH_MAX] = {
740
struct stat stbuf = {
743
int32_t spec_fd = -1;
744
size_t file_len = -1;
745
char *volfile_content = NULL;
746
ssize_t req_size = 0;
747
call_frame_t *frame = NULL;
748
gd1_mgmt_brick_op_req brick_req;
750
void *req = &brick_req;
751
struct rpc_clnt_connection *conn;
752
xlator_t *this = THIS;
753
glusterd_conf_t *conf = THIS->private;
754
extern struct rpc_clnt_program gd_brick_prog;
755
fop_cbk_fn_t cbkfn = my_callback;
758
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_PARAM_NULL,
759
"called with null rpc");
764
if (rpc_clnt_connection_status(conn) != RPC_STATUS_CONNECTED) {
765
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_CONNECT_RETURNED,
766
"not connected yet");
771
brick_req.name = volfile_id;
772
brick_req.input.input_val = NULL;
773
brick_req.input.input_len = 0;
774
brick_req.dict.dict_val = NULL;
775
brick_req.dict.dict_len = 0;
777
frame = create_frame(this, this->ctx->pool);
779
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_FRAME_CREATE_FAIL,
784
if (op == GLUSTERD_SVC_ATTACH) {
787
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL,
793
(void)build_volfile_path(volfile_id, path, sizeof(path), NULL, dict);
795
ret = sys_stat(path, &stbuf);
797
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL,
798
"Unable to stat %s (%s)", path, strerror(errno));
803
file_len = stbuf.st_size;
804
volfile_content = GF_MALLOC(file_len + 1, gf_common_mt_char);
805
if (!volfile_content) {
806
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL);
810
spec_fd = open(path, O_RDONLY);
812
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SVC_ATTACH_FAIL,
813
"failed to read volfile %s", path);
817
ret = sys_read(spec_fd, volfile_content, file_len);
818
if (ret == file_len) {
819
brick_req.input.input_val = volfile_content;
820
brick_req.input.input_len = file_len;
822
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL,
823
"read failed on path %s. File size=%" GF_PRI_SIZET
825
path, file_len, ret);
829
if (dict->count > 0) {
830
ret = dict_allocate_and_serialize(dict, &brick_req.dict.dict_val,
831
&brick_req.dict.dict_len);
833
gf_smsg(this->name, GF_LOG_ERROR, errno,
834
GD_MSG_DICT_ALLOC_AND_SERL_LENGTH_GET_FAIL, NULL);
840
frame->local = GF_CALLOC(1, sizeof(int), gf_gld_mt_int);
841
*((int *)frame->local) = flags;
842
cbkfn = glusterd_svc_attach_cbk;
845
req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
846
iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size);
851
iov.iov_base = iobuf->ptr;
852
iov.iov_len = iobuf_pagesize(iobuf);
854
iobref = iobref_new();
859
iobref_add(iobref, iobuf);
861
/* Create the xdr payload */
862
ret = xdr_serialize_generic(iov, req, (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
869
GF_ATOMIC_INC(conf->blockers);
870
ret = rpc_clnt_submit(rpc, &gd_brick_prog, op, cbkfn, &iov, 1, NULL, 0,
871
iobref, frame, NULL, 0, NULL, 0, NULL);
879
iobref_unref(iobref);
883
if (brick_req.dict.dict_val)
884
GF_FREE(brick_req.dict.dict_val);
886
GF_FREE(volfile_content);
890
STACK_DESTROY(frame->root);
895
glusterd_volume_exists(const char *volname)
897
glusterd_volinfo_t *tmp_volinfo = NULL;
898
gf_boolean_t volume_found = _gf_false;
899
xlator_t *this = THIS;
900
glusterd_conf_t *priv = NULL;
904
priv = this->private;
907
cds_list_for_each_entry(tmp_volinfo, &priv->volumes, vol_list)
909
if (!strcmp(tmp_volinfo->volname, volname)) {
910
gf_msg_debug(this->name, 0, "Volume %s found", volname);
911
volume_found = _gf_true;
920
glusterd_attach_svc(glusterd_svc_t *svc, glusterd_volinfo_t *volinfo, int flags)
922
glusterd_conf_t *conf = THIS->private;
925
rpc_clnt_t *rpc = NULL;
927
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
928
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
929
GF_VALIDATE_OR_GOTO("glusterd", volinfo, out);
931
gf_msg("glusterd", GF_LOG_INFO, 0, GD_MSG_ATTACH_INFO,
932
"adding svc %s (volume=%s) to existing "
933
"process with pid %d",
934
svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc));
936
rpc = rpc_clnt_ref(svc->conn.rpc);
937
for (tries = 15; tries > 0; --tries) {
938
/* There might be a case that the volume for which we're attempting to
939
* attach a shd svc might become stale and in the process of deletion.
940
* Given that the volinfo object is being already passed here before
941
* that sequence of operation has happened we might be operating on a
942
* stale volume. At every sync task switch we should check for existance
945
if (!glusterd_volume_exists(volinfo->volname)) {
946
gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_SVC_ATTACH_FAIL,
948
" is marked as stale, not attempting further shd svc attach "
955
pthread_mutex_lock(&conf->attach_lock);
957
ret = __glusterd_send_svc_configure_req(
958
svc, flags, rpc, svc->proc.volfileid, GLUSTERD_SVC_ATTACH);
960
pthread_mutex_unlock(&conf->attach_lock);
962
volinfo->shd.attached = _gf_true;
967
* It might not actually be safe to manipulate the lock
968
* like this, but if we don't then the connection can
969
* never actually complete and retries are useless.
970
* Unfortunately, all of the alternatives (e.g. doing
971
* all of this in a separate thread) are much more
972
* complicated and risky.
973
* TBD: see if there's a better way
975
synclock_unlock(&conf->big_lock);
977
synclock_lock(&conf->big_lock);
980
gf_msg("glusterd", GF_LOG_WARNING, 0, GD_MSG_SVC_ATTACH_FAIL,
981
"attach failed for %s(volume=%s)", svc->name, volinfo->volname);
989
glusterd_detach_svc(glusterd_svc_t *svc, glusterd_volinfo_t *volinfo, int sig)
991
glusterd_conf_t *conf = THIS->private;
994
rpc_clnt_t *rpc = NULL;
996
GF_VALIDATE_OR_GOTO(THIS->name, conf, out);
997
GF_VALIDATE_OR_GOTO(THIS->name, svc, out);
998
GF_VALIDATE_OR_GOTO(THIS->name, volinfo, out);
1000
gf_msg(THIS->name, GF_LOG_INFO, 0, GD_MSG_DETACH_INFO,
1001
"removing svc %s (volume=%s) from existing "
1002
"process with pid %d",
1003
svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc));
1005
rpc = rpc_clnt_ref(svc->conn.rpc);
1006
for (tries = 15; tries > 0; --tries) {
1008
/*For detach there is no flags, and we are not using sig.*/
1009
pthread_mutex_lock(&conf->attach_lock);
1011
ret = __glusterd_send_svc_configure_req(svc, 0, svc->conn.rpc,
1012
svc->proc.volfileid,
1013
GLUSTERD_SVC_DETACH);
1015
pthread_mutex_unlock(&conf->attach_lock);
1021
* It might not actually be safe to manipulate the lock
1022
* like this, but if we don't then the connection can
1023
* never actually complete and retries are useless.
1024
* Unfortunately, all of the alternatives (e.g. doing
1025
* all of this in a separate thread) are much more
1026
* complicated and risky.
1027
* TBD: see if there's a better way
1029
synclock_unlock(&conf->big_lock);
1031
synclock_lock(&conf->big_lock);
1034
gf_msg("glusterd", GF_LOG_WARNING, 0, GD_MSG_SVC_DETACH_FAIL,
1035
"detach failed for %s(volume=%s)", svc->name, volinfo->volname);
1038
rpc_clnt_unref(rpc);