1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Peter J. Braam <braam@clusterfs.com>
6 * Author: Phil Schwan <phil@clusterfs.com>
7 * Author: Robert Read <rread@clusterfs.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <sys/ioctl.h>
41 #include <sys/types.h>
42 #include <linux/types.h>
43 #include <linux/unistd.h>
45 #include <liblustre.h>
46 #include <linux/obd.h>
47 #include <linux/lustre_lib.h>
48 #include <linux/lustre_user.h>
49 #include <linux/obd_lov.h>
51 #include <portals/ptlctl.h>
53 static void err_msg(char *fmt, ...)
56 int tmp_errno = errno;
59 vfprintf(stderr, fmt, args);
61 fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
64 int op_create_file(char *name, long stripe_size, int stripe_offset,
67 struct lov_user_md lum = { 0 };
70 /* Initialize IOCTL striping pattern structure */
71 lum.lmm_magic = LOV_USER_MAGIC;
72 lum.lmm_stripe_size = stripe_size;
73 lum.lmm_stripe_offset = stripe_offset;
74 lum.lmm_stripe_count = stripe_count;
76 fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
78 err_msg("unable to open '%s'",name);
82 if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) {
83 char *errmsg = "stripe already set";
84 if (errno != EEXIST && errno != EALREADY)
85 errmsg = strerror(errno);
87 fprintf(stderr, "error on ioctl for '%s' (%d): %s\n",
92 err_msg("error on close for '%s' (%d)", name, fd);
104 struct obd_uuid *obduuid;
105 struct obd_ioctl_data data;
106 struct lov_desc desc;
110 struct obd_uuid *uuids;
111 struct lov_user_md *lum;
117 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
118 #define MAX_LOV_UUID_COUNT 1000
119 #define OBD_NOT_FOUND (-1)
121 static int prepare_find(struct find_param *param)
123 int datalen, desclen;
125 int max_ost_count = MAX_LOV_UUID_COUNT;
127 datalen = size_round(sizeof(param->data));
128 desclen = size_round(sizeof(param->desc));
129 param->uuidslen = size_round(max_ost_count * sizeof(*param->uuids));
130 cfglen = datalen + desclen + param->uuidslen;
131 lumlen = lov_mds_md_size(max_ost_count);
133 param->buflen = cfglen;
135 param->buflen = lumlen;
137 /* XXX max ioctl buffer size currently hardcoded to 8192 */
138 if (param->buflen > 8192) {
139 int nuuids, remaining;
141 param->buflen = 8192;
142 nuuids = (param->buflen - datalen - desclen) /
143 sizeof(*param->uuids);
144 param->uuidslen = size_round(nuuids * sizeof(*param->uuids));
145 remaining = nuuids * sizeof(*param->uuids);
146 if (param->uuidslen > remaining)
148 max_ost_count = nuuids;
149 while ((lumlen=lov_mds_md_size(max_ost_count)) > param->buflen)
152 cfglen = datalen + desclen + param->uuidslen;
155 if ((param->buf = malloc(param->buflen)) == NULL) {
156 err_msg("unable to allocate %d bytes of memory for ioctl's",
161 param->lum = (struct lov_user_md *)param->buf;
162 param->uuids = (struct obd_uuid *)param->buf;
163 param->got_uuids = 0;
164 param->obdindex = OBD_NOT_FOUND;
165 param->max_ost_count = max_ost_count;
170 static void cleanup_find(struct find_param *param)
173 free(param->obduuid);
178 static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param)
181 struct obd_uuid *uuidp;
184 param->got_uuids = 1;
185 memset(¶m->data, 0, sizeof(param->data));
186 param->data.ioc_inllen1 = sizeof(struct lov_desc);
187 param->data.ioc_inlbuf1 = (char *)¶m->desc;
188 param->data.ioc_inllen2 = param->uuidslen;
189 param->data.ioc_inlbuf2 = (char *)param->uuids;
191 memset(¶m->desc, 0, sizeof(struct lov_desc));
192 param->desc.ld_tgt_count = param->max_ost_count;
194 if (obd_ioctl_pack(¶m->data, ¶m->buf, param->buflen)) {
195 fprintf(stderr, "internal buffer error from %s\n", dname);
196 return (param->obduuid ? EINVAL : 0);
199 rc = ioctl(dirfd(dir), OBD_IOC_LOV_GET_CONFIG, param->buf);
201 err_msg("error getting LOV config from %s", dname);
202 return (param->obduuid ? errno : 0);
205 if (obd_ioctl_unpack(¶m->data, param->buf, param->buflen)) {
206 err_msg("invalid reply from ioctl from %s", dname);
207 return (param->obduuid ? EINVAL : 0);
210 obdcount = param->desc.ld_tgt_count;
214 if (param->obduuid) {
215 for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++) {
216 if (strncmp(param->obduuid->uuid, uuidp->uuid,
217 sizeof(*uuidp)) == 0) {
222 if (param->obdindex == OBD_NOT_FOUND) {
223 printf("unknown obduuid: %s\n", param->obduuid);
226 } else if (!param->quiet) {
228 for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++)
229 printf("%4d: %s\n", i, uuidp->uuid);
235 void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname,
236 int obdindex, int quiet, int header, int body)
238 int i, obdstripe = 0;
240 if (obdindex != OBD_NOT_FOUND) {
241 for (i = 0; i < lum->lmm_stripe_count; i++) {
242 if (obdindex == lum->lmm_objects[i].l_ost_idx) {
243 printf("%s/%s\n", dname, fname);
249 printf("%s/%s\n", dname, fname);
253 if (header && (obdstripe == 1)) {
254 printf("lmm_magic: 0x%08X\n", lum->lmm_magic);
255 printf("lmm_object_gr: "LPX64"\n", lum->lmm_object_gr);
256 printf("lmm_object_id: "LPX64"\n", lum->lmm_object_id);
257 printf("lmm_stripe_count: %u\n", (int)lum->lmm_stripe_count);
258 printf("lmm_stripe_size: %u\n", lum->lmm_stripe_size);
259 printf("lmm_stripe_pattern: %x\n", lum->lmm_pattern);
265 if ((!quiet) && (obdstripe == 1))
266 printf("\tobdidx\t\t objid\t\tobjid\t\t group\n");
268 for (i = 0; i < lum->lmm_stripe_count; i++) {
269 int idx = lum->lmm_objects[i].l_ost_idx;
270 oid = lum->lmm_objects[i].l_object_id;
271 if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
272 printf("\t%6u\t%14llu\t%#13llx\t%14lld%s\n",
274 (long long)lum->lmm_objects[i].l_object_gr,
275 obdindex == idx ? " *" : "");
281 void lov_dump_user_lmm(struct find_param *param, char *dname, char *fname)
283 switch(*(__u32 *)param->lum) { /* lum->lmm_magic */
284 case LOV_USER_MAGIC_V1:
285 lov_dump_user_lmm_v1(param->lum, dname, fname, param->obdindex,
286 param->quiet, param->verbose,
287 (param->verbose || !param->obduuid));
290 printf("unknown lmm_magic: 0x%08X\n", *(__u32 *)param->lum);
295 static int process_file(DIR *dir, char *dname, char *fname,
296 struct find_param *param)
300 strncpy((char *)param->lum, fname, param->buflen);
302 rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->lum);
304 if (errno == ENODATA) {
305 if (!param->obduuid && !param->quiet)
307 "%s/%s has no stripe info\n",
310 } else if (errno == EISDIR) {
311 fprintf(stderr, "process_file on directory %s/%s!\n",
313 /* add fname to directory list; */
316 err_msg("IOC_MDC_GETSTRIPE ioctl failed");
322 lov_dump_user_lmm(param, dname, fname);
328 static int process_dir(DIR *dir, char *dname, struct find_param *param)
330 struct dirent64 *dirp;
335 if (!param->got_uuids) {
336 rc = get_obd_uuids(dir, dname, param);
341 /* Handle the contents of the directory */
342 while ((dirp = readdir64(dir)) != NULL) {
343 if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
346 switch (dirp->d_type) {
348 err_msg("\"%s\" is UNKNOWN type %d", dirp->d_name,
350 /* If we cared we could stat the file to determine
351 * type and continue on here, but we don't since we
352 * know d_type should be valid for lustre and this
353 * tool only makes sense for lustre filesystems. */
357 if (!param->recursive)
361 strcat(path, dirp->d_name);
362 subdir = opendir(path);
363 if (subdir == NULL) {
364 err_msg("\"%.40s\" opendir failed", path);
367 rc = process_dir(subdir, path, param);
373 rc = process_file(dir, dname, dirp->d_name, param);
385 static int process_path(char *path, struct find_param *param)
391 fname = strrchr(path, '/');
392 if (fname != NULL && fname[1] == '\0') {
393 /* Trailing '/', it must be a dir */
397 err_msg("\"%.40s\" opendir failed", path);
400 rc = process_dir(dir, path, param);
403 } else if ((dir = opendir(path)) != NULL) {
404 /* No trailing '/', but it is still a dir */
405 rc = process_dir(dir, path, param);
408 /* It must be a file (or other non-directory) */
417 dir = opendir(dname);
419 err_msg("\"%.40s\" opendir failed", dname);
422 if (!param->got_uuids)
423 rc = get_obd_uuids(dir, dname, param);
425 rc = process_file(dir, dname, fname, param);
434 int op_find(char *path, struct obd_uuid *obduuid, int recursive,
435 int verbose, int quiet)
437 struct find_param param;
440 memset(¶m, 0, sizeof(param));
441 param.recursive = recursive;
442 param.verbose = verbose;
445 param.obduuid = malloc(sizeof(*obduuid));
446 if (param.obduuid == NULL) {
450 memcpy(param.obduuid, obduuid, sizeof(*obduuid));
453 ret = prepare_find(¶m);
457 process_path(path, ¶m);
459 cleanup_find(¶m);
463 #define MAX_STRING_SIZE 128
465 int op_check(int type_num, char **obd_type, char *dir)
469 char buf[OBD_MAX_IOCTL_BUFFER];
471 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
473 memset(buf, 0, sizeof(buf));
474 data->ioc_version = OBD_IOCTL_VERSION;
475 data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
476 data->ioc_len = obd_ioctl_packlen(data);
478 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
480 buf2 = data->ioc_bulk;
482 if (!data->ioc_inlbuf1) {
483 err_msg("No buffer passed!\n");
489 char obd_type_name[sizeof(struct obd_type)];
490 char obd_name[MAX_STRING_SIZE];
491 char obd_uuid[sizeof(struct obd_uuid)];
494 char rawbuf[OBD_MAX_IOCTL_BUFFER];
496 int max = sizeof(rawbuf);
497 struct obd_ioctl_data datal;
498 struct obd_statfs osfs_buffer;
500 memset (&osfs_buffer, 0, sizeof (osfs_buffer));
502 memset(bufl, 0, sizeof(rawbuf));
503 datal.ioc_pbuf1 = (char *)&osfs_buffer;
504 datal.ioc_plen1 = sizeof (osfs_buffer);
506 j = sscanf(buf2,"%d %s %s %s %s %d",&j,
507 status,obd_type_name,
513 for (k=0;k<type_num;k++)
514 if (strcmp(obd_type_name, obd_type[k]) == 0) {
515 datal.ioc_inlbuf1 = obd_name;
516 datal.ioc_inllen1 = strlen(obd_name) + 1;
518 obd_ioctl_pack(&datal,&bufl,max);
520 rc = ioctl(dirfd(opendir(dir)), OBD_IOC_PING,bufl);
523 fprintf(stderr, "error: check %s: %s\n",
524 obd_name, strerror(rc = errno));
526 printf("%s active.\n",obd_name);
531 for (i=0;buf2[i]!= '\n';i++);
540 #undef MAX_STRING_SIZE
542 int op_catinfo(char *dir, char *keyword, char *node_name)
544 char raw[OBD_MAX_IOCTL_BUFFER];
545 char out[LLOG_CHUNK_SIZE];
547 struct obd_ioctl_data data;
552 sprintf(key, "%s", keyword);
553 memset(raw, 0, sizeof(buf));
554 memset(out, 0, sizeof(out));
555 data.ioc_inlbuf1 = key;
556 data.ioc_inllen1 = strlen(key) + 1;
558 data.ioc_inlbuf2 = node_name;
559 data.ioc_inllen2 = strlen(node_name) + 1;
561 data.ioc_pbuf1 = out;
562 data.ioc_plen1 = sizeof(out);
563 rc = obd_ioctl_pack(&data, &buf, sizeof(raw));
569 err_msg("open %s failed", dir);
573 rc = ioctl(dirfd(root), OBD_IOC_LLOG_CATINFO, buf);
575 err_msg("ioctl OBD_IOC_CATINFO failed");
577 fprintf(stdout, "%s", data.ioc_pbuf1);