4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * (C) Copyright (c) 2015, Cray Inc, all rights reserved.
8 * Copyright (c) 2016, 2017, Intel Corporation.
10 * All rights reserved. This program and the accompanying materials
11 * are made available under the terms of the GNU Lesser General Public License
12 * LGPL version 2.1 or (at your discretion) any later version.
13 * LGPL version 2.1 accompanies this distribution, and is available at
14 * http://www.gnu.org/licenses/lgpl-2.1.html
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
24 * lustre/utils/liblustreapi_util.c
26 * Misc LGPL-licenced utility functions for liblustreapi.
28 * Author: Frank Zago <fzago@cray.com>
40 #include <sys/types.h>
42 #include <sys/syscall.h>
43 #include <lustre/lustreapi.h>
44 #include <linux/lustre/lustre_ver.h> /* only until LUSTRE_VERSION_CODE is gone */
45 #include "lustreapi_internal.h"
48 * Indicate whether the liblustreapi_init() constructor below has run or not.
50 * This can be used by external programs to ensure that the initialization
51 * mechanism has actually worked.
53 bool liblustreapi_initialized;
56 * Initialize the library once at startup.
58 * Initializes the random number generator (random()). Get
59 * data from different places in case one of them fails. This
60 * is enough to get reasonably random numbers, but is not
61 * strong enough to be used for cryptography.
63 static __attribute__ ((constructor)) void liblustreapi_init(void)
69 seed = syscall(SYS_gettid);
71 if (gettimeofday(&tv, NULL) == 0) {
76 fd = open("/dev/urandom", O_RDONLY | O_NOFOLLOW);
81 ret = read(fd, &rnumber, sizeof(rnumber));
82 seed ^= rnumber ^ ret;
87 liblustreapi_initialized = true;
91 * Return the release version for the Lustre modules, e.g. 2.6.92.
93 * The "version" file in /proc currently returns only the line:
96 * but in the past it also returned more lines that should be ignored:
97 * kernel: patchless_client
98 * build: v2_6_92_0-gadb3ee4-2.6.32-431.29.2.el6_lustre.g36cd22b.x86_64
100 * \param version[in,out] buffer to store build version string
101 * \param version_size[in] size of \a version
103 * \retval 0 on success
104 * \retval -1 on failure, errno set
106 int llapi_get_version_string(char *version, unsigned int version_size)
112 if (version == NULL || version_size == 0) {
117 rc = get_lustre_param_value(NULL, NULL, FILTER_BY_NONE, buffer,
118 "version", sizeof(buffer));
124 ptr = strstr(buffer, "lustre:");
126 ptr += strlen("lustre:");
127 while (*ptr == ' ' || *ptr == '\t')
132 llapi_chomp_string(ptr);
134 if (ptr[0] == '\0') {
139 if (snprintf(version, version_size, "%s", ptr) >= version_size) {
146 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 4, 53, 0)
148 * Return the build version of the Lustre code.
150 * The **version argument is pointless, so llapi_get_version_string() is
151 * better to use in the future, but give users a few versions to fix * it.
153 * \param buffer[in] temporary buffer to hold version string
154 * \param buffer_size[in] length of the \a buffer
155 * \param version[out] pointer to the start of build version string
157 * \retval 0 on success
158 * \retval -ve errno on failure
160 int llapi_get_version(char *buffer, int buffer_size, char **version)
163 #if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 8, 53, 0)
167 "%s deprecated, use llapi_get_version_string()\n",
173 rc = llapi_get_version_string(buffer, buffer_size);
174 /* keep old return style for this legacy function */
182 #endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 4, 53, 0) */
185 * fsname must be specified
186 * if poolname is NULL, search tgtname in fsname
187 * if poolname is not NULL:
188 * if poolname not found returns errno < 0
189 * if tgtname is NULL, returns 1 if pool is not empty and 0 if pool empty
190 * if tgtname is not NULL, returns 1 if target is in pool and 0 if not
192 int llapi_search_tgt(const char *fsname, const char *poolname,
193 const char *tgtname, bool is_mdt)
195 char buffer[PATH_MAX];
201 if (fsname && fsname[0] == '\0')
208 if (poolname && poolname[0] == '\0')
211 if (tgtname[0] == '\0')
214 len = strlen(tgtname);
217 /* You need one or the other to have something in it */
218 if (!poolname && !tgtname) {
224 rc = poolpath(¶m, fsname, NULL);
226 snprintf(buffer, sizeof(buffer) - 1, "%s/%s",
227 param.gl_pathv[0], poolname);
228 buffer[sizeof(buffer) - 1] = '\0';
231 rc = get_lustre_param_path(is_mdt ? "lmv" : "lov", fsname,
233 "target_obd", ¶m);
235 strncpy(buffer, param.gl_pathv[0],
237 buffer[sizeof(buffer) - 1] = '\0';
240 cfs_free_param_data(¶m);
244 fd = fopen(buffer, "r");
250 while (fgets(buffer, sizeof(buffer), fd)) {
253 /* Search for an tgtname in the list of all targets
254 * Line format is IDX: fsname-OST/MDTxxxx_UUID STATUS */
255 ptr = strchr(buffer, ' ');
256 if (ptr && strncmp(ptr + 1, tgtname, len) == 0) {
261 /* Search for an tgtname in a pool,
262 * (or an existing non-empty pool if no tgtname) */
263 if (!tgtname || strncmp(buffer, tgtname, len) == 0) {
277 int llapi_search_mdt(const char *fsname, const char *poolname,
280 return llapi_search_tgt(fsname, poolname, mdtname, true);
283 int llapi_search_ost(const char *fsname, const char *poolname,
286 return llapi_search_tgt(fsname, poolname, ostname, false);