"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/mgmt/glusterd/src/glusterd-log-ops.c" (16 Sep 2020, 7783 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-log-ops.c" see the Fossies "Dox" file reference documentation.

    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 #include <glusterfs/common-utils.h>
   11 #include "cli1-xdr.h"
   12 #include "xdr-generic.h"
   13 #include "glusterd.h"
   14 #include "glusterd-op-sm.h"
   15 #include "glusterd-store.h"
   16 #include "glusterd-utils.h"
   17 #include "glusterd-volgen.h"
   18 #include "glusterd-messages.h"
   19 #include <glusterfs/syscall.h>
   20 
   21 #include <signal.h>
   22 
   23 int
   24 __glusterd_handle_log_rotate(rpcsvc_request_t *req)
   25 {
   26     int32_t ret = -1;
   27     gf_cli_req cli_req = {{
   28         0,
   29     }};
   30     dict_t *dict = NULL;
   31     glusterd_op_t cli_op = GD_OP_LOG_ROTATE;
   32     char *volname = NULL;
   33     char msg[64] = {
   34         0,
   35     };
   36     xlator_t *this = NULL;
   37 
   38     GF_ASSERT(req);
   39     this = THIS;
   40     GF_ASSERT(this);
   41 
   42     ret = xdr_to_generic(req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
   43     if (ret < 0) {
   44         // failed to decode msg;
   45         req->rpc_err = GARBAGE_ARGS;
   46         goto out;
   47     }
   48 
   49     if (cli_req.dict.dict_len) {
   50         /* Unserialize the dictionary */
   51         dict = dict_new();
   52 
   53         ret = dict_unserialize(cli_req.dict.dict_val, cli_req.dict.dict_len,
   54                                &dict);
   55         if (ret < 0) {
   56             gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_UNSERIALIZE_FAIL,
   57                    "failed to "
   58                    "unserialize req-buffer to dictionary");
   59             snprintf(msg, sizeof(msg),
   60                      "Unable to decode the "
   61                      "command");
   62             goto out;
   63         }
   64     }
   65 
   66     ret = dict_get_str(dict, "volname", &volname);
   67     if (ret) {
   68         snprintf(msg, sizeof(msg), "Failed to get volume name");
   69         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "%s", msg);
   70         goto out;
   71     }
   72 
   73     gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_LOG_ROTATE_REQ_RECVD,
   74            "Received log rotate req "
   75            "for volume %s",
   76            volname);
   77 
   78     ret = dict_set_uint64(dict, "rotate-key", (uint64_t)time(NULL));
   79     if (ret)
   80         goto out;
   81 
   82     ret = glusterd_op_begin_synctask(req, GD_OP_LOG_ROTATE, dict);
   83 
   84 out:
   85     if (ret) {
   86         if (msg[0] == '\0')
   87             snprintf(msg, sizeof(msg), "Operation failed");
   88         ret = glusterd_op_send_cli_response(cli_op, ret, 0, req, dict, msg);
   89     }
   90 
   91     free(cli_req.dict.dict_val);
   92     return ret;
   93 }
   94 
   95 int
   96 glusterd_handle_log_rotate(rpcsvc_request_t *req)
   97 {
   98     return glusterd_big_locked_handler(req, __glusterd_handle_log_rotate);
   99 }
  100 
  101 /* op-sm */
  102 int
  103 glusterd_op_stage_log_rotate(dict_t *dict, char **op_errstr)
  104 {
  105     int ret = -1;
  106     char *volname = NULL;
  107     glusterd_volinfo_t *volinfo = NULL;
  108     char msg[2048] = {0};
  109     char *brick = NULL;
  110 
  111     ret = dict_get_str(dict, "volname", &volname);
  112     if (ret) {
  113         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
  114                "Unable to get volume name");
  115         goto out;
  116     }
  117 
  118     ret = glusterd_volinfo_find(volname, &volinfo);
  119     if (ret) {
  120         snprintf(msg, sizeof(msg), "Volume %s does not exist", volname);
  121         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg);
  122         *op_errstr = gf_strdup(msg);
  123         goto out;
  124     }
  125 
  126     if (_gf_false == glusterd_is_volume_started(volinfo)) {
  127         snprintf(msg, sizeof(msg),
  128                  "Volume %s needs to be started before"
  129                  " log rotate.",
  130                  volname);
  131         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_STARTED, "%s", msg);
  132         *op_errstr = gf_strdup(msg);
  133         ret = -1;
  134         goto out;
  135     }
  136 
  137     ret = dict_get_str(dict, "brick", &brick);
  138     /* If no brick is specified, do log-rotate for
  139        all the bricks in the volume */
  140     if (ret) {
  141         ret = 0;
  142         goto out;
  143     }
  144 
  145     ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, NULL,
  146                                                  _gf_false);
  147     if (ret) {
  148         snprintf(msg, sizeof(msg),
  149                  "Incorrect brick %s "
  150                  "for volume %s",
  151                  brick, volname);
  152         gf_msg("glusterd", GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s",
  153                msg);
  154         *op_errstr = gf_strdup(msg);
  155         goto out;
  156     }
  157 out:
  158     gf_msg_debug("glusterd", 0, "Returning %d", ret);
  159 
  160     return ret;
  161 }
  162 
  163 int
  164 glusterd_op_log_rotate(dict_t *dict)
  165 {
  166     int ret = -1;
  167     glusterd_conf_t *priv = NULL;
  168     glusterd_volinfo_t *volinfo = NULL;
  169     glusterd_brickinfo_t *brickinfo = NULL;
  170     xlator_t *this = NULL;
  171     char *volname = NULL;
  172     char *brick = NULL;
  173     char logfile[PATH_MAX] = {
  174         0,
  175     };
  176     char pidfile[PATH_MAX] = {
  177         0,
  178     };
  179     FILE *file = NULL;
  180     pid_t pid = 0;
  181     uint64_t key = 0;
  182     int valid_brick = 0;
  183     glusterd_brickinfo_t *tmpbrkinfo = NULL;
  184 
  185     this = THIS;
  186     GF_ASSERT(this);
  187     priv = this->private;
  188     GF_ASSERT(priv);
  189 
  190     ret = dict_get_str(dict, "volname", &volname);
  191     if (ret) {
  192         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
  193                "volname not found");
  194         goto out;
  195     }
  196 
  197     ret = dict_get_uint64(dict, "rotate-key", &key);
  198     if (ret) {
  199         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
  200                "rotate key not found");
  201         goto out;
  202     }
  203 
  204     ret = dict_get_str(dict, "brick", &brick);
  205     /* If no brick is specified, do log-rotate for
  206        all the bricks in the volume */
  207     if (ret)
  208         goto cont;
  209 
  210     ret = glusterd_brickinfo_new_from_brick(brick, &tmpbrkinfo, _gf_false,
  211                                             NULL);
  212     if (ret) {
  213         gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_BRICK_NOT_FOUND,
  214                "cannot get brickinfo from brick");
  215         goto out;
  216     }
  217 
  218 cont:
  219     ret = glusterd_volinfo_find(volname, &volinfo);
  220     if (ret)
  221         goto out;
  222 
  223     ret = -1;
  224     cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
  225     {
  226         if (gf_uuid_compare(brickinfo->uuid, MY_UUID))
  227             continue;
  228 
  229         if (tmpbrkinfo && brick &&
  230             (strcmp(tmpbrkinfo->hostname, brickinfo->hostname) ||
  231              strcmp(tmpbrkinfo->path, brickinfo->path)))
  232             continue;
  233 
  234         valid_brick = 1;
  235 
  236         GLUSTERD_GET_BRICK_PIDFILE(pidfile, volinfo, brickinfo, priv);
  237         file = fopen(pidfile, "r+");
  238         if (!file) {
  239             gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
  240                    "Unable to open pidfile: %s", pidfile);
  241             ret = -1;
  242             goto out;
  243         }
  244 
  245         ret = fscanf(file, "%d", &pid);
  246         if (ret <= 0) {
  247             fclose(file);
  248             gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
  249                    "Unable to read pidfile: %s", pidfile);
  250             ret = -1;
  251             goto out;
  252         }
  253         fclose(file);
  254         file = NULL;
  255 
  256         snprintf(logfile, PATH_MAX, "%s.%" PRIu64, brickinfo->logfile, key);
  257 
  258         ret = sys_rename(brickinfo->logfile, logfile);
  259         if (ret)
  260             gf_msg("glusterd", GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
  261                    "rename failed");
  262 
  263         ret = kill(pid, SIGHUP);
  264         if (ret) {
  265             gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_PID_KILL_FAIL,
  266                    "Unable to SIGHUP to %d", pid);
  267             goto out;
  268         }
  269         ret = 0;
  270 
  271         /* If request was for brick, only one iteration is enough */
  272         if (brick)
  273             break;
  274     }
  275 
  276     if (ret && !valid_brick)
  277         ret = 0;
  278 
  279 out:
  280     if (tmpbrkinfo)
  281         glusterd_brickinfo_delete(tmpbrkinfo);
  282 
  283     return ret;
  284 }