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 + -
显示快捷键?