Whamcloud - gitweb
LU-5030 util: migrate lctl params functions to use cfs_get_paths()
[fs/lustre-release.git] / lustre / utils / liblustreapi_param.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the GNU Lesser General Public License
8  * (LGPL) version 2.1 or (at your discretion) any later version.
9  * (LGPL) version 2.1 accompanies this distribution, and is available at
10  * http://www.gnu.org/licenses/lgpl-2.1.html
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * LGPL HEADER END
18  */
19 /*
20  * lustre/utils/liblustreapi_param.c
21  *
22  * This code handles user interaction with the configuration interface
23  * to the Lustre file system to fine tune it.
24  */
25 #include <errno.h>
26 #include <stdint.h>
27
28 #include <libcfs/util/param.h>
29 #include <lustre/lustre_user.h>
30 #include <lustre/lustreapi.h>
31 #include "lustreapi_internal.h"
32
33 /**
34  * return the parameter's path for a specific device type or mountpoint
35  *
36  * \param param         the results returned to the caller
37  * \param obd_type      Lustre OBD device type
38  *
39  * \param filter        filter combined with the type agrument allow the
40  * \param type          caller to limit the scope of the search for the
41  *                      parameter's path. Typical options are search by
42  *                      Lustre filesystem name or by the path to a file
43  *                      or directory in the filesystem.
44  *
45  * \param param_name    parameter name to fetch
46  *
47  * Using filter and the type argument we can limit the scope of the
48  * search to either the parameter belonging to a specific lustre filesystem
49  * (if it exists) or using a given file or directory path located on a
50  * mounted Lustre filesystem. The last case it can do is a special search
51  * based on exactly what the user passed instead of scanning file paths
52  * or specific file systems.
53  *
54  * If "obd_type" matches a Lustre device then the first matching device
55  * (as with "lctl dl", constrained by \param filter and \param type)
56  * will be used to provide the return value, otherwise the first such
57  * device found will be used.
58  *
59  * Return 0 for success, with the results stored in \param param.
60  * Return -ve value for error.
61  */
62 int
63 get_lustre_param_path(const char *obd_type, const char *filter,
64                       enum param_filter type, const char *param_name,
65                       glob_t *param)
66 {
67         char pattern[PATH_MAX];
68         int rc = 0;
69
70         if (filter == NULL || obd_type == NULL)
71                 return -EINVAL;
72
73         switch (type) {
74         case FILTER_BY_PATH:
75                 rc = llapi_search_fsname(filter, pattern);
76                 if (rc) {
77                         llapi_error(LLAPI_MSG_ERROR, rc,
78                                     "'%s' is not on a Lustre filesystem",
79                                     filter);
80                         return rc;
81                 }
82                 if (strlen(pattern) + 3 > sizeof(pattern))
83                         return -E2BIG;
84                 strncat(pattern, "-*", sizeof(pattern));
85                 break;
86         case FILTER_BY_FS_NAME:
87                 rc = snprintf(pattern, sizeof(pattern) - 1, "%s-*", filter);
88                 if (rc < 0)
89                         return rc;
90                 else if (rc >= sizeof(pattern))
91                         return -EINVAL;
92                 rc = 0;
93                 break;
94         default:
95                 if (strlen(filter) + 1 > sizeof(pattern))
96                         return -E2BIG;
97                 strncpy(pattern, filter, sizeof(pattern));
98                 break;
99         }
100
101         if (param_name != NULL) {
102                 if (cfs_get_param_paths(param, "%s/%s/%s",
103                                        obd_type, pattern, param_name) != 0)
104                         rc = -errno;
105         } else {
106                 if (cfs_get_param_paths(param, "%s/%s",
107                                        obd_type, pattern) != 0)
108                         rc = -errno;
109         }
110
111         return rc;
112 }
113
114 /**
115  * return a parameter of a single line value for a specific device type
116  * or mountpoint
117  *
118  * \param obd_type      Lustre OBD device type
119  *
120  * \param filter        filter combined with the type agruments allow the
121  * \param type          caller to limit the scope of the search for the
122  *                      parameter's path. Typical options are search by
123  *                      Lustre filesystem name or by the path to a file
124  *                      or directory in the filesystem.
125  *
126  * \param param_name    parameter name to fetch
127  * \param value         return buffer for parameter value string
128  * \param val_len       size of buffer for return value
129  *
130  * Using filter and the type argument we can limit the scope of the
131  * search to either the parameter belonging to a specific lustre filesystem
132  * (if it exists) or using a given file or directory path located on a
133  * mounted Lustre filesystem. The last case it can do is a special search
134  * based on exactly what the user passed instead of scanning file paths
135  * or specific file systems.
136  *
137  * If "obd_type" matches a Lustre device then the first matching device
138  * (as with "lctl dl", constrained by \param filter and \param type)
139  * will be used to provide the return value, otherwise the first such
140  * device found will be used.
141  *
142  * Return 0 for success, with a NUL-terminated string in \param value.
143  * Return negative errno value for error.
144  */
145 int
146 get_lustre_param_value(const char *obd_type, const char *filter,
147                        enum param_filter type, const char *param_name,
148                        char *value, size_t val_len)
149 {
150         glob_t param;
151         FILE *fp;
152         int rc;
153
154         rc = get_lustre_param_path(obd_type, filter, type, param_name, &param);
155         if (rc != 0)
156                 return -ENOENT;
157
158         fp = fopen(param.gl_pathv[0], "r");
159         if (fp == NULL) {
160                 rc = -errno;
161                 llapi_error(LLAPI_MSG_ERROR, rc, "error: opening '%s'",
162                             param.gl_pathv[0]);
163                 goto err;
164         }
165
166         if (fgets(value, val_len, fp) == NULL) {
167                 if (!feof(fp))
168                         rc = -ferror(fp);
169         }
170         fclose(fp);
171 err:
172         cfs_free_param_data(&param);
173
174         return rc;
175 }