-/* -*- 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.
/*
* Copyright (c) 2007, 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/
#include <fcntl.h>
#include <errno.h>
#include <string.h>
-#include <sys/mount.h>
-#include <linux/fs.h>
-#include <mntent.h>
-#include <getopt.h>
#include "obdctl.h"
#include <lustre_ver.h>
#include <glob.h>
exit((out != stdout) ? EINVAL : 0);
}
-static int check_mtab_entry(char *spec1, char *spec2, char *mtpt, char *type)
-{
- FILE *fp;
- struct mntent *mnt;
-
- fp = setmntent(MOUNTED, "r");
- if (fp == NULL)
- return(0);
-
- while ((mnt = getmntent(fp)) != NULL) {
- if ((strcmp(mnt->mnt_fsname, spec1) == 0 ||
- strcmp(mnt->mnt_fsname, spec2) == 0) &&
- strcmp(mnt->mnt_dir, mtpt) == 0 &&
- strcmp(mnt->mnt_type, type) == 0) {
- endmntent(fp);
- return(EEXIST);
- }
- }
- endmntent(fp);
-
- return(0);
-}
-
-static int
-update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
- int flags, int freq, int pass)
-{
- FILE *fp;
- struct mntent mnt;
- int rc = 0;
-
- mnt.mnt_fsname = spec;
- mnt.mnt_dir = mtpt;
- mnt.mnt_type = type;
- mnt.mnt_opts = opts ? opts : "";
- mnt.mnt_freq = freq;
- mnt.mnt_passno = pass;
-
- fp = setmntent(MOUNTED, "a+");
- if (fp == NULL) {
- fprintf(stderr, "%s: setmntent(%s): %s:",
- progname, MOUNTED, strerror (errno));
- rc = 16;
- } else {
- if ((addmntent(fp, &mnt)) == 1) {
- fprintf(stderr, "%s: addmntent: %s:",
- progname, strerror (errno));
- rc = 16;
- }
- endmntent(fp);
- }
-
- return rc;
-}
-
/* Get rid of symbolic hostnames for tcp, since kernel can't do lookups */
#define MAXNIDSTR 1024
static char *convert_hostnames(char *s1)
retry = 0;
} else if (val && strncmp(arg, "mgssec", 6) == 0) {
append_option(options, opt);
- } else if (strncmp(opt, "force", 5) == 0) {
+ } else if (strcmp(opt, "force") == 0) {
//XXX special check for 'force' option
++force;
printf("force: %d\n", force);
/* This is to tune the kernel for good SCSI performance.
* For that we set the value of /sys/block/{dev}/queue/max_sectors_kb
* to the value of /sys/block/{dev}/queue/max_hw_sectors_kb */
-int set_blockdev_tunables(char *source)
+int set_blockdev_tunables(char *source, int fan_out)
{
- glob_t glob_info;
+ glob_t glob_info = { 0 };
struct stat stat_buf;
char *chk_major, *chk_minor;
- char *savept, *dev;
+ char *savept = NULL, *dev;
char *ret_path;
char buf[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
char real_path[PATH_MAX] = {'\0'};
* match any entry under /sys/block/. In that case we need to
* match the major/minor number to find the entry under
* sys/block corresponding to /dev/X */
- dev = real_path + strlen(real_path);
- while (--dev > real_path && isdigit(*dev))
- *dev = 0;
- if (strncmp(real_path, "/dev/md_", 8) == 0)
- *dev = 0;
+ /* Don't chop tail digit on /dev/mapper/xxx, LU-478 */
+ if (strncmp(real_path, "/dev/mapper", 11) != 0) {
+ dev = real_path + strlen(real_path);
+ while (--dev > real_path && isdigit(*dev))
+ *dev = 0;
+
+ if (strncmp(real_path, "/dev/md_", 8) == 0)
+ *dev = 0;
+ }
rc = stat(real_path, &stat_buf);
if (rc) {
if (verbose)
fprintf(stderr, "warning: failed to read entries under "
"/sys/block\n");
+ globfree(&glob_info);
return rc;
}
if (verbose)
fprintf(stderr, "warning: opening %s: %s\n",
real_path, strerror(errno));
- return rc;
+ return 0;
}
if (atoi(buf) >= md_stripe_cache_size)
if (verbose)
fprintf(stderr, "warning: opening %s: %s\n",
real_path, strerror(errno));
- return rc;
+ /* No MAX_HW_SECTORS_KB_PATH isn't necessary an
+ * error for some device. */
+ rc = 0;
}
if (strlen(buf) - 1 > 0) {
snprintf(real_path, sizeof(real_path), "%s/%s", path,
MAX_SECTORS_KB_PATH);
rc = write_file(real_path, buf);
- if (rc && verbose)
- fprintf(stderr, "warning: writing to %s: %s\n",
- real_path, strerror(errno));
+ if (rc) {
+ if (verbose)
+ fprintf(stderr, "warning: writing to %s: %s\n",
+ real_path, strerror(errno));
+ /* No MAX_SECTORS_KB_PATH isn't necessary an
+ * error for some device. */
+ rc = 0;
+ }
}
+
+ if (fan_out) {
+ char *slave = NULL;
+ glob_info.gl_pathc = 0;
+ glob_info.gl_offs = 0;
+ /* if device is multipath device, tune its slave devices */
+ snprintf(real_path, sizeof(real_path), "%s/slaves/*", path);
+ rc = glob(real_path, GLOB_NOSORT, NULL, &glob_info);
+
+ for (i = 0; rc == 0 && i < glob_info.gl_pathc; i++){
+ slave = basename(glob_info.gl_pathv[i]);
+ snprintf(real_path, sizeof(real_path), "/dev/%s", slave);
+ rc = set_blockdev_tunables(real_path, 0);
+ }
+
+ if (rc == GLOB_NOMATCH) {
+ /* no slave device is not an error */
+ rc = 0;
+ } else if (rc && verbose) {
+ if (slave == NULL) {
+ fprintf(stderr, "warning: %s, failed to read"
+ " entries under %s/slaves\n",
+ strerror(errno), path);
+ } else {
+ fprintf(stderr, "unable to set tunables for"
+ " slave device %s (slave would be"
+ " unable to handle IO request from"
+ " master %s)\n",
+ real_path, source);
+ }
+ }
+ globfree(&glob_info);
+ }
+
return rc;
}
printf("mounting device %s at %s, flags=%#x options=%s\n",
source, target, flags, optcopy);
- if (!strstr(usource, ":/") && set_blockdev_tunables(source)) {
+ if (!strstr(usource, ":/") && set_blockdev_tunables(source, 1)) {
if (verbose)
fprintf(stderr, "%s: unable to set tunables for %s"
" (may cause reduced IO performance)\n",
argv[0], source);
}
- register_service_tags(usource, source, target);
-
if (!fake) {
/* flags and target get to lustre_get_sb, but not
lustre_fill_super. Lustre ignores the flags, but mount
usource, target, strerror(errno));
if (errno == ENODEV)
fprintf(stderr, "Are the lustre modules loaded?\n"
- "Check /etc/modprobe.conf and /proc/filesystems"
- "\nNote 'alias lustre llite' should be removed"
- " from modprobe.conf\n");
+ "Check /etc/modprobe.conf and "
+ "/proc/filesystems\n");
if (errno == ENOTBLK)
fprintf(stderr, "Do you need -o loop?\n");
if (errno == ENOMEDIUM)