extern int DoLogging;
extern struct afsconf_dir *tdir;
extern int DoPreserveVolumeStats;
+extern int restrictedQueryLevel;
+extern enum vol_s2s_crypt doCrypt;
extern void LogError(afs_int32 errcode);
struct destServer *destination, afs_int32,
struct restoreCookie *cookie);
static afs_int32 VolDump(struct rx_call *, afs_int32, afs_int32, afs_int32);
-static afs_int32 VolRestore(struct rx_call *, afs_int32, afs_int32,
- struct restoreCookie *);
+static afs_int32 VolRestore(struct rx_call *, afs_int32, struct restoreCookie *);
static afs_int32 VolEndTrans(struct rx_call *, afs_int32, afs_int32 *);
static afs_int32 VolSetForwarding(struct rx_call *, afs_int32, afs_int32);
static afs_int32 VolGetStatus(struct rx_call *, afs_int32,
return code;
}
-/* get partition id from a name */
-afs_int32
-PartitionID(char *aname)
-{
- char tc;
- int code = 0;
- char ascii[3];
-
- tc = *aname;
- if (tc == 0)
- return -1; /* unknown */
-
- /* otherwise check for vicepa or /vicepa, or just plain "a" */
- ascii[2] = 0;
- if (!strncmp(aname, "/vicep", 6)) {
- strncpy(ascii, aname + 6, 2);
- } else
- return -1; /* bad partition name */
- /* now partitions are named /vicepa ... /vicepz, /vicepaa, /vicepab, .../vicepzz, and are numbered
- * from 0. Do the appropriate conversion */
- if (ascii[1] == 0) {
- /* one char name, 0..25 */
- if (ascii[0] < 'a' || ascii[0] > 'z')
- return -1; /* wrongo */
- return ascii[0] - 'a';
- } else {
- /* two char name, 26 .. <whatever> */
- if (ascii[0] < 'a' || ascii[0] > 'z')
- return -1; /* wrongo */
- if (ascii[1] < 'a' || ascii[1] > 'z')
- return -1; /* just as bad */
- code = (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
- if (code > VOLMAXPARTS)
- return -1;
- return code;
- }
-}
-
static int
ConvertVolume(VolumeId avol, char *aname, afs_int32 asize)
{
afs_int32 code;
struct diskPartition64 *dp = malloc(sizeof(struct diskPartition64));
+ memset(partition, 0, sizeof(*partition));
code = VolPartitionInfo(acid, pname, dp);
if (!code) {
strncpy(partition->name, dp->name, 32);
{
afs_int32 code;
+ memset(partition, 0, sizeof(*partition));
code = VolPartitionInfo(acid, pname, partition);
osi_auditU(acid, VS_ParInfEvent, code, AUD_STR, pname, AUD_END);
return code;
}
-afs_int32
+static afs_int32
VolPartitionInfo(struct rx_call *acid, char *pname, struct diskPartition64
*partition)
{
struct DiskPartition64 *dp;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
VResetDiskUsage();
dp = VGetPartition(pname, 0);
if (dp) {
VCreateVolume(&error, originalvp->partition->name, newId,
V_parentId(originalvp));
if (error) {
- Log("1 Volser: Clone: Couldn't create new volume; clone aborted\n");
+ Log("1 Volser: Clone: Couldn't create new volume %" AFS_VOLID_FMT " for parent %" AFS_VOLID_FMT "; clone aborted\n",
+ afs_printable_VolumeId_lu(newId), afs_printable_VolumeId_lu(V_parentId(originalvp)));
newvp = (Volume *) 0;
goto fail;
}
goto fail;
}
if (newType == readonlyVolume) {
- AssignVolumeName(&V_disk(newvp), V_name(originalvp), ".readonly");
V_type(newvp) = readonlyVolume;
} else if (newType == backupVolume) {
- AssignVolumeName(&V_disk(newvp), V_name(originalvp), ".backup");
V_type(newvp) = backupVolume;
V_backupId(originalvp) = newId;
}
#ifdef AFS_DEMAND_ATTACH_FS
salv_vp = NULL;
#endif
+
+ /* Clients could have callbacks to the clone ID */
+ FSYNC_VolOp(newId, NULL, FSYNC_VOL_BREAKCBKS, 0l, NULL);
+
if (TRELE(tt)) {
tt = (struct volser_trans *)0;
error = VOLSERTRELE_ERROR;
VolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_uint32 *avolume,
afs_int32 *apart)
{
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
Log("1 Volser: GetNthVolume: Not yet implemented\n");
return VOLSERNO_OP;
}
{
struct volser_trans *tt;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
tt = FindTrans(atid);
if (!tt)
return ENOENT;
return code;
}
+static_inline afs_int32
+MakeClient(struct rx_call *acid, struct rx_securityClass **securityObject,
+ afs_int32 *securityIndex)
+{
+ rxkad_level enc_level = rxkad_clear;
+ int docrypt;
+ int code;
+
+ switch (doCrypt) {
+ case VS2SC_ALWAYS:
+ docrypt = 1;
+ break;
+ case VS2SC_INHERIT:
+ rxkad_GetServerInfo(rx_ConnectionOf(acid), &enc_level, 0, 0, 0, 0, 0);
+ docrypt = (enc_level == rxkad_crypt ? 1 : 0);
+ break;
+ case VS2SC_NEVER:
+ docrypt = 0;
+ break;
+ default:
+ opr_Assert(0 && "doCrypt corrupt?");
+ }
+ if (docrypt)
+ code = afsconf_ClientAuthSecure(tdir, securityObject, securityIndex);
+ else
+ code = afsconf_ClientAuth(tdir, securityObject, securityIndex);
+ return code;
+}
+
static afs_int32
VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
struct destServer *destination, afs_int32 destTrans,
TSetRxCall(tt, NULL, "Forward");
/* get auth info for the this connection (uses afs from ticket file) */
- code = afsconf_ClientAuth(tdir, &securityObject, &securityIndex);
+ code = MakeClient(acid, &securityObject, &securityIndex);
if (code) {
TRELE(tt);
return code;
rx_NewConnection(htonl(destination->destHost),
htons(destination->destPort), VOLSERVICE_ID,
securityObject, securityIndex);
+
+ RXS_Close(securityObject); /* will be freed after connection destroyed */
+
if (!tcon) {
TClearRxCall(tt);
TRELE(tt);
}
/* get auth info for this connection (uses afs from ticket file) */
- code = afsconf_ClientAuth(tdir, &securityObject, &securityIndex);
+ code = MakeClient(acid, &securityObject, &securityIndex);
if (code) {
goto fail; /* in order to audit each failure */
}
}
}
+ /* Security object will be freed when all connections destroyed */
+ RXS_Close(securityObject);
+
/* these next calls implictly call rx_Write when writing out data */
code = DumpVolMulti(tcalls, i, vp, fromDate, 0, codes);
{
afs_int32 code;
- code = VolRestore(acid, atrans, aflags, cookie);
+ code = VolRestore(acid, atrans, cookie);
osi_auditU(acid, VS_RestoreEvent, code, AUD_LONG, atrans, AUD_END);
return code;
}
static afs_int32
-VolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags,
- struct restoreCookie *cookie)
+VolRestore(struct rx_call *acid, afs_int32 atrans, struct restoreCookie *cookie)
{
struct volser_trans *tt;
afs_int32 code, tcode;
DFlushVolume(V_parentId(tt->volume)); /* Ensure dir buffers get dropped */
- code = RestoreVolume(acid, tt->volume, (aflags & 1), cookie); /* last is incrementalp */
+ code = RestoreVolume(acid, tt->volume, cookie);
FSYNC_VolOp(tt->volid, NULL, FSYNC_VOL_BREAKCBKS, 0l, NULL);
TClearRxCall(tt);
tcode = TRELE(tt);
struct VolumeDiskData *td;
struct volser_trans *tt;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
tt = FindTrans(atrans);
if (!tt)
struct volser_trans *tt;
int len;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
/* We need to at least fill it in */
*aname = malloc(1);
if (!*aname)
char namehead[9];
int i;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
strcpy(namehead, "/vicep"); /*7 including null terminator */
/* Just return attached partitions. */
struct DiskPartition64 *dp;
int i, j = 0;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
strcpy(namehead, "/vicep"); /*7 including null terminator */
/* Only report attached partitions */
case VOL_INFO_LIST_SINGLE:
Log("1 Volser: GetVolInfo: Volume %" AFS_VOLID_FMT " (%s:%s) will be destroyed on next salvage\n",
afs_printable_VolumeId_lu(volumeId), pname, volname);
+ goto drop;
default:
goto drop;
int found = 0;
volint_info_handle_t handle;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
volumeInfo->volEntries_val = calloc(1, sizeof(volintInfo));
if (!volumeInfo->volEntries_val)
return ENOMEM;
int found = 0; /*Did we find the volume we need? */
volint_info_handle_t handle;
+ if (!afsconf_CheckRestrictedQuery(tdir, a_rxCidP, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
/*
* Set up our pointers for action, marking our structure to hold exactly
* one entry. Also, assume we'll fail in our quest.
int code;
volint_info_handle_t handle;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
volumeInfo->volEntries_val = calloc(allocSize, sizeof(volintInfo));
if (!volumeInfo->volEntries_val)
return ENOMEM;
int code;
volint_info_handle_t handle;
+ if (!afsconf_CheckRestrictedQuery(tdir, a_rxCidP, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
/*
* Allocate a large array of extended volume info structures, then
* set it up for action.
{
transDebugInfo *pntr;
afs_int32 allocSize = 50;
+ afs_int32 code = 0;
struct volser_trans *tt, *nt, *allTrans;
+ if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+ return VOLSERBAD_ACCESS;
+
transInfo->transDebugEntries_val =
malloc(allocSize * sizeof(transDebugInfo));
if (!transInfo->transDebugEntries_val)
goto done; /*no active transactions */
for (tt = allTrans; tt; tt = nt) { /*copy relevant info into pntr */
nt = tt->next;
+ memset(pntr, 0, sizeof(*pntr));
VTRANS_OBJ_LOCK(tt);
pntr->tid = tt->tid;
pntr->time = tt->time;
pntr->callValid = 0;
if (tt->rxCallPtr) { /*record call related info */
pntr->callValid = 1;
-#if 0
- pntr->readNext = tt->rxCallPtr->rnext;
- pntr->transmitNext = tt->rxCallPtr->tnext;
- pntr->lastSendTime = tt->rxCallPtr->lastSendTime;
- pntr->lastReceiveTime = tt->rxCallPtr->lastReceiveTime;
-#endif
+ rx_GetCallStatus(tt->rxCallPtr, &(pntr->readNext), &(pntr->transmitNext),
+ &(pntr->lastSendTime), &(pntr->lastReceiveTime));
}
VTRANS_OBJ_UNLOCK(tt);
pntr++;
allocSize = (allocSize * 3) / 2;
pntr = realloc(transInfo->transDebugEntries_val,
allocSize * sizeof(transDebugInfo));
+ if (pntr == NULL) {
+ code = ENOMEM;
+ goto done;
+ }
transInfo->transDebugEntries_val = pntr;
pntr =
transInfo->transDebugEntries_val +
done:
VTRANS_UNLOCK;
- return 0;
+ return code;
}
afs_int32
#endif
ttc = NewTrans(volumeId, partId);
if (!ttc) {
- return VOLSERVOLBUSY;
+ ret = VOLSERVOLBUSY;
+ goto done;
}
+ ret = FSYNC_VolOp(volumeId, pname, FSYNC_VOL_NEEDVOLUME, V_VOLUPD,
+ NULL);
+ if (ret != SYNC_OK) {
+ Log("SAFSVolConvertROtoRWvolume: Error %ld trying to check out "
+ "vol %lu part %s.\n", afs_printable_int32_ld(ret),
+ afs_printable_uint32_lu(volumeId), pname);
+ ret = VOLSERFAILEDOP;
+ goto done;
+ }
#ifdef AFS_NAMEI_ENV
ret = namei_ConvertROtoRWvolume(pname, volumeId);
#else
ret = inode_ConvertROtoRWvolume(pname, volumeId);
#endif
+ if (ret != 0) {
+ Log("SAFSVolConvertROtoRWvolume: Error %ld trying to convert "
+ "RO vol %lu to RW. The volume may be in an inconsistent or "
+ "partially converted state; if the volume seems unusable, "
+ "you can try salvaging it or restoring from another RO "
+ "copy.\n", afs_printable_int32_ld(ret),
+ afs_printable_uint32_lu(volumeId));
+ /*
+ * the volume may or may not be usable at this point; let the
+ * fileserver try to attach and decide.
+ */
+ FSYNC_VolOp(volumeId, pname, FSYNC_VOL_ON, 0, NULL);
+ }
break;
}
}
-
+ done:
if (ttc)
DeleteTrans(ttc, 1);
}
afs_int32
-SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new,
+SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 ovid, afs_uint32 onew,
afs_uint32 where, afs_int32 verbose)
{
#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
struct volser_trans *tt = 0, *tt2 = 0;
char caller[MAXKTCNAMELEN];
char line[128];
+ VolumeId new = onew;
+ VolumeId vid = ovid;
if (!afsconf_SuperUser(tdir, acall, caller))
return EPERM;
if (V_device(vol) != V_device(newvol)
|| V_uniquifier(newvol) != 2) {
if (V_device(vol) != V_device(newvol)) {
- sprintf(line, "Volumes %u and %u are not in the same partition, aborted.\n",
- vid, new);
+ sprintf(line, "Volumes %" AFS_VOLID_FMT " and %" AFS_VOLID_FMT " are not in the same partition, aborted.\n",
+ afs_printable_VolumeId_lu(vid),
+ afs_printable_VolumeId_lu(new));
rx_Write(acall, line, strlen(line));
}
if (V_uniquifier(newvol) != 2) {
- sprintf(line, "Volume %u is not freshly created, aborted.\n", new);
+ sprintf(line, "Volume %" AFS_VOLID_FMT " is not freshly created, aborted.\n",
+ afs_printable_VolumeId_lu(new));
rx_Write(acall, line, strlen(line));
}
line[0] = 0;
}
tt = NewTrans(vid, V_device(vol));
if (!tt) {
- sprintf(line, "Couldn't create transaction for %u, aborted.\n", vid);
+ sprintf(line, "Couldn't create transaction for %" AFS_VOLID_FMT ", aborted.\n",
+ afs_printable_VolumeId_lu(vid));
rx_Write(acall, line, strlen(line));
line[0] = 0;
rx_Write(acall, line, 1);
tt2 = NewTrans(new, V_device(newvol));
if (!tt2) {
- sprintf(line, "Couldn't create transaction for %u, aborted.\n", new);
+ sprintf(line, "Couldn't create transaction for %" AFS_VOLID_FMT ", aborted.\n",
+ afs_printable_VolumeId_lu(new));
rx_Write(acall, line, strlen(line));
line[0] = 0;
rx_Write(acall, line, 1);