glusterfs

Форк
0
/
glusterd-log-ops.c 
282 строки · 7.7 Кб
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 "glusterd-op-sm.h"
12
#include "glusterd-store.h"
13
#include "glusterd-utils.h"
14
#include "glusterd-volgen.h"
15
#include "glusterd-messages.h"
16
#include <glusterfs/syscall.h>
17

18
#include <signal.h>
19

20
int
21
__glusterd_handle_log_rotate(rpcsvc_request_t *req)
22
{
23
    int32_t ret = -1;
24
    gf_cli_req cli_req = {{
25
        0,
26
    }};
27
    dict_t *dict = NULL;
28
    glusterd_op_t cli_op = GD_OP_LOG_ROTATE;
29
    char *volname = NULL;
30
    char msg[64] = {
31
        0,
32
    };
33
    xlator_t *this = THIS;
34

35
    GF_ASSERT(req);
36

37
    ret = xdr_to_generic(req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
38
    if (ret < 0) {
39
        // failed to decode msg;
40
        req->rpc_err = GARBAGE_ARGS;
41
        gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_GARBAGE_ARGS, NULL);
42
        goto out;
43
    }
44

45
    if (cli_req.dict.dict_len) {
46
        /* Unserialize the dictionary */
47
        dict = dict_new();
48

49
        ret = dict_unserialize(cli_req.dict.dict_val, cli_req.dict.dict_len,
50
                               &dict);
51
        if (ret < 0) {
52
            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_UNSERIALIZE_FAIL,
53
                   "failed to "
54
                   "unserialize req-buffer to dictionary");
55
            snprintf(msg, sizeof(msg),
56
                     "Unable to decode the "
57
                     "command");
58
            goto out;
59
        }
60
    }
61

62
    ret = dict_get_str(dict, "volname", &volname);
63
    if (ret) {
64
        snprintf(msg, sizeof(msg), "Failed to get volume name");
65
        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, "%s", msg);
66
        goto out;
67
    }
68

69
    gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_LOG_ROTATE_REQ_RECVD,
70
           "Received log rotate req "
71
           "for volume %s",
72
           volname);
73

74
    ret = dict_set_uint64(dict, "rotate-key", (uint64_t)gf_time());
75
    if (ret)
76
        goto out;
77

78
    ret = glusterd_op_begin_synctask(req, GD_OP_LOG_ROTATE, dict);
79

80
out:
81
    if (ret) {
82
        if (msg[0] == '\0')
83
            snprintf(msg, sizeof(msg), "Operation failed");
84
        ret = glusterd_op_send_cli_response(cli_op, ret, 0, req, dict, msg);
85
    }
86

87
    free(cli_req.dict.dict_val);
88
    return ret;
89
}
90

91
int
92
glusterd_handle_log_rotate(rpcsvc_request_t *req)
93
{
94
    return glusterd_big_locked_handler(req, __glusterd_handle_log_rotate);
95
}
96

97
/* op-sm */
98
int
99
glusterd_op_stage_log_rotate(dict_t *dict, char **op_errstr)
100
{
101
    int ret = -1;
102
    char *volname = NULL;
103
    glusterd_volinfo_t *volinfo = NULL;
104
    char msg[2048] = {0};
105
    char *brick = NULL;
106

107
    ret = dict_get_str(dict, "volname", &volname);
108
    if (ret) {
109
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
110
               "Unable to get volume name");
111
        goto out;
112
    }
113

114
    ret = glusterd_volinfo_find(volname, &volinfo);
115
    if (ret) {
116
        snprintf(msg, sizeof(msg), "Volume %s does not exist", volname);
117
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND, "%s", msg);
118
        *op_errstr = gf_strdup(msg);
119
        goto out;
120
    }
121

122
    if (_gf_false == glusterd_is_volume_started(volinfo)) {
123
        snprintf(msg, sizeof(msg),
124
                 "Volume %s needs to be started before"
125
                 " log rotate.",
126
                 volname);
127
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_STARTED, "%s", msg);
128
        *op_errstr = gf_strdup(msg);
129
        ret = -1;
130
        goto out;
131
    }
132

133
    ret = dict_get_str(dict, "brick", &brick);
134
    /* If no brick is specified, do log-rotate for
135
       all the bricks in the volume */
136
    if (ret) {
137
        gf_smsg("glusterd", GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED,
138
                "Key=brick", NULL);
139
        ret = 0;
140
        goto out;
141
    }
142

143
    ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, NULL,
144
                                                 _gf_false);
145
    if (ret) {
146
        snprintf(msg, sizeof(msg),
147
                 "Incorrect brick %s "
148
                 "for volume %s",
149
                 brick, volname);
150
        gf_msg("glusterd", GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY, "%s",
151
               msg);
152
        *op_errstr = gf_strdup(msg);
153
        goto out;
154
    }
155
out:
156
    gf_msg_debug("glusterd", 0, "Returning %d", ret);
157

158
    return ret;
159
}
160

161
int
162
glusterd_op_log_rotate(dict_t *dict)
163
{
164
    int ret = -1;
165
    glusterd_conf_t *priv = NULL;
166
    glusterd_volinfo_t *volinfo = NULL;
167
    glusterd_brickinfo_t *brickinfo = NULL;
168
    char *volname = NULL;
169
    char *brick = NULL;
170
    char logfile[PATH_MAX] = {
171
        0,
172
    };
173
    char pidfile[PATH_MAX] = {
174
        0,
175
    };
176
    FILE *file = NULL;
177
    pid_t pid = 0;
178
    uint64_t key = 0;
179
    int valid_brick = 0;
180
    glusterd_brickinfo_t *tmpbrkinfo = NULL;
181

182
    priv = THIS->private;
183
    GF_ASSERT(priv);
184

185
    ret = dict_get_str(dict, "volname", &volname);
186
    if (ret) {
187
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
188
               "volname not found");
189
        goto out;
190
    }
191

192
    ret = dict_get_uint64(dict, "rotate-key", &key);
193
    if (ret) {
194
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
195
               "rotate key not found");
196
        goto out;
197
    }
198

199
    ret = dict_get_str(dict, "brick", &brick);
200
    /* If no brick is specified, do log-rotate for
201
       all the bricks in the volume */
202
    if (ret) {
203
        gf_smsg("glusterd", GF_LOG_ERROR, -ret, GD_MSG_DICT_GET_FAILED,
204
                "Key=brick", NULL);
205
        goto cont;
206
    }
207

208
    ret = glusterd_brickinfo_new_from_brick(brick, &tmpbrkinfo, _gf_false,
209
                                            NULL);
210
    if (ret) {
211
        gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_BRICK_NOT_FOUND,
212
               "cannot get brickinfo from brick");
213
        goto out;
214
    }
215

216
cont:
217
    ret = glusterd_volinfo_find(volname, &volinfo);
218
    if (ret)
219
        goto out;
220

221
    ret = -1;
222
    cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
223
    {
224
        if (gf_uuid_compare(brickinfo->uuid, MY_UUID))
225
            continue;
226

227
        if (tmpbrkinfo && brick &&
228
            (strcmp(tmpbrkinfo->hostname, brickinfo->hostname) ||
229
             strcmp(tmpbrkinfo->path, brickinfo->path)))
230
            continue;
231

232
        valid_brick = 1;
233

234
        GLUSTERD_GET_BRICK_PIDFILE(pidfile, volinfo, brickinfo, priv);
235
        file = fopen(pidfile, "r+");
236
        if (!file) {
237
            gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
238
                   "Unable to open pidfile: %s", pidfile);
239
            ret = -1;
240
            goto out;
241
        }
242

243
        ret = fscanf(file, "%d", &pid);
244
        if (ret <= 0) {
245
            fclose(file);
246
            gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
247
                   "Unable to read pidfile: %s", pidfile);
248
            ret = -1;
249
            goto out;
250
        }
251
        fclose(file);
252
        file = NULL;
253

254
        snprintf(logfile, PATH_MAX, "%s.%" PRIu64, brickinfo->logfile, key);
255

256
        ret = sys_rename(brickinfo->logfile, logfile);
257
        if (ret)
258
            gf_msg("glusterd", GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
259
                   "rename failed");
260

261
        ret = kill(pid, SIGHUP);
262
        if (ret) {
263
            gf_msg("glusterd", GF_LOG_ERROR, errno, GD_MSG_PID_KILL_FAIL,
264
                   "Unable to SIGHUP to %d", pid);
265
            goto out;
266
        }
267
        ret = 0;
268

269
        /* If request was for brick, only one iteration is enough */
270
        if (brick)
271
            break;
272
    }
273

274
    if (ret && !valid_brick)
275
        ret = 0;
276

277
out:
278
    if (tmpbrkinfo)
279
        glusterd_brickinfo_delete(tmpbrkinfo);
280

281
    return ret;
282
}
283

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.