#include <sys/file.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#endif
#include <sys/stat.h>
#ifdef AFS_AIX_ENV
struct tqElem *next;
};
-
-struct hostent *hostutil_GetHostByName(register char *ahost);
-
#define COMMONPARMS cmd_Seek(ts, 12);\
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
afs_int32 tserver;
extern struct ubik_client *cstruct;
const char *confdir;
-extern struct rx_connection *UV_Bind();
-extern int UV_SetSecurity();
-extern int UV_SetVolumeInfo();
-extern int vsu_SetCrypt();
-extern VL_SetLock();
-extern VL_ReleaseLock();
-extern VL_DeleteEntry();
-extern VL_ListEntry();
-extern VL_GetAddrs();
-extern VL_GetAddrsU();
-extern VL_ChangeAddr();
-
-extern int vsu_ExtractName();
-extern PrintError();
-extern void EnumerateEntry();
-extern void SubEnumerateEntry();
-
static struct tqHead busyHead, notokHead;
fprintf(STDOUT, " Last Access %s",
ctime((time_t *) & pntr->accessDate));
#endif
- if (pntr->updateDate < pntr->creationDate)
- fprintf(STDOUT, " Last Update %s",
- ctime((time_t *) & pntr->creationDate));
- else
+ if (!pntr->updateDate)
+ fprintf(STDOUT, " Last Update Never\n");
+ else {
fprintf(STDOUT, " Last Update %s",
ctime((time_t *) & pntr->updateDate));
- fprintf(STDOUT,
- " %d accesses in the past day (i.e., vnode references)\n",
- pntr->dayUse);
+ fprintf(STDOUT,
+ " %d accesses in the past day (i.e., vnode references)\n",
+ pntr->dayUse);
+ }
} else if (pntr->status == VBUSY) {
*totalBusy += 1;
qPut(&busyHead, pntr->volid);
fprintf(STDOUT, " Last Access %s",
ctime((time_t *) & a_xInfoP->accessDate));
#endif
- if (a_xInfoP->updateDate < a_xInfoP->creationDate)
- fprintf(STDOUT, " Last Update %s",
- ctime((time_t *) & a_xInfoP->creationDate));
- else
+ if (!a_xInfoP->updateDate)
+ fprintf(STDOUT, " Last Update Never\n");
+ else {
fprintf(STDOUT, " Last Update %s",
ctime((time_t *) & a_xInfoP->updateDate));
- fprintf(STDOUT,
- " %d accesses in the past day (i.e., vnode references)\n",
- a_xInfoP->dayUse);
+ fprintf(STDOUT,
+ " %d accesses in the past day (i.e., vnode references)\n",
+ a_xInfoP->dayUse);
+ }
/*
* Print all the read/write and authorship stats.
if (partition != partition_cache) {
MapPartIdIntoName(partition, pname);
partition_cache = partition;
+ } else {
+ pname[0] = '\0';
}
fprintf(STDOUT, "name\t\t%s\n", pntr->name);
fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
return (ENOENT);
}
- memset(&info, 0, sizeof(info));
+ init_volintInfo(&info);
info.volid = volid;
info.type = RWVOL;
- info.dayUse = -1;
- info.maxquota = -1;
- info.flags = -1;
- info.spare0 = -1;
- info.spare1 = -1;
- info.spare2 = -1;
- info.spare3 = -1;
if (as->parms[1].items) {
/* -max <quota> */
static int
CreateVolume(register struct cmd_syndesc *as)
{
- afs_int32 pname;
+ afs_int32 pnum;
char part[10];
afs_int32 volid, code;
struct nvldbentry entry;
as->parms[0].items->data);
return ENOENT;
}
- pname = volutil_GetPartitionID(as->parms[1].items->data);
- if (pname < 0) {
+ pnum = volutil_GetPartitionID(as->parms[1].items->data);
+ if (pnum < 0) {
fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
as->parms[1].items->data);
return ENOENT;
}
- if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
+ if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
if (code)
PrintError("", code);
else
}
code =
- UV_CreateVolume2(tserver, pname, as->parms[2].items->data, quota, 0,
+ UV_CreateVolume2(tserver, pnum, as->parms[2].items->data, quota, 0,
0, 0, 0, &volid);
if (code) {
PrintDiagnostics("create", code);
return code;
}
- MapPartIdIntoName(pname, part);
+ MapPartIdIntoName(pnum, part);
fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
(unsigned long)volid, part, as->parms[0].items->data);
register struct cmd_syndesc *as;
{
- afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
+ afs_int32 volid, fromserver, toserver, frompart, topart;
+ afs_int32 flags, code, err;
char fromPartName[10], toPartName[10];
struct diskPartition partition; /* for space check */
return ENOENT;
}
+ flags = 0;
+ if (as->parms[5].items) flags |= RV_NOCLONE;
+
/*
* check source partition for space to clone volume
*/
/* successful move still not guaranteed but shoot for it */
- code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
+ code =
+ UV_MoveVolume2(volid, fromserver, frompart, toserver, topart, flags);
if (code) {
PrintDiagnostics("move", code);
return code;
CopyVolume(as)
register struct cmd_syndesc *as;
{
- afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
+ afs_int32 volid, fromserver, toserver, frompart, topart, code, err, flags;
char fromPartName[10], toPartName[10], *tovolume;
struct nvldbentry entry;
struct diskPartition partition; /* for space check */
toserver = GetServer(as->parms[4].items->data);
if (toserver == 0) {
fprintf(STDERR, "vos: server '%s' not found in host table\n",
- as->parms[3].items->data);
+ as->parms[4].items->data);
return ENOENT;
}
topart = volutil_GetPartitionID(as->parms[5].items->data);
if (topart < 0) {
fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
- as->parms[4].items->data);
+ as->parms[5].items->data);
return EINVAL;
}
if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
else
fprintf(STDERR,
"vos : partition %s does not exist on the server\n",
- as->parms[4].items->data);
+ as->parms[5].items->data);
return ENOENT;
}
- /*
- * check source partition for space to clone volume
- */
+ flags = 0;
+ if (as->parms[6].items) flags |= RV_OFFLINE;
+ if (as->parms[7].items) flags |= RV_RDONLY;
+ if (as->parms[8].items) flags |= RV_NOCLONE;
MapPartIdIntoName(topart, toPartName);
MapPartIdIntoName(frompart, fromPartName);
/* successful copy still not guaranteed but shoot for it */
code =
- UV_CopyVolume(volid, fromserver, frompart, tovolume, toserver,
- topart);
+ UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
+ topart, 0, flags);
if (code) {
PrintDiagnostics("copy", code);
return code;
static
+ShadowVolume(as)
+ register struct cmd_syndesc *as;
+{
+ afs_int32 volid, fromserver, toserver, frompart, topart, tovolid;
+ afs_int32 code, err, flags;
+ char fromPartName[10], toPartName[10], toVolName[32], *tovolume;
+ struct nvldbentry entry;
+ struct diskPartition partition; /* for space check */
+ volintInfo *p, *q;
+
+ p = (volintInfo *) 0;
+ q = (volintInfo *) 0;
+
+ volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
+ if (volid == 0) {
+ if (err)
+ PrintError("", err);
+ else
+ fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
+ as->parms[0].items->data);
+ return ENOENT;
+ }
+ fromserver = GetServer(as->parms[1].items->data);
+ if (fromserver == 0) {
+ fprintf(STDERR, "vos: server '%s' not found in host table\n",
+ as->parms[1].items->data);
+ return ENOENT;
+ }
+
+ toserver = GetServer(as->parms[3].items->data);
+ if (toserver == 0) {
+ fprintf(STDERR, "vos: server '%s' not found in host table\n",
+ as->parms[3].items->data);
+ return ENOENT;
+ }
+
+ frompart = volutil_GetPartitionID(as->parms[2].items->data);
+ if (frompart < 0) {
+ fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
+ as->parms[2].items->data);
+ return EINVAL;
+ }
+ if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
+ if (code)
+ PrintError("", code);
+ else
+ fprintf(STDERR,
+ "vos : partition %s does not exist on the server\n",
+ as->parms[2].items->data);
+ return ENOENT;
+ }
+
+ topart = volutil_GetPartitionID(as->parms[4].items->data);
+ if (topart < 0) {
+ fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
+ as->parms[4].items->data);
+ return EINVAL;
+ }
+ if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
+ if (code)
+ PrintError("", code);
+ else
+ fprintf(STDERR,
+ "vos : partition %s does not exist on the server\n",
+ as->parms[4].items->data);
+ return ENOENT;
+ }
+
+ if (as->parms[5].items) {
+ tovolume = as->parms[5].items->data;
+ if (!ISNAMEVALID(tovolume)) {
+ fprintf(STDERR,
+ "vos: the name of the root volume %s exceeds the size limit of %d\n",
+ tovolume, VOLSER_OLDMAXVOLNAME - 10);
+ return E2BIG;
+ }
+ if (!VolNameOK(tovolume)) {
+ fprintf(STDERR,
+ "Illegal volume name %s, should not end in .readonly or .backup\n",
+ tovolume);
+ return EINVAL;
+ }
+ if (IsNumeric(tovolume)) {
+ fprintf(STDERR,
+ "Illegal volume name %s, should not be a number\n",
+ tovolume);
+ return EINVAL;
+ }
+ } else {
+ /* use actual name of source volume */
+ code = UV_ListOneVolume(fromserver, frompart, volid, &p);
+ if (code) {
+ fprintf(STDERR, "vos:cannot access volume %lu\n",
+ (unsigned long)volid);
+ exit(1);
+ }
+ strcpy(toVolName, p->name);
+ tovolume = toVolName;
+ /* save p for size checks later */
+ }
+
+ if (as->parms[6].items) {
+ tovolid = vsu_GetVolumeID(as->parms[6].items->data, cstruct, &err);
+ if (tovolid == 0) {
+ if (err)
+ PrintError("", err);
+ else
+ fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
+ as->parms[6].items->data);
+ if (p)
+ free(p);
+ return ENOENT;
+ }
+ } else {
+ tovolid = vsu_GetVolumeID(tovolume, cstruct, &err);
+ if (tovolid == 0) {
+ if (err)
+ PrintError("", err);
+ else
+ fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
+ tovolume);
+ if (p)
+ free(p);
+ return ENOENT;
+ }
+ }
+
+ flags = RV_NOVLDB;
+ if (as->parms[7].items) flags |= RV_OFFLINE;
+ if (as->parms[8].items) flags |= RV_RDONLY;
+ if (as->parms[9].items) flags |= RV_NOCLONE;
+ if (as->parms[10].items) flags |= RV_CPINCR;
+
+ MapPartIdIntoName(topart, toPartName);
+ MapPartIdIntoName(frompart, fromPartName);
+
+ /*
+ * check target partition for space to move volume
+ */
+
+ code = UV_PartitionInfo(toserver, toPartName, &partition);
+ if (code) {
+ fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
+ exit(1);
+ }
+ if (TESTM)
+ fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
+ partition.free);
+
+ /* Don't do this again if we did it above */
+ if (!p) {
+ code = UV_ListOneVolume(fromserver, frompart, volid, &p);
+ if (code) {
+ fprintf(STDERR, "vos:cannot access volume %lu\n",
+ (unsigned long)volid);
+ exit(1);
+ }
+ }
+
+ /* OK if this fails */
+ code = UV_ListOneVolume(toserver, topart, tovolid, &q);
+
+ /* Treat existing volume size as "free" */
+ if (q)
+ p->size = (q->size < p->size) ? p->size - q->size : 0;
+
+ if (partition.free <= p->size) {
+ fprintf(STDERR,
+ "vos: no space on target partition %s to copy volume %lu\n",
+ toPartName, (unsigned long)volid);
+ free(p);
+ if (q) free(q);
+ exit(1);
+ }
+ free(p);
+ if (q) free(q);
+
+ /* successful copy still not guaranteed but shoot for it */
+
+ code =
+ UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
+ topart, tovolid, flags);
+ if (code) {
+ PrintDiagnostics("shadow", code);
+ return code;
+ }
+ MapPartIdIntoName(topart, toPartName);
+ MapPartIdIntoName(frompart, fromPartName);
+ fprintf(STDOUT, "Volume %lu shadowed from %s %s to %s %s \n",
+ (unsigned long)volid, as->parms[1].items->data, fromPartName,
+ as->parms[3].items->data, toPartName);
+
+ return 0;
+}
+
+
+static
+CloneVolume(as)
+ register struct cmd_syndesc *as;
+{
+ afs_int32 server, part, volid, cloneid, voltype;
+ char partName[10], *volname;
+ afs_int32 code, err, flags;
+ struct nvldbentry entry;
+
+ volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
+ if (volid == 0) {
+ if (err)
+ PrintError("", err);
+ else
+ fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
+ as->parms[0].items->data);
+ return ENOENT;
+ }
+
+ if (as->parms[1].items || as->parms[2].items) {
+ if (!as->parms[1].items || !as->parms[2].items) {
+ fprintf(STDERR,
+ "Must specify both -server and -partition options\n");
+ return -1;
+ }
+ server = GetServer(as->parms[1].items->data);
+ if (server == 0) {
+ fprintf(STDERR, "vos: server '%s' not found in host table\n",
+ as->parms[1].items->data);
+ return ENOENT;
+ }
+ part = volutil_GetPartitionID(as->parms[2].items->data);
+ if (part < 0) {
+ fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
+ as->parms[2].items->data);
+ return EINVAL;
+ }
+ if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
+ if (code)
+ PrintError("", code);
+ else
+ fprintf(STDERR,
+ "vos : partition %s does not exist on the server\n",
+ as->parms[2].items->data);
+ return ENOENT;
+ }
+ } else {
+ code = GetVolumeInfo(volid, &server, &part, &voltype, &entry);
+ if (code)
+ return code;
+ }
+
+ volname = 0;
+ if (as->parms[3].items) {
+ volname = as->parms[3].items->data;
+ if (strlen(volname) > VOLSER_OLDMAXVOLNAME - 1) {
+ fprintf(STDERR,
+ "vos: the name of the root volume %s exceeds the size limit of %d\n",
+ volname, VOLSER_OLDMAXVOLNAME - 1);
+ return E2BIG;
+ }
+ if (!VolNameOK(volname)) {
+ fprintf(STDERR,
+ "Illegal volume name %s, should not end in .readonly or .backup\n",
+ volname);
+ return EINVAL;
+ }
+ if (IsNumeric(volname)) {
+ fprintf(STDERR,
+ "Illegal volume name %s, should not be a number\n",
+ volname);
+ return EINVAL;
+ }
+ }
+
+ cloneid = 0;
+ if (as->parms[4].items) {
+ cloneid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
+ if (cloneid == 0) {
+ if (err)
+ PrintError("", err);
+ else
+ fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
+ as->parms[4].items->data);
+ return ENOENT;
+ }
+ }
+
+ flags = 0;
+ if (as->parms[5].items) flags |= RV_OFFLINE;
+ if (as->parms[6].items) flags |= RV_RDONLY;
+
+
+ code =
+ UV_CloneVolume(server, part, volid, cloneid, volname, flags);
+
+ if (code) {
+ PrintDiagnostics("clone", code);
+ return code;
+ }
+ MapPartIdIntoName(part, partName);
+ fprintf(STDOUT, "Created clone for volume %lu\n",
+ as->parms[0].items->data);
+
+ return 0;
+}
+
+
+static
BackupVolume(as)
register struct cmd_syndesc *as;
{
#define FULL 2
#define INC 3
+#define TS_DUMP 1
+#define TS_KEEP 2
+#define TS_NEW 3
+
static
RestoreVolume(as)
register struct cmd_syndesc *as;
{
afs_int32 avolid, aserver, apart, code, vcode, err;
afs_int32 aoverwrite = ASK;
+ afs_int32 acreation = 0, alastupdate = 0;
int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
char prompt;
char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
voltype = ROVOL;
}
+ if (as->parms[8].items) {
+ if ((strcmp(as->parms[8].items->data, "d") == 0)
+ || (strcmp(as->parms[8].items->data, "dump") == 0)) {
+ acreation = TS_DUMP;
+ } else if ((strcmp(as->parms[8].items->data, "k") == 0)
+ || (strcmp(as->parms[8].items->data, "keep") == 0)) {
+ acreation = TS_KEEP;
+ } else if ((strcmp(as->parms[8].items->data, "n") == 0)
+ || (strcmp(as->parms[8].items->data, "new") == 0)) {
+ acreation = TS_NEW;
+ } else {
+ fprintf(STDERR, "vos: %s is not a valid argument to -creation\n",
+ as->parms[8].items->data);
+ exit(1);
+ }
+ }
+
+ if (as->parms[9].items) {
+ if ((strcmp(as->parms[9].items->data, "d") == 0)
+ || (strcmp(as->parms[9].items->data, "dump") == 0)) {
+ alastupdate = TS_DUMP;
+ } else if ((strcmp(as->parms[9].items->data, "k") == 0)
+ || (strcmp(as->parms[9].items->data, "keep") == 0)) {
+ alastupdate = TS_KEEP;
+ } else if ((strcmp(as->parms[9].items->data, "n") == 0)
+ || (strcmp(as->parms[9].items->data, "new") == 0)) {
+ alastupdate = TS_NEW;
+ } else {
+ fprintf(STDERR, "vos: %s is not a valid argument to -lastupdate\n",
+ as->parms[9].items->data);
+ exit(1);
+ }
+ }
+
aserver = GetServer(as->parms[0].items->data);
if (aserver == 0) {
fprintf(STDERR, "vos: server '%s' not found in host table\n",
restoreflags |= RV_OFFLINE;
if (readonly)
restoreflags |= RV_RDONLY;
+
+ switch (acreation) {
+ case TS_DUMP:
+ restoreflags |= RV_CRDUMP;
+ break;
+ case TS_KEEP:
+ restoreflags |= RV_CRKEEP;
+ break;
+ case TS_NEW:
+ restoreflags |= RV_CRNEW;
+ break;
+ default:
+ if (aoverwrite == FULL)
+ restoreflags |= RV_CRNEW;
+ else
+ restoreflags |= RV_CRKEEP;
+ }
+
+ switch (alastupdate) {
+ case TS_DUMP:
+ restoreflags |= RV_LUDUMP;
+ break;
+ case TS_KEEP:
+ restoreflags |= RV_LUKEEP;
+ break;
+ case TS_NEW:
+ restoreflags |= RV_LUNEW;
+ break;
+ default:
+ restoreflags |= RV_LUKEEP;
+ }
+
code =
UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
WriteData, afilename);
SyncVldb(as)
register struct cmd_syndesc *as;
{
- afs_int32 pname, code; /* part name */
+ afs_int32 pnum = 0, code; /* part name */
char part[10];
int flags = 0;
char *volname = 0;
}
if (as->parms[1].items) {
- pname = volutil_GetPartitionID(as->parms[1].items->data);
- if (pname < 0) {
+ pnum = volutil_GetPartitionID(as->parms[1].items->data);
+ if (pnum < 0) {
fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
as->parms[1].items->data);
exit(1);
}
- if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
+ if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
if (code)
PrintError("", code);
else
if (as->parms[2].items) {
/* Synchronize an individual volume */
volname = as->parms[2].items->data;
- code = UV_SyncVolume(tserver, pname, volname, flags);
+ code = UV_SyncVolume(tserver, pnum, volname, flags);
} else {
if (!tserver) {
fprintf(STDERR,
"Without a -volume option, the -server option is required\n");
exit(1);
}
- code = UV_SyncVldb(tserver, pname, flags, 0 /*unused */ );
+ code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ );
}
if (code) {
fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
}
if (flags) {
- MapPartIdIntoName(pname, part);
+ MapPartIdIntoName(pnum, part);
fprintf(STDOUT, " partition %s\n", part);
}
fprintf(STDOUT, "\n");
register struct cmd_syndesc *as;
{
- afs_int32 pname, code; /* part name */
+ afs_int32 pnum, code; /* part name */
char part[10];
int flags = 0;
exit(1);
}
if (as->parms[1].items) {
- pname = volutil_GetPartitionID(as->parms[1].items->data);
- if (pname < 0) {
+ pnum = volutil_GetPartitionID(as->parms[1].items->data);
+ if (pnum < 0) {
fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
as->parms[1].items->data);
exit(1);
}
- if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
+ if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
if (code)
PrintError("", code);
else
exit(1);
}
flags = 1;
+ } else {
+ pnum = -1;
}
- code = UV_SyncServer(tserver, pname, flags, 0 /*unused */ );
+ code = UV_SyncServer(tserver, pnum, flags, 0 /*unused */ );
if (code) {
PrintDiagnostics("syncserv", code);
exit(1);
}
if (flags) {
- MapPartIdIntoName(pname, part);
+ MapPartIdIntoName(pnum, part);
fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
as->parms[0].items->data, part);
} else
{
afs_int32 vcode;
afs_int32 i, j;
+ struct VLCallBack vlcb;
afs_int32 *addrp;
bulkaddrs m_addrs;
ListAddrByAttributes m_attrs;
- afs_int32 m_unique, m_nentries, *m_addrp;
+ afs_int32 m_nentries, *m_addrp;
afs_int32 base, index;
char buf[1024];
m_addrs.bulkaddrs_len = 0;
vcode =
ubik_Call(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
- &m_unique, &m_nentries, &m_addrs);
+ &vlcb, &m_nentries, &m_addrs);
if (vcode) {
fprintf(STDERR,
"vos: could not list the multi-homed server addresses\n");
{
afs_int32 vcode;
afs_int32 i, noresolve = 0, printuuid = 0;
+ struct VLCallBack vlcb;
afs_int32 nentries;
bulkaddrs m_addrs;
ListAddrByAttributes m_attrs;
afsUUID m_uuid, askuuid;
- afs_int32 m_unique, m_nentries;
+ afs_int32 m_nentries;
memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
m_attrs.Mask = VLADDR_INDEX;
m_addrs.bulkaddrs_len = 0;
vcode =
- ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &m_unique, &nentries,
+ ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb, &nentries,
&m_addrs);
if (vcode) {
fprintf(STDERR, "vos: could not list the server addresses\n");
vcode =
ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
- &m_unique, &m_nentries, &m_addrs);
+ &vlcb, &m_nentries, &m_addrs);
if (vcode == VL_NOENT) {
i++;
nentries++;
"machine name on destination");
cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
"partition name on destination");
+ cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
+ "copy live volume without cloning");
COMMONPARMS;
ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume");
"machine name on destination");
cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
"partition name on destination");
+ cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
+ "leave new volume offline");
+ cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
+ "make new volume read-only");
+ cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
+ "copy live volume without cloning");
+ COMMONPARMS;
+
+ ts = cmd_CreateSyntax("shadow", ShadowVolume, 0,
+ "make or update a shadow volume");
+ cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
+ cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
+ cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
+ "partition name on source");
+ cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
+ "machine name on destination");
+ cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
+ "partition name on destination");
+ cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
+ "volume name on destination");
+ cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
+ "volume ID on destination");
+ cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
+ "leave shadow volume offline");
+ cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
+ "make shadow volume read-only");
+ cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
+ "copy live volume without cloning");
+ cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL,
+ "do incremental update if target exists");
COMMONPARMS;
ts = cmd_CreateSyntax("backup", BackupVolume, 0,
cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
COMMONPARMS;
+ ts = cmd_CreateSyntax("clone", CloneVolume, 0,
+ "make clone of a volume");
+ cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
+ cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
+ cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
+ cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
+ "volume name on destination");
+ cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
+ "volume ID on destination");
+ cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
+ "leave clone volume offline");
+ cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
+ "make clone volume read-only, not readwrite");
+ COMMONPARMS;
+
ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
"leave restored volume offline");
cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
"make restored volume read-only");
+ cmd_AddParm(ts, "-creation", CMD_SINGLE, CMD_OPTIONAL,
+ "dump | keep | new");
+ cmd_AddParm(ts, "-lastupdate", CMD_SINGLE, CMD_OPTIONAL,
+ "dump | keep | new");
COMMONPARMS;
ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0,