Whamcloud - gitweb
Issue# 330: Approver: Andreas - New utility to find files affected by loss of an...
authordonmilos <donmilos>
Tue, 5 Nov 2002 01:48:17 +0000 (01:48 +0000)
committerdonmilos <donmilos>
Tue, 5 Nov 2002 01:48:17 +0000 (01:48 +0000)
lustre/include/linux/lustre_lite.h
lustre/llite/file.c
lustre/lov/lov_obd.c
lustre/osc/osc_request.c
lustre/utils/Makefile.am
lustre/utils/lfind.c [new file with mode: 0644]

index ec5ec35..1ed055f 100644 (file)
@@ -255,12 +255,20 @@ void ll_sysctl_clean(void);
 #define LL_IOC_SETFLAGS                 _IOW ('f', 152, long)
 #define LL_IOC_CLRFLAGS                 _IOW ('f', 153, long)
 #define LL_IOC_LOV_SETSTRIPE            _IOW ('f', 154, long)
+#define LL_IOC_LOV_GETSTRIPE            _IOW ('f', 155, long)
+
+struct lov_user_oinfo {
+        __u64 luo_id;   /* object ID on the target OBD */
+        __u32 luo_idx;  /* OBD stripe index in lmd_objects array */
+        __u32 luo_pad;
+};
 
 struct lov_user_md {
         __u64 lum_stripe_size;
         __u32 lum_stripe_pattern;
         __u32 lum_stripe_offset;
         __u32 lum_stripe_count;
+        struct lov_user_oinfo lum_luoinfo[0];
 };
 
 #define O_LOV_DELAY_CREATE 0100000000  /* hopefully this does not conflict */
index 0bd1198..5648826 100644 (file)
@@ -605,10 +605,62 @@ out_lov_up:
         return rc;
 }
 
+static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
+{
+        struct lov_user_md lum;
+        struct lov_user_md *lump;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct lov_stripe_md *lsm = lli->lli_smd;
+        struct lov_user_oinfo *luoip;
+        struct lov_oinfo *loip;
+        int count, len, i, rc;
+
+        rc = copy_from_user(&lum, (void *)arg, sizeof(lum));
+        if (rc)
+                RETURN(rc);
+
+        if ((count = lsm->lsm_stripe_count) == 0)
+                count = 1;
+
+        if (lum.lum_stripe_count < count)
+                RETURN(-EINVAL);
+
+        len = sizeof(*lump) + count * sizeof(*luoip);
+
+        rc = verify_area(VERIFY_WRITE, (void *)arg, len);
+        if (rc)
+                RETURN(rc);
+
+        lump = (struct lov_user_md *)arg;
+        lump->lum_stripe_count = count;
+        luoip = lump->lum_luoinfo;
+
+        if (lsm->lsm_stripe_count == 0) {
+                lump->lum_stripe_size = 0;
+                lump->lum_stripe_pattern = 0;
+                lump->lum_stripe_offset = 0;
+                luoip->luo_idx = 0;
+                luoip->luo_id = lsm->lsm_object_id;
+        } else {
+                lump->lum_stripe_size = lsm->lsm_stripe_size;
+                lump->lum_stripe_pattern = lsm->lsm_stripe_pattern;
+                lump->lum_stripe_offset = lsm->lsm_stripe_offset;
+
+                loip = lsm->lsm_oinfo;
+                for (i = 0; i < count; i++, luoip++, loip++) {
+                        luoip->luo_idx = loip->loi_ost_idx;
+                        luoip->luo_id = loip->loi_id;
+                }
+        }
+
+        RETURN(0);
+}
+
 int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                   unsigned long arg)
 {
         struct ll_file_data *fd = (struct ll_file_data *)file->private_data;
+        struct lustre_handle *conn;
         int flags;
 
         switch(cmd) {
@@ -631,6 +683,8 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 return 0;
         case LL_IOC_LOV_SETSTRIPE:
                 return ll_lov_setstripe(inode, file, (struct lov_user_md *)arg);
+        case LL_IOC_LOV_GETSTRIPE:
+                return ll_lov_getstripe(inode, arg);
 
         /* We need to special case any other ioctls we want to handle,
          * to send them to the MDS/OST as appropriate and to properly
@@ -643,7 +697,8 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
         case EXT2_IOC_SETVERSION_NEW:
         */
         default:
-                return -ENOTTY;
+                conn = ll_i2obdconn(inode);
+                return obd_iocontrol(cmd, conn, 0, NULL, (void *)arg);
         }
 }
 
index 9d57f0e..0530a82 100644 (file)
@@ -1298,13 +1298,48 @@ static int lov_iocontrol(long cmd, struct lustre_handle *conn, int len,
         struct obd_device *obddev = class_conn2obd(conn);
         struct obd_ioctl_data *data = karg;
         struct lov_obd *lov = &obddev->u.lov;
-        int rc, i;
+        struct lov_desc *desc;
+        struct lov_tgt_desc *tgtdesc;
+        obd_uuid_t *uuidp;
+        char *buf;
+        int rc, i, count;
         ENTRY;
 
         switch (cmd) {
         case IOC_LOV_SET_OSC_ACTIVE:
                 rc = lov_set_osc_active(lov,data->ioc_inlbuf1,data->ioc_offset);
                 break;
+        case OBD_IOC_LOV_GET_CONFIG:
+                buf = NULL;
+                len = 0;
+                if (obd_ioctl_getdata(&buf, &len, (void *)uarg))
+                        RETURN(-EINVAL);
+
+                data = (struct obd_ioctl_data *)buf;
+
+                if (sizeof(*desc) > data->ioc_inllen1) {
+                        OBD_FREE(buf, len);
+                        RETURN(-EINVAL);
+                }
+
+                count = lov->desc.ld_tgt_count;
+
+                if (sizeof(*uuidp) * count > data->ioc_inllen2) {
+                        OBD_FREE(buf, len);
+                        RETURN(-EINVAL);
+                }
+
+                desc = (struct lov_desc *)data->ioc_inlbuf1;
+                uuidp = (obd_uuid_t *)data->ioc_inlbuf2;
+                memcpy(desc, &(lov->desc), sizeof(*desc));
+
+                tgtdesc = lov->tgts;
+                for (i = 0; i < count; i++, uuidp++, tgtdesc++)
+                        memcpy(uuidp, tgtdesc->uuid, sizeof(*uuidp));
+
+                rc = copy_to_user((void *)uarg, buf, len);
+                OBD_FREE(buf, len);
+                break;
         default:
                 if (lov->desc.ld_tgt_count == 0)
                         RETURN(-ENOTTY);
index a28de1f..6de5d7e 100644 (file)
@@ -811,7 +811,44 @@ static int osc_iocontrol(long cmd, struct lustre_handle *conn, int len,
                 obddev->u.cli.cl_containing_lov = (struct obd_device *)karg;
                 GOTO(out, err);
         }
+        case OBD_IOC_LOV_GET_CONFIG: {
+                char *buf;
+                struct lov_desc *desc;
+                obd_uuid_t *uuidp;
 
+                buf = NULL;
+                len = 0;
+                if (obd_ioctl_getdata(&buf, &len, (void *)uarg))
+                        GOTO(out, err = -EINVAL);
+
+                data = (struct obd_ioctl_data *)buf;
+
+                if (sizeof(*desc) > data->ioc_inllen1) {
+                        OBD_FREE(buf, len);
+                        GOTO(out, err = -EINVAL);
+                }
+
+                if (data->ioc_inllen2 < sizeof(*uuidp)) {
+                        OBD_FREE(buf, len);
+                        GOTO(out, err = -EINVAL);
+                }
+
+                desc = (struct lov_desc *)data->ioc_inlbuf1;
+                desc->ld_tgt_count = 1;
+                desc->ld_active_tgt_count = 1;
+                desc->ld_default_stripe_count = 1;
+                desc->ld_default_stripe_size = 0;
+                desc->ld_default_stripe_offset = 0;
+                desc->ld_pattern = 0;
+                memcpy(desc->ld_uuid,  obddev->obd_uuid, sizeof(*uuidp));
+
+                uuidp = (obd_uuid_t *)data->ioc_inlbuf2;
+                memcpy(uuidp,  obddev->obd_uuid, sizeof(*uuidp));
+
+                err = copy_to_user((void *)uarg, buf, len);
+                OBD_FREE(buf, len);
+                GOTO(out, err);
+        }
         default:
                 GOTO(out, err = -ENOTTY);
         }
index 497fc75..dc713f4 100644 (file)
@@ -6,10 +6,12 @@ KFLAGS:=
 CPPFLAGS = $(HAVE_LIBREADLINE)
 obdctl_LDADD := $(LIBREADLINE)
 lctl_LDADD := $(LIBREADLINE) -lptlctl
-sbin_PROGRAMS = lctl obdctl
+sbin_PROGRAMS = lctl lfind obdctl
 sbin_SCRIPTS = lconf lmc
 obdctl_SOURCES = parser.c obdctl.c obd.c parser.h obdctl.h
 lctl_SOURCES = parser.c obd.c lctl.c parser.h
+lfind_SOURCES = lfind.c
+lfind_CPPFLAGS = -D_XOPEN_SOURCE=500
 EXTRA_DIST = $(sbin_SCRIPTS)
 
 include $(top_srcdir)/Rules
diff --git a/lustre/utils/lfind.c b/lustre/utils/lfind.c
new file mode 100644 (file)
index 0000000..6628a9c
--- /dev/null
@@ -0,0 +1,318 @@
+#define _XOPEN_SOURCE 500
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <ftw.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#define        printk printf
+#include <linux/lustre_lib.h>
+#include <linux/lustre_lite.h>
+
+#warning Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c
+#define MAX_LOV_UUID_COUNT     1000
+#define OBD_NOT_FOUND          ((__u32)-1)
+#define        debugMsg                if (debug) printf
+
+char *         cmd;
+int            debug;
+struct option  longOpts[] = {
+                       {"debug", 0, 0, 'd'},
+                       {"help", 0, 0, 'h'},
+                       {"obd", 1, 0, 'o'},
+                       {"query", 0, 0, 'o'},
+                       {0, 0, 0, 0}
+               };
+int            query;
+char *         shortOpts = "dho:qv";
+char *         usageMsg = "[ --obd <obd uuid> | --query ] <dir|file> ...";
+
+int            max_stripe_count = MAX_LOV_UUID_COUNT;
+obd_uuid_t *   obduuid;
+__u32          obdcount;
+__u32          obdindex;
+char *         buf;
+int            buflen;
+struct obd_ioctl_data data;
+struct lov_desc desc;
+obd_uuid_t *   uuids;
+int            uuidslen;
+int            cfglen;
+struct lov_user_md *lum;
+int            lumlen;
+
+void   init();
+void   usage(FILE *stream);
+void   errMsg(char *fmt, ...);
+void   processPath(char *path);
+int    processFile(
+               const char *path,
+               const struct stat *sp,
+               int flag,
+               struct FTW *ftwp
+       );
+__u32  getobdindex(const char *path);
+
+int
+main (int argc, char **argv) {
+       int c;
+
+       cmd = basename(argv[0]);
+
+       while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
+               switch (c) {
+               case 'd':
+                       debug++;
+                       break;
+               case 'o':
+                       if (obduuid) {
+                               errMsg("obd '%s' already specified: '%s'.",
+                                       obduuid, optarg);
+                               exit(1);
+                       }
+
+                       obduuid = (obd_uuid_t *)optarg;
+                       break;
+               case 'h':
+                       usage(stdout);
+                       exit(0);
+               case 'q':
+                       query++;
+                       break;
+               case '?':
+                       usage(stderr);
+                       exit(1);
+               default:
+                       errMsg("Internal error. Valid '%s' unrecognized.",
+                               argv[optind - 1]);
+                       usage(stderr);
+                       exit(1);
+               }
+       }
+
+       if (optind >= argc) {
+               usage(stderr);
+               exit(1);
+       }
+
+       if (obduuid == NULL)
+               query++;
+
+       init();
+
+       do {
+               processPath(argv[optind]);
+       } while (++optind < argc);
+
+       exit (0);
+}
+
+void
+init()
+{
+       int datalen, desclen;
+
+       datalen = size_round(sizeof(data));
+       desclen = size_round(sizeof(desc));
+       uuidslen = size_round(max_stripe_count * sizeof(*uuids));
+       cfglen = datalen + desclen + uuidslen;
+       lumlen = sizeof(*lum) + max_stripe_count * sizeof(*lum->lum_luoinfo);
+       if (cfglen > lumlen)
+               buflen = cfglen;
+       else
+               buflen = lumlen;
+
+#warning max ioctl buffer size currently hardcoded to 8192
+       if (buflen > 8192) {
+               int nuuids, remaining, nluoinfos;
+
+               buflen = 8192;
+               nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
+               uuidslen = size_round(nuuids * sizeof(*uuids));
+               remaining = nuuids * sizeof(*uuids);
+               if (uuidslen > remaining)
+                       nuuids--;
+               nluoinfos = (buflen - sizeof(*lum)) / sizeof(*lum->lum_luoinfo);
+               if (nuuids > nluoinfos)
+                       max_stripe_count = nluoinfos;
+               else
+                       max_stripe_count = nuuids;
+
+               cfglen = datalen + desclen + uuidslen;
+               lumlen = sizeof(*lum) + max_stripe_count *
+                               sizeof(*lum->lum_luoinfo);
+       }
+
+       if ((buf = malloc(buflen)) == NULL) {
+               errMsg("Unable to allocate %d bytes of memory for ioctl's.",
+                       buflen);
+               exit(1);
+       }
+
+       lum = (struct lov_user_md *)buf;
+       uuids = (obd_uuid_t *)buf;
+}
+
+void
+usage(FILE *stream)
+{
+       fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
+}
+
+void
+errMsg(char *fmt, ...)
+{
+       va_list args;
+
+       fprintf(stderr, "%s: ", cmd);
+       va_start(args, fmt);
+       vfprintf(stderr, fmt, args);
+       va_end(args);
+       fprintf(stderr, "\n");
+}
+
+void
+processPath(char *path)
+{
+       obdindex = OBD_NOT_FOUND;
+       nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT);
+}
+
+int
+processFile(const char *path,
+       const struct stat *sp,
+       int flag,
+       struct FTW *ftwp
+) {
+       struct lov_user_oinfo *luoinfo;
+       int fd;
+       int count;
+       int rc;
+       int i;
+
+       if (flag != FTW_F)
+               return 0;
+
+       if ((obdcount == 0) && (getobdindex(path) == OBD_NOT_FOUND)) {
+               /* terminate nftw walking this tree */
+               return(1);
+       }
+
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               errMsg("open \"%.20s\" failed.", path);
+               perror("open");
+               exit(1);
+       }
+
+       memset((void *)buf, 0, buflen);
+        lum->lum_stripe_count = max_stripe_count;
+
+       if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lum)) < 0) {
+               errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed.");
+               perror("ioctl");
+               exit(1);
+       }
+
+       close(fd);
+
+       count = lum->lum_stripe_count;
+       luoinfo = lum->lum_luoinfo;
+
+       if (query) {
+               printf("%s\n", path);
+               for (i = 0; i < count; i++, luoinfo++) {
+                       printf("%4d: obdindex: %-4d objid: %lld\n",
+                               i, luoinfo->luo_idx, luoinfo->luo_id);
+               }
+               return(0);
+       }
+
+       debugMsg("LL_IOC_LOV_GETSTRIPE:%s: obdindex: %d count: %d\n",
+               path, obdindex, count);
+
+       for (i = 0; i < count; i++, luoinfo++) {
+               debugMsg("%-4d: obdidx: %-4d objid: %lld\n",
+                       i, luoinfo->luo_idx, luoinfo->luo_id);
+               if (luoinfo->luo_idx == obdindex) {
+                       printf("%s\n", path);
+                       return 0;
+               }
+       }
+
+       return(0);
+}
+
+__u32
+getobdindex(const char *path)
+{
+       obd_uuid_t *uuidp;
+       int fd;
+       int rc;
+       int i;
+
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               errMsg("open \"%.20s\" failed.", path);
+               perror("open");
+               exit(1);
+       }
+
+        data.ioc_inllen1 = sizeof(desc);
+        data.ioc_inlbuf1 = (char *)&desc;
+        data.ioc_inllen2 = uuidslen;
+        data.ioc_inlbuf2 = (char *)uuids;
+        data.ioc_inllen3 = 0;
+
+        memset(&desc, 0, sizeof(desc));
+        desc.ld_tgt_count = max_stripe_count;
+
+        if (obd_ioctl_pack(&data, &buf, buflen)) {
+                errMsg("internal buffering error.");
+               exit(1);
+        }
+
+        rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
+        if (rc) {
+               errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno);
+               perror("ioctl");
+                exit(1);
+        }
+
+       if (obd_ioctl_unpack(&data, buf, buflen)) {
+               errMsg("Invalid reply from ioctl.");
+                exit(1);
+       }
+
+       close(fd);
+
+        obdcount = desc.ld_tgt_count;
+
+       if (query) {
+               printf("OBDS:\n");
+               for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
+                       printf("%4d: %s\n", i, (char *)uuidp);
+
+               return(0);
+       }
+
+        for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
+               rc = strncmp((const char *)obduuid, (const char *)uuidp,
+                               sizeof(*uuidp));
+               if (rc == 0) {
+                       obdindex = i;
+                       break;
+               }
+       }
+
+       if (obdindex == OBD_NOT_FOUND) {
+               errMsg("obd UUID '%s' not found.", obduuid);
+               return(OBD_NOT_FOUND);
+       }
+
+       return(0);
+}