From 9fca71287d2c9730139a0472c6ee891603e72672 Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Fri, 15 Feb 2013 16:58:16 -0500 Subject: [PATCH] vos: move convertROtoRW core logic to vsprocs Create new vsprocs routine UV_ConvertRO in preparation for adding new function to vos convertROtoRW. Change-Id: Ic66ecbf7cacb277891bec9f8783040995ce6ce17 Reviewed-on: http://gerrit.openafs.org/9277 Tested-by: BuildBot Reviewed-by: D Brashear --- src/volser/liboafs_volser.la.sym | 1 + src/volser/volser_internal.h | 3 +- src/volser/vos.c | 111 +--------------------- src/volser/vsprocs.c | 153 +++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 110 deletions(-) diff --git a/src/volser/liboafs_volser.la.sym b/src/volser/liboafs_volser.la.sym index 7f7875ca8..f827c6d84 100644 --- a/src/volser/liboafs_volser.la.sym +++ b/src/volser/liboafs_volser.la.sym @@ -16,6 +16,7 @@ UV_BackupVolume UV_Bind UV_ChangeLocation UV_CloneVolume +UV_ConvertRO UV_CopyVolume2 UV_CreateVolume3 UV_DeleteVolume diff --git a/src/volser/volser_internal.h b/src/volser/volser_internal.h index c082e0cef..adf48e124 100644 --- a/src/volser/volser_internal.h +++ b/src/volser/volser_internal.h @@ -126,7 +126,8 @@ extern int UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver, extern int UV_GetSize(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart, afs_int32 fromdate, struct volintSize *vol_size); - +extern int UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid, + struct nvldbentry *entry); extern int verbose; extern int noresolve; #endif diff --git a/src/volser/vos.c b/src/volser/vos.c index 78b8cc41a..b6cb029e8 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -5504,16 +5504,13 @@ ConvertRO(struct cmd_syndesc *as, void *arock) afs_uint32 volid; afs_uint32 server; afs_int32 code, i, same; - struct nvldbentry entry, checkEntry, storeEntry; + struct nvldbentry entry; afs_int32 vcode; - afs_int32 rwindex = 0; afs_uint32 rwserver = 0; afs_int32 rwpartition = 0; - afs_int32 roindex = 0; afs_uint32 roserver = 0; afs_int32 ropartition = 0; int force = 0; - struct rx_connection *aconn; int c, dc; server = GetServer(as->parms[0].items->data); @@ -5566,7 +5563,6 @@ ConvertRO(struct cmd_syndesc *as, void *arock) MapHostToNetwork(&entry); for (i = 0; i < entry.nServers; i++) { if (entry.serverFlags[i] & ITSRWVOL) { - rwindex = i; rwserver = entry.serverNumber[i]; rwpartition = entry.serverPartition[i]; if (roserver) @@ -5580,7 +5576,6 @@ ConvertRO(struct cmd_syndesc *as, void *arock) return ENOENT; } if (same) { - roindex = i; roserver = entry.serverNumber[i]; ropartition = entry.serverPartition[i]; if (rwserver) @@ -5614,110 +5609,8 @@ ConvertRO(struct cmd_syndesc *as, void *arock) } } - vcode = - ubik_VL_SetLock(cstruct, 0, entry.volumeId[RWVOL], RWVOL, - VLOP_MOVE); - if (vcode) { - fprintf(STDERR, - "Unable to lock volume %lu, code %d\n", - (unsigned long)entry.volumeId[RWVOL],vcode); - 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) { - fprintf(STDERR, - "Converting RO volume %lu to RW volume failed with code %d\n", - (unsigned long)volid, code); - PrintError("convertROtoRW ", code); - goto error_exit; - } - /* Update the VLDB to match what we did on disk as much as possible. */ - /* If the converted RO was in the VLDB, make it look like the new RW. */ - if (roserver) { - entry.serverFlags[roindex] = ITSRWVOL; - } else { - /* Add a new site entry for the newly created RW. It's possible - * (but unlikely) that we are already at MAXNSERVERS and that this - * new site will invalidate the whole VLDB entry; however, - * VLDB_ReplaceEntry will detect this and return VL_BADSERVER, - * so we need no extra guard logic here. - */ - afs_int32 newrwindex = entry.nServers; - (entry.nServers)++; - entry.serverNumber[newrwindex] = server; - entry.serverPartition[newrwindex] = partition; - entry.serverFlags[newrwindex] = ITSRWVOL; - } - entry.flags |= RW_EXISTS; - entry.flags &= ~BACK_EXISTS; - - /* if the old RW was in the VLDB, remove it by decrementing the number */ - /* of servers, replacing the RW entry with the last entry, and zeroing */ - /* out the last entry. */ - if (rwserver) { - (entry.nServers)--; - if (rwindex != entry.nServers) { - entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers]; - entry.serverPartition[rwindex] = - entry.serverPartition[entry.nServers]; - entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers]; - entry.serverNumber[entry.nServers] = 0; - entry.serverPartition[entry.nServers] = 0; - entry.serverFlags[entry.nServers] = 0; - } - } - entry.flags &= ~RO_EXISTS; - for (i = 0; i < entry.nServers; i++) { - if (entry.serverFlags[i] & ITSROVOL) { - if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE))) - entry.flags |= RO_EXISTS; - } - } - MapNetworkToHost(&entry, &storeEntry); - code = - VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry, - (LOCKREL_OPCODE | LOCKREL_AFSID | - LOCKREL_TIMESTAMP)); - if (code) { - fprintf(STDERR, - "Warning: volume converted, but vldb update failed with code %d!\n", - code); - } + code = UV_ConvertRO(server, partition, volid, &entry); - error_exit: - vcode = UV_LockRelease(entry.volumeId[RWVOL]); - if (vcode) { - fprintf(STDERR, - "Unable to unlock volume %lu, code %d\n", - (unsigned long)entry.volumeId[RWVOL],vcode); - PrintError("", vcode); - } return code; } diff --git a/src/volser/vsprocs.c b/src/volser/vsprocs.c index 9366dcb94..6bd35d6b4 100644 --- a/src/volser/vsprocs.c +++ b/src/volser/vsprocs.c @@ -1338,6 +1338,159 @@ cfail: return error; } +/* Convert volume from RO to RW; adjust the VLDB entry to match. + * The nvldbentry passed to us has already been MapHostToNetwork'd + * by the caller. + */ + +int +UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid, + struct nvldbentry *entry) +{ + afs_int32 code, i, same; + struct nvldbentry checkEntry, storeEntry; + afs_int32 vcode; + afs_int32 rwindex = 0; + afs_uint32 rwserver = 0; + afs_int32 roindex = 0; + afs_uint32 roserver = 0; + struct rx_connection *aconn; + + vcode = + ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL, + VLOP_MOVE); + if (vcode) { + fprintf(STDERR, + "Unable to lock volume %lu, code %d\n", + (unsigned long)entry->volumeId[RWVOL],vcode); + 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; + } + + /* extract information from the original entry */ + for (i = 0; i < entry->nServers; i++) { + if (entry->serverFlags[i] & ITSRWVOL) { + rwindex = i; + rwserver = entry->serverNumber[i]; + /* rwpartition = entry->serverPartition[i]; */ + if (roserver) + break; + } else if ((entry->serverFlags[i] & ITSROVOL) && !roserver) { + same = VLDB_IsSameAddrs(server, entry->serverNumber[i], &code); + if (code) { + fprintf(STDERR, + "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n", + server, code); + code = ENOENT; + goto error_exit; + } + if (same) { + roindex = i; + roserver = entry->serverNumber[i]; + /* ropartition = entry->serverPartition[i]; */ + if (rwserver) + break; + } + } + } + + aconn = UV_Bind(server, AFSCONF_VOLUMEPORT); + code = AFSVolConvertROtoRWvolume(aconn, partition, volid); + if (code) { + fprintf(STDERR, + "Converting RO volume %lu to RW volume failed with code %d\n", + (unsigned long)volid, code); + PrintError("convertROtoRW ", code); + goto error_exit; + } + /* Update the VLDB to match what we did on disk as much as possible. */ + /* If the converted RO was in the VLDB, make it look like the new RW. */ + if (roserver) { + entry->serverFlags[roindex] = ITSRWVOL; + } else { + /* Add a new site entry for the newly created RW. It's possible + * (but unlikely) that we are already at MAXNSERVERS and that this + * new site will invalidate the whole VLDB entry; however, + * VLDB_ReplaceEntry will detect this and return VL_BADSERVER, + * so we need no extra guard logic here. + */ + afs_int32 newrwindex = entry->nServers; + (entry->nServers)++; + entry->serverNumber[newrwindex] = server; + entry->serverPartition[newrwindex] = partition; + entry->serverFlags[newrwindex] = ITSRWVOL; + } + entry->flags |= RW_EXISTS; + entry->flags &= ~BACK_EXISTS; + + /* if the old RW was in the VLDB, remove it by decrementing the number */ + /* of servers, replacing the RW entry with the last entry, and zeroing */ + /* out the last entry. */ + if (rwserver) { + (entry->nServers)--; + if (rwindex != entry->nServers) { + entry->serverNumber[rwindex] = entry->serverNumber[entry->nServers]; + entry->serverPartition[rwindex] = + entry->serverPartition[entry->nServers]; + entry->serverFlags[rwindex] = entry->serverFlags[entry->nServers]; + entry->serverNumber[entry->nServers] = 0; + entry->serverPartition[entry->nServers] = 0; + entry->serverFlags[entry->nServers] = 0; + } + } + entry->flags &= ~RO_EXISTS; + for (i = 0; i < entry->nServers; i++) { + if (entry->serverFlags[i] & ITSROVOL) { + if (!(entry->serverFlags[i] & (RO_DONTUSE | NEW_REPSITE))) + entry->flags |= RO_EXISTS; + } + } + MapNetworkToHost(entry, &storeEntry); + code = + VLDB_ReplaceEntry(entry->volumeId[RWVOL], RWVOL, &storeEntry, + (LOCKREL_OPCODE | LOCKREL_AFSID | + LOCKREL_TIMESTAMP)); + if (code) { + fprintf(STDERR, + "Warning: volume converted, but vldb update failed with code %d!\n", + code); + } + + error_exit: + vcode = UV_LockRelease(entry->volumeId[RWVOL]); + if (vcode) { + fprintf(STDERR, + "Unable to unlock volume %lu, code %d\n", + (unsigned long)entry->volumeId[RWVOL],vcode); + PrintError("", vcode); + } + return code; +} + + /* Move volume on to * . The operation is almost idempotent. The following * flags are recognized: -- 2.39.5