"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c" (16 Sep 2020, 14162 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "glusterd-snapd-svc.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2    Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
    3    This file is part of GlusterFS.
    4 
    5    This file is licensed to you under your choice of the GNU Lesser
    6    General Public License, version 3 or any later version (LGPLv3 or
    7    later), or the GNU General Public License, version 2 (GPLv2), in all
    8    cases as published by the Free Software Foundation.
    9 */
   10 
   11 #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>
   24 
   25 char *snapd_svc_name = "snapd";
   26 
   27 static void
   28 glusterd_svc_build_snapd_logdir(char *logdir, char *volname, size_t len)
   29 {
   30     glusterd_conf_t *priv = THIS->private;
   31     snprintf(logdir, len, "%s/snaps/%s", priv->logdir, volname);
   32 }
   33 
   34 static void
   35 glusterd_svc_build_snapd_logfile(char *logfile, char *logdir, size_t len)
   36 {
   37     snprintf(logfile, len, "%s/snapd.log", logdir);
   38 }
   39 
   40 void
   41 glusterd_snapdsvc_build(glusterd_svc_t *svc)
   42 {
   43     svc->manager = glusterd_snapdsvc_manager;
   44     svc->start = glusterd_snapdsvc_start;
   45     svc->stop = glusterd_svc_stop;
   46 }
   47 
   48 int
   49 glusterd_snapdsvc_init(void *data)
   50 {
   51     int ret = -1;
   52     char rundir[PATH_MAX] = {
   53         0,
   54     };
   55     char sockpath[PATH_MAX] = {
   56         0,
   57     };
   58     char pidfile[PATH_MAX] = {
   59         0,
   60     };
   61     char volfile[PATH_MAX] = {
   62         0,
   63     };
   64     char logdir[PATH_MAX] = {
   65         0,
   66     };
   67     char logfile[PATH_MAX] = {
   68         0,
   69     };
   70     char volfileid[256] = {0};
   71     glusterd_svc_t *svc = NULL;
   72     glusterd_volinfo_t *volinfo = NULL;
   73     glusterd_conf_t *priv = NULL;
   74     glusterd_conn_notify_t notify = NULL;
   75     xlator_t *this = NULL;
   76     char *volfileserver = NULL;
   77     int32_t len = 0;
   78 
   79     this = THIS;
   80     GF_ASSERT(this);
   81 
   82     priv = this->private;
   83     GF_ASSERT(priv);
   84 
   85     volinfo = data;
   86 
   87     svc = &(volinfo->snapd.svc);
   88 
   89     ret = snprintf(svc->name, sizeof(svc->name), "%s", snapd_svc_name);
   90     if (ret < 0)
   91         goto out;
   92 
   93     notify = glusterd_snapdsvc_rpc_notify;
   94 
   95     glusterd_svc_build_snapd_rundir(volinfo, rundir, sizeof(rundir));
   96     glusterd_svc_create_rundir(rundir);
   97 
   98     /* Initialize the connection mgmt */
   99     glusterd_svc_build_snapd_socket_filepath(volinfo, sockpath,
  100                                              sizeof(sockpath));
  101     ret = glusterd_conn_init(&(svc->conn), sockpath, 600, notify);
  102     if (ret)
  103         goto out;
  104 
  105     /* Initialize the process mgmt */
  106     glusterd_svc_build_snapd_pidfile(volinfo, pidfile, sizeof(pidfile));
  107     glusterd_svc_build_snapd_volfile(volinfo, volfile, sizeof(volfile));
  108     glusterd_svc_build_snapd_logdir(logdir, volinfo->volname, sizeof(logdir));
  109     ret = mkdir_p(logdir, 0755, _gf_true);
  110     if ((ret == -1) && (EEXIST != errno)) {
  111         gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED,
  112                "Unable to create logdir %s", logdir);
  113         goto out;
  114     }
  115     glusterd_svc_build_snapd_logfile(logfile, logdir, sizeof(logfile));
  116     len = snprintf(volfileid, sizeof(volfileid), "snapd/%s", volinfo->volname);
  117     if ((len < 0) || (len >= sizeof(volfileid))) {
  118         ret = -1;
  119         goto out;
  120     }
  121 
  122     if (dict_get_str(this->options, "transport.socket.bind-address",
  123                      &volfileserver) != 0) {
  124         volfileserver = "localhost";
  125     }
  126     ret = glusterd_proc_init(&(svc->proc), snapd_svc_name, pidfile, logdir,
  127                              logfile, volfile, volfileid, volfileserver);
  128     if (ret)
  129         goto out;
  130 
  131 out:
  132     gf_msg_debug(this->name, 0, "Returning %d", ret);
  133     return ret;
  134 }
  135 
  136 int
  137 glusterd_snapdsvc_manager(glusterd_svc_t *svc, void *data, int flags)
  138 {
  139     int ret = 0;
  140     xlator_t *this = THIS;
  141     glusterd_volinfo_t *volinfo = NULL;
  142 
  143     volinfo = data;
  144 
  145     if (!svc->inited) {
  146         ret = glusterd_snapdsvc_init(volinfo);
  147         if (ret) {
  148             gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_INIT_FAIL,
  149                    "Failed to initialize "
  150                    "snapd service for volume %s",
  151                    volinfo->volname);
  152             goto out;
  153         } else {
  154             svc->inited = _gf_true;
  155             gf_msg_debug(THIS->name, 0,
  156                          "snapd service "
  157                          "initialized");
  158         }
  159     }
  160 
  161     ret = glusterd_is_snapd_enabled(volinfo);
  162     if (ret == -1) {
  163         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
  164                "Failed to read volume "
  165                "options");
  166         goto out;
  167     }
  168 
  169     if (ret) {
  170         if (!glusterd_is_volume_started(volinfo)) {
  171             if (glusterd_proc_is_running(&svc->proc)) {
  172                 ret = svc->stop(svc, SIGTERM);
  173                 if (ret)
  174                     gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL,
  175                            "Couldn't stop snapd for "
  176                            "volume: %s",
  177                            volinfo->volname);
  178             } else {
  179                 /* Since snapd is not running set ret to 0 */
  180                 ret = 0;
  181             }
  182             goto out;
  183         }
  184 
  185         ret = glusterd_snapdsvc_create_volfile(volinfo);
  186         if (ret) {
  187             gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_CREATE_FAIL,
  188                    "Couldn't create "
  189                    "snapd volfile for volume: %s",
  190                    volinfo->volname);
  191             goto out;
  192         }
  193 
  194         ret = svc->start(svc, flags);
  195         if (ret) {
  196             gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL,
  197                    "Couldn't start "
  198                    "snapd for volume: %s",
  199                    volinfo->volname);
  200             goto out;
  201         }
  202 
  203         glusterd_volinfo_ref(volinfo);
  204         ret = glusterd_conn_connect(&(svc->conn));
  205         if (ret) {
  206             glusterd_volinfo_unref(volinfo);
  207             goto out;
  208         }
  209 
  210     } else if (glusterd_proc_is_running(&svc->proc)) {
  211         ret = svc->stop(svc, SIGTERM);
  212         if (ret) {
  213             gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_STOP_FAIL,
  214                    "Couldn't stop snapd for volume: %s", volinfo->volname);
  215             goto out;
  216         }
  217         volinfo->snapd.port = 0;
  218     }
  219 
  220 out:
  221     if (ret) {
  222         gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s",
  223                  volinfo->volname, svc->name);
  224     }
  225     gf_msg_debug(THIS->name, 0, "Returning %d", ret);
  226 
  227     return ret;
  228 }
  229 
  230 int32_t
  231 glusterd_snapdsvc_start(glusterd_svc_t *svc, int flags)
  232 {
  233     int ret = -1;
  234     runner_t runner = {
  235         0,
  236     };
  237     glusterd_conf_t *priv = NULL;
  238     xlator_t *this = NULL;
  239     char valgrind_logfile[PATH_MAX] = {0};
  240     int snapd_port = 0;
  241     char msg[1024] = {
  242         0,
  243     };
  244     char snapd_id[PATH_MAX] = {
  245         0,
  246     };
  247     glusterd_volinfo_t *volinfo = NULL;
  248     glusterd_snapdsvc_t *snapd = NULL;
  249     char *localtime_logging = NULL;
  250     int32_t len = 0;
  251 
  252     this = THIS;
  253     GF_ASSERT(this);
  254 
  255     priv = this->private;
  256     GF_ASSERT(priv);
  257 
  258     if (glusterd_proc_is_running(&svc->proc)) {
  259         ret = 0;
  260         goto out;
  261     }
  262 
  263     /* Get volinfo->snapd from svc object */
  264     snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc);
  265     if (!snapd) {
  266         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL,
  267                "Failed to get snapd object "
  268                "from snapd service");
  269         goto out;
  270     }
  271 
  272     /* Get volinfo from snapd */
  273     volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd);
  274     if (!volinfo) {
  275         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
  276                "Failed to get volinfo from "
  277                "from snapd");
  278         goto out;
  279     }
  280 
  281     ret = sys_access(svc->proc.volfile, F_OK);
  282     if (ret) {
  283         gf_msg(this->name, GF_LOG_DEBUG, 0, GD_MSG_VOLINFO_GET_FAIL,
  284                "snapd Volfile %s is not present", svc->proc.volfile);
  285         /* If glusterd is down on one of the nodes and during
  286          * that time "USS is enabled" for the first time. After some
  287          * time when the glusterd which was down comes back it tries
  288          * to look for the snapd volfile and it does not find snapd
  289          * volfile and because of this starting of snapd fails.
  290          * Therefore, if volfile is not present then create a fresh
  291          * volfile.
  292          */
  293         ret = glusterd_snapdsvc_create_volfile(volinfo);
  294         if (ret) {
  295             gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
  296                    "Couldn't create "
  297                    "snapd volfile for volume: %s",
  298                    volinfo->volname);
  299             goto out;
  300         }
  301     }
  302     runinit(&runner);
  303 
  304     if (this->ctx->cmd_args.valgrind) {
  305         len = snprintf(valgrind_logfile, PATH_MAX, "%s/valgrind-snapd.log",
  306                        svc->proc.logdir);
  307         if ((len < 0) || (len >= PATH_MAX)) {
  308             ret = -1;
  309             goto out;
  310         }
  311 
  312         runner_add_args(&runner, "valgrind", "--leak-check=full",
  313                         "--trace-children=yes", "--track-origins=yes", NULL);
  314         runner_argprintf(&runner, "--log-file=%s", valgrind_logfile);
  315     }
  316 
  317     snprintf(snapd_id, sizeof(snapd_id), "snapd-%s", volinfo->volname);
  318     runner_add_args(&runner, SBIN_DIR "/glusterfsd", "-s",
  319                     svc->proc.volfileserver, "--volfile-id",
  320                     svc->proc.volfileid, "-p", svc->proc.pidfile, "-l",
  321                     svc->proc.logfile, "--brick-name", snapd_id, "-S",
  322                     svc->conn.sockpath, "--process-name", svc->name, NULL);
  323     if (dict_get_str(priv->opts, GLUSTERD_LOCALTIME_LOGGING_KEY,
  324                      &localtime_logging) == 0) {
  325         if (strcmp(localtime_logging, "enable") == 0)
  326             runner_add_arg(&runner, "--localtime-logging");
  327     }
  328 
  329     snapd_port = pmap_assign_port(THIS, volinfo->snapd.port, snapd_id);
  330     if (!snapd_port) {
  331         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PORTS_EXHAUSTED,
  332                "All the ports in the range are exhausted, can't start "
  333                "snapd for volume %s",
  334                volinfo->volname);
  335         ret = -1;
  336         goto out;
  337     }
  338 
  339     volinfo->snapd.port = snapd_port;
  340 
  341     runner_add_arg(&runner, "--brick-port");
  342     runner_argprintf(&runner, "%d", snapd_port);
  343     runner_add_arg(&runner, "--xlator-option");
  344     runner_argprintf(&runner, "%s-server.listen-port=%d", volinfo->volname,
  345                      snapd_port);
  346     runner_add_arg(&runner, "--no-mem-accounting");
  347 
  348     snprintf(msg, sizeof(msg), "Starting the snapd service for volume %s",
  349              volinfo->volname);
  350     runner_log(&runner, this->name, GF_LOG_DEBUG, msg);
  351 
  352     if (flags == PROC_START_NO_WAIT) {
  353         ret = runner_run_nowait(&runner);
  354     } else {
  355         synclock_unlock(&priv->big_lock);
  356         {
  357             ret = runner_run(&runner);
  358         }
  359         synclock_lock(&priv->big_lock);
  360     }
  361 
  362 out:
  363     return ret;
  364 }
  365 
  366 int
  367 glusterd_snapdsvc_restart()
  368 {
  369     glusterd_volinfo_t *volinfo = NULL;
  370     glusterd_volinfo_t *tmp = NULL;
  371     int ret = 0;
  372     xlator_t *this = THIS;
  373     glusterd_conf_t *conf = NULL;
  374     glusterd_svc_t *svc = NULL;
  375 
  376     GF_ASSERT(this);
  377 
  378     conf = this->private;
  379     GF_ASSERT(conf);
  380 
  381     cds_list_for_each_entry_safe(volinfo, tmp, &conf->volumes, vol_list)
  382     {
  383         /* Start per volume snapd svc */
  384         if (volinfo->status == GLUSTERD_STATUS_STARTED) {
  385             svc = &(volinfo->snapd.svc);
  386             ret = svc->manager(svc, volinfo, PROC_START_NO_WAIT);
  387             if (ret) {
  388                 gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_START_FAIL,
  389                        "Couldn't resolve snapd for "
  390                        "vol: %s on restart",
  391                        volinfo->volname);
  392                 gf_event(EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s",
  393                          volinfo->volname, svc->name);
  394                 goto out;
  395             }
  396         }
  397     }
  398 out:
  399     return ret;
  400 }
  401 
  402 int
  403 glusterd_snapdsvc_rpc_notify(glusterd_conn_t *conn, rpc_clnt_event_t event)
  404 {
  405     int ret = 0;
  406     glusterd_svc_t *svc = NULL;
  407     xlator_t *this = NULL;
  408     glusterd_volinfo_t *volinfo = NULL;
  409     glusterd_snapdsvc_t *snapd = NULL;
  410 
  411     this = THIS;
  412     GF_ASSERT(this);
  413 
  414     svc = cds_list_entry(conn, glusterd_svc_t, conn);
  415     if (!svc) {
  416         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_GET_FAIL,
  417                "Failed to get the service");
  418         return -1;
  419     }
  420     snapd = cds_list_entry(svc, glusterd_snapdsvc_t, svc);
  421     if (!snapd) {
  422         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPD_OBJ_GET_FAIL,
  423                "Failed to get the "
  424                "snapd object");
  425         return -1;
  426     }
  427 
  428     volinfo = cds_list_entry(snapd, glusterd_volinfo_t, snapd);
  429     if (!volinfo) {
  430         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
  431                "Failed to get the "
  432                "volinfo object");
  433         return -1;
  434     }
  435 
  436     switch (event) {
  437         case RPC_CLNT_CONNECT:
  438             gf_msg_debug(this->name, 0,
  439                          "%s has connected with "
  440                          "glusterd.",
  441                          svc->name);
  442             gf_event(EVENT_SVC_CONNECTED, "volume=%s;svc_name=%s",
  443                      volinfo->volname, svc->name);
  444             svc->online = _gf_true;
  445             break;
  446 
  447         case RPC_CLNT_DISCONNECT:
  448             if (svc->online) {
  449                 gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_NODE_DISCONNECTED,
  450                        "%s has disconnected "
  451                        "from glusterd.",
  452                        svc->name);
  453                 gf_event(EVENT_SVC_DISCONNECTED, "volume=%s;svc_name=%s",
  454                          volinfo->volname, svc->name);
  455                 svc->online = _gf_false;
  456             }
  457             break;
  458 
  459         case RPC_CLNT_DESTROY:
  460             glusterd_volinfo_unref(volinfo);
  461             break;
  462 
  463         default:
  464             gf_msg_trace(this->name, 0, "got some other RPC event %d", event);
  465             break;
  466     }
  467 
  468     return ret;
  469 }