liblustreapi.c

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

C
1,677
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (C) 2002 Cluster File Systems, Inc. *   Author: Peter J. Braam <braam@clusterfs.com> *   Author: Phil Schwan <phil@clusterfs.com> *   Author: Robert Read <rread@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. * *//* for O_DIRECTORY */#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <string.h>#include <stddef.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <dirent.h>#include <stdarg.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/syscall.h>#include <fnmatch.h>#ifdef HAVE_ASM_TYPES_H#include <asm/types.h>#endif#ifdef HAVE_LINUX_UNISTD_H#include <linux/unistd.h>#else#include <unistd.h>#endif#include <liblustre.h>#include <lnet/lnetctl.h>#include <obd.h>#include <lustre_lib.h>#include <lustre/liblustreapi.h>#include <obd_lov.h>static unsigned llapi_dir_filetype_table[] = {        [DT_UNKNOWN]= 0,        [DT_FIFO]= S_IFIFO,        [DT_CHR] = S_IFCHR,        [DT_DIR] = S_IFDIR,        [DT_BLK] = S_IFBLK,        [DT_REG] = S_IFREG,        [DT_LNK] = S_IFLNK,        [DT_SOCK]= S_IFSOCK,#if defined(DT_DOOR) && defined(S_IFDOOR)        [DT_DOOR]= S_IFDOOR,#endif};#if defined(DT_DOOR) && defined(S_IFDOOR)static const int DT_MAX = DT_DOOR;#elsestatic const int DT_MAX = DT_SOCK;#endifstatic unsigned llapi_filetype_dir_table[] = {        [0]= DT_UNKNOWN,        [S_IFIFO]= DT_FIFO,        [S_IFCHR] = DT_CHR,        [S_IFDIR] = DT_DIR,        [S_IFBLK] = DT_BLK,        [S_IFREG] = DT_REG,        [S_IFLNK] = DT_LNK,        [S_IFSOCK]= DT_SOCK,#if defined(DT_DOOR) && defined(S_IFDOOR)        [S_IFDOOR]= DT_DOOR,#endif};#if defined(DT_DOOR) && defined(S_IFDOOR)static const int S_IFMAX = DT_DOOR;#elsestatic const int S_IFMAX = DT_SOCK;#endif/* liblustreapi message level */static int llapi_msg_level = LLAPI_MSG_MAX;void llapi_msg_set_level(int level){        /* ensure level is in the good range */        if (level < LLAPI_MSG_OFF)                llapi_msg_level = LLAPI_MSG_OFF;        else if (level > LLAPI_MSG_MAX)                llapi_msg_level = LLAPI_MSG_MAX;        else                llapi_msg_level = level;}void llapi_err(int level, char *fmt, ...){        va_list args;        int tmp_errno = abs(errno);        if ((level & LLAPI_MSG_MASK) > llapi_msg_level)                return;        va_start(args, fmt);        vfprintf(stderr, fmt, args);        va_end(args);        if (level & LLAPI_MSG_NO_ERRNO)                fprintf(stderr, "\n");        else                fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);}#define llapi_err_noerrno(level, fmt, a...)                             \        llapi_err((level) | LLAPI_MSG_NO_ERRNO, fmt, ## a)void llapi_printf(int level, char *fmt, ...){        va_list args;        if ((level & LLAPI_MSG_MASK) > llapi_msg_level)                return;        va_start(args, fmt);        vfprintf(stdout, fmt, args);        va_end(args);}int parse_size(char *optarg, unsigned long long *size,               unsigned long long *size_units){        char *end;        *size = strtoul(optarg, &end, 0);        if (*end != '\0') {                if ((*end == 'b') && *(end+1) == '\0' &&                    (*size & (~0ULL << (64 - 9))) == 0) {                        *size <<= 9;                        *size_units = 1 << 9;                } else if ((*end == 'k' || *end == 'K') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 10))) == 0) {                        *size <<= 10;                        *size_units = 1 << 10;                } else if ((*end == 'm' || *end == 'M') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 20))) == 0) {                        *size <<= 20;                        *size_units = 1 << 20;                } else if ((*end == 'g' || *end == 'G') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 30))) == 0) {                        *size <<= 30;                        *size_units = 1 << 30;                } else if ((*end == 't' || *end == 'T') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 40))) == 0) {                        *size <<= 40;                        *size_units = 1ULL << 40;                } else if ((*end == 'p' || *end == 'P') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 50))) == 0) {                        *size <<= 50;                        *size_units = 1ULL << 50;                } else if ((*end == 'e' || *end == 'E') &&                           *(end+1) == '\0' && (*size &                           (~0ULL << (64 - 60))) == 0) {                        *size <<= 60;                        *size_units = 1ULL << 60;                } else {                        return -1;                }        }        return 0;}int llapi_file_open(const char *name, int flags, int mode,                    unsigned long stripe_size, int stripe_offset,                    int stripe_count, int stripe_pattern){        struct lov_user_md lum = { 0 };        int fd, rc = 0;        int isdir = 0;        int page_size;        fd = open(name, flags | O_LOV_DELAY_CREATE, mode);        if (fd < 0 && errno == EISDIR) {                fd = open(name, O_DIRECTORY | O_RDONLY);                isdir++;        }        if (fd < 0) {                rc = -errno;                llapi_err(LLAPI_MSG_ERROR, "unable to open '%s'", name);                return rc;        }        /* 64 KB is the largest common page size I'm aware of (on ia64), but         * check the local page size just in case. */        page_size = LOV_MIN_STRIPE_SIZE;        if (getpagesize() > page_size) {                page_size = getpagesize();                llapi_err_noerrno(LLAPI_MSG_WARN,                                   "warning: your page size (%u) is "                                  "larger than expected (%u)", page_size,                                   LOV_MIN_STRIPE_SIZE);        }        if (stripe_size < 0 || (stripe_size & (LOV_MIN_STRIPE_SIZE - 1))) {                errno = rc = -EINVAL;                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe_size %lu, "                          "must be an even multiple of %d bytes",                           stripe_size, page_size);                goto out;        }        if (stripe_offset < -1 || stripe_offset > MAX_OBD_DEVICES) {                errno = rc = -EINVAL;                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe offset %d",                           stripe_offset);                goto out;        }        if (stripe_count < -1 || stripe_count > LOV_MAX_STRIPE_COUNT) {                errno = rc = -EINVAL;                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe count %d",                           stripe_count);                goto out;        }        if (stripe_count > 0 && (__u64)stripe_size * stripe_count > 0xffffffff){                errno = rc = -EINVAL;                llapi_err(LLAPI_MSG_ERROR, "error: stripe_size %lu * "                          "stripe_count %u exceeds 4GB", stripe_size,                           stripe_count);                goto out;        }        /*  Initialize IOCTL striping pattern structure */        lum.lmm_magic = LOV_USER_MAGIC;        lum.lmm_pattern = stripe_pattern;        lum.lmm_stripe_size = stripe_size;        lum.lmm_stripe_count = stripe_count;        lum.lmm_stripe_offset = stripe_offset;        if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) {                char *errmsg = "stripe already set";                rc = -errno;                if (errno != EEXIST && errno != EALREADY)                        errmsg = strerror(errno);                llapi_err_noerrno(LLAPI_MSG_ERROR,                                  "error on ioctl "LPX64" for '%s' (%d): %s",                                  (__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg);        }out:        if (rc) {                close(fd);                fd = rc;        }        return fd;}int llapi_file_create(const char *name, unsigned long stripe_size,                      int stripe_offset, int stripe_count, int stripe_pattern){        int fd;        fd = llapi_file_open(name, O_CREAT | O_WRONLY, 0644, stripe_size,                             stripe_offset, stripe_count, stripe_pattern);        if (fd < 0)                return fd;        close(fd);        return 0;}typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d,                              void *data, struct dirent64 *de);#define MAX_LOV_UUID_COUNT      max(LOV_MAX_STRIPE_COUNT, 1000)#define OBD_NOT_FOUND           (-1)static int common_param_init(struct find_param *param){        param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT);        if ((param->lmd = malloc(sizeof(lstat_t) + param->lumlen)) == NULL) {                llapi_err(LLAPI_MSG_ERROR,                           "error: allocation of %d bytes for ioctl",                          sizeof(lstat_t) + param->lumlen);                return -ENOMEM;        }        param->got_uuids = 0;        param->obdindexes = NULL;        param->obdindex = OBD_NOT_FOUND;        return 0;}static void find_param_fini(struct find_param *param){        if (param->obdindexes)                free(param->obdindexes);        if (param->lmd)                free(param->lmd);}/* * If uuidp is NULL, return the number of available obd uuids. * If uuidp is non-NULL, then it will return the uuids of the obds. If * there are more OSTs then allocated to uuidp, then an error is returned with * the ost_count set to number of available obd uuids. */int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count){        char lov_name[sizeof(struct obd_uuid)];        char buf[1024];        FILE *fp;        int rc = 0, index = 0;        /* Get the lov name */        rc = ioctl(fd, OBD_IOC_GETNAME, (void *) lov_name);        if (rc) {                rc = errno;                llapi_err(LLAPI_MSG_ERROR, "error: can't get lov name");                return rc;        }        /* Now get the ost uuids from /proc */        snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd",                 lov_name);        fp = fopen(buf, "r");        if (fp == NULL) {                rc = errno;                llapi_err(LLAPI_MSG_ERROR, "error: opening '%s'", buf);                return rc;        }        while (fgets(buf, sizeof(buf), fp) != NULL) {                if (uuidp && (index < *ost_count)) {                        if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) <2)                                break;                }                index++;        }        fclose(fp);        if (uuidp && (index >= *ost_count))                return -EOVERFLOW;        *ost_count = index;        return rc;}/* Here, param->obduuid points to a single obduuid, the index of which is * returned in param->obdindex */static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param){        char uuid[sizeof(struct obd_uuid)];        char buf[1024];        FILE *fp;        int rc = 0, index;        /* Get the lov name */        rc = ioctl(dirfd(dir), OBD_IOC_GETNAME, (void *)uuid);        if (rc) {                if (errno != ENOTTY) {                        rc = errno;                        llapi_err(LLAPI_MSG_ERROR,                                   "error: can't get lov name: %s", dname);                } else {                        rc = 0;                }                return rc;        }        param->got_uuids = 1;        /* Now get the ost uuids from /proc */        snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd",                 uuid);        fp = fopen(buf, "r");        if (fp == NULL) {                rc = errno;                llapi_err(LLAPI_MSG_ERROR, "error: opening '%s'", buf);                return rc;        }        if (!param->obduuid && !param->quiet && !param->obds_printed)                llapi_printf(LLAPI_MSG_NORMAL, "OBDS:\n");        while (fgets(buf, sizeof(buf), fp) != NULL) {                if (sscanf(buf, "%d: %s", &index, uuid) < 2)                        break;                if (param->obduuid) {                        if (strncmp((char *)param->obduuid->uuid, uuid,                                    sizeof(uuid)) == 0) {                                param->obdindex = index;                                break;                        }                } else if (!param->quiet && !param->obds_printed) {

⌨️ 快捷键说明

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