11
#include <glusterfs/globals.h>
12
#include <glusterfs/run.h>
13
#include "glusterd-utils.h"
14
#include "glusterd-volgen.h"
15
#include "glusterd-shd-svc.h"
16
#include "glusterd-shd-svc-helper.h"
17
#include "glusterd-svc-helper.h"
18
#include "glusterd-store.h"
20
#define GD_SHD_PROCESS_NAME "--process-name"
21
char *shd_svc_name = "glustershd";
24
glusterd_shdsvc_build(glusterd_svc_t *svc)
27
ret = snprintf(svc->name, sizeof(svc->name), "%s", shd_svc_name);
31
CDS_INIT_LIST_HEAD(&svc->mux_svc);
32
svc->manager = glusterd_shdsvc_manager;
33
svc->start = glusterd_shdsvc_start;
34
svc->stop = glusterd_shdsvc_stop;
35
svc->reconfigure = glusterd_shdsvc_reconfigure;
39
glusterd_shdsvc_init(void *data, glusterd_conn_t *mux_conn,
40
glusterd_svc_proc_t *mux_svc)
43
char rundir[PATH_MAX] = {
46
char sockpath[PATH_MAX] = {
49
char pidfile[PATH_MAX] = {
52
char volfile[PATH_MAX] = {
55
char logdir[PATH_MAX] = {
58
char logfile[PATH_MAX] = {
61
char volfileid[256] = {0};
62
glusterd_svc_t *svc = NULL;
63
glusterd_volinfo_t *volinfo = NULL;
64
glusterd_conf_t *priv = NULL;
65
glusterd_muxsvc_conn_notify_t notify = NULL;
66
xlator_t *this = THIS;
67
char *volfileserver = NULL;
71
GF_VALIDATE_OR_GOTO(this->name, priv, out);
74
GF_VALIDATE_OR_GOTO(this->name, data, out);
75
GF_VALIDATE_OR_GOTO(this->name, mux_svc, out);
77
svc = &(volinfo->shd.svc);
79
ret = snprintf(svc->name, sizeof(svc->name), "%s", shd_svc_name);
83
notify = glusterd_muxsvc_common_rpc_notify;
84
glusterd_store_perform_node_state_store(volinfo);
86
GLUSTERD_GET_SHD_RUNDIR(rundir, volinfo, priv);
87
glusterd_svc_create_rundir(rundir);
89
glusterd_svc_build_logfile_path(shd_svc_name, priv->logdir, logfile,
93
if (mux_conn && mux_svc->rpc) {
95
svc->conn.rpc = rpc_clnt_ref(mux_svc->rpc);
96
ret = snprintf(svc->conn.sockpath, sizeof(svc->conn.sockpath), "%s",
101
ret = mkdir_p(priv->logdir, 0755, _gf_true);
102
if ((ret == -1) && (EEXIST != errno)) {
103
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED,
104
"Unable to create logdir %s", logdir);
108
glusterd_svc_build_shd_socket_filepath(volinfo, sockpath,
110
ret = glusterd_muxsvc_conn_init(&(svc->conn), mux_svc, sockpath, 600,
116
mux_svc->rpc = rpc_clnt_ref(svc->conn.rpc);
120
glusterd_svc_build_shd_pidfile(volinfo, pidfile, sizeof(pidfile));
121
glusterd_svc_build_shd_volfile_path(volinfo, volfile, PATH_MAX);
122
len = snprintf(volfileid, sizeof(volfileid), "shd/%s", volinfo->volname);
123
if ((len < 0) || (len >= sizeof(volfileid))) {
128
if (dict_get_str(this->options, "transport.socket.bind-address",
129
&volfileserver) != 0) {
130
volfileserver = "localhost";
132
ret = glusterd_proc_init(&(svc->proc), shd_svc_name, pidfile, logdir,
133
logfile, volfile, volfileid, volfileserver);
138
gf_msg_debug(this->name, 0, "Returning %d", ret);
143
glusterd_shdsvc_create_volfile(glusterd_volinfo_t *volinfo)
145
char filepath[PATH_MAX] = {
150
dict_t *mod_dict = NULL;
151
xlator_t *this = THIS;
153
glusterd_svc_build_shd_volfile_path(volinfo, filepath, PATH_MAX);
154
if (!glusterd_is_shd_compatible_volume(volinfo)) {
162
mod_dict = dict_new();
164
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL);
168
ret = dict_set_uint32(mod_dict, "cluster.background-self-heal-count", 0);
170
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
171
"Key=cluster.background-self-heal-count", NULL);
175
ret = dict_set_str(mod_dict, "cluster.data-self-heal", "on");
177
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
178
"Key=cluster.data-self-heal", NULL);
182
ret = dict_set_str(mod_dict, "cluster.metadata-self-heal", "on");
184
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
185
"Key=cluster.metadata-self-heal", NULL);
189
ret = dict_set_str(mod_dict, "cluster.entry-self-heal", "on");
191
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
192
"Key=cluster.entry-self-heal", NULL);
196
ret = glusterd_shdsvc_generate_volfile(volinfo, filepath, mod_dict);
198
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
199
"Failed to create volfile");
205
dict_unref(mod_dict);
206
gf_msg_debug(this->name, 0, "Returning %d", ret);
212
glusterd_svcs_shd_compatible_volumes_stopped(glusterd_svc_t *svc)
214
glusterd_svc_proc_t *svc_proc = NULL;
215
glusterd_shdsvc_t *shd = NULL;
216
glusterd_svc_t *temp_svc = NULL;
217
glusterd_volinfo_t *volinfo = NULL;
218
gf_boolean_t comp = _gf_false;
219
glusterd_conf_t *conf = THIS->private;
221
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
222
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
223
pthread_mutex_lock(&conf->attach_lock);
225
svc_proc = svc->svc_proc;
228
cds_list_for_each_entry(temp_svc, &svc_proc->svcs, mux_svc)
231
shd = cds_list_entry(svc, glusterd_shdsvc_t, svc);
233
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_SHD_OBJ_GET_FAIL,
234
"Failed to get shd object "
240
volinfo = cds_list_entry(shd, glusterd_volinfo_t, shd);
242
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
243
"Failed to get volinfo from "
247
if (!glusterd_is_shd_compatible_volume(volinfo))
249
if (volinfo->status == GLUSTERD_STATUS_STARTED)
255
pthread_mutex_unlock(&conf->attach_lock);
261
glusterd_shdsvc_manager(glusterd_svc_t *svc, void *data, int flags)
264
glusterd_volinfo_t *volinfo = NULL;
265
glusterd_conf_t *conf = NULL;
266
gf_boolean_t shd_restart = _gf_false;
268
conf = THIS->private;
269
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
270
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
272
GF_VALIDATE_OR_GOTO("glusterd", volinfo, out);
274
if (volinfo->is_snap_volume) {
280
while (conf->restart_shd) {
281
synccond_wait(&conf->cond_restart_shd, &conf->big_lock);
283
conf->restart_shd = _gf_true;
284
shd_restart = _gf_true;
287
glusterd_volinfo_ref(volinfo);
289
if (!glusterd_is_shd_compatible_volume(volinfo)) {
295
ret = svc->stop(svc, SIGTERM);
299
ret = glusterd_shdsvc_create_volfile(volinfo);
303
ret = glusterd_shd_svc_mux_init(volinfo, svc);
305
gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_FAILED_INIT_SHDSVC,
306
"Failed to init shd service");
318
if (glusterd_svcs_shd_compatible_volumes_stopped(svc)) {
323
ret = svc->stop(svc, SIGTERM);
324
} else if (volinfo) {
325
if (volinfo->status != GLUSTERD_STATUS_STARTED) {
326
ret = svc->stop(svc, SIGTERM);
330
if (volinfo->status == GLUSTERD_STATUS_STARTED) {
331
ret = svc->start(svc, flags);
338
conf->restart_shd = _gf_false;
339
synccond_broadcast(&conf->cond_restart_shd);
342
glusterd_volinfo_unref(volinfo);
344
gf_event(EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name);
345
gf_msg_debug(THIS->name, 0, "Returning %d", ret);
351
glusterd_new_shd_svc_start(glusterd_svc_t *svc, int flags)
354
char glusterd_uuid_option[PATH_MAX] = {0};
355
char client_pid[32] = {0};
356
dict_t *cmdline = NULL;
357
xlator_t *this = THIS;
359
cmdline = dict_new();
363
ret = snprintf(glusterd_uuid_option, sizeof(glusterd_uuid_option),
364
"*replicate*.node-uuid=%s", uuid_utoa(MY_UUID));
368
ret = snprintf(client_pid, sizeof(client_pid), "--client-pid=%d",
369
GF_CLIENT_PID_SELF_HEALD);
373
ret = dict_set_str(cmdline, "arg", client_pid);
375
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
383
ret = dict_set_str(cmdline, "arg4", svc->name);
385
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
390
ret = dict_set_str(cmdline, "arg3", GD_SHD_PROCESS_NAME);
392
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
397
ret = dict_set_str(cmdline, "arg2", glusterd_uuid_option);
399
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
404
ret = dict_set_str(cmdline, "arg1", "--xlator-option");
406
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
411
ret = glusterd_svc_start(svc, flags, cmdline);
413
gf_smsg(this->name, GF_LOG_ERROR, errno,
414
GD_MSG_GLUSTER_SERVICE_START_FAIL, NULL);
418
ret = glusterd_conn_connect(&(svc->conn));
426
glusterd_recover_shd_attach_failure(glusterd_volinfo_t *volinfo,
427
glusterd_svc_t *svc, int flags)
430
glusterd_svc_proc_t *mux_proc = NULL;
431
glusterd_conf_t *conf = NULL;
433
conf = THIS->private;
435
if (!conf || !volinfo || !svc)
437
glusterd_shd_svcproc_cleanup(&volinfo->shd);
438
mux_proc = glusterd_svcprocess_new();
442
ret = glusterd_shdsvc_init(volinfo, NULL, mux_proc);
445
pthread_mutex_lock(&conf->attach_lock);
447
cds_list_add_tail(&mux_proc->svc_proc_list, &conf->shd_procs);
448
svc->svc_proc = mux_proc;
449
cds_list_del_init(&svc->mux_svc);
450
cds_list_add_tail(&svc->mux_svc, &mux_proc->svcs);
452
pthread_mutex_unlock(&conf->attach_lock);
454
ret = glusterd_new_shd_svc_start(svc, flags);
456
volinfo->shd.attached = _gf_true;
462
glusterd_shdsvc_start(glusterd_svc_t *svc, int flags)
465
glusterd_shdsvc_t *shd = NULL;
466
glusterd_volinfo_t *volinfo = NULL;
467
glusterd_conf_t *conf = NULL;
469
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
470
conf = THIS->private;
471
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
474
shd = cds_list_entry(svc, glusterd_shdsvc_t, svc);
476
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_SHD_OBJ_GET_FAIL,
477
"Failed to get shd object "
483
volinfo = cds_list_entry(shd, glusterd_volinfo_t, shd);
485
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
486
"Failed to get volinfo from "
491
if (volinfo->status != GLUSTERD_STATUS_STARTED)
494
glusterd_volinfo_ref(volinfo);
497
ret = glusterd_shd_svc_mux_init(volinfo, svc);
503
glusterd_volinfo_ref(volinfo);
505
ret = glusterd_attach_svc(svc, volinfo, flags);
507
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
508
"Failed to attach shd svc(volume=%s) to pid=%d",
509
volinfo->volname, glusterd_proc_get_pid(&svc->proc));
510
glusterd_shd_svcproc_cleanup(&volinfo->shd);
511
glusterd_volinfo_unref(volinfo);
516
ret = glusterd_new_shd_svc_start(svc, flags);
518
shd->attached = _gf_true;
522
glusterd_shd_svcproc_cleanup(&volinfo->shd);
524
glusterd_volinfo_unref(volinfo);
526
gf_msg_debug(THIS->name, 0, "Returning %d", ret);
532
glusterd_shdsvc_reconfigure(glusterd_volinfo_t *volinfo)
535
xlator_t *this = THIS;
536
gf_boolean_t identical = _gf_false;
537
dict_t *mod_dict = NULL;
538
glusterd_svc_t *svc = NULL;
546
glusterd_volinfo_ref(volinfo);
547
svc = &(volinfo->shd.svc);
548
if (glusterd_svcs_shd_compatible_volumes_stopped(svc))
557
if (!glusterd_is_shd_compatible_volume(volinfo)) {
565
mod_dict = dict_new();
567
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL);
571
ret = dict_set_uint32(mod_dict, "cluster.background-self-heal-count", 0);
573
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
574
"Key=cluster.background-self-heal-count", NULL);
578
ret = dict_set_str(mod_dict, "cluster.data-self-heal", "on");
580
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
581
"Key=cluster.data-self-heal", NULL);
585
ret = dict_set_str(mod_dict, "cluster.metadata-self-heal", "on");
587
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
588
"Key=cluster.metadata-self-heal", NULL);
592
ret = dict_set_int32(mod_dict, "graph-check", 1);
594
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
595
"Key=graph-check", NULL);
599
ret = dict_set_str(mod_dict, "cluster.entry-self-heal", "on");
601
gf_smsg(this->name, GF_LOG_ERROR, -ret, GD_MSG_DICT_SET_FAILED,
602
"Key=cluster.entry-self-heal", NULL);
606
ret = glusterd_volume_svc_check_volfile_identical(
607
"glustershd", mod_dict, volinfo, glusterd_shdsvc_generate_volfile,
622
identical = _gf_false;
623
ret = glusterd_volume_svc_check_topology_identical(
624
"glustershd", mod_dict, volinfo, glusterd_shdsvc_generate_volfile,
633
ret = glusterd_shdsvc_create_volfile(volinfo);
635
ret = glusterd_fetchspec_notify(THIS);
644
ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT);
648
glusterd_volinfo_unref(volinfo);
650
dict_unref(mod_dict);
651
gf_msg_debug(this->name, 0, "Returning %d", ret);
656
glusterd_shdsvc_restart(void)
658
glusterd_volinfo_t *volinfo = NULL;
659
glusterd_volinfo_t *tmp = NULL;
661
xlator_t *this = THIS;
662
glusterd_conf_t *conf = NULL;
663
glusterd_svc_t *svc = NULL;
665
conf = this->private;
666
GF_VALIDATE_OR_GOTO(this->name, conf, out);
668
pthread_mutex_lock(&conf->volume_lock);
669
cds_list_for_each_entry_safe(volinfo, tmp, &conf->volumes, vol_list)
671
glusterd_volinfo_ref(volinfo);
672
pthread_mutex_unlock(&conf->volume_lock);
674
if (volinfo->status == GLUSTERD_STATUS_STARTED) {
675
svc = &(volinfo->shd.svc);
676
ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT);
678
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SHD_START_FAIL,
679
"Couldn't start shd for "
680
"vol: %s on restart",
682
gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s",
683
volinfo->volname, svc->name);
684
glusterd_volinfo_unref(volinfo);
688
glusterd_volinfo_unref(volinfo);
689
pthread_mutex_lock(&conf->volume_lock);
691
pthread_mutex_unlock(&conf->volume_lock);
697
glusterd_shdsvc_stop(glusterd_svc_t *svc, int sig)
700
glusterd_svc_proc_t *svc_proc = NULL;
701
glusterd_shdsvc_t *shd = NULL;
702
glusterd_volinfo_t *volinfo = NULL;
703
gf_boolean_t empty = _gf_false;
704
glusterd_conf_t *conf = NULL;
706
xlator_t *this = THIS;
708
conf = this->private;
709
GF_VALIDATE_OR_GOTO("glusterd", conf, out);
710
GF_VALIDATE_OR_GOTO("glusterd", svc, out);
711
svc_proc = svc->svc_proc;
717
gf_msg_debug("glusterd", 0, "svc_proc is null, ie shd already stopped");
723
shd = cds_list_entry(svc, glusterd_shdsvc_t, svc);
725
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_SHD_OBJ_GET_FAIL,
726
"Failed to get shd object "
732
volinfo = cds_list_entry(shd, glusterd_volinfo_t, shd);
734
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
735
"Failed to get volinfo from "
740
glusterd_volinfo_ref(volinfo);
741
pthread_mutex_lock(&conf->attach_lock);
743
if (!gf_is_service_running(svc->proc.pidfile, &pid)) {
744
gf_msg_debug(this->name, 0, "shd isn't running");
746
cds_list_del_init(&svc->mux_svc);
747
empty = cds_list_empty(&svc_proc->svcs);
749
svc_proc->status = GF_SVC_STOPPING;
750
cds_list_del_init(&svc_proc->svc_proc_list);
753
pthread_mutex_unlock(&conf->attach_lock);
756
glusterd_volinfo_ref(volinfo);
757
svc_proc->data = volinfo;
758
ret = glusterd_svc_stop(svc, sig);
760
glusterd_volinfo_unref(volinfo);
764
if (!empty && pid != -1) {
765
ret = glusterd_detach_svc(svc, volinfo, sig);
767
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_STOP_FAIL,
768
"shd service is failed to detach volume %s from pid %d",
769
volinfo->volname, glusterd_proc_get_pid(&svc->proc));
771
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_SVC_STOP_SUCCESS,
772
"Shd service is detached for volume %s from pid %d",
773
volinfo->volname, glusterd_proc_get_pid(&svc->proc));
775
svc->online = _gf_false;
776
gf_unlink(svc->proc.pidfile);
777
glusterd_shd_svcproc_cleanup(shd);
779
glusterd_volinfo_unref(volinfo);
781
gf_msg_debug(this->name, 0, "Returning %d", ret);