X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flustre_cfg.c;h=93adfb3075088cb21166122726f0ffcc587619be;hb=fd4cee4cc545679d2a00c2a20939564e36700631;hp=3d8806584764e563435e69d175a088753424e5f5;hpb=04248c9069d87bea8e3b7b400c541c97ff292ac2;p=fs%2Flustre-release.git diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index 3d88065..93adfb3 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011, 2012, Whamcloud, Inc. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -77,13 +77,26 @@ static char * lcfg_devname; int lcfg_set_devname(char *name) { + char *ptr; + int digit = 1; + if (name) { if (lcfg_devname) free(lcfg_devname); /* quietly strip the unnecessary '$' */ if (*name == '$' || *name == '%') name++; - if (isdigit(*name)) { + + ptr = name; + while (*ptr != '\0') { + if (!isdigit(*ptr)) { + digit = 0; + break; + } + ptr++; + } + + if (digit) { /* We can't translate from dev # to name */ lcfg_devname = NULL; } else { @@ -491,19 +504,48 @@ int jt_lcfg_param(int argc, char **argv) } /* Param set in config log on MGS */ -/* conf_param key1=value1 [key2=value2...] */ +/* conf_param key=value */ +/* Note we can actually send mgc conf_params from clients, but currently + * that's only done for default file striping (see ll_send_mgc_param), + * and not here. */ +/* After removal of a parameter (-d) Lustre will use the default + * AT NEXT REBOOT, not immediately. */ int jt_lcfg_mgsparam(int argc, char **argv) { - int i, rc; + int rc; + int del = 0; struct lustre_cfg_bufs bufs; struct lustre_cfg *lcfg; + char *buf = NULL; - if ((argc >= LUSTRE_CFG_MAX_BUFCOUNT) || (argc <= 1)) + /* mgs_setparam processes only lctl buf #1 */ + if ((argc > 3) || (argc <= 1)) return CMD_HELP; + while ((rc = getopt(argc, argv, "d")) != -1) { + switch (rc) { + case 'd': + del = 1; + break; + default: + return CMD_HELP; + } + } + lustre_cfg_bufs_reset(&bufs, NULL); - for (i = 1; i < argc; i++) { - lustre_cfg_bufs_set_string(&bufs, i, argv[i]); + if (del) { + char *ptr; + + /* for delete, make it "=\0" */ + buf = malloc(strlen(argv[optind]) + 2); + /* put an '=' on the end in case it doesn't have one */ + sprintf(buf, "%s=", argv[optind]); + /* then truncate after the first '=' */ + ptr = strchr(buf, '='); + *(++ptr) = '\0'; + lustre_cfg_bufs_set_string(&bufs, 1, buf); + } else { + lustre_cfg_bufs_set_string(&bufs, 1, argv[optind]); } /* We could put other opcodes here. */ @@ -511,6 +553,8 @@ int jt_lcfg_mgsparam(int argc, char **argv) rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg); lustre_cfg_free(lcfg); + if (buf) + free(buf); if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -539,6 +583,8 @@ static char *display_name(char *filename, int show_type) if (strncmp(filename, "lustre/", strlen("lustre/")) == 0) filename += strlen("lustre/"); + else if (strncmp(filename, "lnet/", strlen("lnet/")) == 0) + filename += strlen("lnet/"); /* replace '/' with '.' to match conf_param and sysctl */ tmp = filename; @@ -613,10 +659,35 @@ static void clean_path(char *path) } } +/* Supporting file paths creates perilous behavoir: LU-888. + * Path support is deprecated. + * If a path is supplied it must begin with /proc. */ +static void lprocfs_param_pattern(const char *cmd, const char *path, char *buf, + size_t buf_size) +{ + /* test path to see if it begins with '/proc/' */ + if (strncmp(path, "/proc/", strlen("/proc/")) == 0) { + static int warned; + if (!warned) { + fprintf(stderr, "%s: specifying parameters via " + "full paths is deprecated.\n", cmd); +#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2,6,50,0) +#warning "remove deprecated full path tunable access" +#endif + warned = 1; + } + snprintf(buf, buf_size, "%s", path); + } else { + snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s", + path); + } +} + struct param_opts { - int only_path; - int show_path; - int show_type; + int only_path:1; + int show_path:1; + int show_type:1; + int recursive:1; }; static int listparam_cmdline(int argc, char **argv, struct param_opts *popt) @@ -626,12 +697,16 @@ static int listparam_cmdline(int argc, char **argv, struct param_opts *popt) popt->show_path = 1; popt->only_path = 1; popt->show_type = 0; + popt->recursive = 0; - while ((ch = getopt(argc, argv, "F")) != -1) { + while ((ch = getopt(argc, argv, "FR")) != -1) { switch (ch) { case 'F': popt->show_type = 1; break; + case 'R': + popt->recursive = 1; + break; default: return -1; } @@ -647,7 +722,8 @@ static int listparam_display(struct param_opts *popt, char *pattern) glob_t glob_info; char filename[PATH_MAX + 1]; /* extra 1 byte for file type */ - rc = glob(pattern, GLOB_BRACE, NULL, &glob_info); + rc = glob(pattern, GLOB_BRACE | (popt->recursive ? GLOB_MARK : 0), + NULL, &glob_info); if (rc) { fprintf(stderr, "error: list_param: %s: %s\n", pattern, globerrstr(rc)); @@ -656,11 +732,25 @@ static int listparam_display(struct param_opts *popt, char *pattern) for (i = 0; i < glob_info.gl_pathc; i++) { char *valuename = NULL; + int last; + + /* Trailing '/' will indicate recursion into directory */ + last = strlen(glob_info.gl_pathv[i]) - 1; + /* Remove trailing '/' or it will be converted to '.' */ + if (last > 0 && glob_info.gl_pathv[i][last] == '/') + glob_info.gl_pathv[i][last] = '\0'; + else + last = 0; strcpy(filename, glob_info.gl_pathv[i]); valuename = display_name(filename, popt->show_type); if (valuename) printf("%s\n", valuename); + if (last) { + strcpy(filename, glob_info.gl_pathv[i]); + strcat(filename, "/*"); + listparam_display(popt, filename); + } } globfree(&glob_info); @@ -669,30 +759,25 @@ static int listparam_display(struct param_opts *popt, char *pattern) int jt_lcfg_listparam(int argc, char **argv) { - int fp; int rc = 0, i; struct param_opts popt; char pattern[PATH_MAX]; char *path; rc = listparam_cmdline(argc, argv, &popt); - if (rc < 0 || rc >= argc) + if (rc == argc && popt.recursive) { + rc--; /* we know at least "-R" is a parameter */ + argv[rc] = "*"; + } else if (rc < 0 || rc >= argc) { return CMD_HELP; + } for (i = rc; i < argc; i++) { path = argv[i]; clean_path(path); - /* If the entire path is specified as input */ - fp = open(path, O_RDONLY); - if (fp < 0) { - snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s", - path); - } else { - strcpy(pattern, path); - close(fp); - } + lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); rc = listparam_display(&popt, pattern); if (rc < 0) @@ -709,6 +794,7 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt) popt->show_path = 1; popt->only_path = 0; popt->show_type = 0; + popt->recursive = 0; while ((ch = getopt(argc, argv, "nNF")) != -1) { switch (ch) { @@ -805,7 +891,6 @@ static int getparam_display(struct param_opts *popt, char *pattern) int jt_lcfg_getparam(int argc, char **argv) { - int fp; int rc = 0, i; struct param_opts popt; char pattern[PATH_MAX]; @@ -820,15 +905,7 @@ int jt_lcfg_getparam(int argc, char **argv) clean_path(path); - /* If the entire path is specified as input */ - fp = open(path, O_RDONLY); - if (fp < 0) { - snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s", - path); - } else { - strcpy(pattern, path); - close(fp); - } + lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); if (popt.only_path) rc = listparam_display(&popt, pattern); @@ -848,6 +925,7 @@ static int setparam_cmdline(int argc, char **argv, struct param_opts *popt) popt->show_path = 1; popt->only_path = 0; popt->show_type = 0; + popt->recursive = 0; while ((ch = getopt(argc, argv, "n")) != -1) { switch (ch) { @@ -907,7 +985,6 @@ static int setparam_display(struct param_opts *popt, char *pattern, char *value) int jt_lcfg_setparam(int argc, char **argv) { - int fp; int rc = 0, i; struct param_opts popt; char pattern[PATH_MAX]; @@ -935,15 +1012,7 @@ int jt_lcfg_setparam(int argc, char **argv) clean_path(path); - /* If the entire path is specified as input */ - fp = open(path, O_RDONLY); - if (fp < 0) { - snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s", - path); - } else { - strcpy(pattern, path); - close(fp); - } + lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); rc = setparam_display(&popt, pattern, value); path = NULL; @@ -954,3 +1023,4 @@ int jt_lcfg_setparam(int argc, char **argv) return 0; } +