Skip to content

Commit

Permalink
Rework find_by_guid
Browse files Browse the repository at this point in the history
Account for spare and L2cache vdevs by skipping the txg for those devices.
Removed besting check for find by guid.
  • Loading branch information
evansus committed Jun 17, 2014
1 parent d44e519 commit 0c6e5cc
Showing 1 changed file with 46 additions and 15 deletions.
61 changes: 46 additions & 15 deletions module/zfs/vdev_iokit_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ vdev_iokit_find_by_guid(vdev_iokit_t * dvd, uint64_t guid)
nvlist_t * config = 0;

uint64_t min_size = SPA_MINDEVSIZE; /* 64 Mb */
uint64_t txg = 0, besttxg = 0;
uint64_t state = 0, txg = 0;
uint64_t current_guid = 0;

if (!dvd || guid == 0)
Expand Down Expand Up @@ -787,8 +787,10 @@ vdev_iokit_find_by_guid(vdev_iokit_t * dvd, uint64_t guid)
/* Try to read a config label from this disk */
if (vdev_iokit_read_label(dvd, &config) != 0) {
/* Failed to read config */
if (config)
if (config) {
nvlist_free(config);
config = 0;
}

/* No config found - clear the vd_iokit_hl */
dvd->vd_iokit_hl = 0;
Expand All @@ -803,15 +805,32 @@ vdev_iokit_find_by_guid(vdev_iokit_t * dvd, uint64_t guid)
/* Checking config - clear the vd_iokit_hl meanwhile */
dvd->vd_iokit_hl = 0;

/* Get and check txg and guid */
/*
* Check that a valid config was loaded
* skip devices that are unavailable,
* uninitialized, or potentially active
*/
if (nvlist_lookup_uint64(config,
ZPOOL_CONFIG_POOL_TXG, &txg) != 0 ||
nvlist_lookup_uint64(config,
ZPOOL_CONFIG_GUID, &current_guid) != 0 ||
txg < besttxg || current_guid != guid) {
ZPOOL_CONFIG_POOL_STATE, &state) != 0 ||
state > POOL_STATE_L2CACHE) {

txg = 0;
current_guid = 0;
nvlist_free(config);
config = 0;

/* Pop from list */
allDisks->removeObject(currentEntry);
currentEntry = 0;
currentDisk = 0;
continue;
}

/*
* Fetch txg number unless spare or l2cache
*/
if (state != POOL_STATE_SPARE &&
state != POOL_STATE_L2CACHE &&
(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {

nvlist_free(config);
config = 0;
Expand All @@ -823,12 +842,21 @@ vdev_iokit_find_by_guid(vdev_iokit_t * dvd, uint64_t guid)
continue;
}

besttxg = txg;
/* Get and check guid */
if (nvlist_lookup_uint64(config,
ZPOOL_CONFIG_GUID, &current_guid) != 0 ||
current_guid != guid) {

/* Previous match? Release it */
if (matchedDisk) {
matchedDisk->release();
matchedDisk = 0;
current_guid = 0;

nvlist_free(config);
config = 0;

/* Pop from list */
allDisks->removeObject(currentEntry);
currentEntry = 0;
currentDisk = 0;
continue;
}

/* Save it and up the retain count */
Expand All @@ -840,7 +868,10 @@ vdev_iokit_find_by_guid(vdev_iokit_t * dvd, uint64_t guid)
currentEntry = 0;
currentDisk = 0;

/* Loop in case there is a better match */
/* Find by guid breaks on the first match */
if (matchedDisk) {
break;
}
}

if (config) {
Expand Down

2 comments on commit 0c6e5cc

@evansus
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rottegift OK This should do it. I've tested (lightly) with manual import and cachefile import, with all devices present, all devices renumbered, and with an individual cache device missing. Seems to be working in all cases I've tried.

find_by_guid is now aware of spare / L2cache devices so this should solve the issues we were running into.

When you have a chance, could you build and test this on your end?

@rottegift
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, on it.

Please sign in to comment.