X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=cmd%2Fzinject%2Ftranslate.c;h=fc1612738e111f8e8df2b357101df68963522291;hb=e2e229eb180fce8a67ba62c0e404d47e82c4c24d;hp=c85e024b62fac3b71dfec4e5da2c8c7c921f05f6;hpb=172bb4bd5e4afef721dd4d2972d8680d983f144b;p=zfs.git diff --git a/cmd/zinject/translate.c b/cmd/zinject/translate.c index c85e024..fc16127 100644 --- a/cmd/zinject/translate.c +++ b/cmd/zinject/translate.c @@ -19,14 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include -#undef verify /* both libzfs.h and zfs_context.h want to define this */ - #include #include @@ -69,6 +67,18 @@ ziprintf(const char *fmt, ...) va_end(ap); } +static void +compress_slashes(const char *src, char *dest) +{ + while (*src != '\0') { + *dest = *src++; + while (*dest == '/' && *src == '/') + ++src; + ++dest; + } + *dest = '\0'; +} + /* * Given a full path to a file, translate into a dataset name and a relative * path within the dataset. 'dataset' must be at least MAXNAMELEN characters, @@ -76,13 +86,16 @@ ziprintf(const char *fmt, ...) * buffer, which we need later to get the object ID. */ static int -parse_pathname(const char *fullpath, char *dataset, char *relpath, +parse_pathname(const char *inpath, char *dataset, char *relpath, struct stat64 *statbuf) { struct extmnttab mp; FILE *fp; int match; const char *rel; + char fullpath[MAXPATHLEN]; + + compress_slashes(inpath, fullpath); if (fullpath[0] != '/') { (void) fprintf(stderr, "invalid object '%s': must be full " @@ -103,7 +116,7 @@ parse_pathname(const char *fullpath, char *dataset, char *relpath, } if ((fp = fopen(MNTTAB, "r")) == NULL) { - (void) fprintf(stderr, "cannot open /etc/mnttab\n"); + (void) fprintf(stderr, "cannot open /etc/mtab\n"); return (-1); } @@ -162,8 +175,8 @@ object_from_path(const char *dataset, const char *path, struct stat64 *statbuf, */ sync(); - if ((err = dmu_objset_open(dataset, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { + err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, FTAG, &os); + if (err != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); return (-1); @@ -172,7 +185,7 @@ object_from_path(const char *dataset, const char *path, struct stat64 *statbuf, record->zi_objset = dmu_objset_id(os); record->zi_object = statbuf->st_ino; - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); return (0); } @@ -221,6 +234,8 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range, } switch (type) { + default: + break; case TYPE_DATA: break; @@ -247,17 +262,17 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range, * Get the dnode associated with object, so we can calculate the block * size. */ - if ((err = dmu_objset_open(dataset, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { + if ((err = dmu_objset_own(dataset, DMU_OST_ANY, + B_TRUE, FTAG, &os)) != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); goto out; } if (record->zi_object == 0) { - dn = os->os->os_meta_dnode; + dn = DMU_META_DNODE(os); } else { - err = dnode_hold(os->os, record->zi_object, FTAG, &dn); + err = dnode_hold(os, record->zi_object, FTAG, &dn); if (err != 0) { (void) fprintf(stderr, "failed to hold dnode " "for object %llu\n", @@ -306,11 +321,11 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range, ret = 0; out: if (dn) { - if (dn != os->os->os_meta_dnode) + if (dn != DMU_META_DNODE(os)) dnode_rele(dn, FTAG); } if (os) - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); return (ret); } @@ -335,6 +350,8 @@ translate_record(err_type_t type, const char *object, const char *range, * MOS objects are treated specially. */ switch (type) { + default: + break; case TYPE_MOS: record->zi_type = 0; break; @@ -347,8 +364,8 @@ translate_record(err_type_t type, const char *object, const char *range, case TYPE_CONFIG: record->zi_type = DMU_OT_PACKED_NVLIST; break; - case TYPE_BPLIST: - record->zi_type = DMU_OT_BPLIST; + case TYPE_BPOBJ: + record->zi_type = DMU_OT_BPOBJ; break; case TYPE_SPACEMAP: record->zi_type = DMU_OT_SPACE_MAP; @@ -460,7 +477,23 @@ translate_device(const char *pool, const char *device, err_type_t label_type, &record->zi_guid) == 0); } + /* + * Device faults can take on three different forms: + * 1). delayed or hanging I/O + * 2). zfs label faults + * 3). generic disk faults + */ + if (record->zi_timer != 0) { + record->zi_cmd = ZINJECT_DELAY_IO; + } else if (label_type != TYPE_INVAL) { + record->zi_cmd = ZINJECT_LABEL_FAULT; + } else { + record->zi_cmd = ZINJECT_DEVICE_FAULT; + } + switch (label_type) { + default: + break; case TYPE_LABEL_UBERBLOCK: record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]); record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1; @@ -469,6 +502,14 @@ translate_device(const char *pool, const char *device, err_type_t label_type, record->zi_start = offsetof(vdev_label_t, vl_vdev_phys); record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1; break; + case TYPE_LABEL_PAD1: + record->zi_start = offsetof(vdev_label_t, vl_pad1); + record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1; + break; + case TYPE_LABEL_PAD2: + record->zi_start = offsetof(vdev_label_t, vl_pad2); + record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1; + break; } return (0); }