Skip to content

Commit a43cb21

Browse files
allanjudedon-brady
andcommitted
Extend import_progress kstat with a notes field
Detail the import progress of log spacemaps as they can take a very long time. Also grab the spa_note() messages to, as they provide insight into what is happening Sponsored-By: OpenDrives Inc. Sponsored-By: Klara Inc. Co-authored-by: Don Brady <[email protected]> Signed-off-by: Don Brady <[email protected]>
1 parent a94860a commit a43cb21

File tree

6 files changed

+250
-6
lines changed

6 files changed

+250
-6
lines changed

include/sys/spa.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,9 @@ extern int spa_import_progress_set_max_txg(uint64_t pool_guid,
971971
uint64_t max_txg);
972972
extern int spa_import_progress_set_state(uint64_t pool_guid,
973973
spa_load_state_t spa_load_state);
974+
extern void spa_import_progress_set_notes(spa_t *spa, const char *notes);
975+
extern void spa_import_progress_set_notes_nolog(spa_t *spa,
976+
const char *notes);
974977

975978
/* Pool configuration locks */
976979
extern int spa_config_tryenter(spa_t *spa, int locks, const void *tag,

module/zfs/spa.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type)
31093109
spa->spa_load_state = state;
31103110
(void) spa_import_progress_set_state(spa_guid(spa),
31113111
spa_load_state(spa));
3112+
spa_import_progress_set_notes(spa, "spa_load()");
31123113

31133114
gethrestime(&spa->spa_loaded_ts);
31143115
error = spa_load_impl(spa, type, &ereport);
@@ -3375,6 +3376,12 @@ spa_activity_check(spa_t *spa, uberblock_t *ub, nvlist_t *config)
33753376

33763377
import_expire = gethrtime() + import_delay;
33773378

3379+
char buf[128];
3380+
(void) snprintf(buf, sizeof (buf), "Checking MMP activity, waiting "
3381+
"%llu ms", (u_longlong_t)NSEC2MSEC(import_delay));
3382+
spa_import_progress_set_notes(spa, buf);
3383+
3384+
int interations = 0;
33783385
while (gethrtime() < import_expire) {
33793386
(void) spa_import_progress_set_mmp_check(spa_guid(spa),
33803387
NSEC2SEC(import_expire - gethrtime()));
@@ -3408,6 +3415,14 @@ spa_activity_check(spa_t *spa, uberblock_t *ub, nvlist_t *config)
34083415
break;
34093416
}
34103417
error = 0;
3418+
3419+
if (interations++ % 30 == 0 && import_expire > gethrtime()) {
3420+
uint64_t remaining = import_expire - gethrtime();
3421+
(void) snprintf(buf, sizeof (buf), "Checking MMP "
3422+
"activity, %llu ms remaining",
3423+
(u_longlong_t)remaining);
3424+
spa_import_progress_set_notes(spa, buf);
3425+
}
34113426
}
34123427

34133428
out:
@@ -4995,6 +5010,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
49955010
/*
49965011
* Retrieve the checkpoint txg if the pool has a checkpoint.
49975012
*/
5013+
spa_import_progress_set_notes(spa, "Loading checkpoint txg");
49985014
error = spa_ld_read_checkpoint_txg(spa);
49995015
if (error != 0)
50005016
return (error);
@@ -5007,6 +5023,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50075023
* initiated. Otherwise we could be reading from indirect vdevs before
50085024
* we have loaded their mappings.
50095025
*/
5026+
spa_import_progress_set_notes(spa, "Loading indirect vdev metadata");
50105027
error = spa_ld_open_indirect_vdev_metadata(spa);
50115028
if (error != 0)
50125029
return (error);
@@ -5015,6 +5032,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50155032
* Retrieve the full list of active features from the MOS and check if
50165033
* they are all supported.
50175034
*/
5035+
spa_import_progress_set_notes(spa, "Checking feature flags");
50185036
error = spa_ld_check_features(spa, &missing_feat_write);
50195037
if (error != 0)
50205038
return (error);
@@ -5023,13 +5041,15 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50235041
* Load several special directories from the MOS needed by the dsl_pool
50245042
* layer.
50255043
*/
5044+
spa_import_progress_set_notes(spa, "Loading special MOS directories");
50265045
error = spa_ld_load_special_directories(spa);
50275046
if (error != 0)
50285047
return (error);
50295048

50305049
/*
50315050
* Retrieve pool properties from the MOS.
50325051
*/
5052+
spa_import_progress_set_notes(spa, "Loading properties");
50335053
error = spa_ld_get_props(spa);
50345054
if (error != 0)
50355055
return (error);
@@ -5038,6 +5058,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50385058
* Retrieve the list of auxiliary devices - cache devices and spares -
50395059
* and open them.
50405060
*/
5061+
spa_import_progress_set_notes(spa, "Loading AUX vdevs");
50415062
error = spa_ld_open_aux_vdevs(spa, type);
50425063
if (error != 0)
50435064
return (error);
@@ -5046,14 +5067,17 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50465067
* Load the metadata for all vdevs. Also check if unopenable devices
50475068
* should be autoreplaced.
50485069
*/
5070+
spa_import_progress_set_notes(spa, "Loading vdev metadata");
50495071
error = spa_ld_load_vdev_metadata(spa);
50505072
if (error != 0)
50515073
return (error);
50525074

5075+
spa_import_progress_set_notes(spa, "Loading dedup tables");
50535076
error = spa_ld_load_dedup_tables(spa);
50545077
if (error != 0)
50555078
return (error);
50565079

5080+
spa_import_progress_set_notes(spa, "Loading BRT");
50575081
error = spa_ld_load_brt(spa);
50585082
if (error != 0)
50595083
return (error);
@@ -5062,6 +5086,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50625086
* Verify the logs now to make sure we don't have any unexpected errors
50635087
* when we claim log blocks later.
50645088
*/
5089+
spa_import_progress_set_notes(spa, "Verifying Log Devices");
50655090
error = spa_ld_verify_logs(spa, type, ereport);
50665091
if (error != 0)
50675092
return (error);
@@ -5083,6 +5108,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50835108
* state. When performing an extreme rewind, we verify the whole pool,
50845109
* which can take a very long time.
50855110
*/
5111+
spa_import_progress_set_notes(spa, "Verifying pool data");
50865112
error = spa_ld_verify_pool_data(spa);
50875113
if (error != 0)
50885114
return (error);
@@ -5092,13 +5118,15 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
50925118
* we write anything to the pool because we'd need to update the space
50935119
* accounting using the deflated sizes.
50945120
*/
5121+
spa_import_progress_set_notes(spa, "Calculating deflated space");
50955122
spa_update_dspace(spa);
50965123

50975124
/*
50985125
* We have now retrieved all the information we needed to open the
50995126
* pool. If we are importing the pool in read-write mode, a few
51005127
* additional steps must be performed to finish the import.
51015128
*/
5129+
spa_import_progress_set_notes(spa, "Starting import");
51025130
if (spa_writeable(spa) && (spa->spa_load_state == SPA_LOAD_RECOVER ||
51035131
spa->spa_load_max_txg == UINT64_MAX)) {
51045132
uint64_t config_cache_txg = spa->spa_config_txg;
@@ -5122,6 +5150,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
51225150
(u_longlong_t)spa->spa_uberblock.ub_checkpoint_txg);
51235151
}
51245152

5153+
spa_import_progress_set_notes(spa, "Claiming ZIL blocks");
51255154
/*
51265155
* Traverse the ZIL and claim all blocks.
51275156
*/
@@ -5141,13 +5170,15 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
51415170
* will have been set for us by ZIL traversal operations
51425171
* performed above.
51435172
*/
5173+
spa_import_progress_set_notes(spa, "Syncing ZIL claims");
51445174
txg_wait_synced(spa->spa_dsl_pool, spa->spa_claim_max_txg);
51455175

51465176
/*
51475177
* Check if we need to request an update of the config. On the
51485178
* next sync, we would update the config stored in vdev labels
51495179
* and the cachefile (by default /etc/zfs/zpool.cache).
51505180
*/
5181+
spa_import_progress_set_notes(spa, "Updating configs");
51515182
spa_ld_check_for_config_update(spa, config_cache_txg,
51525183
update_config_cache);
51535184

@@ -5156,6 +5187,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
51565187
* Then check all DTLs to see if anything needs resilvering.
51575188
* The resilver will be deferred if a rebuild was started.
51585189
*/
5190+
spa_import_progress_set_notes(spa, "Starting resilvers");
51595191
if (vdev_rebuild_active(spa->spa_root_vdev)) {
51605192
vdev_rebuild_restart(spa);
51615193
} else if (!dsl_scan_resilvering(spa->spa_dsl_pool) &&
@@ -5169,6 +5201,8 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
51695201
*/
51705202
spa_history_log_version(spa, "open", NULL);
51715203

5204+
spa_import_progress_set_notes(spa,
5205+
"Restarting device removals");
51725206
spa_restart_removal(spa);
51735207
spa_spawn_aux_threads(spa);
51745208

@@ -5181,19 +5215,26 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
51815215
* auxiliary threads above (from which the livelist
51825216
* deletion zthr is part of).
51835217
*/
5218+
spa_import_progress_set_notes(spa,
5219+
"Cleaning up inconsistent objsets");
51845220
(void) dmu_objset_find(spa_name(spa),
51855221
dsl_destroy_inconsistent, NULL, DS_FIND_CHILDREN);
51865222

51875223
/*
51885224
* Clean up any stale temporary dataset userrefs.
51895225
*/
5226+
spa_import_progress_set_notes(spa,
5227+
"Cleaning up temporary userrefs");
51905228
dsl_pool_clean_tmp_userrefs(spa->spa_dsl_pool);
51915229

51925230
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
5231+
spa_import_progress_set_notes(spa, "Restarting initialize");
51935232
vdev_initialize_restart(spa->spa_root_vdev);
5233+
spa_import_progress_set_notes(spa, "Restarting TRIM");
51945234
vdev_trim_restart(spa->spa_root_vdev);
51955235
vdev_autotrim_restart(spa);
51965236
spa_config_exit(spa, SCL_CONFIG, FTAG);
5237+
spa_import_progress_set_notes(spa, "Finished importing");
51975238
}
51985239

51995240
spa_import_progress_remove(spa_guid(spa));

module/zfs/spa_log_spacemap.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,7 @@ spa_ld_log_sm_data(spa_t *spa)
11531153

11541154
uint_t pn = 0;
11551155
uint64_t ps = 0;
1156+
uint64_t nsm = 0;
11561157
psls = sls = avl_first(&spa->spa_sm_logs_by_txg);
11571158
while (sls != NULL) {
11581159
/* Prefetch log spacemaps up to 16 TXGs or MBs ahead. */
@@ -1185,6 +1186,13 @@ spa_ld_log_sm_data(spa_t *spa)
11851186
summary_add_data(spa, sls->sls_txg,
11861187
sls->sls_mscount, 0, sls->sls_nblocks);
11871188

1189+
char buf[128];
1190+
(void) snprintf(buf, sizeof (buf),
1191+
"Read %llu of %llu log space maps",
1192+
(u_longlong_t)nsm,
1193+
(u_longlong_t)avl_numnodes(&spa->spa_sm_logs_by_txg));
1194+
spa_import_progress_set_notes_nolog(spa, buf);
1195+
11881196
struct spa_ld_log_sm_arg vla = {
11891197
.slls_spa = spa,
11901198
.slls_txg = sls->sls_txg
@@ -1200,6 +1208,7 @@ spa_ld_log_sm_data(spa_t *spa)
12001208

12011209
pn--;
12021210
ps -= space_map_length(sls->sls_sm);
1211+
nsm++;
12031212
space_map_close(sls->sls_sm);
12041213
sls->sls_sm = NULL;
12051214
sls = AVL_NEXT(&spa->spa_sm_logs_by_txg, sls);
@@ -1210,7 +1219,7 @@ spa_ld_log_sm_data(spa_t *spa)
12101219

12111220
hrtime_t read_logs_endtime = gethrtime();
12121221
spa_load_note(spa,
1213-
"read %llu log space maps (%llu total blocks - blksz = %llu bytes) "
1222+
"Read %llu log space maps (%llu total blocks - blksz = %llu bytes) "
12141223
"in %lld ms", (u_longlong_t)avl_numnodes(&spa->spa_sm_logs_by_txg),
12151224
(u_longlong_t)spa_log_sm_nblocks(spa),
12161225
(u_longlong_t)zfs_log_sm_blksz,

module/zfs/spa_misc.c

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ spa_load_note(spa_t *spa, const char *fmt, ...)
426426

427427
zfs_dbgmsg("spa_load(%s, config %s): %s", spa->spa_name,
428428
spa->spa_trust_config ? "trusted" : "untrusted", buf);
429+
430+
spa_import_progress_set_notes_nolog(spa, buf);
429431
}
430432

431433
/*
@@ -2184,6 +2186,7 @@ typedef struct spa_import_progress {
21842186
uint64_t pool_guid; /* unique id for updates */
21852187
char *pool_name;
21862188
spa_load_state_t spa_load_state;
2189+
char *spa_load_notes;
21872190
uint64_t mmp_sec_remaining; /* MMP activity check */
21882191
uint64_t spa_load_max_txg; /* rewind txg */
21892192
procfs_list_node_t smh_node;
@@ -2194,9 +2197,9 @@ spa_history_list_t *spa_import_progress_list = NULL;
21942197
static int
21952198
spa_import_progress_show_header(struct seq_file *f)
21962199
{
2197-
seq_printf(f, "%-20s %-14s %-14s %-12s %s\n", "pool_guid",
2200+
seq_printf(f, "%-20s %-14s %-14s %-12s %-16s %s\n", "pool_guid",
21982201
"load_state", "multihost_secs", "max_txg",
2199-
"pool_name");
2202+
"pool_name", "notes");
22002203
return (0);
22012204
}
22022205

@@ -2205,11 +2208,12 @@ spa_import_progress_show(struct seq_file *f, void *data)
22052208
{
22062209
spa_import_progress_t *sip = (spa_import_progress_t *)data;
22072210

2208-
seq_printf(f, "%-20llu %-14llu %-14llu %-12llu %s\n",
2211+
seq_printf(f, "%-20llu %-14llu %-14llu %-12llu %-16s %s\n",
22092212
(u_longlong_t)sip->pool_guid, (u_longlong_t)sip->spa_load_state,
22102213
(u_longlong_t)sip->mmp_sec_remaining,
22112214
(u_longlong_t)sip->spa_load_max_txg,
2212-
(sip->pool_name ? sip->pool_name : "-"));
2215+
(sip->pool_name ? sip->pool_name : "-"),
2216+
(sip->spa_load_notes ? sip->spa_load_notes : "-"));
22132217

22142218
return (0);
22152219
}
@@ -2223,6 +2227,8 @@ spa_import_progress_truncate(spa_history_list_t *shl, unsigned int size)
22232227
sip = list_remove_head(&shl->procfs_list.pl_list);
22242228
if (sip->pool_name)
22252229
spa_strfree(sip->pool_name);
2230+
if (sip->spa_load_notes)
2231+
spa_strfree(sip->spa_load_notes);
22262232
kmem_free(sip, sizeof (spa_import_progress_t));
22272233
shl->size--;
22282234
}
@@ -2278,6 +2284,10 @@ spa_import_progress_set_state(uint64_t pool_guid,
22782284
sip = list_prev(&shl->procfs_list.pl_list, sip)) {
22792285
if (sip->pool_guid == pool_guid) {
22802286
sip->spa_load_state = load_state;
2287+
if (sip->spa_load_notes != NULL) {
2288+
spa_strfree(sip->spa_load_notes);
2289+
sip->spa_load_notes = NULL;
2290+
}
22812291
error = 0;
22822292
break;
22832293
}
@@ -2287,6 +2297,50 @@ spa_import_progress_set_state(uint64_t pool_guid,
22872297
return (error);
22882298
}
22892299

2300+
static void
2301+
spa_import_progress_set_notes_impl(spa_t *spa, const char *notes,
2302+
boolean_t log_dbgmsg)
2303+
{
2304+
spa_history_list_t *shl = spa_import_progress_list;
2305+
spa_import_progress_t *sip;
2306+
uint64_t pool_guid = spa_guid(spa);
2307+
2308+
if (shl->size == 0)
2309+
return;
2310+
2311+
mutex_enter(&shl->procfs_list.pl_lock);
2312+
for (sip = list_tail(&shl->procfs_list.pl_list); sip != NULL;
2313+
sip = list_prev(&shl->procfs_list.pl_list, sip)) {
2314+
if (sip->pool_guid == pool_guid) {
2315+
if (sip->spa_load_notes != NULL) {
2316+
spa_strfree(sip->spa_load_notes);
2317+
sip->spa_load_notes = NULL;
2318+
}
2319+
if (notes != NULL) {
2320+
sip->spa_load_notes = spa_strdup(notes);
2321+
if (log_dbgmsg) {
2322+
zfs_dbgmsg("'%s' %s", sip->pool_name,
2323+
notes);
2324+
}
2325+
}
2326+
break;
2327+
}
2328+
}
2329+
mutex_exit(&shl->procfs_list.pl_lock);
2330+
}
2331+
2332+
void
2333+
spa_import_progress_set_notes(spa_t *spa, const char *notes)
2334+
{
2335+
spa_import_progress_set_notes_impl(spa, notes, B_TRUE);
2336+
}
2337+
2338+
void
2339+
spa_import_progress_set_notes_nolog(spa_t *spa, const char *notes)
2340+
{
2341+
spa_import_progress_set_notes_impl(spa, notes, B_FALSE);
2342+
}
2343+
22902344
int
22912345
spa_import_progress_set_max_txg(uint64_t pool_guid, uint64_t load_max_txg)
22922346
{
@@ -2355,6 +2409,7 @@ spa_import_progress_add(spa_t *spa)
23552409
poolname = spa_name(spa);
23562410
sip->pool_name = spa_strdup(poolname);
23572411
sip->spa_load_state = spa_load_state(spa);
2412+
sip->spa_load_notes = NULL;
23582413

23592414
mutex_enter(&shl->procfs_list.pl_lock);
23602415
procfs_list_add(&shl->procfs_list, sip);
@@ -2374,6 +2429,8 @@ spa_import_progress_remove(uint64_t pool_guid)
23742429
if (sip->pool_guid == pool_guid) {
23752430
if (sip->pool_name)
23762431
spa_strfree(sip->pool_name);
2432+
if (sip->spa_load_notes)
2433+
spa_strfree(sip->spa_load_notes);
23772434
list_remove(&shl->procfs_list.pl_list, sip);
23782435
shl->size--;
23792436
kmem_free(sip, sizeof (spa_import_progress_t));

tests/runfiles/linux.run

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ tags = ['functional', 'cli_root', 'zpool_expand']
8686
tests = ['zpool_import_hostid_changed',
8787
'zpool_import_hostid_changed_unclean_export',
8888
'zpool_import_hostid_changed_cachefile',
89-
'zpool_import_hostid_changed_cachefile_unclean_export']
89+
'zpool_import_hostid_changed_cachefile_unclean_export',
90+
'zpool_import_status']
9091
tags = ['functional', 'cli_root', 'zpool_import']
9192

9293
[tests/functional/cli_root/zpool_reopen:Linux]

0 commit comments

Comments
 (0)