From f01486033289ee0868f7b35772abbc852d943243 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Thu, 23 Jun 2016 11:24:10 -0400 Subject: [PATCH] Fix detection of devmapper metadata reservation Because new versions of devicemapper may add additional fields to the output of 'dmsetup status', change the check to use SplitN to get the minimum fields required, and ignore any additional fields after the one we care about. --- devicemapper/thin_pool_watcher.go | 14 +++++++------- devicemapper/thin_pool_watcher_test.go | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/devicemapper/thin_pool_watcher.go b/devicemapper/thin_pool_watcher.go index 4062f1fe..bf2300a3 100644 --- a/devicemapper/thin_pool_watcher.go +++ b/devicemapper/thin_pool_watcher.go @@ -150,8 +150,8 @@ func (w *ThinPoolWatcher) Refresh() error { } const ( - thinPoolDmsetupStatusTokens = 11 thinPoolDmsetupStatusHeldMetadataRoot = 6 + thinPoolDmsetupStatusMinFields = thinPoolDmsetupStatusHeldMetadataRoot + 1 ) // checkReservation checks to see whether the thin device is currently holding @@ -163,14 +163,14 @@ func (w *ThinPoolWatcher) checkReservation(poolName string) (bool, error) { return false, err } - tokens := strings.Split(string(output), " ") - // Split returns the input as the last item in the result, adjust the - // number of tokens by one - if len(tokens) != thinPoolDmsetupStatusTokens+1 { - return false, fmt.Errorf("unexpected output of dmsetup status command; expected 11 fields, got %v; output: %v", len(tokens), string(output)) + // we care about the field at fields[thinPoolDmsetupStatusHeldMetadataRoot], + // so make sure we get enough fields + fields := strings.Fields(string(output)) + if len(fields) < thinPoolDmsetupStatusMinFields { + return false, fmt.Errorf("unexpected output of dmsetup status command; expected at least %d fields, got %v; output: %v", thinPoolDmsetupStatusMinFields, len(fields), string(output)) } - heldMetadataRoot := tokens[thinPoolDmsetupStatusHeldMetadataRoot] + heldMetadataRoot := fields[thinPoolDmsetupStatusHeldMetadataRoot] currentlyReserved := heldMetadataRoot != "-" return currentlyReserved, nil } diff --git a/devicemapper/thin_pool_watcher_test.go b/devicemapper/thin_pool_watcher_test.go index 27039add..a4862fc1 100644 --- a/devicemapper/thin_pool_watcher_test.go +++ b/devicemapper/thin_pool_watcher_test.go @@ -45,6 +45,18 @@ func TestRefresh(t *testing.T) { }, expectedError: true, }, + { + name: "no existing reservation - ok with minimum # of fields", + dmsetupCommands: []fake.DmsetupCommand{ + {"status", "0 75497472 thin-pool 65 327/524288 14092/589824 -", nil}, // status check + {"message", "", nil}, // make reservation + {"message", "", nil}, // release reservation + }, + thinLsOutput: usage, + expectedError: false, + deviceId: "2", + expectedUsage: 23456, + }, { name: "no existing reservation - ok", dmsetupCommands: []fake.DmsetupCommand{ @@ -182,11 +194,6 @@ func TestCheckReservation(t *testing.T) { statusResult: "0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - ", expectedResult: false, }, - { - name: "malformed input", - statusResult: "0 12345 14092/45678 36 rw discard_passdown error_if_no_space needs_check ", - expectedErr: fmt.Errorf("not gonna work"), - }, } for _, tc := range cases {