X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi_util.c;h=59f7e98bdb430d5048c41544984a59beb22bad72;hb=9d5d2714c074a51c9a348b917f3cf32c5005b3b8;hp=efd9d3c916ae2f88bff7c7ae5e7ef5fd5c6adca9;hpb=432dc1efa71e56e364b07c9cd0d0ba1feffadce1;p=fs%2Flustre-release.git diff --git a/lustre/utils/liblustreapi_util.c b/lustre/utils/liblustreapi_util.c index efd9d3c..59f7e98 100644 --- a/lustre/utils/liblustreapi_util.c +++ b/lustre/utils/liblustreapi_util.c @@ -5,6 +5,8 @@ * * (C) Copyright (c) 2015, Cray Inc, all rights reserved. * + * Copyright (c) 2016, 2017, Intel Corporation. + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * LGPL version 2.1 or (at your discretion) any later version. @@ -26,26 +28,38 @@ * Author: Frank Zago */ +#include +#include +#include +#include +#include #include +#include +#include #include -#include #include #include #include -#include #include +#include +#include /* only until LUSTRE_VERSION_CODE is gone */ +#include "lustreapi_internal.h" /* * Indicate whether the liblustreapi_init() constructor below has run or not. * - * This can be used by external programs to ensure if the initialization + * This can be used by external programs to ensure that the initialization * mechanism has actually worked. */ bool liblustreapi_initialized; - -/* - * Initializes the library +/** + * Initialize the library once at startup. + * + * Initializes the random number generator (random()). Get + * data from different places in case one of them fails. This + * is enough to get reasonably random numbers, but is not + * strong enough to be used for cryptography. */ static __attribute__ ((constructor)) void liblustreapi_init(void) { @@ -53,10 +67,6 @@ static __attribute__ ((constructor)) void liblustreapi_init(void) struct timeval tv; int fd; - /* Initializes the random number generator (random()). Get - * data from different places in case one of them fails. This - * is enough to get reasonably random numbers, but is not - * strong enough to be used for cryptography. */ seed = syscall(SYS_gettid); if (gettimeofday(&tv, NULL) == 0) { @@ -77,3 +87,227 @@ static __attribute__ ((constructor)) void liblustreapi_init(void) srandom(seed); liblustreapi_initialized = true; } + +/** + * Return the release version for the Lustre modules, e.g. 2.6.92. + * + * The "version" file in /proc currently returns only the line: + * lustre: 2.8.52 + * + * but in the past it also returned more lines that should be ignored: + * kernel: patchless_client + * build: v2_6_92_0-gadb3ee4-2.6.32-431.29.2.el6_lustre.g36cd22b.x86_64 + * + * \param version[in,out] buffer to store build version string + * \param version_size[in] size of \a version + * + * \retval 0 on success + * \retval -1 on failure, errno set + */ +int llapi_get_version_string(char *version, unsigned int version_size) +{ + char buffer[4096]; + char *ptr; + int rc; + + if (version == NULL || version_size == 0) { + errno = EINVAL; + return -1; + } + + rc = get_lustre_param_value(NULL, NULL, FILTER_BY_NONE, buffer, + "version", sizeof(buffer)); + if (rc < 0) { + errno = -rc; + return -1; + } + + ptr = strstr(buffer, "lustre:"); + if (ptr) { + ptr += strlen("lustre:"); + while (*ptr == ' ' || *ptr == '\t') + ptr++; + } else { + ptr = buffer; + } + llapi_chomp_string(ptr); + + if (ptr[0] == '\0') { + errno = ENODATA; + return -1; + } + + if (snprintf(version, version_size, "%s", ptr) >= version_size) { + errno = EOVERFLOW; + return -1; + } + return 0; +} + +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 4, 53, 0) +/** + * Return the build version of the Lustre code. + * + * The **version argument is pointless, so llapi_get_version_string() is + * better to use in the future, but give users a few versions to fix * it. + * + * \param buffer[in] temporary buffer to hold version string + * \param buffer_size[in] length of the \a buffer + * \param version[out] pointer to the start of build version string + * + * \retval 0 on success + * \retval -ve errno on failure + */ +int llapi_get_version(char *buffer, int buffer_size, char **version) +{ + int rc; +#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 8, 53, 0) + static bool printed; + if (!printed) { + fprintf(stderr, + "%s deprecated, use llapi_get_version_string()\n", + __func__); + printed = true; + } +#endif + + rc = llapi_get_version_string(buffer, buffer_size); + /* keep old return style for this legacy function */ + if (rc == -1) + rc = -errno; + else + *version = buffer; + + 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; +}