1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * You should have received a copy of the GNU General Public License
5 * along with Lustre; if not, write to the Free Software
6 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9 #define DEBUG_SUBSYSTEM S_LOG
16 #include <linux/obd_class.h>
17 #include <linux/lustre_log.h>
18 #include <portals/list.h>
19 #include "llog_internal.h"
21 static int str2logid(struct llog_logid *logid, char *str, int len)
23 char *start, *end, *endp;
30 if (start - str >= len - 1)
32 end = strchr(start, '#');
33 if (end == NULL || end == start)
37 logid->lgl_oid = simple_strtoull(start, &endp, 16);
42 if (start - str >= len - 1)
44 end = strchr(start, '#');
45 if (end == NULL || end == start)
49 logid->lgl_ogr = simple_strtoull(start, &endp, 16);
54 if (start - str >= len - 1)
56 logid->lgl_ogen = simple_strtoul(start, &endp, 16);
63 static int llog_print_cb(struct llog_handle *handle, struct llog_rec_hdr *rec,
66 struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
67 static int l, remains, from, to;
72 if (ioc_data->ioc_inllen1) {
74 remains = ioc_data->ioc_inllen4 +
75 size_round(ioc_data->ioc_inllen1) +
76 size_round(ioc_data->ioc_inllen2) +
77 size_round(ioc_data->ioc_inllen3);
78 from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
81 to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
84 out = ioc_data->ioc_bulk;
85 ioc_data->ioc_inllen1 = 0;
88 cur_index = le32_to_cpu(rec->lrh_index);
91 if (to > 0 && cur_index > to)
94 if (le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT) {
95 struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
96 if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
97 CERROR("invalid record in catalog\n");
101 l = snprintf(out, remains,
102 "[index]: %05d [logid]: #%llx#%llx#%08x\n",
103 cur_index, lir->lid_id.lgl_oid,
104 lir->lid_id.lgl_ogr, lir->lid_id.lgl_ogen);
106 l = snprintf(out, remains,
107 "[index]: %05d [type]: %02x [len]: %04d\n",
108 cur_index, le32_to_cpu(rec->lrh_type),
109 le32_to_cpu(rec->lrh_len));
114 CERROR("not enough space for print log records\n");
115 RETURN(-LLOG_EEMPTY);
121 static int llog_remove_log(struct llog_handle *cat, struct llog_logid *logid)
123 struct llog_handle *log;
126 down_write(&cat->lgh_lock);
127 rc = llog_cat_id2handle(cat, &log, logid);
129 CDEBUG(D_IOCTL, "cannot find log #%0llx#%0llx#%08x\n",
130 logid->lgl_oid, logid->lgl_ogr, logid->lgl_ogen);
131 GOTO(out, rc = -ENOENT);
134 index = log->u.phd.phd_cookie.lgc_index;
136 rc = llog_destroy(log);
138 CDEBUG(D_IOCTL, "cannot destroy log\n");
141 rc = llog_cancel_rec(cat, index);
143 up_write(&cat->lgh_lock);
148 int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data)
150 struct llog_logid logid;
152 struct llog_handle *handle = NULL;
154 if (*data->ioc_inlbuf1 == '#') {
155 err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
158 err = llog_create(ctxt, &handle, &logid, NULL);
161 } else if (*data->ioc_inlbuf1 == '$') {
162 char *name = data->ioc_inlbuf1 + 1;
163 err = llog_create(ctxt, &handle, NULL, name);
167 GOTO(out, err = -EINVAL);
170 err = llog_init_handle(handle, 0, NULL);
172 GOTO(out_close, err = -ENOENT);
175 case OBD_IOC_LLOG_INFO: {
177 int remains = data->ioc_inllen2 +
178 size_round(data->ioc_inllen1);
179 char *out = data->ioc_bulk;
181 l = snprintf(out, remains,
182 "logid: #%llx#%llx#%08x\n"
184 "records count: %d\n"
186 handle->lgh_id.lgl_oid, handle->lgh_id.lgl_ogr,
187 handle->lgh_id.lgl_ogen,
188 le32_to_cpu(handle->lgh_hdr->llh_flags),
189 le32_to_cpu(handle->lgh_hdr->llh_flags) &
190 LLOG_F_IS_CAT ? "cat" : "plain",
191 le32_to_cpu(handle->lgh_hdr->llh_count),
192 handle->lgh_last_idx);
196 CERROR("not enough space for log header info\n");
198 GOTO(out_close, err);
200 case OBD_IOC_LLOG_PRINT: {
201 LASSERT(data->ioc_inllen1);
202 err = llog_process(handle, llog_print_cb, data);
203 if (err == -LLOG_EEMPTY)
206 GOTO(out_close, err);
208 case OBD_IOC_LLOG_CANCEL: {
209 struct llog_cookie cookie;
210 struct llog_logid plain;
213 if (!le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
214 GOTO(out_close, err = -EINVAL);
216 err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
218 GOTO(out_close, err);
219 cookie.lgc_lgl = plain;
220 cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3,
223 GOTO(out_close, err = -EINVAL);
225 err = llog_cat_cancel_records(handle, 1, &cookie);
226 GOTO(out_close, err);
228 case OBD_IOC_LLOG_REMOVE: {
229 struct llog_logid plain;
231 if (!le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
232 GOTO(out_close, err = -EINVAL);
234 err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
236 GOTO(out_close, err);
237 err = llog_remove_log(handle, &plain);
238 GOTO(out_close, err);
243 if (handle->lgh_hdr &&
244 le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
245 llog_cat_put(handle);
251 EXPORT_SYMBOL(llog_ioctl);
253 int llog_catlog_list(struct obd_device *obd, int count,
254 struct obd_ioctl_data *data)
257 struct llog_logid *idarray, *id;
258 char name[32] = "CATLIST";
260 int l, remains, rc = 0;
262 size = sizeof(*idarray) * count;
264 OBD_ALLOC(idarray, size);
267 memset(idarray, 0, size);
269 rc = llog_get_cat_list(obd, obd, name, count, idarray);
271 OBD_FREE(idarray, size);
275 out = data->ioc_bulk;
276 remains = data->ioc_inllen1;
278 for (i = 0; i < count; i++) {
279 l = snprintf(out, remains,
280 "catalog log: #%llx#%llx#%08x\n",
281 id->lgl_oid, id->lgl_ogr, id->lgl_ogen);
286 CWARN("not enough memory for catlog list\n");
290 OBD_FREE(idarray, size);
294 EXPORT_SYMBOL(llog_catlog_list);