X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=b7c2a66dce0e3a3510cf6a5ca363d1559a233aa4;hb=46be9348209094476135412fc7100b15c00f8c77;hp=ca1a49036deb04a5bc89a4722fb71e2ae0f804f7;hpb=7ce2000eb0f4e7b7ea1f362c17099881098cfef7;p=fs%2Flustre-release.git diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index ca1a490..b7c2a66 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -39,9 +39,16 @@ #include #include #include +#ifdef HAVE_LINUX_TYPES_H #include +#else +#include "types.h" +#endif +#ifdef HAVE_LINUX_UNISTD_H #include - +#else +#include +#endif #include #include #include @@ -66,6 +73,7 @@ int llapi_file_create(char *name, long stripe_size, int stripe_offset, { struct lov_user_md lum = { 0 }; int fd, rc = 0; + int isdir = 0; /* Initialize IOCTL striping pattern structure */ lum.lmm_magic = LOV_USER_MAGIC; @@ -75,8 +83,10 @@ int llapi_file_create(char *name, long stripe_size, int stripe_offset, lum.lmm_stripe_offset = stripe_offset; fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); - if (errno == EISDIR) + if (errno == EISDIR) { fd = open(name, O_DIRECTORY | O_RDONLY); + isdir++; + } if (fd < 0) { err_msg("unable to open '%s'",name); @@ -84,6 +94,19 @@ int llapi_file_create(char *name, long stripe_size, int stripe_offset, return rc; } + /* setting stripe pattern 0 -1 0 to a dir means to delete it */ + if (isdir) { + if (stripe_size == 0 && stripe_count == 0 && + stripe_offset == -1) + lum.lmm_stripe_size = -1; + } else { + if (stripe_size == -1) { + err_msg("deleting file stripe info is not allowed\n"); + rc = -EPERM; + goto out; + } + } + if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) { char *errmsg = "stripe already set"; if (errno != EEXIST && errno != EALREADY) @@ -93,6 +116,52 @@ int llapi_file_create(char *name, long stripe_size, int stripe_offset, name, fd, errmsg); rc = -errno; } +out: + if (close(fd) < 0) { + err_msg("error on close for '%s' (%d)", name, fd); + if (rc == 0) + rc = -errno; + } + return rc; +} + +int op_create_dir(char *name, int stripe_count) +{ + struct ll_user_mkdir_stripe lums = { 0 }; + int fd, rc = 0; + char *dot = "."; + char *dirname; + + dirname = rindex(name, '/'); + if (!dirname) { + dirname = "name"; + name = dot; + } else { + *dirname = 0; + dirname++; + } + lums.lums_nstripes = stripe_count; + lums.lums_namelen = strlen(dirname); + lums.lums_name = dirname; + /* XXX: Probably users might want to specify permissions as well? */ + lums.lums_mode = 0755; + + fd = open(name, O_RDONLY|O_DIRECTORY); + if (name != dot) + *(dirname-1) = '/'; + if (fd < 0) { + err_msg("unable to open '%s'",name); + rc = -errno; + return rc; + } + + if (ioctl(fd, LL_IOC_MDC_MKDIRSTRIPE, &lums)) { + char *errmsg = strerror(errno); + + fprintf(stderr, "error on ioctl for '%s' (%d): %s\n", + name, fd, errmsg); + rc = -errno; + } if (close(fd) < 0) { err_msg("error on close for '%s' (%d)", name, fd); if (rc == 0) @@ -110,14 +179,16 @@ int op_create_file(char *name, long stripe_size, int stripe_offset, } struct find_param { - int recursive; - int verbose; - int quiet; - struct obd_uuid *obduuid; - int lumlen; - struct lov_user_md *lum; - int got_uuids; - int obdindex; + int recursive; + int verbose; + int quiet; + int showfid; + struct obd_uuid *obduuid; + int datalen; + struct lov_user_md *data; + int got_uuids; + int obdindex; + __u32 *obdgens; }; /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */ @@ -126,16 +197,23 @@ struct find_param { static int prepare_find(struct find_param *param) { - param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT); - if ((param->lum = malloc(param->lumlen)) == NULL) { - err_msg("unable to allocate %d bytes of memory for ioctl", - param->lumlen); - return ENOMEM; + if (param->showfid) { + param->datalen = PATH_MAX + 1; + if ((param->data = malloc(param->datalen)) == NULL) { + err_msg("unable to allocate %d bytes of memory for ioctl", + param->datalen); + return ENOMEM; + } + } else { + param->datalen = lov_mds_md_size(MAX_LOV_UUID_COUNT); + if ((param->data = malloc(param->datalen)) == NULL) { + err_msg("unable to allocate %d bytes of memory for ioctl", + param->datalen); + return ENOMEM; + } } - param->got_uuids = 0; param->obdindex = OBD_NOT_FOUND; - return 0; } @@ -143,11 +221,12 @@ static void cleanup_find(struct find_param *param) { if (param->obduuid) free(param->obduuid); - if (param->lum) - free(param->lum); + if (param->data) + free(param->data); } -int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) +int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, + __u32 *obdgens, int *ost_count) { struct obd_ioctl_data data = { 0, }; struct lov_desc desc = { 0, }; @@ -155,7 +234,8 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) int max_ost_count, rc; max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) - - size_round(sizeof(desc))) / sizeof(*uuidp); + size_round(sizeof(desc))) / + (sizeof(*uuidp) + sizeof(*obdgens)); if (max_ost_count > *ost_count) max_ost_count = *ost_count; @@ -163,6 +243,8 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) data.ioc_inlbuf1 = (char *)&desc; data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp)); data.ioc_inlbuf2 = (char *)uuidp; + data.ioc_inllen3 = size_round(max_ost_count * sizeof(*obdgens)); + data.ioc_inlbuf3 = (char *)obdgens; desc.ld_tgt_count = max_ost_count; @@ -189,18 +271,19 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) out: free(buf); - return 0; + return rc; } static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param) { struct obd_uuid uuids[1024], *uuidp; + __u32 obdgens[1024], *genp; int obdcount = 1024; int rc, i; param->got_uuids = 1; - rc = llapi_lov_get_uuids(dirfd(dir), uuids, &obdcount); + rc = llapi_lov_get_uuids(dirfd(dir), uuids, obdgens, &obdcount); if (rc != 0) return (param->obduuid ? rc : 0); @@ -209,7 +292,7 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param) if (param->obduuid) { for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) { - if (strncmp(param->obduuid->uuid, uuidp->uuid, + if (strncmp((char *)param->obduuid->uuid, (char *)uuidp->uuid, sizeof(*uuidp)) == 0) { param->obdindex = i; break; @@ -220,11 +303,16 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param) return EINVAL; } } else if (!param->quiet) { - printf("OBDS:\n"); - for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) - printf("%4d: %s\n", i, uuidp->uuid); - } + printf("OBDS:\tobdidx\t\tobdgen\t\t obduuid\n"); + uuidp = uuids; + genp = obdgens; + for (i = 0; i < obdcount; i++, uuidp++, genp++) { + if (obd_uuid_empty(uuidp)) + continue; + printf("\t%6u\t%14u\t\t %s\n", i, *genp, uuidp->uuid); + } + } return 0; } @@ -267,16 +355,17 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname, if (body) { if ((!quiet) && (obdstripe == 1)) - printf("\tobdidx\t\t objid\t\tobjid\t\t group\n"); + printf("\tobdidx\t\t obdgen\t\t objid\t\tobjid\t\t group\n"); for (i = 0; i < lum->lmm_stripe_count; i++) { int idx = lum->lmm_objects[i].l_ost_idx; long long oid = lum->lmm_objects[i].l_object_id; + int gen = lum->lmm_objects[i].l_ost_gen; long long gr = lum->lmm_objects[i].l_object_gr; if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) - printf("\t%6u\t%14llu\t%#13llx\t%14llu%s\n", - idx, oid, oid, gr, - obdindex == idx ? " *" : ""); + printf("\t%6u\t%14u\t%14llu\t%#13llx\t%14lld%s\n", + idx, gen, oid, oid, gr, + obdindex == idx ? " *" : ""); } printf("\n"); } @@ -284,18 +373,37 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname, void llapi_lov_dump_user_lmm(struct find_param *param, char *dname, char *fname) { - switch(*(__u32 *)param->lum) { /* lum->lmm_magic */ + switch(*(__u32 *)param->data) { /* lum->lmm_magic */ case LOV_USER_MAGIC_V1: - lov_dump_user_lmm_v1(param->lum, dname, fname, param->obdindex, + lov_dump_user_lmm_v1(param->data, dname, fname, param->obdindex, param->quiet, param->verbose, (param->verbose || !param->obduuid)); break; default: - printf("unknown lmm_magic: 0x%08X\n", *(__u32 *)param->lum); + printf("unknown lmm_magic: 0x%08X\n", *(__u32 *)param->data); return; } } +void llapi_dump_fid(struct find_param *param, char *dname, char *fname) +{ + if (!param->quiet) { + int n = 0; + char path[PATH_MAX + 1]; + + n = snprintf(path, PATH_MAX, "%s/%s", + dname, fname); + + if (n > 40) + n = 1; + else + n = 40 - n; + + printf("%s:%*s"DLID4"\n", path, n, "", + OLID4((struct lustre_id *)param->data)); + } +} + int llapi_file_get_stripe(char *path, struct lov_user_md *lum) { char *dname, *fname; @@ -315,7 +423,7 @@ int llapi_file_get_stripe(char *path, struct lov_user_md *lum) if (dname == NULL) return ENOMEM; strncpy(dname, path, fname - path); - dname[fname - path + 1] = '\0'; + dname[fname - path] = '\0'; fname++; } @@ -339,6 +447,50 @@ int llapi_file_get_stripe(char *path, struct lov_user_md *lum) return rc; } +int llapi_file_get_fid(char *path, void *data) +{ + char *dname, *fname; + int fd, rc = 0; + + fname = strrchr(path, '/'); + + if (fname == NULL) { + dname = (char *)malloc(2); + if (dname == NULL) + return ENOMEM; + strcpy(dname, "."); + fname = path; + } else { + dname = (char *)malloc(fname - path + 1); + if (dname == NULL) + return ENOMEM; + strncpy(dname, path, fname - path); + dname[fname - path] = '\0'; + fname++; + + if (!strlen(fname)) + fname = "."; + } + + if ((fd = open(dname, O_RDONLY)) == -1) { + free(dname); + return errno; + } + + strncpy((char *)data, fname, strlen(fname)); + if (ioctl(fd, IOC_MDC_SHOWFID, (void *)data) == -1) { + close(fd); + free(dname); + return errno; + } + + if (close(fd) == -1) + rc = errno; + + free(dname); + return rc; +} + /* short term backwards compat only */ int op_get_file_stripe(char *path, struct lov_user_md *lum) { @@ -350,30 +502,39 @@ static int process_file(DIR *dir, char *dname, char *fname, { int rc; - strncpy((char *)param->lum, fname, param->lumlen); + if (param->showfid) { + char path[PATH_MAX + 1]; - rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->lum); - if (rc) { - if (errno == ENODATA) { - if (!param->obduuid && !param->quiet) - fprintf(stderr, - "%s/%s has no stripe info\n", + snprintf(path, PATH_MAX, "%s/%s", dname, fname); + rc = llapi_file_get_fid(path, (void *)param->data); + if (rc) { + err_msg("IOC_MDC_SHOWFID ioctl failed"); + return rc; + } + llapi_dump_fid(param, dname, fname); + } else { + strncpy((char *)param->data, fname, param->datalen); + rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->data); + if (rc) { + if (errno == ENODATA) { + if (!param->obduuid && !param->quiet) + fprintf(stderr, + "%s/%s has no stripe info\n", + dname, fname); + rc = 0; + } else if (errno == EISDIR) { + fprintf(stderr, "process_file on directory %s/%s!\n", dname, fname); - rc = 0; - } else if (errno == EISDIR) { - fprintf(stderr, "process_file on directory %s/%s!\n", - dname, fname); - /* add fname to directory list; */ - rc = errno; - } else { - err_msg("IOC_MDC_GETSTRIPE ioctl failed"); - rc = errno; + /* add fname to directory list; */ + rc = errno; + } else { + err_msg("IOC_MDC_GETSTRIPE ioctl failed"); + rc = errno; + } + return rc; } - return rc; + llapi_lov_dump_user_lmm(param, dname, fname); } - - llapi_lov_dump_user_lmm(param, dname, fname); - return 0; } @@ -400,31 +561,40 @@ unsigned char handle_dt_unknown(char *parent, char *entry) static int process_dir(DIR *dir, char *dname, struct find_param *param) { + char path[PATH_MAX + 1]; struct dirent64 *dirp; DIR *subdir; - char path[1024]; int rc; - if (!param->got_uuids) { - rc = setup_obd_uuids(dir, dname, param); - if (rc) + /* retrieve dir's stripe info */ + if (param->showfid) { + rc = llapi_file_get_fid(dname, (void *)param->data); + if (rc) { + err_msg("IOC_MDC_SHOWFID ioctl failed"); return rc; - } + } + llapi_dump_fid(param, dname, ""); + } else { + if (!param->got_uuids) { + rc = setup_obd_uuids(dir, dname, param); + if (rc) + return rc; + } - /* retrieve dir's stripe info */ - strncpy((char *)param->lum, dname, param->lumlen); - rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->lum); - if (rc) { - if (errno == ENODATA) { - if (!param->obduuid && param->verbose) - printf("%s/%s has no stripe info\n", dname, ""); - rc = 0; + strncpy((char *)param->data, dname, param->datalen); + rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->data); + if (rc) { + if (errno == ENODATA) { + if (!param->obduuid && param->verbose) + printf("%s/%s has no stripe info\n", dname, ""); + rc = 0; + } else { + err_msg("IOC_MDC_GETSTRIPE ioctl failed"); + return errno; + } } else { - err_msg("IOC_MDC_GETSTRIPE ioctl failed"); - return errno; + llapi_lov_dump_user_lmm(param, dname, ""); } - } else { - llapi_lov_dump_user_lmm(param, dname, ""); } /* Handle the contents of the directory */ @@ -444,7 +614,6 @@ static int process_dir(DIR *dir, char *dname, struct find_param *param) * know d_type should be valid for lustre and this * tool only makes sense for lustre filesystems. */ return EINVAL; - break; case DT_DIR: if (!param->recursive) break; @@ -511,8 +680,10 @@ static int process_path(char *path, struct find_param *param) err_msg("\"%.40s\" opendir failed", dname); rc = errno; } else { - if (!param->got_uuids) - rc = setup_obd_uuids(dir, dname, param); + if (!param->showfid) { + if (!param->got_uuids) + rc = setup_obd_uuids(dir, dname, param); + } if (rc == 0) rc = process_file(dir, dname, fname, param); closedir(dir); @@ -523,13 +694,14 @@ static int process_path(char *path, struct find_param *param) } int llapi_find(char *path, struct obd_uuid *obduuid, int recursive, - int verbose, int quiet) + int verbose, int quiet, int showfid) { struct find_param param; int ret = 0; memset(¶m, 0, sizeof(param)); param.recursive = recursive; + param.showfid = showfid; param.verbose = verbose; param.quiet = quiet; if (obduuid) { @@ -573,8 +745,7 @@ int llapi_target_check(int type_num, char **obd_type, char *dir) char rawbuf[OBD_MAX_IOCTL_BUFFER]; char *bufl = rawbuf; char *bufp = buf; - int max = sizeof(rawbuf); - struct obd_ioctl_data datal; + struct obd_ioctl_data datal = { 0, }; struct obd_statfs osfs_buffer; while(bufp[0] == ' ') @@ -596,7 +767,11 @@ int llapi_target_check(int type_num, char **obd_type, char *dir) datal.ioc_inlbuf1 = obd_name; datal.ioc_inllen1 = strlen(obd_name) + 1; - obd_ioctl_pack(&datal,&bufl,max); + rc = obd_ioctl_pack(&datal, &bufl, OBD_MAX_IOCTL_BUFFER); + if (rc) { + fprintf(stderr, "internal buffer error packing\n"); + break; + } rc = ioctl(dirfd(opendir(dir)), OBD_IOC_PING, bufl);