From 3c489db55811dfe3fdf5e555bf229989e5b58aa6 Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Mon, 20 Aug 2012 17:39:06 -0400 Subject: [PATCH] vos: convertROtoRW susceptible to VLDB changes during override prompt vos convertROtoRW obtains a VLDB entry, then peforms some setup logic (including a possible user prompt) before obtaining a volume lock. This exposes the code to possible time-of-check/time-of-use issues. After obtaining the volume lock, get a second copy of the VLDB entry and compare it to the first copy; if it has changed, fail the conversion with an error message asking the user to re-issue the vos convertROtoRW command. Change-Id: I9c1a634cea2e22188869d54b00b7831aed12b1cd Reviewed-on: http://gerrit.openafs.org/8008 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/volser/vos.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/volser/vos.c b/src/volser/vos.c index fc43f5d..89b5bd8 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -5497,7 +5497,7 @@ ConvertRO(struct cmd_syndesc *as, void *arock) afs_uint32 volid; afs_uint32 server; afs_int32 code, i, same; - struct nvldbentry entry, storeEntry; + struct nvldbentry entry, checkEntry, storeEntry; afs_int32 vcode; afs_int32 rwindex = 0; afs_uint32 rwserver = 0; @@ -5542,6 +5542,7 @@ ConvertRO(struct cmd_syndesc *as, void *arock) if (as->parms[3].items) force = 1; + memset(&entry, 0, sizeof(entry)); vcode = VLDB_GetEntryByID(volid, -1, &entry); if (vcode) { fprintf(STDERR, @@ -5552,7 +5553,6 @@ ConvertRO(struct cmd_syndesc *as, void *arock) } /* use RO volid even if user specified RW or BK volid */ - if (volid != entry.volumeId[ROVOL]) volid = entry.volumeId[ROVOL]; @@ -5617,6 +5617,30 @@ ConvertRO(struct cmd_syndesc *as, void *arock) PrintError("", vcode); return -1; } + + /* make sure the VLDB entry hasn't changed since we started */ + memset(&checkEntry, 0, sizeof(checkEntry)); + vcode = VLDB_GetEntryByID(volid, -1, &checkEntry); + if (vcode) { + fprintf(STDERR, + "Could not fetch the entry for volume %lu from VLDB\n", + (unsigned long)volid); + PrintError("convertROtoRW ", vcode); + code = vcode; + goto error_exit; + } + + MapHostToNetwork(&checkEntry); + entry.flags &= ~VLOP_ALLOPERS; /* clear any stale lock operation flags */ + entry.flags |= VLOP_MOVE; /* set to match SetLock operation above */ + if (memcmp(&entry, &checkEntry, sizeof(entry)) != 0) { + fprintf(STDERR, + "VLDB entry for volume %lu has changed; please reissue the command.\n", + (unsigned long)volid); + code = -1; + goto error_exit; + } + aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); code = AFSVolConvertROtoRWvolume(aconn, partition, volid); if (code) { -- 1.9.4