X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=b7c2a66dce0e3a3510cf6a5ca363d1559a233aa4;hb=46be9348209094476135412fc7100b15c00f8c77;hp=987550c2d80aec120e8aa3356db7581f744759e5;hpb=a8f99c578c89cf1164f6c4c7fa7eb136b3a28587;p=fs%2Flustre-release.git diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 987550c..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 @@ -61,21 +68,25 @@ static void err_msg(char *fmt, ...) fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno); } -int op_create_file(char *name, long stripe_size, int stripe_offset, - int stripe_count) +int llapi_file_create(char *name, long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern) { struct lov_user_md lum = { 0 }; int fd, rc = 0; + int isdir = 0; /* Initialize IOCTL striping pattern structure */ lum.lmm_magic = LOV_USER_MAGIC; + lum.lmm_pattern = stripe_pattern; lum.lmm_stripe_size = stripe_size; - lum.lmm_stripe_offset = stripe_offset; lum.lmm_stripe_count = stripe_count; + 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); @@ -83,6 +94,19 @@ int op_create_file(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) @@ -92,6 +116,7 @@ int op_create_file(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) @@ -100,21 +125,70 @@ int op_create_file(char *name, long stripe_size, int stripe_offset, 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) + rc = -errno; + } + return rc; +} + +/* short term backwards compat only */ +int op_create_file(char *name, long stripe_size, int stripe_offset, + int stripe_count) +{ + return llapi_file_create(name, stripe_size, stripe_offset, + stripe_count, 0); +} + struct find_param { - int recursive; - int verbose; - int quiet; - struct obd_uuid *obduuid; - struct obd_ioctl_data data; - struct lov_desc desc; - int uuidslen; - char *buf; - int buflen; - struct obd_uuid *uuids; - struct lov_user_md *lum; - int got_uuids; - int obdindex; - int max_ost_count; + 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 */ @@ -123,50 +197,23 @@ struct find_param { static int prepare_find(struct find_param *param) { - int datalen, desclen; - int cfglen, lumlen; - int max_ost_count = MAX_LOV_UUID_COUNT; - - datalen = size_round(sizeof(param->data)); - desclen = size_round(sizeof(param->desc)); - param->uuidslen = size_round(max_ost_count * sizeof(*param->uuids)); - cfglen = datalen + desclen + param->uuidslen; - lumlen = lov_mds_md_size(max_ost_count); - if (cfglen > lumlen) - param->buflen = cfglen; - else - param->buflen = lumlen; - - /* XXX max ioctl buffer size currently hardcoded to 8192 */ - if (param->buflen > 8192) { - int nuuids, remaining; - - param->buflen = 8192; - nuuids = (param->buflen - datalen - desclen) / - sizeof(*param->uuids); - param->uuidslen = size_round(nuuids * sizeof(*param->uuids)); - remaining = nuuids * sizeof(*param->uuids); - if (param->uuidslen > remaining) - nuuids--; - max_ost_count = nuuids; - while ((lumlen=lov_mds_md_size(max_ost_count)) > param->buflen) - --max_ost_count; - - cfglen = datalen + desclen + param->uuidslen; - } - - if ((param->buf = malloc(param->buflen)) == NULL) { - err_msg("unable to allocate %d bytes of memory for ioctl's", - param->buflen); - 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->lum = (struct lov_user_md *)param->buf; - param->uuids = (struct obd_uuid *)param->buf; param->got_uuids = 0; param->obdindex = OBD_NOT_FOUND; - param->max_ost_count = max_ost_count; - return 0; } @@ -174,49 +221,78 @@ static void cleanup_find(struct find_param *param) { if (param->obduuid) free(param->obduuid); - if (param->buf) - free(param->buf); + if (param->data) + free(param->data); } -static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param) +int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, + __u32 *obdgens, int *ost_count) { - int obdcount; - struct obd_uuid *uuidp; - int rc, i; - - param->got_uuids = 1; - memset(¶m->data, 0, sizeof(param->data)); - param->data.ioc_inllen1 = sizeof(struct lov_desc); - param->data.ioc_inlbuf1 = (char *)¶m->desc; - param->data.ioc_inllen2 = param->uuidslen; - param->data.ioc_inlbuf2 = (char *)param->uuids; - - memset(¶m->desc, 0, sizeof(struct lov_desc)); - param->desc.ld_tgt_count = param->max_ost_count; - - if (obd_ioctl_pack(¶m->data, ¶m->buf, param->buflen)) { - fprintf(stderr, "internal buffer error from %s\n", dname); - return (param->obduuid ? EINVAL : 0); + struct obd_ioctl_data data = { 0, }; + struct lov_desc desc = { 0, }; + char *buf = NULL; + int max_ost_count, rc; + + max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) - + size_round(sizeof(desc))) / + (sizeof(*uuidp) + sizeof(*obdgens)); + if (max_ost_count > *ost_count) + max_ost_count = *ost_count; + + data.ioc_inllen1 = sizeof(desc); + 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; + + if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) { + fprintf(stderr, "internal buffer error packing\n"); + rc = EINVAL; + goto out; } - rc = ioctl(dirfd(dir), OBD_IOC_LOV_GET_CONFIG, param->buf); + rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); if (rc) { - err_msg("error getting LOV config from %s", dname); - return (param->obduuid ? errno : 0); + err_msg("error getting LOV config"); + rc = errno; + goto out; } - if (obd_ioctl_unpack(¶m->data, param->buf, param->buflen)) { - err_msg("invalid reply from ioctl from %s", dname); - return (param->obduuid ? EINVAL : 0); + if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) { + fprintf(stderr, "invalid reply from ioctl"); + rc = EINVAL; + goto out; } - obdcount = param->desc.ld_tgt_count; + *ost_count = desc.ld_tgt_count; +out: + free(buf); + + 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, obdgens, &obdcount); + if (rc != 0) + return (param->obduuid ? rc : 0); + if (obdcount == 0) return 0; if (param->obduuid) { - for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++) { - if (strncmp(param->obduuid->uuid, uuidp->uuid, + for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) { + if (strncmp((char *)param->obduuid->uuid, (char *)uuidp->uuid, sizeof(*uuidp)) == 0) { param->obdindex = i; break; @@ -227,11 +303,16 @@ static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param) return EINVAL; } } else if (!param->quiet) { - printf("OBDS:\n"); - for (i = 0, uuidp = param->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; } @@ -259,9 +340,9 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname, printf("count: %d, size: %d, offset: %d\n\n", lum->lmm_stripe_count, lum->lmm_stripe_size, (short int)lum->lmm_stripe_offset); - } + } return; - } + } if (header && (obdstripe == 1)) { printf("lmm_magic: 0x%08X\n", lum->lmm_magic); @@ -273,39 +354,57 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname, } if (body) { - long long oid; - 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; - oid = lum->lmm_objects[i].l_object_id; + 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%14lld%s\n", - idx, oid, oid, - (long long)lum->lmm_objects[i].l_object_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"); } } -void lov_dump_user_lmm(struct find_param *param, 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; } } -int get_file_stripe(char *path, struct lov_user_md *lum) +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; int fd, rc = 0; @@ -324,7 +423,7 @@ int get_file_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++; } @@ -348,35 +447,94 @@ int get_file_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) +{ + return llapi_file_get_stripe(path, lum); +} + static int process_file(DIR *dir, char *dname, char *fname, - struct find_param *param) + struct find_param *param) { int rc; - strncpy((char *)param->lum, fname, param->buflen); + 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); } - - lov_dump_user_lmm(param, dname, fname); - return 0; } @@ -403,32 +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 = get_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->buflen); - rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->lum); - if (rc) { - if (errno == ENODATA) { - if (!param->obduuid && !param->quiet) - 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 { - lov_dump_user_lmm(param, dname, ""); } /* Handle the contents of the directory */ @@ -448,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; @@ -515,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 = get_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); @@ -526,15 +693,15 @@ static int process_path(char *path, struct find_param *param) return rc; } - -int op_find(char *path, struct obd_uuid *obduuid, int recursive, - int verbose, int quiet) +int llapi_find(char *path, struct obd_uuid *obduuid, int recursive, + 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) { @@ -559,68 +726,72 @@ out: #define MAX_STRING_SIZE 128 #define DEVICES_LIST "/proc/fs/lustre/devices" -int op_check(int type_num, char **obd_type, char *dir) +int llapi_target_check(int type_num, char **obd_type, char *dir) { + char buf[MAX_STRING_SIZE]; + FILE *fp = fopen(DEVICES_LIST, "r"); int rc = 0; int i; - char buf[MAX_STRING_SIZE]; - FILE *fp = fopen(DEVICES_LIST, "r"); - if (fp == NULL) { - fprintf(stderr, "error: %s could not open file " - DEVICES_LIST " .\n", strerror(rc = errno)); + fprintf(stderr, "error: %s opening "DEVICES_LIST"\n", + strerror(rc = errno)); return rc; } while (fgets(buf, sizeof(buf), fp) != NULL) { char *obd_type_name = NULL; char *obd_name = NULL; - 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] == ' ') bufp += 1; + + while(bufp[0] == ' ') + ++bufp; + for(i = 0; i < 3; i++) { obd_type_name = strsep(&bufp, " "); } obd_name = strsep(&bufp, " "); - memset (&osfs_buffer, 0, sizeof (osfs_buffer)); + memset(&osfs_buffer, 0, sizeof (osfs_buffer)); memset(bufl, 0, sizeof(rawbuf)); datal.ioc_pbuf1 = (char *)&osfs_buffer; - datal.ioc_plen1 = sizeof (osfs_buffer); + datal.ioc_plen1 = sizeof(osfs_buffer); - for (i=0;i