1 #define _XOPEN_SOURCE 500
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
16 #include <liblustre.h>
17 #include <linux/obd.h>
18 #include <linux/lustre_lib.h>
19 #include <linux/lustre_lite.h>
20 #include <linux/obd_lov.h>
22 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
23 #define MAX_LOV_UUID_COUNT 1000
24 #define OBD_NOT_FOUND ((__u32)-1)
27 struct option longOpts[] = {
31 {"verbose", 0, 0, 'v'},
36 char * shortOpts = "ho:qv";
37 char * usageMsg = "[ --obd <obd uuid> | --query ] <dir|file> ...";
39 int max_ost_count = MAX_LOV_UUID_COUNT;
40 struct obd_uuid * obduuid;
45 struct obd_ioctl_data data;
47 struct obd_uuid * uuids;
50 struct lov_mds_md *lmm;
54 void usage(FILE *stream);
55 void errMsg(char *fmt, ...);
56 void processPath(char *path);
59 const struct stat *sp,
63 __u32 getobdindex(const char *path);
66 main (int argc, char **argv) {
69 cmd = basename(argv[0]);
71 while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
75 errMsg("obd '%s' already specified: '%s'.",
80 obduuid = (struct obd_uuid *)optarg;
95 errMsg("Internal error. Valid '%s' unrecognized.",
102 if (optind >= argc) {
113 processPath(argv[optind]);
114 } while (++optind < argc);
122 int datalen, desclen;
124 datalen = size_round(sizeof(data));
125 desclen = size_round(sizeof(desc));
126 uuidslen = size_round(max_ost_count * sizeof(*uuids));
127 cfglen = datalen + desclen + uuidslen;
128 lmmlen = lov_mds_md_size(max_ost_count);
134 /* XXX max ioctl buffer size currently hardcoded to 8192 */
136 int nuuids, remaining, nluoinfos;
139 nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
140 uuidslen = size_round(nuuids * sizeof(*uuids));
141 remaining = nuuids * sizeof(*uuids);
142 if (uuidslen > remaining)
144 nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects);
145 if (nuuids > nluoinfos)
146 max_ost_count = nluoinfos;
148 max_ost_count = nuuids;
150 cfglen = datalen + desclen + uuidslen;
151 lmmlen = lov_mds_md_size(max_ost_count);
154 if ((buf = malloc(buflen)) == NULL) {
155 errMsg("Unable to allocate %d bytes of memory for ioctl's.",
160 lmm = (struct lov_mds_md *)buf;
161 uuids = (struct obd_uuid *)buf;
167 fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
171 errMsg(char *fmt, ...)
175 fprintf(stderr, "%s: ", cmd);
177 vfprintf(stderr, fmt, args);
179 fprintf(stderr, "\n");
183 processPath(char *path)
185 obdindex = OBD_NOT_FOUND;
186 nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT);
190 processFile(const char *path, const struct stat *sp, int flag, struct FTW *ftwp)
200 if (getobdindex(path) == OBD_NOT_FOUND && obdcount == 0) {
201 /* terminate nftw walking this tree */
205 if ((fd = open(path, O_RDONLY | O_LOV_DELAY_CREATE)) < 0) {
206 errMsg("open \"%.20s\" failed.", path);
211 memset((void *)buf, 0, buflen);
212 lmm->lmm_magic = LOV_MAGIC;
213 lmm->lmm_ost_count = max_ost_count;
215 if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lmm)) < 0) {
216 errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed.");
223 if (query || verbose ||
224 (obdindex != OBD_NOT_FOUND &&
225 lmm->lmm_objects[obdindex].l_object_id))
226 printf("%s\n", path);
229 printf("lmm_magic: 0x%x\n", lmm->lmm_magic);
230 printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id);
231 printf("lmm_stripe_offset: %u\n", (int)lmm->lmm_stripe_offset);
232 printf("lmm_stripe_count: %u\n", (int)lmm->lmm_stripe_count);
233 printf("lmm_stripe_size: %u\n", (int)lmm->lmm_stripe_size);
234 printf("lmm_ost_count: %u\n", lmm->lmm_ost_count);
235 printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf);
238 count = lmm->lmm_ost_count;
240 if (query || verbose) {
242 int ost = lmm->lmm_stripe_offset;
245 for (i = 0; i < count; i++, ost++) {
246 ost %= lmm->lmm_ost_count;
247 if ((oid = lmm->lmm_objects[ost].l_object_id)) {
249 printf("\tobdidx\t objid\n");
252 printf("\t%6u\t%8llu%s\n",
253 ost, oid, obdindex == ost ? " *" : "");
265 getobdindex(const char *path)
267 struct obd_uuid *uuidp;
272 if ((fd = open(path, O_RDONLY)) < 0) {
273 errMsg("open \"%.20s\" failed.", path);
278 data.ioc_inllen1 = sizeof(desc);
279 data.ioc_inlbuf1 = (char *)&desc;
280 data.ioc_inllen2 = uuidslen;
281 data.ioc_inlbuf2 = (char *)uuids;
282 data.ioc_inllen3 = 0;
284 memset(&desc, 0, sizeof(desc));
285 desc.ld_tgt_count = max_ost_count;
287 if (obd_ioctl_pack(&data, &buf, buflen)) {
288 errMsg("internal buffering error.");
292 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
294 errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno);
299 if (obd_ioctl_unpack(&data, buf, buflen)) {
300 errMsg("Invalid reply from ioctl.");
306 obdcount = desc.ld_tgt_count;
308 if (query || verbose) {
310 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
311 printf("%4d: %s\n", i, (char *)uuidp);
316 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
317 rc = strncmp((const char *)obduuid, (const char *)uuidp,
325 if (obdindex == OBD_NOT_FOUND) {
326 errMsg("obd UUID '%s' not found.", obduuid);
327 return(OBD_NOT_FOUND);