From: pschwan Date: Fri, 31 Jan 2003 21:16:03 +0000 (+0000) Subject: - merge b_md into b_intent X-Git-Tag: v1_7_100~1^100~78 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=2adb27b93b471b882d22eb3ab0265cbbcae8cff0;p=fs%2Flustre-release.git - merge b_md into b_intent - rename invalidate-show.diff, at andreas's request --- diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh new file mode 100755 index 0000000..b57b169 --- /dev/null +++ b/lustre/tests/recovery-small.sh @@ -0,0 +1,123 @@ +#!/bin/sh + +set -ex + +LUSTRE=${LUSTRE:-`dirname $0`/..} +PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests + +. $LUSTRE/../ltest/functional/llite/common/common.sh + +PDSH='pdsh -S -w' + +# XXX I wish all this stuff was in some default-config.sh somewhere +MDSNODE=${MDSNODE:-dev2} +OSTNODE=${OSTNODE:-dev3} +CLIENT=${CLIENTNODE:-dev4} +NETWORKTYPE=${NETWORKTYPE:-tcp} +MOUNTPT=${MOUNTPT:-/mnt/lustre} +CONFIG=recovery-small.xml +MDSDEV=/tmp/mds +OSTDEV=/tmp/ost +MDSSIZE=100000 +OSTSIZE=100000 + +do_mds() { + $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" +} + +do_client() { + $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" +} + +do_ost() { + $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" +} + +drop_request() { + do_mds "echo 0x121 > /proc/sys/lustre/fail_loc" + do_client "$1" + do_mds "echo 0 > /proc/sys/lustre/fail_loc" +} + +drop_reply() { + do_mds "echo 0x120 > /proc/sys/lustre/fail_loc" + do_client "$@" + do_mds "echo 0 > /proc/sys/lustre/fail_loc" +} + +make_config() { + rm -f $CONFIG + for NODE in $CLIENT $MDSNODE $OSTNODE; do + lmc -m $CONFIG --add net --node $NODE --nid `h2$NETWORKTYPE $NODE` \ + --nettype $NETWORKTYPE || exit 4 + done + lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \ + --size $MDSSIZE || exit 5 + lmc -m $CONFIG --add ost --node $OSTNODE --obd obd1 --dev $OSTDEV \ + --size $OSTSIZE || exit 6 + lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \ + --obd obd1 || exit 7 +} + +start_mds() { + do_mds "lconf $@ $CONFIG" +} + +shutdown_mds() { + do_mds "lconf $@ --cleanup $CONFIG" +} + +start_ost() { + do_ost "lconf $@ $CONFIG" +} + +shutdown_ost() { + do_ost "lconf $@ --cleanup $CONFIG" +} + +mount_client() { + do_client "lconf $@ $CONFIG" +} + +unmount_client() { + do_client "lconf $@ --cleanup $CONFIG" +} + +setup() { + make_config + start_mds --reformat + start_ost --reformat + # XXX we should write our own upcall, when we move this somewhere better. + mount_client --timeout=10 \ + --recovery_upcall=$PWD/../../ltest/functional/llite/09/client-upcall.sh +} + +cleanup() { + unmount_client || true + shutdown_mds || true + shutdown_ost || true +} + +replay() { + if [ $# -gt 1 ]; then + do_client "$1" + shift + fi + do_mds "sync" + do_mds 'echo -e "device \$mds1\\nprobe\\nnotransno\\nreadonly" | lctl' + do_client "$1" & + shutdown_mds -f + start_mds + wait +} + +if [ ! -z "$ONLY" ]; then + eval "$ONLY" + exit $? +fi + +setup +drop_request "mcreate /mnt/lustre/1" +drop_reply "mcreate /mnt/lustre/2" +replay "mcreate /mnt/lustre/3" +cleanup diff --git a/lustre/utils/obdio.c b/lustre/utils/obdio.c new file mode 100644 index 0000000..f79d21d --- /dev/null +++ b/lustre/utils/obdio.c @@ -0,0 +1,474 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2002 Cluster File Systems, Inc. + * Author: Eric Barton + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include /* for IOC_LOV_SET_OSC_ACTIVE */ +#include /* for struct lov_stripe_md */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include /* needed for PAGE_SIZE - rread */ + +#define __KERNEL__ +#include +#undef __KERNEL__ + +#include "obdctl.h" + +struct obdio_conn { + int oc_fd; + uint64_t oc_conn_addr; + uint64_t oc_conn_cookie; + struct obd_ioctl_data oc_data; + char oc_buffer[8192]; +}; + +char * +obdio_alloc_aligned_buffer (char **spacep, int size) +{ + int pagesize = getpagesize(); + char *space = malloc (size + pagesize - 1); + + *spacep = space; + if (space == NULL) + return (NULL); + + return ((char *)(((unsigned long)space + pagesize - 1) & ~(pagesize - 1))); +} + +void +obdio_iocinit (struct obdio_conn *conn) +{ + memset (&conn->oc_data, 0, sizeof (conn->oc_data)); + conn->oc_data.ioc_version = OBD_IOCTL_VERSION; + conn->oc_data.ioc_addr = conn->oc_conn_addr; + conn->oc_data.ioc_cookie = conn->oc_conn_cookie; + conn->oc_data.ioc_len = sizeof (conn->oc_data); +} + +int +obdio_ioctl (struct obdio_conn *conn, int cmd) +{ + char *buf = conn->oc_buffer; + int rc; + int rc2; + + rc = obd_ioctl_pack (&conn->oc_data, &buf, sizeof (conn->oc_buffer)); + if (rc != 0) { + fprintf (stderr, "obd_ioctl_pack: %d (%s)\n", + rc, strerror (errno)); + abort (); + } + + rc = ioctl (conn->oc_fd, cmd, buf); + if (rc != 0) + return (rc); + + rc2 = obd_ioctl_unpack (&conn->oc_data, buf, sizeof (conn->oc_buffer)); + if (rc2 != 0) { + fprintf (stderr, "obd_ioctl_unpack: %d (%s)\n", + rc2, strerror (errno)); + abort (); + } + + return (rc); +} + +struct obdio_conn * +obdio_connect (int device) +{ + struct obdio_conn *conn; + int rc; + + conn = malloc (sizeof (*conn)); + if (conn == NULL) { + fprintf (stderr, "obdio_connect: no memory\n"); + return (NULL); + } + memset (conn, 0, sizeof (*conn)); + + conn->oc_fd = open ("/dev/obd", O_RDWR); + if (conn->oc_fd < 0) { + fprintf (stderr, "Can't open /dev/obd: %s\n", + strerror (errno)); + goto failed; + } + + obdio_iocinit (conn); + conn->oc_data.ioc_dev = device; + rc = obdio_ioctl (conn, OBD_IOC_DEVICE); + if (rc != 0) { + fprintf (stderr, "Can't set device %d: %s\n", + device, strerror (errno)); + goto failed; + } + + obdio_iocinit (conn); + rc = obdio_ioctl (conn, OBD_IOC_CONNECT); + if (rc != 0) { + fprintf (stderr, "Can't connect to device %d: %s\n", + device, strerror (errno)); + goto failed; + } + + conn->oc_conn_addr = conn->oc_data.ioc_addr; + conn->oc_conn_cookie = conn->oc_data.ioc_cookie; + return (conn); + + failed: + free (conn); + return (NULL); +} + +void +obdio_disconnect (struct obdio_conn *conn) +{ + close (conn->oc_fd); + /* obdclass will automatically close on last ref */ + free (conn); +} + +int +obdio_open (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) +{ + int rc; + + obdio_iocinit (conn); + + conn->oc_data.ioc_obdo1.o_id = oid; + conn->oc_data.ioc_obdo1.o_mode = S_IFREG; + conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; + + rc = obdio_ioctl (conn, OBD_IOC_OPEN); + + if (rc == 0) + obd_oa2handle (fh, &conn->oc_data.ioc_obdo1); + + return (rc); +} + +int +obdio_close (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) +{ + obdio_iocinit (conn); + + + conn->oc_data.ioc_obdo1.o_id = oid; + conn->oc_data.ioc_obdo1.o_mode = S_IFREG; + obd_handle2oa (&conn->oc_data.ioc_obdo1, fh); + conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | + OBD_MD_FLMODE | OBD_MD_FLHANDLE; + + return (obdio_ioctl (conn, OBD_IOC_CLOSE)); +} + +int +obdio_pread (struct obdio_conn *conn, uint64_t oid, + char *buffer, uint32_t count, uint64_t offset) +{ + obdio_iocinit (conn); + + conn->oc_data.ioc_obdo1.o_id = oid; + conn->oc_data.ioc_obdo1.o_mode = S_IFREG; + conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; + + conn->oc_data.ioc_pbuf2 = buffer; + conn->oc_data.ioc_plen2 = count; + conn->oc_data.ioc_count = count; + conn->oc_data.ioc_offset = offset; + + return (obdio_ioctl (conn, OBD_IOC_BRW_READ)); +} + +int +obdio_pwrite (struct obdio_conn *conn, uint64_t oid, + char *buffer, uint32_t count, uint64_t offset) +{ + obdio_iocinit (conn); + + conn->oc_data.ioc_obdo1.o_id = oid; + conn->oc_data.ioc_obdo1.o_mode = S_IFREG; + conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; + + conn->oc_data.ioc_pbuf2 = buffer; + conn->oc_data.ioc_plen2 = count; + conn->oc_data.ioc_count = count; + conn->oc_data.ioc_offset = offset; + + return (obdio_ioctl (conn, OBD_IOC_BRW_WRITE)); +} + +void +obdio_test_extent (struct obdio_conn *conn, uint32_t myid, int reps, + uint64_t oid, uint64_t offset, uint32_t size) +{ + char *space; + char *buffer = obdio_alloc_aligned_buffer (&space, size); + uint32_t *ibuf; + int i; + int j; + int rc; + + if (buffer == NULL) { + fprintf (stderr, "Can't allocate buffer size %d\n", size); + abort (); + } + + for (i = 0; i < reps; i++) { + ibuf = (uint32_t *) buffer; + for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) { + ibuf[0] = myid; + ibuf[1] = i; + ibuf[2] = j; + ibuf[3] = myid; + ibuf += 4; + } + + rc = obdio_pwrite (conn, oid, buffer, size, offset); + if (rc != 0) { + fprintf (stderr, "Error writing "LPX64" @ "LPU64" for %u: %s\n", + oid, offset, size, strerror (errno)); + abort (); + } + + memset (buffer, 0xbb, size); + + rc = obdio_pread (conn, oid, buffer, size, offset); + if (rc != 0) { + fprintf (stderr, "Error reading "LPX64" @ "LPU64" for %u: %s\n", + oid, offset, size, strerror (errno)); + abort (); + } + + ibuf = (uint32_t *) buffer; + for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) { + if (ibuf[0] != myid || + ibuf[1] != i || + ibuf[2] != j || + ibuf[3] != myid) { + fprintf (stderr, "Error checking "LPX64" @ "LPU64" for %u, chunk %d: %s\n", + oid, offset, size, j, strerror (errno)); + fprintf (stderr, "Expected [%x,%x,%x,%x], got [%x,%x,%x,%x]\n", + myid, i, j, myid, ibuf[0], ibuf[1], ibuf[2], ibuf[3]); + abort (); + } + ibuf += 4; + } + } +} + +int +parse_kmg (uint64_t *valp, char *str) +{ + uint64_t val; + char mod[32]; + + switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod)) + { + default: + return (-1); + + case 1: + *valp = val; + return (0); + + case 2: + switch (*mod) + { + case 'g': + case 'G': + *valp = val << 30; + return (0); + + case 'm': + case 'M': + *valp = val << 20; + return (0); + + case 'k': + case 'K': + *valp = val << 10; + return (0); + + default: + *valp = val; + return (0); + } + } +} + +void +usage (char *cmdname, int help) +{ + char *name = strrchr (cmdname, '/'); + + if (name == NULL) + name = cmdname; + + fprintf (help ? stdout : stderr, + "usage: %s -d device -s size -o offset [-i id][-n reps] oid\n", + name); +} + +int +main (int argc, char **argv) +{ + struct lustre_handle fh; + uint32_t myid = getpid (); + uint64_t oid; + uint64_t base_offset = 0; + int set_base = 0; + uint32_t size = 0; + int set_size = 0; + int device = 0; + int set_device = 0; + int reps = 1; + char *end; + struct obdio_conn *conn; + uint64_t val; + int rc; + int c; + + while ((c = getopt (argc, argv, "hi:s:b:d:n:")) != -1) + switch (c) { + case 'h': + usage (argv[0], 1); + return (0); + + case 'i': + myid = strtol (optarg, &end, 0); + if (end == optarg || *end != 0) { + fprintf (stderr, "Can't parse id %s\n", + optarg); + return (1); + } + myid = (uint32_t)val; + break; + + case 's': + if (parse_kmg (&val, optarg) != 0) { + fprintf (stderr, "Can't parse size %s\n", + optarg); + return (1); + } + size = (uint32_t)val; + set_size++; + break; + + case 'b': + if (parse_kmg (&val, optarg) != 0) { + fprintf (stderr, "Can't parse base offset %s\n", + optarg); + return (1); + } + base_offset = val; + set_base++; + break; + + case 'd': + device = strtol (optarg, &end, 0); + if (end == optarg || *end != 0) { + fprintf (stderr, "Can't parse device %s\n", + optarg); + return (1); + } + set_device++; + break; + case 'n': + if (parse_kmg (&val, optarg) != 0) { + fprintf (stderr, "Can't parse reps %s\n", + optarg); + return (1); + } + reps = (int)val; + break; + + default: + usage (argv[0], 0); + return (1); + } + + if (!set_size || + !set_base || + !set_device || + optind == argc) { + fprintf (stderr, "No %s specified\n", + !set_size ? "size" : + !set_base ? "base offset" : + !set_device ? "device" : "object id"); + return (1); + } + + oid = strtoull (argv[optind], &end, 0); + if (end == argv[optind] || *end != 0) { + fprintf (stderr, "Can't parse object id %s\n", + argv[optind]); + return (1); + } + + conn = obdio_connect (device); + if (conn == NULL) + return (1); + + rc = obdio_open (conn, oid, &fh); + if (rc != 0) { + fprintf (stderr, "Failed to open object "LPX64": %s\n", + oid, strerror (errno)); + return (1); + } + + obdio_test_extent (conn, myid, reps, oid, base_offset, size); + + rc = obdio_close (conn, oid, &fh); + if (rc != 0) { + fprintf (stderr, "Error closing object "LPX64": %s\n", + oid, strerror (errno)); + return (1); + } + + obdio_disconnect (conn); + return (0); +} + + diff --git a/lustre/utils/obdstat.c b/lustre/utils/obdstat.c new file mode 100644 index 0000000..b66fcc3 --- /dev/null +++ b/lustre/utils/obdstat.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include + +struct one_stat { + char *name; + int fd; + long long current; + long long delta; +}; + +struct one_stat *read_bytes; +struct one_stat *read_reqs; +struct one_stat *write_bytes; +struct one_stat *write_reqs; +struct one_stat *getattr_reqs; +struct one_stat *setattr_reqs; +struct one_stat *create_reqs; +struct one_stat *destroy_reqs; +struct one_stat *statfs_reqs; +struct one_stat *open_reqs; +struct one_stat *close_reqs; +struct one_stat *punch_reqs; + +struct one_stat * +init_one_stat (char *basename, char *name) +{ + char fname[1024]; + struct one_stat *stat = (struct one_stat *)malloc (sizeof (*stat)); + + if (stat == NULL) { + fprintf (stderr, "Can't allocate stat %s: %s\n", + name, strerror (errno)); + abort (); + } + + snprintf (fname, sizeof (fname), "%s/%s", basename, name); + + memset (stat, 0, sizeof (*stat)); + stat->name = name; + + stat->fd = open (fname, O_RDONLY); + if (stat->fd < 0 ) { + fprintf (stderr, "Can't open stat %s: %s\n", + fname, strerror (errno)); + abort (); + } + + return (stat); +} + +void +update_one_stat (struct one_stat *stat) +{ + static char buffer[1024]; + long long prev = stat->current; + int nob; + + lseek (stat->fd, 0, SEEK_SET); + nob = read (stat->fd, buffer, sizeof (buffer) - 1); + if (nob < 0) { + fprintf (stderr, "Can't read stat %s: %s\n", + stat->name, strerror (errno)); + abort (); + } + + buffer[nob] = 0; + if (sscanf (buffer, "%Ld", &stat->current) != 1) { + fprintf (stderr, "Can't parse stat %s: %s\n", + stat->name, strerror (errno)); + abort (); + } + + stat->delta = stat->current - prev; +} + +double +timenow () +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return (tv.tv_sec + tv.tv_usec / 1000000.0); +} + +void +do_stat (void) +{ + static double last = 0.0; + double now; + double t; + + now = timenow(); + + update_one_stat (read_bytes); + update_one_stat (read_reqs); + update_one_stat (write_bytes); + update_one_stat (write_reqs); + update_one_stat (getattr_reqs); + update_one_stat (setattr_reqs); + update_one_stat (open_reqs); + update_one_stat (close_reqs); + update_one_stat (create_reqs); + update_one_stat (destroy_reqs); + update_one_stat (statfs_reqs); + update_one_stat (punch_reqs); + + if (last == 0.0) { + printf ("R %Ld/%Ld W %Ld/%Ld attr %Ld/%Ld open %Ld/%Ld create %Ld/%Ld stat %Ld punch %Ld\n", + read_bytes->current, read_reqs->current, + write_bytes->current, write_reqs->current, + getattr_reqs->current, setattr_reqs->current, + open_reqs->current, close_reqs->current, + create_reqs->current, destroy_reqs->current, + statfs_reqs->current, punch_reqs->current); + } else { + t = now - last; + + printf ("R %7Ld (%6d/s %7.2fMb/s) W %7Ld (%6d/s %7.2fMb/s)", + read_reqs->delta, (int)(read_reqs->delta / t), + read_bytes->delta / ((1<<20) * t), + write_reqs->delta, (int)(write_reqs->delta / t), + write_bytes->delta / ((1<<20) * t)); + + if (getattr_reqs->delta != 0) + printf (" ga:%Ld", getattr_reqs->delta); + + if (setattr_reqs->delta != 0) + printf (" sa:%Ld", setattr_reqs->delta); + + if (open_reqs->delta != 0) + printf (" op:%Ld", open_reqs->delta); + + if (close_reqs->delta != 0) + printf (" cl:%Ld", close_reqs->delta); + + if (create_reqs->delta != 0) + printf (" cx:%Ld", create_reqs->delta); + + if (destroy_reqs->delta != 0) + printf (" dx:%Ld", destroy_reqs->delta); + + if (statfs_reqs->delta != 0) + printf (" st:%Ld", statfs_reqs->delta); + + if (punch_reqs->delta != 0) + printf (" pu:%Ld", punch_reqs->delta); + + printf ("\n"); + } + + last = timenow(); +} + +int main (int argc, char **argv) +{ + char *basedir = "/proc/sys/obdfilter"; + int interval = 0; + + if (argc > 1) + interval = atoi (argv[1]); + + read_bytes = init_one_stat (basedir, "read_bytes"); + read_reqs = init_one_stat (basedir, "read_reqs"); + write_bytes = init_one_stat (basedir, "write_bytes"); + write_reqs = init_one_stat (basedir, "write_reqs"); + getattr_reqs = init_one_stat (basedir, "getattr_reqs"); + setattr_reqs = init_one_stat (basedir, "setattr_reqs"); + create_reqs = init_one_stat (basedir, "create_reqs"); + destroy_reqs = init_one_stat (basedir, "destroy_reqs"); + statfs_reqs = init_one_stat (basedir, "statfs_reqs"); + open_reqs = init_one_stat (basedir, "open_reqs"); + close_reqs = init_one_stat (basedir, "close_reqs"); + punch_reqs = init_one_stat (basedir, "punch_reqs"); + + do_stat (); + + if (interval == 0) + return (0); + + for (;;) { + sleep (interval); + do_stat (); + } +}