[OpenAFS] Re: status of "vos clone/shadow"?
Dan Hyde
Dan Hyde <drh@umich.edu>
Thu, 28 Jun 2007 01:39:12 -0400
> Is there any place from which we can get the changes you made to the
> fileserver/dbserver code?
I just posted the following two patches:
Sorry for the delay.
-------------------------------------------------------------------------
The following patch(s) add a bit (byte) to the volume header (reserveb3
becomes volIsShadow). This is used to prevent accidentially putting
shadow volumes into the VLDB. It is also used to prevent non-admin
access to shadow volumes.
Thanks.
=========
diff -u viced/afsfileprocs.c viced/afsfileprocs.c
--- viced/afsfileprocs.c 2006-04-07 01:36:59.000000000 -0400
+++ viced/afsfileprocs.c 2006-07-17 22:01:16.000000000 -0400
@@ -739,6 +739,11 @@
if (!VanillaUser(*client))
(*rights) |= PRSFS_LOOKUP;
#endif /* ADMIN_IMPLICIT_LOOKUP */
+ /* restrict access to shadow volumes */
+ if (V_volIsShadow(*volptr) && VanillaUser(*client)) {
+ (*rights) = (*anyrights) = 0;
+ return (EACCES);
+ }
return errorCode;
} /*GetVolumePackage */
diff -u vol/vol-info.c vol/vol-info.c
--- vol/vol-info.c 2005-05-08 02:10:27.000000000 -0400
+++ vol/vol-info.c 2006-06-28 13:05:13.000000000 -0400
@@ -692,6 +692,7 @@
V_dayUse(vp), V_weekUse(vp)[0], V_weekUse(vp)[1], V_weekUse(vp)[2],
V_weekUse(vp)[3], V_weekUse(vp)[4], V_weekUse(vp)[5],
V_weekUse(vp)[6], date(V_dayUseDate(vp)));
+ printf("volIsShadow = %d\n", V_volIsShadow(vp));
}
/* GetFileInfo
diff -u vol/volume.h vol/volume.h
--- vol/volume.h 2005-05-30 00:41:29.000000000 -0400
+++ vol/volume.h 2006-06-28 13:05:13.000000000 -0400
@@ -225,7 +225,8 @@
#define DONT_SALVAGE 0xE5
#endif /* ALPHA_DUX40_ENV */
byte dontSalvage; /* If this is on, then don't bother salvaging this volume */
- byte reserveb3;
+ byte volIsShadow; /* If this is on, this volume is a shadow of another volume. Used
+ * to make sure we don't accidentially populate the VLDB */
bit32 reserved1[6];
@@ -373,6 +374,7 @@
#define V_needsCallback(vp) ((vp)->header->diskstuff.needsCallback)
#define V_destroyMe(vp) ((vp)->header->diskstuff.destroyMe)
#define V_dontSalvage(vp) ((vp)->header->diskstuff.dontSalvage)
+#define V_volIsShadow(vp) ((vp)->header->diskstuff.volIsShadow)
#define V_maxquota(vp) ((vp)->header->diskstuff.maxquota)
#define V_minquota(vp) ((vp)->header->diskstuff.minquota)
#define V_maxfiles(vp) ((vp)->header->diskstuff.maxfiles)
diff -u volser/volint.xg volser/volint.xg
--- volser/volint.xg 2003-06-19 12:06:58.000000000 -0400
+++ volser/volint.xg 2006-06-28 13:05:13.000000000 -0400
@@ -109,7 +109,7 @@
afs_int32 spare0; /* Used to hold the minquota value */
afs_int32 spare1; /* Used to hold the weekuse value */
afs_int32 spare2;
- afs_int32 spare3;
+ afs_int32 spare3; /* Used to hold the unsigned char volIsShadow */
};
/*
diff -u volser/volprocs.c volser/volprocs.c
--- volser/volprocs.c 2006-01-24 22:25:49.000000000 -0500
+++ volser/volprocs.c 2006-06-28 13:05:13.000000000 -0400
@@ -1043,6 +1043,12 @@
} else {
V_inService(vp) = 1;
}
+
+ if (aflags & VTIsShadow) {
+ V_volIsShadow(vp) = 1;
+ } else if (aflags & VTNotShadow) {
+ V_volIsShadow(vp) = 0;
+ }
VUpdateVolume(&error, vp);
tt->vflags = aflags;
tt->rxCallPtr = (struct rx_call *)0;
@@ -1544,6 +1550,8 @@
td->creationDate = astatus->creationDate;
if (astatus->updateDate != -1)
td->updateDate = astatus->updateDate;
+ if (astatus->spare3 != -1)
+ td->volIsShadow = astatus->spare3;
VUpdateVolume(&error, tv);
tt->rxCallPtr = (struct rx_call *)0;
if (TRELE(tt))
@@ -1849,7 +1857,8 @@
(long)tv->header->diskstuff.weekUse[4] +
(long)tv->header->diskstuff.weekUse[5] +
(long)tv->header->diskstuff.weekUse[6];
- pntr->flags = pntr->spare2 = pntr->spare3 = (long)0;
+ pntr->flags = pntr->spare2 = (long)0;
+ pntr->spare3 = tv->header->diskstuff.volIsShadow;
VDetachVolume(&error, tv); /*free the volume */
tv = (Volume *) 0;
if (error) {
@@ -2224,7 +2233,8 @@
(long)tv->header->diskstuff.weekUse[4] +
(long)tv->header->diskstuff.weekUse[5] +
(long)tv->header->diskstuff.weekUse[6];
- pntr->flags = pntr->spare2 = pntr->spare3 = (long)0;
+ pntr->flags = pntr->spare2 = (long)0;
+ pntr->spare3 = tv->header->diskstuff.volIsShadow;
VDetachVolume(&error, tv); /*free the volume */
tv = (Volume *) 0;
if (error) {
diff -u volser/volser.p.h volser/volser.p.h
--- volser/volser.p.h 2005-07-11 15:27:29.000000000 -0400
+++ volser/volser.p.h 2006-06-28 13:05:13.000000000 -0400
@@ -19,6 +19,8 @@
#define VTDeleteOnSalvage 1 /* delete on next salvage */
#define VTOutOfService 2 /* never put this volume online */
#define VTDeleted 4 /* deleted, don't do anything else */
+#define VTIsShadow 8 /* tag so we don't sync by mistake */
+#define VTNotShadow 0x10 /* tag so we don't sync by mistake */
/* iflags, representing "attach mode" for this volume at the start of this transaction */
#define ITOffline 1 /* volume offline on server (returns VOFFLINE) */
@@ -169,6 +171,8 @@
#define RV_CPINCR 0x20000
#define RV_NOVLDB 0x40000
#define RV_NOCLONE 0x80000
+#define RV_SETSHADOW 0x08000
+#define RV_CLRSHADOW 0x04000
struct ubik_client;
extern afs_uint32 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp);
diff -u volser/vos.c volser/vos.c
--- volser/vos.c 2005-12-15 23:26:40.000000000 -0500
+++ volser/vos.c 2006-06-28 13:05:13.000000000 -0400
@@ -1080,7 +1080,7 @@
fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
- fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
+ fprintf(STDOUT, "volIsShadow\t%s\t(Optional)\n", pntr->spare3 ? "Y" : "N");
return;
}
@@ -2487,7 +2487,7 @@
}
}
- flags = RV_NOVLDB;
+ flags = RV_NOVLDB | RV_SETSHADOW;
if (as->parms[7].items) flags |= RV_OFFLINE;
if (as->parms[8].items) flags |= RV_RDONLY;
if (as->parms[9].items) flags |= RV_NOCLONE;
@@ -3672,6 +3672,7 @@
afs_int32 pnum = 0, code; /* part name */
char part[10];
int flags = 0;
+ int forceshadows = 0;
char *volname = 0;
tserver = 0;
@@ -3709,17 +3710,21 @@
}
}
+ if (as->parms[3].items) {
+ forceshadows = 1;
+ }
+
if (as->parms[2].items) {
/* Synchronize an individual volume */
volname = as->parms[2].items->data;
- code = UV_SyncVolume(tserver, pnum, volname, flags);
+ code = UV_SyncVolume2(tserver, pnum, volname, flags, forceshadows);
} else {
if (!tserver) {
fprintf(STDERR,
"Without a -volume option, the -server option is required\n");
exit(1);
}
- code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ );
+ code = UV_SyncVldb(tserver, pnum, flags, forceshadows );
}
if (code) {
@@ -5873,6 +5878,8 @@
cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
+ cmd_AddParm(ts, "-forceshadows", CMD_FLAG, CMD_OPTIONAL,
+ "add shadows to VLDB");
COMMONPARMS;
ts = cmd_CreateSyntax("syncserv", SyncServer, 0,
diff -u volser/vsprocs.c volser/vsprocs.c
--- volser/vsprocs.c 2006-01-24 22:49:53.000000000 -0500
+++ volser/vsprocs.c 2006-07-06 11:38:08.000000000 -0400
@@ -171,7 +171,10 @@
void *cookie, manyResults * results);
static afs_int32 CheckVolume(volintInfo * volumeinfo, afs_int32 aserver,
afs_int32 apart, afs_int32 * modentry,
- afs_uint32 * maxvolid);
+ afs_uint32 * maxvolid,
+ struct rx_connection *aconn);
+static afs_int32 ClearShadow(struct rx_connection *aconn,
+ afs_int32 avol, afs_int32 apart);
/*map the partition <partId> into partition name <partName>*/
@@ -2019,6 +2022,8 @@
* RV_CPINCR - do incremental dump if target exists
* RV_NOVLDB - don't create/update VLDB entry
* RV_NOCLONE - don't use a copy clone
+ * RV_SETSHADOW -set tag so we don't sync by mistake
+ * RV_CLRSHADOW -clear tag so shadow is treated as a normal RW
*/
int
UV_CopyVolume2(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
@@ -2050,6 +2055,7 @@
error = 0;
pntg = 0;
newVol = 0;
+ cloneVol = 0;
/* support control-c processing */
if (setjmp(env))
@@ -2071,13 +2077,19 @@
/* check if we can shortcut and use a local clone instead of a full copy */
if (afromserver == atoserver && afrompart == atopart) {
justclone = 1;
+ if (atovolid) {
+ fprintf(STDOUT,
+ "Shadowing volume %u onto itself not allowed\n",
+ atovolid);
+ fflush(STDOUT);
+ goto mfail;
+ }
}
/* ***
* clone the read/write volume locally.
* ***/
- cloneVol = 0;
if (!(flags & RV_NOCLONE)) {
VPRINT1("Starting transaction on source volume %u ...", afromvol);
code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
@@ -2295,11 +2307,15 @@
&cookie);
EGOTO1(mfail, code,
"Failed to do the%s dump from old site to new site\n",
- afromvol);
+ (flags & RV_NOCLONE) ? "" : " incremental");
VDONE;
VPRINT1("Setting volume flags on destination volume %u ...", newVol);
volflag = ((flags & RV_OFFLINE) ? VTOutOfService : 0); /* off or on-line */
+ if (flags & RV_SETSHADOW)
+ volflag |= VTIsShadow;
+ if (flags & RV_CLRSHADOW)
+ volflag |= VTNotShadow;
code = AFSVolSetFlags(toconn, totid, volflag);
EGOTO(mfail, code,
"Failed to set the flags to make destination volume online\n");
@@ -5223,7 +5239,8 @@
*/
static afs_int32
CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
- afs_int32 * modentry, afs_uint32 * maxvolid)
+ afs_int32 * modentry, afs_uint32 * maxvolid, struct
+ rx_connection *aconn)
{
int idx, j;
afs_int32 code, error = 0;
@@ -5231,6 +5248,7 @@
char pname[10];
int pass = 0, islocked = 0, createentry, addvolume, modified, mod;
afs_int32 rwvolid;
+ afs_int32 volIsShadow;
if (modentry)
*modentry = 0;
@@ -5595,7 +5613,7 @@
if (createentry) {
code = VLDB_CreateEntry(&storeEntry);
if (code) {
- fprintf(STDOUT,
+ fprintf(STDERR,
"Could not create a VLDB entry for the volume %lu\n",
(unsigned long)rwvolid);
ERROR_EXIT(code);
@@ -5613,6 +5631,15 @@
ERROR_EXIT(code);
}
}
+ volIsShadow = volumeinfo->spare3;
+ if (volIsShadow) {
+ code = ClearShadow(aconn, volumeinfo->volid, apart);
+ if (code) {
+ fprintf(STDERR, "Could not clear shadow flag for volume %u\n",
+ volumeinfo->volid);
+ ERROR_EXIT(code);
+ }
+ }
if (modentry)
*modentry = modified;
} else if (pass == 2) {
@@ -5669,6 +5696,43 @@
return 0;
}
+static afs_int32
+ClearShadow(struct rx_connection *aconn, afs_int32 avol, afs_int32 apart)
+{
+ afs_int32 error = 0, tid = 0, rcode = 0;
+ register afs_int32 code = 0;
+
+ code = AFSVolTransCreate(aconn, avol, apart, ITOffline, &tid);
+ if (code) {
+ fprintf(STDERR, "Failed to start a transaction on the shadow volume %u\n",
+ avol);
+ error = code;
+ }
+
+ if (!code) {
+ code = AFSVolSetFlags(aconn, tid, VTNotShadow);
+ if (code) {
+ fprintf(STDERR, "Failed to set the flags on the shadow volume %u\n",
+ avol);
+ error = code;
+ }
+ }
+
+ if (tid) {
+ code = AFSVolEndTrans(aconn, tid, &rcode);
+ if (code || rcode) {
+ fprintf(STDERR, "Failed to end the transaction on the shadow volume %u\n",
+ avol);
+ if (!error)
+ error = (code ? code : rcode);
+ }
+ }
+
+ return error;
+
+}
+
+
/* UV_SyncVolume()
* Synchronise <aserver> <apart>(if flags = 1) <avolid>.
* Synchronize an individual volume against a sever and partition.
@@ -5676,7 +5740,7 @@
* if the volume exists on specified servers (similar to syncvldb).
*/
int
-UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
+UV_SyncVolume2(afs_int32 aserver, afs_int32 apart, char *avolname, int flags, int force)
{
struct rx_connection *aconn = 0;
afs_int32 j, k, code, vcode, error = 0;
@@ -5687,6 +5751,7 @@
struct partList PartList;
afs_int32 pcnt, rv;
afs_int32 maxvolid = 0;
+ afs_int32 volIsShadow;
volumeInfo.volEntries_val = (volintInfo *) 0;
volumeInfo.volEntries_len = 0;
@@ -5768,14 +5833,24 @@
ERROR_EXIT(code);
}
} else {
- /* Found one, sync it with VLDB entry */
- code =
- CheckVolume(volumeInfo.volEntries_val, aserver,
- PartList.partId[j], &mod, &maxvolid);
- if (code)
- ERROR_EXIT(code);
- if (mod)
- modified++;
+ /* Found one */
+ volIsShadow = volumeInfo.volEntries_val->spare3;
+ if (volIsShadow && !force) {
+ if (tverbose) {
+ fprintf(STDOUT,
+ "You must use -forceshadows to sync this volume to the VLDB.\n");
+ }
+ } else {
+ /* sync it with VLDB entry */
+ code =
+ CheckVolume(volumeInfo.volEntries_val,
+ aserver, PartList.partId[j], &mod,
+ &maxvolid, aconn);
+ if (code)
+ ERROR_EXIT(code);
+ if (mod)
+ modified++;
+ }
}
if (volumeInfo.volEntries_val)
@@ -5821,7 +5896,8 @@
/* Found one, sync it with VLDB entry */
code =
CheckVolume(volumeInfo.volEntries_val, aserver,
- PartList.partId[k], &mod, &maxvolid);
+ PartList.partId[k], &mod, &maxvolid,
+ aconn);
if (code)
ERROR_EXIT(code);
if (mod)
@@ -5895,6 +5971,14 @@
return error;
}
+
+int
+UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
+{
+ return UV_SyncVolume2(aserver, apart, avolname, flags, 0);
+}
+
+
/* UV_SyncVldb()
* Synchronise vldb with the file server <aserver> and,
* optionally, <apart>.
@@ -5913,6 +5997,7 @@
afs_int32 failures = 0, modifications = 0, tentries = 0;
afs_int32 modified;
afs_uint32 maxvolid = 0;
+ afs_int32 volIsShadow;
volumeInfo.volEntries_val = (volintInfo *) 0;
volumeInfo.volEntries_len = 0;
@@ -5968,13 +6053,21 @@
fflush(STDOUT);
}
- code = CheckVolume(vi, aserver, apart, &modified, &maxvolid);
- if (code) {
- PrintError("", code);
- failures++;
- pfail++;
- } else if (modified) {
- modifications++;
+ volIsShadow = vi->spare3;
+ if (volIsShadow && !force) {
+ if (verbose) {
+ fprintf(STDOUT,
+ "You must use -forceshadows to sync this volume to the VLDB.\n");
+ }
+ } else {
+ /* sync it with VLDB entry */
+ code = CheckVolume(vi, aserver, apart, &modified, &maxvolid, aconn);
+ if (code) {
+ PrintError("", code);
+ failures++;
+ pfail++;
+ } else if (modified)
+ modifications++;
}
if (verbose) {
-------------------------------------------------------------------------
The following fixes a bug in the UV_CopyVolume2 cleanup code. Without
this patch, the cleanup code will delete the source volume.
Thanks.
========
diff -u volser/vsprocs.c volser/vsprocs.c
--- volser/vsprocs.c 2007-03-09 16:53:45.000000000 -0500
+++ volser/vsprocs.c 2007-03-14 16:10:14.000000000 -0400
@@ -2496,7 +2496,7 @@
VPRINT1("Recovery: Creating transaction on clone volume %u ...",
cloneVol);
code =
- AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline,
+ AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline,
&clonetid);
if (!code) {
VDONE;