X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=inline;f=lustre%2Futils%2Fliblustreapi_util.c;h=c19674ed9c4705974065dbdf247ecf85929dca09;hb=94b0568059ec9825ee96de89dab8f156703e222c;hp=f0f199108297dad0d1ce930f5911d857947b6816;hpb=971b0393a6d0e45051c9875efa2c7179cbf7d4c5;p=fs%2Flustre-release.git diff --git a/lustre/utils/liblustreapi_util.c b/lustre/utils/liblustreapi_util.c index f0f1991..c19674e 100644 --- a/lustre/utils/liblustreapi_util.c +++ b/lustre/utils/liblustreapi_util.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -180,3 +181,209 @@ int llapi_get_version(char *buffer, int buffer_size, char **version) return rc; } #endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 4, 53, 0) */ + +/* + * fsname must be specified + * if poolname is NULL, search tgtname in fsname + * if poolname is not NULL: + * if poolname not found returns errno < 0 + * if tgtname is NULL, returns 1 if pool is not empty and 0 if pool empty + * if tgtname is not NULL, returns 1 if target is in pool and 0 if not + */ +int llapi_search_tgt(const char *fsname, const char *poolname, + const char *tgtname, bool is_mdt) +{ + char buffer[PATH_MAX]; + size_t len = 0; + glob_t param; + FILE *fd; + int rc; + + if (fsname && fsname[0] == '\0') + fsname = NULL; + if (!fsname) { + rc = -EINVAL; + goto out; + } + + if (poolname && poolname[0] == '\0') + poolname = NULL; + if (tgtname) { + if (tgtname[0] == '\0') + tgtname = NULL; + else + len = strlen(tgtname); + } + + /* You need one or the other to have something in it */ + if (!poolname && !tgtname) { + rc = -EINVAL; + goto out; + } + + if (poolname) { + rc = poolpath(¶m, fsname, NULL); + if (!rc) { + snprintf(buffer, sizeof(buffer) - 1, "%s/%s", + param.gl_pathv[0], poolname); + buffer[sizeof(buffer) - 1] = '\0'; + } + } else { + rc = get_lustre_param_path(is_mdt ? "lmv" : "lov", fsname, + FILTER_BY_FS_NAME, + "target_obd", ¶m); + if (!rc) { + strncpy(buffer, param.gl_pathv[0], + sizeof(buffer) - 1); + buffer[sizeof(buffer) - 1] = '\0'; + } + } + cfs_free_param_data(¶m); + if (rc) + goto out; + + fd = fopen(buffer, "r"); + if (!fd) { + rc = -errno; + goto out; + } + + while (fgets(buffer, sizeof(buffer), fd)) { + if (!poolname) { + char *ptr; + /* Search for an tgtname in the list of all targets + * Line format is IDX: fsname-OST/MDTxxxx_UUID STATUS */ + ptr = strchr(buffer, ' '); + if (ptr && strncmp(ptr + 1, tgtname, len) == 0) { + rc = 1; + goto out_close; + } + } else { + /* Search for an tgtname in a pool, + * (or an existing non-empty pool if no tgtname) */ + if (!tgtname || strncmp(buffer, tgtname, len) == 0) { + rc = 1; + goto out_close; + } + } + } +out_close: + fclose(fd); +out: + if (rc < 0) + errno = -rc; + return rc; +} + +int llapi_search_mdt(const char *fsname, const char *poolname, + const char *mdtname) +{ + return llapi_search_tgt(fsname, poolname, mdtname, true); +} + +int llapi_search_ost(const char *fsname, const char *poolname, + const char *ostname) +{ + return llapi_search_tgt(fsname, poolname, ostname, false); +} + +int llapi_rmfid(const char *path, struct fid_array *fa) +{ + char rootpath[PATH_MAX]; + int fd, rc; + +retry_open: + fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW); + if (fd < 0) { + if (errno == ENOENT && path != rootpath) { + rc = llapi_search_rootpath(rootpath, path); + if (!rc) { + path = rootpath; + goto retry_open; + } + } else { + return -errno; + } + } + + rc = ioctl(fd, LL_IOC_RMFID, fa); + close(fd); + + return rc ? -errno : 0; +} + +int llapi_get_fsname_instance(const char *path, char *fsname, size_t fsname_len, + char *instance, size_t instance_len) +{ + struct obd_uuid uuid_buf; + char *uuid = uuid_buf.uuid; + char *ptr; + int rc; + + memset(&uuid_buf, 0, sizeof(uuid_buf)); + rc = llapi_file_get_lov_uuid(path, &uuid_buf); + if (rc) + return rc; + + /* + * We want to turn fs-foo-clilov-ffff88002738bc00 into 'fs-foo' and + * 'ffff88002738bc00' in a portable way that doesn't depend on what is + * after "-clilov-" as it may change to a UUID string in the future. + * Unfortunately, the "fsname" part may contain a dash, so we can't + * just skip to the first dash, and if the "instance" is a UUID in the + * future we can't necessarily go to the last dash either. + */ + ptr = strstr(uuid, "-clilov-"); + if (!ptr || (!fsname && !instance)) { + rc = -EINVAL; + goto out; + } + + *ptr = '\0'; + ptr += strlen("-clilov-"); + if (instance) { + snprintf(instance, instance_len, "%s", ptr); + if (strlen(ptr) >= instance_len) + rc = -ENAMETOOLONG; + } + + if (fsname) { + snprintf(fsname, fsname_len, "%s", uuid); + if (strlen(uuid) >= fsname_len) + rc = -ENAMETOOLONG; + } + +out: + errno = -rc; + return rc; +} + +int llapi_getname(const char *path, char *name, size_t namelen) +{ + char fsname[16]; + char instance[40]; + int rc; + + rc = llapi_get_fsname_instance(path, fsname, sizeof(fsname), + instance, sizeof(instance)); + if (rc) + return rc; + + snprintf(name, namelen, "%s-%s", fsname, instance); + if (strlen(fsname) + 1 + strlen(instance) >= namelen) { + rc = -ENAMETOOLONG; + errno = -rc; + } + + return rc; +} + +int llapi_get_instance(const char *path, char *instance, size_t instance_len) +{ + return llapi_get_fsname_instance(path, NULL, 0, instance, instance_len); +} + +int llapi_get_fsname(const char *path, char *fsname, size_t fsname_len) +{ + return llapi_get_fsname_instance(path, fsname, fsname_len, NULL, 0); +}