1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Peter J. Braam <braam@clusterfs.com>
6 * Author: Phil Schwan <phil@clusterfs.com>
7 * Author: Andreas Dilger <adilger@clusterfs.com>
8 * Author: Robert Read <rread@clusterfs.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre 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
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <sys/ioctl.h>
35 #include <liblustre.h>
37 #include <lustre_lib.h>
38 #include <lustre_cfg.h>
39 #include <lustre/lustre_idl.h>
40 #include <lustre_dlm.h>
41 #include <obd.h> /* for struct lov_stripe_md */
43 #include <lustre/lustre_build_version.h>
54 #include <lnet/lnetctl.h>
58 static char * lcfg_devname;
60 int lcfg_set_devname(char *name)
65 /* quietly strip the unnecessary '$' */
66 if (*name == '$' || *name == '%')
69 /* We can't translate from dev # to name */
72 lcfg_devname = strdup(name);
80 char * lcfg_get_devname(void)
85 int jt_lcfg_device(int argc, char **argv)
87 return jt_obd_device(argc, argv);
90 int jt_lcfg_attach(int argc, char **argv)
92 struct lustre_cfg_bufs bufs;
93 struct lustre_cfg *lcfg;
99 lustre_cfg_bufs_reset(&bufs, NULL);
101 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
102 lustre_cfg_bufs_set_string(&bufs, 0, argv[2]);
103 lustre_cfg_bufs_set_string(&bufs, 2, argv[3]);
105 lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
106 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
107 lustre_cfg_free(lcfg);
109 fprintf(stderr, "error: %s: LCFG_ATTACH %s\n",
110 jt_cmdname(argv[0]), strerror(rc = errno));
111 } else if (argc == 3) {
114 lcfg_set_devname(argv[2]);
115 if (strlen(argv[2]) > 128) {
116 printf("Name too long to set environment\n");
119 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
120 rc = setenv(name, argv[1], 1);
122 printf("error setting env variable %s\n", name);
125 lcfg_set_devname(argv[2]);
131 int jt_lcfg_setup(int argc, char **argv)
133 struct lustre_cfg_bufs bufs;
134 struct lustre_cfg *lcfg;
138 if (lcfg_devname == NULL) {
139 fprintf(stderr, "%s: please use 'device name' to set the "
140 "device name for config commands.\n",
141 jt_cmdname(argv[0]));
145 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
150 for (i = 1; i < argc; i++) {
151 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
154 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
155 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
156 lustre_cfg_free(lcfg);
158 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
159 strerror(rc = errno));
164 int jt_obd_detach(int argc, char **argv)
166 struct lustre_cfg_bufs bufs;
167 struct lustre_cfg *lcfg;
170 if (lcfg_devname == NULL) {
171 fprintf(stderr, "%s: please use 'device name' to set the "
172 "device name for config commands.\n",
173 jt_cmdname(argv[0]));
177 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
182 lcfg = lustre_cfg_new(LCFG_DETACH, &bufs);
183 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
184 lustre_cfg_free(lcfg);
186 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
187 strerror(rc = errno));
192 int jt_obd_cleanup(int argc, char **argv)
194 struct lustre_cfg_bufs bufs;
195 struct lustre_cfg *lcfg;
198 char flags[3] = { 0 };
202 if (lcfg_devname == NULL) {
203 fprintf(stderr, "%s: please use 'device name' to set the "
204 "device name for config commands.\n",
205 jt_cmdname(argv[0]));
209 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
211 if (argc < 1 || argc > 3)
214 /* we are protected from overflowing our buffer by the argc
217 for (n = 1; n < argc; n++) {
218 if (strcmp(argv[n], "force") == 0) {
219 flags[flag_cnt++] = force;
220 } else if (strcmp(argv[n], "failover") == 0) {
221 flags[flag_cnt++] = failover;
223 fprintf(stderr, "unknown option: %s", argv[n]);
229 lustre_cfg_bufs_set_string(&bufs, 1, flags);
232 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
233 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
234 lustre_cfg_free(lcfg);
236 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
237 strerror(rc = errno));
243 int do_add_uuid(char * func, char *uuid, lnet_nid_t nid)
246 struct lustre_cfg_bufs bufs;
247 struct lustre_cfg *lcfg;
249 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
251 lustre_cfg_bufs_set_string(&bufs, 1, uuid);
253 lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
254 lcfg->lcfg_nid = nid;
255 /* Poison NAL -- pre 1.4.6 will LASSERT on 0 NAL, this way it
256 doesn't work without crashing (bz 10130) */
257 lcfg->lcfg_nal = 0x5a;
260 fprintf(stderr, "adding\tnid: %d\tuuid: %s\n",
261 lcfg->lcfg_nid, uuid);
263 rc = lcfg_ioctl(func, OBD_DEV_ID, lcfg);
264 lustre_cfg_free(lcfg);
266 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
271 printf ("Added uuid %s: %s\n", uuid, libcfs_nid2str(nid));
275 int jt_lcfg_add_uuid(int argc, char **argv)
283 nid = libcfs_str2nid(argv[2]);
284 if (nid == LNET_NID_ANY) {
285 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
289 return do_add_uuid(argv[0], argv[1], nid);
292 int obd_add_uuid(char *uuid, lnet_nid_t nid)
294 return do_add_uuid("obd_add_uuid", uuid, nid);
297 int jt_lcfg_del_uuid(int argc, char **argv)
300 struct lustre_cfg_bufs bufs;
301 struct lustre_cfg *lcfg;
304 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
308 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
309 if (strcmp (argv[1], "_all_"))
310 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
312 lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs);
313 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
314 lustre_cfg_free(lcfg);
316 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
326 int jt_lcfg_del_mount_option(int argc, char **argv)
329 struct lustre_cfg_bufs bufs;
330 struct lustre_cfg *lcfg;
335 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
338 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
340 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
341 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
342 lustre_cfg_free(lcfg);
344 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
345 strerror(rc = errno));
350 int jt_lcfg_set_timeout(int argc, char **argv)
353 struct lustre_cfg_bufs bufs;
354 struct lustre_cfg *lcfg;
356 fprintf(stderr, "%s has been deprecated. Use conf_param instead.\n"
357 "e.g. conf_param lustre-MDT0000 obd_timeout=50\n",
358 jt_cmdname(argv[0]));
365 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
366 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
367 lcfg->lcfg_num = atoi(argv[1]);
369 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
370 //rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
372 lustre_cfg_free(lcfg);
374 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
375 strerror(rc = errno));
382 int jt_lcfg_add_conn(int argc, char **argv)
384 struct lustre_cfg_bufs bufs;
385 struct lustre_cfg *lcfg;
396 if (lcfg_devname == NULL) {
397 fprintf(stderr, "%s: please use 'device name' to set the "
398 "device name for config commands.\n",
399 jt_cmdname(argv[0]));
403 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
405 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
407 lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs);
408 lcfg->lcfg_num = priority;
410 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
411 lustre_cfg_free (lcfg);
413 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
414 strerror(rc = errno));
420 int jt_lcfg_del_conn(int argc, char **argv)
422 struct lustre_cfg_bufs bufs;
423 struct lustre_cfg *lcfg;
429 if (lcfg_devname == NULL) {
430 fprintf(stderr, "%s: please use 'device name' to set the "
431 "device name for config commands.\n",
432 jt_cmdname(argv[0]));
436 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
438 /* connection uuid */
439 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
441 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
443 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
444 lustre_cfg_free(lcfg);
446 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
447 strerror(rc = errno));
453 /* Param set locally, directly on target */
454 int jt_lcfg_param(int argc, char **argv)
457 struct lustre_cfg_bufs bufs;
458 struct lustre_cfg *lcfg;
460 if (argc >= LUSTRE_CFG_MAX_BUFCOUNT)
463 lustre_cfg_bufs_reset(&bufs, NULL);
465 for (i = 1; i < argc; i++) {
466 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
469 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
471 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
472 lustre_cfg_free(lcfg);
474 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
475 strerror(rc = errno));
480 /* Param set in config log on MGS */
481 /* conf_param key1=value1 [key2=value2...] */
482 int jt_lcfg_mgsparam(int argc, char **argv)
485 struct lustre_cfg_bufs bufs;
486 struct lustre_cfg *lcfg;
488 if ((argc >= LUSTRE_CFG_MAX_BUFCOUNT) || (argc <= 1))
491 lustre_cfg_bufs_reset(&bufs, NULL);
492 for (i = 1; i < argc; i++) {
493 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
496 /* We could put other opcodes here. */
497 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
499 rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
500 lustre_cfg_free(lcfg);
502 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
503 strerror(rc = errno));
509 /* Display the path in the same format as sysctl
510 * For eg. obdfilter.lustre-OST0000.stats */
511 static char *display_name(char *filename)
515 filename += strlen("/proc/");
516 if (strncmp(filename, "fs/", strlen("fs/")) == 0)
517 filename += strlen("fs/");
519 filename += strlen("sys/");
521 if (strncmp(filename, "lustre/", strlen("lustre/")) == 0)
522 filename += strlen("lustre/");
524 /* replace '/' with '.' to match conf_param and sysctl */
526 while ((tmp = strchr(tmp, '/')) != NULL)
532 /* Find a character in a length limited string */
533 static char *strnchr(const char *p, char c, size_t n)
546 int jt_lcfg_getparam(int argc, char **argv)
549 int rc = 0, i, show_path = 0;
550 char buf[CFS_PAGE_SIZE] = {'\0'}, pattern[PATH_MAX];
554 if (argc == 3 && strcmp(argv[1], "-n") == 0) {
556 } else if (argc == 2) {
563 /* If the input is in form Eg. obdfilter.*.stats */
564 if (strchr(path, '.')) {
566 while (*tmp != '\0') {
573 /* If the entire path is specified as input */
574 fp = open(path, O_RDONLY);
576 snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
579 strcpy(pattern, path);
583 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
585 fprintf(stderr, "error : glob %s: %s \n", pattern,strerror(rc));
589 for (i = 0; i < glob_info.gl_pathc; i++) {
590 char *valuename = NULL;
593 filename = strdup(glob_info.gl_pathv[i]);
594 valuename = display_name(filename);
597 /* Write the contents of file to stdout */
598 fp = open(glob_info.gl_pathv[i], O_RDONLY);
600 fprintf(stderr, "error: %s: opening('%s') failed: %s\n",
601 jt_cmdname(argv[0]), glob_info.gl_pathv[i],
607 rc = read(fp, buf, sizeof(buf));
611 fprintf(stderr, "error: %s: read('%s') "
612 "failed: %s\n", jt_cmdname(argv[0]),
613 glob_info.gl_pathv[i], strerror(errno));
616 /* Print the output in the format path=value if the
617 * value contains no new line character or cab be
618 * occupied in a line, else print value on new line */
619 if (valuename && show_path) {
620 int longbuf = strnchr(buf, rc - 1, '\n') != NULL
622 printf("%s=%s", valuename, longbuf ? "\n" : buf);
628 rc = write(fileno(stdout), buf, rc);
630 fprintf(stderr, "error: %s: write to stdout "
631 "failed: %s\n", jt_cmdname(argv[0]),
636 memset(buf, 0, sizeof(buf));
640 globfree(&glob_info);
645 int jt_lcfg_setparam(int argc, char **argv)
648 int fp, show_path = 0;
649 char pattern[PATH_MAX];
650 char *path, *value, *tmp;
654 if (argc == 4 && (strcmp(argv[1], "-n") == 0)) {
655 /* Format: lctl set_param -n param value */
658 } else if (argc == 3) {
659 if (strcmp(argv[1], "-n") != 0) {
660 /* Format: lctl set_param param value */
663 } else if ((value = strchr(argv[2], '=')) != NULL) {
664 /* Format: lctl set_param -n param=value */
669 fprintf(stderr, "error: %s Incorrect arguments."
671 jt_cmdname(argv[0]));
674 } else if (argc == 2 && ((value = strchr(argv[1], '=')) != NULL)) {
675 /* Format: lctl set_param param=value */
680 fprintf(stderr, "error: %s Incorrect arguments. See Usage\n",
681 jt_cmdname(argv[0]));
685 /* If the input is in form Eg. obdfilter.*.stats */
686 if (strchr(path, '.')) {
688 while (*tmp != '\0') {
695 fp = open(path, O_RDONLY);
697 snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
700 strcpy(pattern, path);
704 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
706 fprintf(stderr, "error : glob %s: %s \n", pattern,strerror(rc));
709 for (i = 0; i < glob_info.gl_pathc; i++) {
711 char *valuename, *filename;
712 filename = strdup(glob_info.gl_pathv[i]);
713 valuename = display_name(filename);
714 printf("%s=%s\n", valuename, value);
716 /* Write the new value to the file */
717 fp = open(glob_info.gl_pathv[i], O_WRONLY);
719 rc = write(fp, value, strlen(value));
722 "error writing to file %s\n",
723 glob_info.gl_pathv[i]);
728 fprintf(stderr, "error: %s: %s opening %s\n",
729 jt_cmdname(argv[0]), strerror(rc = errno),
730 glob_info.gl_pathv[i]);
734 globfree(&glob_info);