[OpenAFS-devel] [PATCH] OpenAFS 1.3.84: conditionally support cloning of RO volumes

Jason A. Dillaman dillaman@umich.edu
Sat, 2 Jul 2005 12:44:37 -0400


This is a multi-part message in MIME format.

------=_NextPart_000_0068_01C57F03.D171E920
Content-Type: multipart/alternative;
	boundary="----=_NextPart_001_0069_01C57F03.D171E920"


------=_NextPart_001_0069_01C57F03.D171E920
Content-Type: text/plain;
	charset="US-ASCII"
Content-Transfer-Encoding: 7bit

The attached patch updates the "vos" utility of OpenAFS 1.3.84 as follows:

 

            * added "-allowRO" flag to "vos copy", "vos shadow", and "vos
clone" to permit the cloning of RO volumes. 

            * added "-addVLDB" flag to "vos clone" to add a VLDB entry for
the clone.

 

With this patch in place, you can, for each volume, create a shadow volume
on another server (one time operation).  Then you can incrementally copy the
volume to its shadow on a regular interval and create a snapshot clone so
that you can recover the volume to a specific instance.  The goal of this
patch is to provide an alternate mode for backing up an AFS file server
without using tapes.

 

Jason A. Dillaman

 

 

 


------=_NextPart_001_0069_01C57F03.D171E920
Content-Type: text/html;
	charset="US-ASCII"
Content-Transfer-Encoding: quoted-printable

<html xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns=3D"http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=3DContent-Type content=3D"text/html; =
charset=3Dus-ascii">
<meta name=3DGenerator content=3D"Microsoft Word 11 (filtered medium)">
<style>
<!--
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:"Times New Roman";}
a:link, span.MsoHyperlink
	{color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;}
span.EmailStyle17
	{mso-style-type:personal-compose;
	font-family:Arial;
	color:windowtext;}
@page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
	{page:Section1;}
-->
</style>

</head>

<body lang=3DEN-US link=3Dblue vlink=3Dpurple>

<div class=3DSection1>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>The attached patch updates the &#8220;vos&#8221; =
utility of
OpenAFS 1.3.84 as follows:<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;
* added &#8220;-allowRO&#8221; flag to &#8220;vos copy&#8221;, =
&#8220;vos
shadow&#8221;, and &#8220;vos clone&#8221; to permit the cloning of RO =
volumes.
<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
added &#8220;-addVLDB&#8221; flag to &#8220;vos clone&#8221; to add a =
VLDB
entry for the clone.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>With this patch in place, you can, for each volume, =
create a
shadow volume on another server (one time operation).&nbsp; Then you can
incrementally copy the volume to its shadow on a regular interval and =
create a
snapshot clone so that you can recover the volume to a specific =
instance.&nbsp;
The goal of this patch is to provide an alternate mode for backing up an =
AFS
file server without using tapes.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>Jason A. Dillaman<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>&nbsp;<o:p></o:p></span></font></p>

</div>

</body>

</html>

------=_NextPart_001_0069_01C57F03.D171E920--

------=_NextPart_000_0068_01C57F03.D171E920
Content-Type: application/octet-stream;
	name="clone-ro-openafs-1.3.84.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="clone-ro-openafs-1.3.84.patch"

Index: src/libadmin/vos/vsprocs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/libadmin/vos/vsprocs.c,v
retrieving revision 1.11
diff -u -r1.11 vsprocs.c
--- src/libadmin/vos/vsprocs.c	29 Nov 2003 22:08:14 -0000	1.11
+++ src/libadmin/vos/vsprocs.c	1 Jul 2005 15:42:59 -0000
@@ -22,7 +22,7 @@
 #include <afs/param.h>
=20
 RCSID
-    ("$Header: /cvs/openafs/src/libadmin/vos/vsprocs.c,v 1.11 =
2003/11/29 22:08:14 jaltman Exp $");
+    ("$Header: /cvs/openafs/src/libadmin/vos/vsprocs.c,v 1.4 2005/07/01 =
03:03:03 dillaman Exp $");
=20
 #include "vsprocs.h"
 #include "vosutils.h"
@@ -568,7 +568,7 @@
=20
     /* Do the clone. Default flags on clone are set to delete on =
salvage and out of service */
     strcpy(vname, "move-clone-temp");
-    tst =3D AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, =
&newVol);
+    tst =3D AFSVolClone(fromconn, fromtid, 0, 0, readonlyVolume, vname, =
&newVol);
     if (tst) {
 	goto fail_UV_MoveVolume;
     }
@@ -1080,7 +1080,7 @@
      * volume exists or not
      */
     if (backexists) {
-	tst =3D AFSVolReClone(aconn, ttid, backupID);
+	tst =3D AFSVolReClone(aconn, ttid, backupID, 0);
 	if (tst) {
 	    goto fail_UV_BackupVolume;
 	}
@@ -1088,7 +1088,7 @@
 	strcpy(vname, entry.name);
 	strcat(vname, ".backup");
=20
-	tst =3D AFSVolClone(aconn, ttid, 0, backupVolume, vname, &backupID);
+	tst =3D AFSVolClone(aconn, ttid, 0, 0, backupVolume, vname, =
&backupID);
 	if (tst) {
 	    goto fail_UV_BackupVolume;
 	}
@@ -1242,9 +1242,9 @@
     }
=20
     /* Create the new clone. If it exists, then reclone it */
-    tst =3D AFSVolClone(conn, tid, 0, readonlyVolume, vname, rovidp);
+    tst =3D AFSVolClone(conn, tid, 0, 0, readonlyVolume, vname, =
rovidp);
     if (tst =3D=3D VVOLEXISTS) {
-	tst =3D AFSVolReClone(conn, tid, *rovidp);
+	tst =3D AFSVolReClone(conn, tid, *rovidp, 0);
 	if (tst) {
 	    goto fail_CloneVol;
 	}
@@ -1614,7 +1614,7 @@
=20
 	/* Clone or reclone the volume */
 	if (roexists) {
-	    tst =3D AFSVolReClone(fromconn, clonetid, cloneVolId);
+	    tst =3D AFSVolReClone(fromconn, clonetid, cloneVolId, 0);
 	    if (tst) {
 		goto fail_UV_ReleaseVolume;
 	    }
@@ -1626,7 +1626,7 @@
 		strcpy(vname, "readonly-clone-temp");
 	    }
 	    tst =3D
-		AFSVolClone(fromconn, clonetid, 0, readonlyVolume, vname,
+		AFSVolClone(fromconn, clonetid, 0, 0, readonlyVolume, vname,
 			    &cloneVolId);
 	    if (tst) {
 		goto fail_UV_ReleaseVolume;
Index: src/volser/volint.xg
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/volser/volint.xg,v
retrieving revision 1.4
diff -u -r1.4 volint.xg
--- src/volser/volint.xg	19 Jun 2003 16:06:58 -0000	1.4
+++ src/volser/volint.xg	1 Jul 2005 15:43:03 -0000
@@ -264,6 +264,7 @@
 proc Clone(
   IN afs_int32 trans,
   IN afs_int32 purgeVol,
+  IN afs_int32 allowRO,
   IN afs_int32 newType,
   IN string newName<>,
   INOUT afs_int32 *newVol
@@ -349,7 +350,8 @@
=20
 proc ReClone(
   IN afs_int32 tid,
-  afs_int32 cloneID
+  afs_int32 cloneID,
+  IN afs_int32 allowRO
 ) =3D VOLRECLONE;
=20
 proc ListOneVolume(
Index: src/volser/volprocs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/volser/volprocs.c,v
retrieving revision 1.34.2.3
diff -u -r1.34.2.3 volprocs.c
--- src/volser/volprocs.c	13 Dec 2004 19:41:13 -0000	1.34.2.3
+++ src/volser/volprocs.c	1 Jul 2005 15:43:03 -0000
@@ -11,7 +11,7 @@
 #include <afs/param.h>
=20
 RCSID
-    ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.34.2.3 2004/12/13 =
19:41:13 shadow Exp $");
+    ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.4 2005/07/01 =
03:03:03 dillaman Exp $");
=20
 #include <stdio.h>
 #include <sys/types.h>
@@ -511,20 +511,20 @@
 /* for efficiency reasons, sometimes faster to piggyback a purge here =
*/
 afs_int32
 SAFSVolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId, =

-	     afs_int32 newType, char *newName, afs_int32 *newNumber)
+	     afs_int32 allowRO, afs_int32 newType, char *newName, afs_int32 =
*newNumber)
 {
     afs_int32 code;
=20
-    code =3D VolClone(acid, atrans, purgeId, newType, newName, =
newNumber);
+    code =3D VolClone(acid, atrans, purgeId, allowRO, newType, newName, =
newNumber);
     osi_auditU(acid, VS_CloneEvent, code, AUD_LONG, atrans, AUD_LONG, =
purgeId,
-	       AUD_STR, newName, AUD_LONG, newType, AUD_LONG, *newNumber,
+	       AUD_LONG, allowRO, AUD_STR, newName, AUD_LONG, newType, =
AUD_LONG, *newNumber,
 	       AUD_END);
     return code;
 }
=20
 afs_int32
 VolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId,=20
-	     afs_int32 newType, char *newName, afs_int32 *newNumber)
+	     afs_int32 allowRO, afs_int32 newType, char *newName, afs_int32 =
*newNumber)
 {
     VolumeId newId;
     register struct Volume *originalvp, *purgevp, *newvp;
@@ -580,7 +580,7 @@
     }
     originalvp =3D tt->volume;
     if ((V_type(originalvp) =3D=3D backupVolume)
-	|| (V_type(originalvp) =3D=3D readonlyVolume)) {
+	|| ((!allowRO) && (V_type(originalvp) =3D=3D readonlyVolume))) {
 	Log("1 Volser: Clone: The volume to be cloned must be a read/write; =
aborted\n");
 	error =3D EROFS;
 	goto fail;
@@ -696,18 +696,18 @@
=20
 /* reclone this volume into the specified id */
 afs_int32
-SAFSVolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 =
cloneId)
+SAFSVolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 =
cloneId, afs_int32 allowRO)
 {
     afs_int32 code;
=20
-    code =3D VolReClone(acid, atrans, cloneId);
+    code =3D VolReClone(acid, atrans, cloneId, allowRO);
     osi_auditU(acid, VS_ReCloneEvent, code, AUD_LONG, atrans, AUD_LONG,
-	       cloneId, AUD_END);
+	       cloneId, AUD_LONG, allowRO, AUD_END);
     return code;
 }
=20
 afs_int32
-VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
+VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId, =
afs_int32 allowRO)
 {
     register struct Volume *originalvp, *clonevp;
     Error error, code;
@@ -742,7 +742,7 @@
=20
     originalvp =3D tt->volume;
     if ((V_type(originalvp) =3D=3D backupVolume)
-	|| (V_type(originalvp) =3D=3D readonlyVolume)) {
+	|| ((!allowRO) && (V_type(originalvp) =3D=3D readonlyVolume))) {
 	Log("1 Volser: Clone: The volume to be cloned must be a read/write; =
aborted\n");
 	error =3D EROFS;
 	goto fail;
Index: src/volser/volser.p.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/volser/volser.p.h,v
retrieving revision 1.8
diff -u -r1.8 volser.p.h
--- src/volser/volser.p.h	29 Jul 2004 03:44:08 -0000	1.8
+++ src/volser/volser.p.h	1 Jul 2005 15:43:03 -0000
@@ -159,6 +159,7 @@
 /* Also used for UV_CopyVolume and UV_CloneVolume */
 #define RV_FULLRST	0x00001
 #define RV_OFFLINE	0x00002
+#define RV_ALLOWRO	0x00004
 #define RV_CRDUMP	0x00010
 #define RV_CRKEEP	0x00020
 #define RV_CRNEW	0x00040
Index: src/volser/vos.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/volser/vos.c,v
retrieving revision 1.40.2.9
diff -u -r1.40.2.9 vos.c
--- src/volser/vos.c	15 Apr 2005 18:46:25 -0000	1.40.2.9
+++ src/volser/vos.c	1 Jul 2005 15:43:03 -0000
@@ -11,7 +11,7 @@
 #include <afs/param.h>
=20
 RCSID
-    ("$Header: /cvs/openafs/src/volser/vos.c,v 1.40.2.9 2005/04/15 =
18:46:25 shadow Exp $");
+    ("$Header: /cvs/openafs/src/volser/vos.c,v 1.5 2005/07/01 03:03:03 =
dillaman Exp $");
=20
 #include <sys/types.h>
 #ifdef AFS_NT40_ENV
@@ -2300,6 +2300,7 @@
     if (as->parms[6].items) flags |=3D RV_OFFLINE;
     if (as->parms[7].items) flags |=3D RV_RDONLY;
     if (as->parms[8].items) flags |=3D RV_NOCLONE;
+    if (as->parms[9].items) flags |=3D RV_ALLOWRO;
=20
     MapPartIdIntoName(topart, toPartName);
     MapPartIdIntoName(frompart, fromPartName);
@@ -2487,6 +2488,7 @@
     if (as->parms[8].items) flags |=3D RV_RDONLY;
     if (as->parms[9].items) flags |=3D RV_NOCLONE;
     if (as->parms[10].items) flags |=3D RV_CPINCR;
+    if (as->parms[11].items) flags |=3D RV_ALLOWRO;
=20
     MapPartIdIntoName(topart, toPartName);
     MapPartIdIntoName(frompart, fromPartName);
@@ -2642,7 +2644,8 @@
     flags =3D 0;
     if (as->parms[5].items) flags |=3D RV_OFFLINE;
     if (as->parms[6].items) flags |=3D RV_RDONLY;
-
+    if (as->parms[7].items) flags |=3D RV_ALLOWRO;
+    if (!as->parms[8].items)flags |=3D RV_NOVLDB;
=20
     code =3D=20
 	UV_CloneVolume(server, part, volid, cloneid, volname, flags);
@@ -5731,6 +5734,8 @@
 		"make new volume read-only");
     cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
 		"copy live volume without cloning");
+    cmd_AddParm(ts, "-allowRO", CMD_FLAG, CMD_OPTIONAL,
+    		"allow a RO volume to be copied");
     COMMONPARMS;
=20
     ts =3D cmd_CreateSyntax("shadow", ShadowVolume, 0,
@@ -5755,6 +5760,8 @@
 		"copy live volume without cloning");
     cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL,
 		"do incremental update if target exists");
+    cmd_AddParm(ts, "-allowRO", CMD_FLAG, CMD_OPTIONAL,
+    		"allow a RO volume to be shadowed");
     COMMONPARMS;
=20
     ts =3D cmd_CreateSyntax("backup", BackupVolume, 0,
@@ -5775,6 +5782,10 @@
 		"leave clone volume offline");
     cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
 		"make clone volume read-only, not readwrite");
+    cmd_AddParm(ts, "-allowRO", CMD_FLAG, CMD_OPTIONAL,
+    		"allow a RO volume to be cloned");
+    cmd_AddParm(ts, "-addVLDB", CMD_FLAG, CMD_OPTIONAL,
+    		"add cloned volume to VLDB");
     COMMONPARMS;
=20
     ts =3D cmd_CreateSyntax("release", ReleaseVolume, 0, "release a =
volume");
Index: src/volser/vsprocs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/openafs/src/volser/vsprocs.c,v
retrieving revision 1.33.2.4
diff -u -r1.33.2.4 vsprocs.c
--- src/volser/vsprocs.c	15 Apr 2005 18:46:26 -0000	1.33.2.4
+++ src/volser/vsprocs.c	1 Jul 2005 15:43:03 -0000
@@ -11,7 +11,7 @@
 #include <afs/param.h>
=20
 RCSID
-    ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.33.2.4 2005/04/15 =
18:46:26 shadow Exp $");
+    ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.7 2005/07/01 =
04:17:48 dillaman Exp $");
=20
 #include <stdio.h>
 #include <sys/types.h>
@@ -1275,7 +1275,7 @@
 	VPRINT1("Cloning source volume %u ...", afromvol);
 	strcpy(vname, "move-clone-temp");
 	code =3D
-	    AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &newVol);
+	    AFSVolClone(fromconn, fromtid, 0, 0, readonlyVolume, vname, =
&newVol);
 	EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
 	       afromvol);
 	VDONE;
@@ -2018,6 +2018,7 @@
  *     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_ALLOWRO - allow a volume to be copied from a RO
  */
 int
 UV_CopyVolume2(afs_int32 afromvol, afs_int32 afromserver, afs_int32 =
afrompart,
@@ -2114,7 +2115,7 @@
 	VPRINT1("Cloning source volume %u ...", afromvol);
 	strcpy(vname, "copy-clone-temp");
 	code =3D
-	    AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname,
+	    AFSVolClone(fromconn, fromtid, 0, (flags & RV_ALLOWRO) ? 1 : 0, =
readonlyVolume, vname,
 			&cloneVol);
 	EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
 	       afromvol);
@@ -2648,7 +2649,7 @@
     if (backexists) {
 	VPRINT1("Re-cloning backup volume %u ...", backupID);
=20
-	code =3D AFSVolReClone(aconn, ttid, backupID);
+	code =3D AFSVolReClone(aconn, ttid, backupID, 0);
 	if (code) {
 	    fprintf(STDERR, "Could not re-clone backup volume %lu\n",
 		    (unsigned long)backupID);
@@ -2661,7 +2662,7 @@
 	strcpy(vname, entry.name);
 	strcat(vname, ".backup");
=20
-	code =3D AFSVolClone(aconn, ttid, 0, backupVolume, vname, &backupID);
+	code =3D AFSVolClone(aconn, ttid, 0, 0, backupVolume, vname, =
&backupID);
 	if (code) {
 	    fprintf(STDERR, "Failed to clone the volume %lu\n",
 		    (unsigned long)avolid);
@@ -2786,6 +2787,7 @@
  *=20
  *     RV_RDONLY  - target volume is RO
  *     RV_OFFLINE - leave target volume offline
+ *     RV_ALLOWRO - allow the cloning of a RO volume
  */
=20
 int
@@ -2794,11 +2796,12 @@
 {
     struct rx_connection *aconn =3D (struct rx_connection *)0;
     afs_int32 ttid =3D 0, btid =3D 0;
-    afs_int32 code =3D 0, rcode =3D 0;
+    afs_int32 code =3D 0, rcode =3D 0, vcode =3D 0;
     char vname[VOLSER_MAXVOLNAME + 1];
     afs_int32 error =3D 0;
     int backexists =3D 1;
     volEntries volumeInfo;
+    struct nvldbentry newentry, storeEntry;
=20
     aconn =3D UV_Bind(aserver, AFSCONF_VOLUMEPORT);
=20
@@ -2875,7 +2878,7 @@
     if (backexists) {
 	VPRINT1("Re-cloning clone volume %u ...", acloneid);
=20
-	code =3D AFSVolReClone(aconn, ttid, acloneid);
+	code =3D AFSVolReClone(aconn, ttid, acloneid, (flags & RV_ALLOWRO) ? 1 =
: 0);
 	if (code) {
 	    fprintf(STDERR, "Could not re-clone backup volume %lu\n",
 		    (unsigned long)acloneid);
@@ -2886,6 +2889,7 @@
 	VPRINT1("Creating a new clone %u ...", acloneid);
=20
 	code =3D AFSVolClone(aconn, ttid, 0,
+			   (flags & RV_ALLOWRO) ? 1 : 0,
 			   (flags & RV_RDONLY) ? readonlyVolume : backupVolume,
 			   aname, &acloneid);
 	if (code) {
@@ -2907,8 +2911,7 @@
 	goto bfail;
     }
=20
-    /* Now go back to the backup volume and bring it on line */
-    if (!(flags & RV_OFFLINE)) {
+    if (!(flags & RV_OFFLINE) || !(flags & RV_NOVLDB)) {
 	code =3D AFSVolTransCreate(aconn, acloneid, apart, ITOffline, &btid);
 	if (code) {
 	    fprintf(STDERR,
@@ -2917,7 +2920,10 @@
 	    error =3D code;
 	    goto bfail;
 	}
-
+    }
+   =20
+    /* Now go back to the backup volume and bring it on line */
+    if (!(flags & RV_OFFLINE)) {
 	code =3D AFSVolSetFlags(aconn, btid, 0);
 	if (code) {
 	    fprintf(STDERR, "Could not mark the clone volume %lu on line \n",
@@ -2925,7 +2931,40 @@
 	    error =3D code;
 	    goto bfail;
 	}
+    }
+
+    /* create the vldb entry for the copied volume */
+    if (!(flags & RV_NOVLDB)) {
+	strncpy(newentry.name, aname, VOLSER_OLDMAXVOLNAME);
+	newentry.nServers =3D 1;
+	newentry.serverNumber[0] =3D aserver;
+	newentry.serverPartition[0] =3D apart;
+	newentry.flags =3D (flags & RV_RDONLY) ? RO_EXISTS : BACK_EXISTS;
+	newentry.serverFlags[0] =3D (flags & RV_RDONLY) ? ITSROVOL : =
ITSBACKVOL;
+	newentry.volumeId[RWVOL] =3D acloneid;
+	newentry.volumeId[ROVOL] =3D (flags & RV_RDONLY) ? acloneid : 0;
+	newentry.volumeId[BACKVOL] =3D (flags & RV_RDONLY) ? 0 : acloneid;
+	newentry.cloneId =3D 0;
+	/*map into right byte order, before passing to xdr, the stuff has to =
be in host
+	 * byte order. Xdr converts it into network order */
+	MapNetworkToHost(&newentry, &storeEntry);
+	/* create the vldb entry */
+	vcode =3D VLDB_CreateEntry(&storeEntry);
+	if (vcode) {
+	    fprintf(STDERR,
+		    "Could not create a VLDB entry for the volume %s %lu\n",
+		    aname, (unsigned long)acloneid);
+	    /*destroy the created volume */
+	    VPRINT1("Deleting the newly created volume %u\n", acloneid);
+	    AFSVolDeleteVolume(aconn, btid);
+	    error =3D vcode;
+	    goto bfail;
+	}
+	VPRINT2("Created the VLDB entry for the volume %s %u\n", aname,
+		acloneid);
+    }
=20
+    if (!(flags & RV_OFFLINE) || !(flags & RV_NOVLDB)) {
 	code =3D AFSVolEndTrans(aconn, btid, &rcode);
 	btid =3D 0;
 	if (code || rcode) {
@@ -3344,7 +3383,7 @@
 	/* Clone or reclone the volume */
 	if (roexists) {
 	    VPRINT1("Recloning RW volume %u...", cloneVolId);
-	    code =3D AFSVolReClone(fromconn, clonetid, cloneVolId);
+	    code =3D AFSVolReClone(fromconn, clonetid, cloneVolId, 0);
 	    ONERROR(code, afromvol, "Failed to reclone the RW volume %u\n");
 	    VDONE;
 	} else {
@@ -3357,7 +3396,7 @@
 		VPRINT1("Cloning RW volume %u to temporary RO...", afromvol);
 	    }
 	    code =3D
-		AFSVolClone(fromconn, clonetid, 0, readonlyVolume, vname,
+		AFSVolClone(fromconn, clonetid, 0, 0, readonlyVolume, vname,
 			    &cloneVolId);
 	    ONERROR(code, afromvol, "Failed to clone the RW volume %u\n");
 	    VDONE;
@@ -3957,7 +3996,7 @@
 	    clonevol);
     strcpy(vname, "dump-clone-temp");
     code =3D
-	AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol);
+	AFSVolClone(fromconn, fromtid, 0, 0, readonlyVolume, vname, =
&clonevol);
     EGOTO1(error_exit, code, "Failed to clone the source volume %u\n",
 	   afromvol);
     VDONE;
@@ -4942,7 +4981,7 @@
 	    }
=20
 	    code =3D
-		AFSVolClone(aconn, tid, 0, readonlyVolume, cloneName,
+		AFSVolClone(aconn, tid, 0, 0, readonlyVolume, cloneName,
 			    &(curPtr->volCloneId));
 	    if (code) {
 		curPtr->volFlags &=3D ~CLONEVALID;

------=_NextPart_000_0068_01C57F03.D171E920--