mount_lustre.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 627 行 · 第 1/2 页

C
627
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (C) 2002 Cluster File Systems, Inc. *   Author: Robert Read <rread@clusterfs.com> *   Author: Nathan Rutman <nathan@clusterfs.com> * *   This file is part of Lustre, http://www.lustre.org. * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <sys/mount.h>#include <mntent.h>#include <getopt.h>#include <sys/utsname.h>#include "obdctl.h"#include <lustre_ver.h>#include <glob.h>#include <ctype.h>#include <limits.h>#define MAX_HW_SECTORS_KB_PATH  "queue/max_hw_sectors_kb"#define MAX_SECTORS_KB_PATH     "queue/max_sectors_kb"int          verbose = 0;int          nomtab = 0;int          fake = 0;int          force = 0;static char *progname = NULL;void usage(FILE *out){        fprintf(out, "%s v"LUSTRE_VERSION_STRING"\n", progname);        fprintf(out, "\nThis mount helper should only be invoked via the "                "mount (8) command,\ne.g. mount -t lustre dev dir\n\n");        fprintf(out, "usage: %s [-fhnv] [-o <mntopt>] <device> <mountpt>\n",                progname);        fprintf(out,                "\t<device>: the disk device, or for a client:\n"                "\t\t<mgmtnid>[:<altmgtnid>...]:/<filesystem>-client\n"                "\t<filesystem>: name of the Lustre filesystem (e.g. lustre1)\n"                "\t<mountpt>: filesystem mountpoint (e.g. /mnt/lustre)\n"                "\t-f|--fake: fake mount (updates /etc/mtab)\n"                "\t--force: force mount even if already in /etc/mtab\n"                "\t-h|--help: print this usage message\n"                "\t-n|--nomtab: do not update /etc/mtab after mount\n"                "\t-v|--verbose: print verbose config settings\n"                "\t<mntopt>: one or more comma separated of:\n"                "\t\t(no)flock,(no)user_xattr,(no)acl\n"                "\t\tnosvc: only start MGC/MGS obds\n"                "\t\texclude=<ostname>[:<ostname>] : colon-separated list of "                "inactive OSTs (e.g. lustre-OST0001)\n"                );        exit((out != stdout) ? EINVAL : 0);}static int check_mtab_entry(char *spec, 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, spec) == 0 &&                        strcmp(mnt->mnt_dir, mtpt) == 0 &&                        strcmp(mnt->mnt_type, type) == 0) {                        endmntent(fp);                        return(EEXIST);                }        }        endmntent(fp);        return(0);}static intupdate_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 1024static char *convert_hostnames(char *s1){        char *converted, *s2 = 0, *c;        char sep;        int left = MAXNIDSTR;        lnet_nid_t nid;        converted = malloc(left);        c = converted;        while ((left > 0) && (*s1 != '/')) {                s2 = strpbrk(s1, ",:");                if (!s2)                        goto out_free;                sep = *s2;                *s2 = '\0';                nid = libcfs_str2nid(s1);                *s2 = sep;                      /* back to original string */                if (nid == LNET_NID_ANY)                        goto out_free;                c += snprintf(c, left, "%s%c", libcfs_nid2str(nid), sep);                left = converted + MAXNIDSTR - c;                s1 = s2 + 1;        }        snprintf(c, left, "%s", s1);        return converted;out_free:        fprintf(stderr, "%s: Can't parse NID '%s'\n", progname, s1);        free(converted);        return NULL;}/***************************************************************************** * * This part was cribbed from util-linux/mount/mount.c.  There was no clear * license information, but many other files in the package are identified as * GNU GPL, so it's a pretty safe bet that was their intent. * ****************************************************************************/struct opt_map {        const char *opt;        /* option name */        int inv;                /* true if flag value should be inverted */        int mask;               /* flag mask value */};static const struct opt_map opt_map[] = {  /*"optname", inv,ms_mask */  /* These flags are parsed by mount, not lustre */  { "defaults", 0, 0         },      /* default options */  { "remount",  0, MS_REMOUNT},      /* remount with different options */  { "rw",       1, MS_RDONLY },      /* read-write */  { "ro",       0, MS_RDONLY },      /* read-only */  { "exec",     1, MS_NOEXEC },      /* permit execution of binaries */  { "noexec",   0, MS_NOEXEC },      /* don't execute binaries */  { "suid",     1, MS_NOSUID },      /* honor suid executables */  { "nosuid",   0, MS_NOSUID },      /* don't honor suid executables */  { "dev",      1, MS_NODEV  },      /* interpret device files  */  { "nodev",    0, MS_NODEV  },      /* don't interpret devices */  { "sync",     0, MS_SYNCHRONOUS},  /* synchronous I/O */  { "async",    1, MS_SYNCHRONOUS},  /* asynchronous I/O */  { "atime",    1, MS_NOATIME  },    /* set file access time on read */  { "noatime",  0, MS_NOATIME  },    /* do not set file access time on read */#ifdef MS_NODIRATIME  { "diratime", 1, MS_NODIRATIME },  /* set file access time on read */  { "nodiratime",0,MS_NODIRATIME },  /* do not set file access time on read */#endif#ifdef MS_RELATIME  { "relatime", 0, MS_RELATIME },  /* set file access time on read */  { "norelatime",1,MS_RELATIME },  /* do not set file access time on read */#endif  { "auto",     0, 0         },      /* Can be mounted using -a */  { "noauto",   0, 0         },      /* Can only be mounted explicitly */  { "nousers",  1, 0         },      /* Forbid ordinary user to mount */  { "nouser",   1, 0         },      /* Forbid ordinary user to mount */  { "noowner",  1, 0         },      /* Device owner has no special privs */  { "_netdev",  0, 0         },      /* Device accessible only via network */  { NULL,       0, 0         }};/****************************************************************************//* 1  = don't pass on to lustre   0  = pass on to lustre */static int parse_one_option(const char *check, int *flagp){        const struct opt_map *opt;        for (opt = &opt_map[0]; opt->opt != NULL; opt++) {                if (strncmp(check, opt->opt, strlen(opt->opt)) == 0) {                        if (opt->mask) {                                if (opt->inv)                                        *flagp &= ~(opt->mask);                                else                                        *flagp |= opt->mask;                        }                        return 1;                }        }        /* Assume any unknown options are valid and pass them on.  The mount           will fail if lmd_parse, ll_options or ldiskfs doesn't recognize it.*/        return 0;}/* Replace options with subset of Lustre-specific options, and   fill in mount flags */int parse_options(char *orig_options, int *flagp){        char *options, *opt, *nextopt;        options = calloc(strlen(orig_options) + 1, 1);        *flagp = 0;        nextopt = orig_options;        while ((opt = strsep(&nextopt, ","))) {                if (!*opt)                        /* empty option */                        continue;                if (parse_one_option(opt, flagp) == 0) {                        /* pass this on as an option */                        if (*options)                                strcat(options, ",");                        strcat(options, opt);                }        }        strcpy(orig_options, options);        free(options);        return 0;}int read_file(char *path, char *buf, int size){        FILE *fd;        fd = fopen(path, "r");        if (fd == NULL)                return errno;        fgets(buf, size, fd);        fclose(fd);        return 0;}int write_file(char *path, char *buf){        FILE *fd;        fd = fopen(path, "w");        if (fd == NULL)                return errno;        fputs(buf, fd);        fclose(fd);        return 0;}/* 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_tunables(char *source, int src_len){        glob_t glob_info;        struct stat stat_buf;        char *chk_major, *chk_minor;        char *savept, *dev, *s2 = 0;        char *ret_path;        char buf[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};        char real_path[PATH_MAX] = {'\0'};        int i, rc = 0;        int major, minor;        if (!source)                return -EINVAL;        ret_path = realpath(source, real_path);        if (ret_path == NULL) {                if (verbose)                        fprintf(stderr, "warning: %s: cannot resolve: %s",                                source, strerror(errno));                return -EINVAL;        }        src_len = sizeof(real_path);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?