git://git.camperquake.de
/
zfs.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix read-only pool hang on unmount
[zfs.git]
/
cmd
/
zinject
/
zinject.c
diff --git
a/cmd/zinject/zinject.c
b/cmd/zinject/zinject.c
index
3ad90e3
..
13d067d
100644
(file)
--- a/
cmd/zinject/zinject.c
+++ b/
cmd/zinject/zinject.c
@@
-20,6
+20,7
@@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
*/
/*
@@
-235,8
+236,8
@@
usage(void)
"\t\t'pad1', or 'pad2'.\n"
"\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n"
"\n"
"\t\t'pad1', or 'pad2'.\n"
"\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n"
"\n"
- "\tzinject -d device -A <degrade|fault> pool\n"
- "\t\tPerform a specific action on a particular device\n"
+ "\tzinject -d device -A <degrade|fault>
-D <delay secs>
pool\n"
+ "\t\tPerform a specific action on a particular device
.
\n"
"\n"
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
"\t\tCause the pool to stop writing blocks yet not\n"
"\n"
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
"\t\tCause the pool to stop writing blocks yet not\n"
@@
-566,13
+567,23
@@
main(int argc, char **argv)
zinject_record_t record = { 0 };
char pool[MAXNAMELEN];
char dataset[MAXNAMELEN];
zinject_record_t record = { 0 };
char pool[MAXNAMELEN];
char dataset[MAXNAMELEN];
- zfs_handle_t *zhp;
+ zfs_handle_t *zhp
= NULL
;
int nowrites = 0;
int dur_txg = 0;
int dur_secs = 0;
int ret;
int flags = 0;
int nowrites = 0;
int dur_txg = 0;
int dur_secs = 0;
int ret;
int flags = 0;
+ if ((g_zfs = libzfs_init()) == NULL)
+ return (1);
+
+ libzfs_print_on_error(g_zfs, B_TRUE);
+
+ if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
+ (void) fprintf(stderr, "failed to open ZFS device\n");
+ return (1);
+ }
+
if (argc == 1) {
/*
* No arguments. Print the available handlers. If there are no
if (argc == 1) {
/*
* No arguments. Print the available handlers. If there are no
@@
-589,7
+600,7
@@
main(int argc, char **argv)
}
while ((c = getopt(argc, argv,
}
while ((c = getopt(argc, argv,
- ":aA:b:d:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
+ ":aA:b:d:
D:
f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
@@
-615,6
+626,16
@@
main(int argc, char **argv)
case 'd':
device = optarg;
break;
case 'd':
device = optarg;
break;
+ case 'D':
+ errno = 0;
+ record.zi_timer = strtoull(optarg, &end, 10);
+ if (errno != 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid i/o delay "
+ "value: '%s'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
case 'e':
if (strcasecmp(optarg, "io") == 0) {
error = EIO;
case 'e':
if (strcasecmp(optarg, "io") == 0) {
error = EIO;
@@
-679,6
+700,7
@@
main(int argc, char **argv)
case 'p':
(void) strlcpy(record.zi_func, optarg,
sizeof (record.zi_func));
case 'p':
(void) strlcpy(record.zi_func, optarg,
sizeof (record.zi_func));
+ record.zi_cmd = ZINJECT_PANIC;
break;
case 'q':
quiet = 1;
break;
case 'q':
quiet = 1;
@@
-752,23
+774,15
@@
main(int argc, char **argv)
argc -= optind;
argv += optind;
argc -= optind;
argv += optind;
- if ((g_zfs = libzfs_init()) == NULL)
- return (1);
-
- libzfs_print_on_error(g_zfs, B_TRUE);
-
- if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
- (void) fprintf(stderr, "failed to open ZFS device\n");
- return (1);
- }
+ if (record.zi_duration != 0)
+ record.zi_cmd = ZINJECT_IGNORED_WRITES;
if (cancel != NULL) {
/*
* '-c' is invalid with any other options.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
if (cancel != NULL) {
/*
* '-c' is invalid with any other options.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || record.zi_func[0] != '\0' ||
- record.zi_duration != 0) {
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
@@
-800,8
+814,7
@@
main(int argc, char **argv)
* for doing injection, so handle it separately here.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
* for doing injection, so handle it separately here.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || record.zi_func[0] != '\0' ||
- record.zi_duration != 0) {
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
@@
-835,7
+848,7
@@
main(int argc, char **argv)
} else if (raw != NULL) {
if (range != NULL || type != TYPE_INVAL || level != 0 ||
} else if (raw != NULL) {
if (range != NULL || type != TYPE_INVAL || level != 0 ||
- record.zi_
func[0] != '\0' || record.zi_duration != 0
) {
+ record.zi_
cmd != ZINJECT_UNINITIALIZED
) {
(void) fprintf(stderr, "raw (-b) format with "
"any other options\n");
usage();
(void) fprintf(stderr, "raw (-b) format with "
"any other options\n");
usage();
@@
-858,13
+871,14
@@
main(int argc, char **argv)
return (1);
}
return (1);
}
+ record.zi_cmd = ZINJECT_DATA_FAULT;
if (translate_raw(raw, &record) != 0)
return (1);
if (!error)
error = EIO;
if (translate_raw(raw, &record) != 0)
return (1);
if (!error)
error = EIO;
- } else if (record.zi_
func[0] != '\0'
) {
+ } else if (record.zi_
cmd == ZINJECT_PANIC
) {
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || device != NULL
|| record.zi_duration != 0
) {
+ level != 0 || device != NULL) {
(void) fprintf(stderr, "panic (-p) incompatible with "
"other options\n");
usage();
(void) fprintf(stderr, "panic (-p) incompatible with "
"other options\n");
usage();
@@
-882,7
+896,7
@@
main(int argc, char **argv)
if (argv[1] != NULL)
record.zi_type = atoi(argv[1]);
dataset[0] = '\0';
if (argv[1] != NULL)
record.zi_type = atoi(argv[1]);
dataset[0] = '\0';
- } else if (record.zi_
duration != 0
) {
+ } else if (record.zi_
cmd == ZINJECT_IGNORED_WRITES
) {
if (nowrites == 0) {
(void) fprintf(stderr, "-s or -g meaningless "
"without -I (ignore writes)\n");
if (nowrites == 0) {
(void) fprintf(stderr, "-s or -g meaningless "
"without -I (ignore writes)\n");
@@
-936,6
+950,7
@@
main(int argc, char **argv)
return (1);
}
return (1);
}
+ record.zi_cmd = ZINJECT_DATA_FAULT;
if (translate_record(type, argv[0], range, level, &record, pool,
dataset) != 0)
return (1);
if (translate_record(type, argv[0], range, level, &record, pool,
dataset) != 0)
return (1);
@@
-951,20
+966,16
@@
main(int argc, char **argv)
if (dataset[0] != '\0' && domount) {
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
if (dataset[0] != '\0' && domount) {
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
-#ifdef HAVE_ZPL
if (zfs_unmount(zhp, NULL, 0) != 0)
return (1);
if (zfs_unmount(zhp, NULL, 0) != 0)
return (1);
-#endif /* HAVE_ZPL */
}
record.zi_error = error;
ret = register_handler(pool, flags, &record, quiet);
}
record.zi_error = error;
ret = register_handler(pool, flags, &record, quiet);
-#ifdef HAVE_ZPL
if (dataset[0] != '\0' && domount)
ret = (zfs_mount(zhp, NULL, 0) != 0);
if (dataset[0] != '\0' && domount)
ret = (zfs_mount(zhp, NULL, 0) != 0);
-#endif /* HAVE_ZPL */
libzfs_fini(g_zfs);
libzfs_fini(g_zfs);