📄 obd.c
字号:
/* -*- 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: Andreas Dilger <adilger@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. * */#include <stdlib.h>#include <sys/ioctl.h>#include <fcntl.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <stdio.h>#include <stdarg.h>#include <signal.h>#include "obdctl.h"#include <obd.h> /* for struct lov_stripe_md */#include <lustre/lustre_build_version.h>#include <unistd.h>#include <sys/un.h>#include <time.h>#include <sys/time.h>#include <errno.h>#include <string.h>#include <ctype.h>#ifdef HAVE_ASM_PAGE_H#include <asm/page.h> /* needed for PAGE_SIZE - rread */#endif#include <obd_class.h>#include <lnet/lnetctl.h>#include "parser.h"#include "platform.h"#include <stdio.h>#define MAX_STRING_SIZE 128#define DEVICES_LIST "/proc/fs/lustre/devices"#if HAVE_LIBPTHREAD#include <sys/ipc.h>#include <sys/shm.h>#include <pthread.h>#define MAX_THREADS 1024struct shared_data { __u64 counters[MAX_THREADS]; __u64 offsets[MAX_THREADS]; int running; int barrier; int stop; l_mutex_t mutex; l_cond_t cond;};static struct shared_data *shared_data;static __u64 counter_snapshot[2][MAX_THREADS];static int prev_valid;static struct timeval prev_time;static int thread;static int nthreads;#elseconst int thread = 0;const int nthreads = 1;#endifstatic char rawbuf[8192];static char *buf = rawbuf;static int max = sizeof(rawbuf);static int cur_device = -1;#define MAX_STRIPES 170struct lov_oinfo lov_oinfos[MAX_STRIPES];struct lsm_buffer { struct lov_stripe_md lsm; struct lov_oinfo *ptrs[MAX_STRIPES];} lsm_buffer;static int l2_ioctl(int dev_id, int opc, void *buf){ return l_ioctl(dev_id, opc, buf);}#define IOC_INIT(data) \do { \ memset(&data, 0, sizeof(data)); \ data.ioc_dev = cur_device; \} while (0)#define IOC_PACK(func, data) \do { \ memset(buf, 0, sizeof(rawbuf)); \ if (obd_ioctl_pack(&data, &buf, max)) { \ fprintf(stderr, "error: %s: invalid ioctl\n", \ jt_cmdname(func)); \ return -2; \ } \} while (0)#define IOC_UNPACK(func, data) \do { \ if (obd_ioctl_unpack(&data, buf, max)) { \ fprintf(stderr, "error: %s: invalid reply\n", \ jt_cmdname(func)); \ return -2; \ } \} while (0)int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg){ struct obd_ioctl_data data; int rc; IOC_INIT(data); data.ioc_type = LUSTRE_CFG_TYPE; data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens); data.ioc_pbuf1 = (void *)lcfg; IOC_PACK(func, data); rc = l_ioctl(dev_id, OBD_IOC_PROCESS_CFG, buf); return rc;}static int do_device(char *func, char *devname);int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg){ struct obd_ioctl_data data; static int mgs_device = -1; char mgs[] = "$MGS"; int rc; /* Always operates on MGS dev */ if (mgs_device == -1) { do_disconnect(NULL, 1); rc = do_device("mgsioc", mgs); if (rc) { errno = ENODEV; return -1; } mgs_device = cur_device; } IOC_INIT(data); data.ioc_dev = mgs_device; data.ioc_type = LUSTRE_CFG_TYPE; data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens); data.ioc_pbuf1 = (void *)lcfg; IOC_PACK(func, data); rc = l_ioctl(dev_id, OBD_IOC_PARAM, buf); if (rc == ENODEV) fprintf(stderr, "Is the MGS running on this node?\n"); if (rc == ENOSYS) fprintf(stderr, "Make sure cfg_device is set first.\n"); if (rc == EINVAL) fprintf(stderr, "cfg_device should be of the form " "'lustre-MDT0000'\n"); return rc;}char *obdo_print(struct obdo *obd){ char buf[1024]; sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64 "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64 "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n" "misc: %x\nnlink: %d,\nvalid "LPX64"\n", obd->o_id, obd->o_gr, obd->o_atime, obd->o_mtime, obd->o_ctime, obd->o_size, obd->o_blocks, obd->o_blksize, obd->o_mode, obd->o_uid, obd->o_gid, obd->o_flags, obd->o_misc, obd->o_nlink, obd->o_valid); return strdup(buf);}#define BAD_VERBOSE (-999999999)#define N2D_OFF 0x100 /* So we can tell between error codes and devices */static int do_name2dev(char *func, char *name){ struct obd_ioctl_data data; int rc; IOC_INIT(data); data.ioc_inllen1 = strlen(name) + 1; data.ioc_inlbuf1 = name; IOC_PACK(func, data); rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf); if (rc < 0) return errno; IOC_UNPACK(func, data); return data.ioc_dev + N2D_OFF;}/* * resolve a device name to a device number. * supports a number, $name or %uuid. */int parse_devname(char *func, char *name){ int rc; int ret = -1; if (!name) return ret; if (isdigit(name[0])) { ret = strtoul(name, NULL, 0); } else { if (name[0] == '$' || name[0] == '%') name++; rc = do_name2dev(func, name); if (rc >= N2D_OFF) { ret = rc - N2D_OFF; // printf("Name %s is device %d\n", name, ret); } else { fprintf(stderr, "No device found for name %s: %s\n", name, strerror(rc)); } } return ret;}static voidreset_lsmb (struct lsm_buffer *lsmb){ memset (&lsmb->lsm, 0, sizeof (lsmb->lsm)); memset(lov_oinfos, 0, sizeof(lov_oinfos)); lsmb->lsm.lsm_magic = LOV_MAGIC;}static intparse_lsm (struct lsm_buffer *lsmb, char *string){ struct lov_stripe_md *lsm = &lsmb->lsm; char *end; int i; /* * object_id[=size#count[@offset:id]*] */ reset_lsmb (lsmb); lsm->lsm_object_id = strtoull (string, &end, 0); if (end == string) return (-1); string = end; if (*string == 0) return (0); if (*string != '=') return (-1); string++; lsm->lsm_stripe_size = strtoul (string, &end, 0); if (end == string) return (-1); string = end; if (*string != '#') return (-1); string++; lsm->lsm_stripe_count = strtoul (string, &end, 0); if (end == string) return (-1); string = end; if (*string == 0) /* don't have to specify obj ids */ return (0); for (i = 0; i < lsm->lsm_stripe_count; i++) { if (*string != '@') return (-1); string++; lsm->lsm_oinfo[i]->loi_ost_idx = strtoul(string, &end, 0); if (*end != ':') return (-1); string = end + 1; lsm->lsm_oinfo[i]->loi_id = strtoull(string, &end, 0); string = end; } if (*string != 0) return (-1); return (0);}char *jt_cmdname(char *func){ static char buf[512]; if (thread) { sprintf(buf, "%s-%d", func, thread); return buf; } return func;}#define difftime(a, b) \ ((a)->tv_sec - (b)->tv_sec + \ ((a)->tv_usec - (b)->tv_usec) / 1000000.0)static int be_verbose(int verbose, struct timeval *next_time, __u64 num, __u64 *next_num, int num_total){ struct timeval now; if (!verbose) return 0; if (next_time != NULL) gettimeofday(&now, NULL); /* A positive verbosity means to print every X iterations */ if (verbose > 0 && (num >= *next_num || num >= num_total)) { *next_num += verbose; if (next_time) { next_time->tv_sec = now.tv_sec - verbose; next_time->tv_usec = now.tv_usec; } return 1; } /* A negative verbosity means to print at most each X seconds */ if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0.0){ next_time->tv_sec = now.tv_sec - verbose; next_time->tv_usec = now.tv_usec; *next_num = num; return 1; } return 0;}static int get_verbose(char *func, const char *arg){ int verbose; char *end; if (!arg || arg[0] == 'v') verbose = 1; else if (arg[0] == 's' || arg[0] == 'q') verbose = 0; else { verbose = (int)strtoul(arg, &end, 0); if (*end) { fprintf(stderr, "error: %s: bad verbose option '%s'\n", jt_cmdname(func), arg); return BAD_VERBOSE; } } if (verbose < 0) printf("Print status every %d seconds\n", -verbose); else if (verbose == 1) printf("Print status every operation\n"); else if (verbose > 1) printf("Print status every %d operations\n", verbose); return verbose;}int do_disconnect(char *func, int verbose){ lcfg_set_devname(NULL); cur_device = -1; return 0;}#ifdef MAX_THREADSstatic void shmem_setup(void){ /* Create new segment */ int shmid = shmget(IPC_PRIVATE, sizeof(*shared_data), 0600); if (shmid == -1) { fprintf(stderr, "Can't create shared data: %s\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -