11
#include <glusterfs/globals.h>
12
#include <glusterfs/run.h>
13
#include "glusterd-utils.h"
14
#include "glusterd-volgen.h"
15
#include "glusterd-messages.h"
16
#include "glusterd-svc-mgmt.h"
17
#include "glusterd-svc-helper.h"
18
#include "glusterd-conn-mgmt.h"
19
#include "glusterd-proc-mgmt.h"
20
#include "glusterd-snapd-svc.h"
21
#include "glusterd-snapd-svc-helper.h"
22
#include "glusterd-snapshot-utils.h"
23
#include <glusterfs/syscall.h>
25
char *snapd_svc_name = "snapd";
28
glusterd_svc_build_snapd_logdir(char *logdir, char *volname, size_t len)
30
glusterd_conf_t *priv = THIS->private;
31
snprintf(logdir, len, "%s/snaps/%s", priv->logdir, volname);
36
glusterd_snapdsvc_build(glusterd_svc_t *svc)
38
svc->manager = glusterd_snapdsvc_manager;
39
svc->start = glusterd_snapdsvc_start;
40
svc->stop = glusterd_svc_stop;
44
glusterd_snapdsvc_init(void *data)
47
char rundir[PATH_MAX] = {
50
char sockpath[PATH_MAX] = {
53
char pidfile[PATH_MAX] = {
56
char volfile[PATH_MAX] = {
59
char logdir[PATH_MAX] = {
62
char logfile[PATH_MAX] = {
65
char volfileid[256] = {0};
66
glusterd_svc_t *svc = NULL;
67
glusterd_volinfo_t *volinfo = NULL;
68
glusterd_conf_t *priv = NULL;
69
glusterd_conn_notify_t notify = NULL;
70
xlator_t *this = THIS;
71
char *volfileserver = NULL;
79
svc = &(volinfo->snapd.svc);
81
ret = snprintf(svc->name, sizeof(svc->name), "%s", snapd_svc_name);
83
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
87
notify = glusterd_snapdsvc_rpc_notify;
89
glusterd_svc_build_snapd_rundir(volinfo, rundir, sizeof(rundir));
90
glusterd_svc_create_rundir(rundir);
93
glusterd_svc_build_snapd_socket_filepath(volinfo, sockpath,
95
ret = glusterd_conn_init(&(svc->conn), sockpath, 600, notify);
100
glusterd_svc_build_snapd_pidfile(volinfo, pidfile, sizeof(pidfile));
101
glusterd_svc_build_snapd_volfile(volinfo, volfile, sizeof(volfile));
102
glusterd_svc_build_snapd_logdir(logdir, volinfo->volname, sizeof(logdir));
103
ret = mkdir_p(logdir, 0755, _gf_true);
104
if ((ret == -1) && (EEXIST != errno)) {
105
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED,
106
"Unable to create logdir %s", logdir);
109
len = snprintf(logfile, sizeof(logfile), "%s/snapd.log", logdir);
110
if ((len < 0) || (len >= sizeof(logfile))) {
111
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
115
len = snprintf(volfileid, sizeof(volfileid), "snapd/%s", volinfo->volname);
116
if ((len < 0) || (len >= sizeof(volfileid))) {
117
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
122
if (dict_get_str(this->options, "transport.socket.bind-address",
123
&volfileserver) != 0) {
124
volfileserver = "localhost";
126
ret = glusterd_proc_init(&(svc->proc), snapd_svc_name, pidfile, logdir,
127
logfile, volfile, volfileid, volfileserver);
132
gf_msg_debug(this->name, 0, "Returning %d", ret);
137
glusterd_snapdsvc_manager(glusterd_svc_t *svc, void *data, int flags)
140
xlator_t *this = THIS;
141
glusterd_volinfo_t *volinfo = NULL;
146
ret = glusterd_snapdsvc_init(volinfo);
148
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_INIT_FAIL,
149
"Failed to initialize "
150
"snapd service for volume %s",
154
svc->inited = _gf_true;
155
gf_msg_debug(this->name, 0,
161
ret = glusterd_is_snapd_enabled(volinfo);
163
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
164
"Failed to read volume "
170
if (!glusterd_is_volume_started(volinfo)) {
171
if (glusterd_proc_is_running(&svc->proc)) {
172
ret = svc->stop(svc, SIGTERM);
174
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL,
175
"Couldn't stop snapd for "
185
ret = glusterd_snapdsvc_create_volfile(volinfo);
187
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_CREATE_FAIL,
189
"snapd volfile for volume: %s",
194
ret = svc->start(svc, flags);
196
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL,
198
"snapd for volume: %s",
203
glusterd_volinfo_ref(volinfo);
204
ret = glusterd_conn_connect(&(svc->conn));
206
glusterd_volinfo_unref(volinfo);
210
} else if (glusterd_proc_is_running(&svc->proc)) {
211
ret = svc->stop(svc, SIGTERM);
213
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL,
214
"Couldn't stop snapd for volume: %s", volinfo->volname);
217
volinfo->snapd.port = 0;
222
gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s",
223
volinfo->volname, svc->name);
225
gf_msg_debug(this->name, 0, "Returning %d", ret);
231
glusterd_snapdsvc_start(glusterd_svc_t *svc, int flags)
237
glusterd_conf_t *priv = NULL;
238
xlator_t *this = THIS;
239
char valgrind_logfile[PATH_MAX] = {0};
244
char snapd_id[PATH_MAX] = {
247
glusterd_volinfo_t *volinfo = NULL;
248
glusterd_snapdsvc_t *snapd = NULL;
249
char *localtime_logging = NULL;
252
priv = this->private;
255
if (glusterd_proc_is_running(&svc->proc)) {
261
snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc);
263
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL,
264
"Failed to get snapd object "
265
"from snapd service");
270
volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd);
272
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
273
"Failed to get volinfo from "
278
ret = sys_access(svc->proc.volfile, F_OK);
280
gf_msg(this->name, GF_LOG_DEBUG, 0, GD_MSG_VOLINFO_GET_FAIL,
281
"snapd Volfile %s is not present", svc->proc.volfile);
290
ret = glusterd_snapdsvc_create_volfile(volinfo);
292
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
294
"snapd volfile for volume: %s",
301
if (this->ctx->cmd_args.vgtool != _gf_none) {
302
len = snprintf(valgrind_logfile, PATH_MAX, "%s/valgrind-snapd.log",
304
if ((len < 0) || (len >= PATH_MAX)) {
305
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
310
if (this->ctx->cmd_args.vgtool == _gf_memcheck)
311
runner_add_args(&runner, "valgrind", "--leak-check=full",
312
"--trace-children=yes", "--track-origins=yes",
315
runner_add_args(&runner, "valgrind", "--tool=drd", NULL);
317
runner_argprintf(&runner, "--log-file=%s", valgrind_logfile);
320
snprintf(snapd_id, sizeof(snapd_id), "snapd-%s", volinfo->volname);
321
runner_add_args(&runner, SBIN_DIR "/glusterfsd", "-s",
322
svc->proc.volfileserver, "--volfile-id",
323
svc->proc.volfileid, "-p", svc->proc.pidfile, "-l",
324
svc->proc.logfile, "--brick-name", snapd_id, "-S",
325
svc->conn.sockpath, "--process-name", svc->name, NULL);
326
if (dict_get_str(priv->opts, GLUSTERD_LOCALTIME_LOGGING_KEY,
327
&localtime_logging) == 0) {
328
if (strcmp(localtime_logging, "enable") == 0)
329
runner_add_arg(&runner, "--localtime-logging");
332
snapd_port = pmap_assign_port(this, volinfo->snapd.port, snapd_id);
334
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PORTS_EXHAUSTED,
335
"All the ports in the range are exhausted, can't start "
336
"snapd for volume %s",
342
volinfo->snapd.port = snapd_port;
344
runner_add_arg(&runner, "--brick-port");
345
runner_argprintf(&runner, "%d", snapd_port);
346
runner_add_arg(&runner, "--xlator-option");
347
runner_argprintf(&runner, "%s-server.listen-port=%d", volinfo->volname,
349
runner_add_arg(&runner, "--no-mem-accounting");
351
snprintf(msg, sizeof(msg), "Starting the snapd service for volume %s",
353
runner_log(&runner, this->name, GF_LOG_DEBUG, msg);
355
if (flags == PROC_START_NO_WAIT) {
356
ret = runner_run_nowait(&runner);
358
synclock_unlock(&priv->big_lock);
360
ret = runner_run(&runner);
362
synclock_lock(&priv->big_lock);
370
glusterd_snapdsvc_restart(void)
372
glusterd_volinfo_t *volinfo = NULL;
373
glusterd_volinfo_t *tmp = NULL;
375
xlator_t *this = THIS;
376
glusterd_conf_t *conf = NULL;
377
glusterd_svc_t *svc = NULL;
379
conf = this->private;
382
cds_list_for_each_entry_safe(volinfo, tmp, &conf->volumes, vol_list)
385
if (volinfo->status == GLUSTERD_STATUS_STARTED) {
386
svc = &(volinfo->snapd.svc);
387
ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT);
389
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL,
390
"Couldn't resolve snapd for "
391
"vol: %s on restart",
393
gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s",
394
volinfo->volname, svc->name);
404
glusterd_snapdsvc_rpc_notify(glusterd_conn_t *conn, rpc_clnt_event_t event)
407
glusterd_svc_t *svc = NULL;
408
xlator_t *this = THIS;
409
glusterd_volinfo_t *volinfo = NULL;
410
glusterd_snapdsvc_t *snapd = NULL;
412
svc = cds_list_entry(conn, glusterd_svc_t, conn);
414
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_GET_FAIL,
415
"Failed to get the service");
418
snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc);
420
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL,
426
volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd);
428
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
435
case RPC_CLNT_CONNECT:
436
gf_msg_debug(this->name, 0,
437
"%s has connected with "
440
gf_event(EVENT_SVC_CONNECTED, "volume=%s;svc_name=%s",
441
volinfo->volname, svc->name);
442
svc->online = _gf_true;
445
case RPC_CLNT_DISCONNECT:
447
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_NODE_DISCONNECTED,
448
"%s has disconnected "
451
gf_event(EVENT_SVC_DISCONNECTED, "volume=%s;svc_name=%s",
452
volinfo->volname, svc->name);
453
svc->online = _gf_false;
457
case RPC_CLNT_DESTROY:
458
glusterd_volinfo_unref(volinfo);
462
gf_msg_trace(this->name, 0, "got some other RPC event %d", event);