4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2015, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lustre/ptlrpc/llog_server.c
33 * remote api for llog - server side
35 * Author: Andreas Dilger <adilger@clusterfs.com>
38 #define DEBUG_SUBSYSTEM S_LOG
40 #include <obd_class.h>
41 #include <lu_target.h>
42 #include <lustre_log.h>
43 #include <lustre_net.h>
45 static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
47 if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
48 return llog_cat_close(env, lgh);
50 return llog_close(env, lgh);
53 /* Only open is supported, no new llog can be created remotely */
54 int llog_origin_handle_open(struct ptlrpc_request *req)
56 struct obd_export *exp = req->rq_export;
57 struct obd_device *obd = exp->exp_obd;
58 struct llog_handle *loghandle;
59 struct llogd_body *body;
60 struct llog_logid *logid = NULL;
61 struct llog_ctxt *ctxt;
67 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
69 RETURN(err_serious(-EFAULT));
71 rc = req_capsule_server_pack(&req->rq_pill);
73 RETURN(err_serious(-ENOMEM));
75 if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
76 logid = &body->lgd_logid;
78 if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
79 name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
82 CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
85 if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
86 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d name=%s\n",
87 obd->obd_name, body->lgd_ctxt_idx, name);
91 ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
93 CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
94 obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
98 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
99 name, LLOG_OPEN_EXISTS);
103 body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
104 body->lgd_logid = loghandle->lgh_id;
106 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
113 int llog_origin_handle_next_block(struct ptlrpc_request *req)
115 struct llog_handle *loghandle;
116 struct llogd_body *body;
117 struct llogd_body *repbody;
118 struct llog_ctxt *ctxt;
125 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
127 RETURN(err_serious(-EFAULT));
129 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
130 LLOG_MIN_CHUNK_SIZE);
131 rc = req_capsule_server_pack(&req->rq_pill);
133 RETURN(err_serious(-ENOMEM));
135 if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
136 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
137 req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
141 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
144 if (CFS_FAIL_PRECHECK(OBD_FAIL_MDS_LLOG_UMOUNT_RACE))
147 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
148 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
152 flags = body->lgd_llh_flags;
153 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
158 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
161 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
162 rc = llog_next_block(req->rq_svc_thread->t_env, loghandle,
163 &repbody->lgd_saved_index, repbody->lgd_index,
164 &repbody->lgd_cur_offset, ptr,
165 LLOG_MIN_CHUNK_SIZE);
170 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
176 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
178 struct llog_handle *loghandle;
179 struct llogd_body *body;
180 struct llogd_body *repbody;
181 struct llog_ctxt *ctxt;
188 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
190 RETURN(err_serious(-EFAULT));
192 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
193 LLOG_MIN_CHUNK_SIZE);
194 rc = req_capsule_server_pack(&req->rq_pill);
196 RETURN(err_serious(-ENOMEM));
198 if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
199 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
200 req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
204 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
208 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
209 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
213 flags = body->lgd_llh_flags;
214 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
219 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
222 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
223 rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle,
224 body->lgd_index, ptr, LLOG_MIN_CHUNK_SIZE);
230 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
236 int llog_origin_handle_read_header(struct ptlrpc_request *req)
238 struct llog_handle *loghandle;
239 struct llogd_body *body;
240 struct llog_log_hdr *hdr;
241 struct llog_ctxt *ctxt;
247 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
249 RETURN(err_serious(-EFAULT));
251 rc = req_capsule_server_pack(&req->rq_pill);
253 RETURN(err_serious(-ENOMEM));
255 if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
256 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
257 req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
261 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
265 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
266 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
271 * llog_init_handle() reads the llog header
273 flags = body->lgd_llh_flags;
274 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
278 flags = loghandle->lgh_hdr->llh_flags;
280 hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
281 *hdr = *loghandle->lgh_hdr;
284 llog_origin_close(req->rq_svc_thread->t_env, loghandle);