aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/zdb/zdb.c
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2019-08-13 08:11:57 -0600
committerBrian Behlendorf <[email protected]>2019-08-13 08:11:57 -0600
commitc8242a96ba8495013cc2f2e12ea6202e61796462 (patch)
tree89367092fe6fde1942c7cf6d05721ce40807e3fc /cmd/zdb/zdb.c
parenta43570c5f3ca11957c23b4e073a520963cd9cfb2 (diff)
spa_load_verify() may consume too much memory
When a pool is imported it will scan the pool to verify the integrity of the data and metadata. The amount it scans will depend on the import flags provided. On systems with small amounts of memory or when importing a pool from the crash kernel, it's possible for spa_load_verify to issue too many I/Os that it consumes all the memory of the system resulting in an OOM message or a hang. To prevent this, we limit the amount of memory that the initial pool scan can consume. This change will, by default, use 1/16th of the ARC for scan I/Os to prevent running the system out of memory during import. Reviewed-by: Matt Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Signed-off-by: George Wilson [email protected] External-issue: DLPX-65237 External-issue: DLPX-65238 Closes #9146
Diffstat (limited to 'cmd/zdb/zdb.c')
-rw-r--r--cmd/zdb/zdb.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 088ef3c05..e05323f0a 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -111,7 +111,7 @@ typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
uint64_t *zopt_object = NULL;
static unsigned zopt_objects = 0;
-uint64_t max_inflight = 1000;
+uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
static int leaked_objects = 0;
static range_tree_t *mos_refd_objs;
@@ -3806,7 +3806,7 @@ zdb_blkptr_done(zio_t *zio)
abd_free(zio->io_abd);
mutex_enter(&spa->spa_scrub_lock);
- spa->spa_load_verify_ios--;
+ spa->spa_load_verify_bytes -= BP_GET_PSIZE(bp);
cv_broadcast(&spa->spa_scrub_io_cv);
if (ioerr && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
@@ -3877,9 +3877,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
flags |= ZIO_FLAG_SPECULATIVE;
mutex_enter(&spa->spa_scrub_lock);
- while (spa->spa_load_verify_ios > max_inflight)
+ while (spa->spa_load_verify_bytes > max_inflight_bytes)
cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
- spa->spa_load_verify_ios++;
+ spa->spa_load_verify_bytes += size;
mutex_exit(&spa->spa_scrub_lock);
zio_nowait(zio_read(NULL, spa, bp, abd, size,
@@ -4895,6 +4895,7 @@ dump_block_stats(spa_t *spa)
ZIO_FLAG_GODFATHER);
}
}
+ ASSERT0(spa->spa_load_verify_bytes);
/*
* Done after zio_wait() since zcb_haderrors is modified in
@@ -6681,10 +6682,10 @@ main(int argc, char **argv)
break;
/* NB: Sort single match options below. */
case 'I':
- max_inflight = strtoull(optarg, NULL, 0);
- if (max_inflight == 0) {
+ max_inflight_bytes = strtoull(optarg, NULL, 0);
+ if (max_inflight_bytes == 0) {
(void) fprintf(stderr, "maximum number "
- "of inflight I/Os must be greater "
+ "of inflight bytes must be greater "
"than 0\n");
usage();
}