AC_CHECK_HEADERS(mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h)
AC_CHECK_HEADERS(sys/mount.h strings.h termios.h signal.h)
AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h sys/user.h)
-AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h)
+AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h values.h)
if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_pam" = yes; then
HAVE_PAM="yes"
#include <afsconfig.h>
#include <afs/param.h>
+#ifndef AFS_NT40_ENV
+#include <netdb.h>
+#endif
RCSID
("$Header$");
return 0;
}
+/*
+ * Parse a server name/address and return the address in HOST BYTE order
+ */
+static afs_uint32
+GetServer(char *aname)
+{
+ register struct hostent *th;
+ afs_uint32 addr;
+ int b1, b2, b3, b4;
+ register afs_int32 code;
+ char hostname[MAXHOSTCHARS];
+
+ code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
+ if (code == 4) {
+ addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+ addr = ntohl(addr); /* convert to host order */
+ } else {
+ th = gethostbyname(aname);
+ if (!th)
+ return 0;
+ memcpy(&addr, th->h_addr, sizeof(addr));
+ }
+
+ if (addr == htonl(0x7f000001)) { /* local host */
+ code = gethostname(hostname, MAXHOSTCHARS);
+ if (code)
+ return 0;
+ th = gethostbyname(hostname); /* returns host byte order */
+ if (!th)
+ return 0;
+ memcpy(&addr, th->h_addr, sizeof(addr));
+ }
+
+ return (addr);
+}
+
+static void
+Print_vos_volintInfo(afs_uint32 server, afs_uint32 partition, volintInfo* pinfo, const char *prefix)
+{
+ static afs_uint32 server_cache;
+ static int cache_valid = 0;
+ static char hostname[256], address[32];
+
+ if (!cache_valid || server != server_cache) {
+ struct in_addr s;
+
+ s.s_addr = server;
+ strcpy(hostname, hostutil_GetNameByINet(server));
+ strcpy(address, inet_ntoa(s));
+ server_cache = server;
+ cache_valid = 1;
+ }
+
+
+ printf("%sname\t\t%s\n",prefix, pinfo->name);
+ printf("%sid\t\t%lu\n",prefix, pinfo->volid);
+ printf("%sserv\t\t%s\t%s\n",prefix, address,hostname);
+ printf("%spart\t\t%u\n", prefix,partition);
+
+ switch (pinfo->status) {
+ case 2: /* VOK */
+ printf("%sstatus\t\tOK\n",prefix);
+ break;
+ case 101: /* VBUSY */
+ printf("%sstatus\t\tBUSY\n",prefix);
+ return;
+ default:
+ printf("%sstatus\t\tUNATTACHABLE\n",prefix);
+ return;
+ }
+ printf("%sbackupID\t%lu\n",prefix, pinfo->backupID);
+ printf("%sparentID\t%lu\n",prefix, pinfo->parentID);
+ printf("%scloneID\t%lu\n",prefix, pinfo->cloneID);
+ printf("%sinUse\t\t%s\n",prefix, pinfo->inUse ? "Y" : "N");
+ printf("%sneedsSalvaged\t%s\n",prefix, pinfo->needsSalvaged ? "Y" : "N");
+ /* 0xD3 is from afs/volume.h since I had trouble including the file */
+ printf("%sdestroyMe\t%s\n",prefix, pinfo->destroyMe == 0xD3 ? "Y" : "N");
+ switch (pinfo->type) {
+ case 0:
+ printf("%stype\t\tRW\n",prefix);
+ break;
+ case 1:
+ printf("%stype\t\tRO\n",prefix);
+ break;
+ case 2:
+ printf("%stype\t\tBK\n",prefix);
+ break;
+ default:
+ printf("%stype\t\t?\n",prefix);
+ break;
+ }
+ printf("%screationDate\t%-9lu\n", prefix,pinfo->creationDate);
+ printf("%saccessDate\t%-9lu\n", prefix,pinfo->accessDate);
+ printf("%supdateDate\t%-9lu\n", prefix,pinfo->updateDate);
+ printf("%sbackupDate\t%-9lu\n", prefix,pinfo->backupDate);
+ printf("%scopyDate\t%-9lu\n", prefix,pinfo->copyDate);
+
+ printf("%sflags\t\t%#lx\t(Optional)\n",prefix, pinfo->flags);
+ printf("%sdiskused\t%u\n",prefix, pinfo->size);
+ printf("%smaxquota\t%u\n",prefix, pinfo->maxquota);
+ printf("%sminquota\t%lu\t(Optional)\n",prefix, pinfo->spare0);
+ printf("%sfilecount\t%u\n",prefix, pinfo->filecount);
+ printf("%sdayUse\t\t%u\n",prefix, pinfo->dayUse);
+ printf("%sweekUse\t%lu\t(Optional)\n",prefix, pinfo->spare1);
+ printf("%svolUpdateCounter\t\t%lu\t(Optional)\n",prefix, pinfo->spare2);
+ printf("%sspare3\t\t%lu\t(Optional)\n",prefix, pinfo->spare3);
+}
+
+int
+DoVosVolumeGet2(struct cmd_syndesc *as, char *arock)
+{
+ typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
+ afs_status_t st = 0;
+ void *vos_server = NULL;
+ afs_uint32 partition_id;
+ afs_uint32 volume_id;
+
+ volintInfo info;
+ memset(&info, 0, sizeof(struct volintInfo));
+
+ if (as->parms[SERVER].items) {
+ if (!vos_ServerOpen
+ (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
+ ERR_ST_EXT("vos_ServerOpen", st);
+ }
+ }
+
+ if (as->parms[PARTITION].items) {
+ partition_id =
+ GetPartitionIdFromString(as->parms[PARTITION].items->data);
+ }
+
+ if (as->parms[VOLUME].items) {
+ const char *volume = as->parms[VOLUME].items->data;
+ volume_id = GetVolumeIdFromString(volume);
+ }
+
+
+ if (!vos_VolumeGet2
+ (cellHandle, vos_server, 0, partition_id, volume_id, &info, &st)) {
+ ERR_ST_EXT("vos_VolumeGet2", st);
+ }
+
+
+ Print_vos_volintInfo(GetServer(as->parms[SERVER].items->data),partition_id,&info," ");
+
+ return 0;
+}
+
+
+int
+DoVos_ClearVolUpdateCounter(struct cmd_syndesc *as, char *arock)
+{
+ typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
+ afs_status_t st = 0;
+ void *vos_server = NULL;
+ unsigned int partition_id;
+ unsigned int volume_id;
+
+ if (as->parms[SERVER].items) {
+ if (!vos_ServerOpen
+ (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
+ ERR_ST_EXT("vos_ServerOpen", st);
+ }
+ }
+
+ if (as->parms[PARTITION].items) {
+ partition_id =
+ GetPartitionIdFromString(as->parms[PARTITION].items->data);
+ }
+
+ if (as->parms[VOLUME].items) {
+ const char *volume = as->parms[VOLUME].items->data;
+ volume_id = GetVolumeIdFromString(volume);
+ }
+
+ if (!vos_ClearVolUpdateCounter
+ (cellHandle, vos_server,partition_id, volume_id, &st)) {
+ ERR_ST_EXT("vos_ClearVolUpdateCounter", st);
+ }
+
+ return 0;
+}
+
void
SetupVosAdminCmd(void)
{
"new quota in 1kb units");
SetupCommonCmdArgs(ts);
+ ts = cmd_CreateSyntax("VosVolumeGet2", DoVosVolumeGet2, 0,
+ "get a volume entry");
+ cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
+ "server that houses volume");
+ cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
+ "partition that houses volume");
+ cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
+ "volume to retrieve");
+ SetupCommonCmdArgs(ts);
+
+ ts = cmd_CreateSyntax("ClearVolUpdateCounter", DoVos_ClearVolUpdateCounter, 0,
+ "clear volUpdateCounter");
+ cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
+ "server that houses volume");
+ cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
+ "partition that houses volume");
+ cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
+ "volume");
+ SetupCommonCmdArgs(ts);
+
}
+
memset((void *)&tstatus, 0, sizeof(tstatus));
tstatus.dayUse = -1;
+ tstatus.spare2 = -1;
tstatus.maxquota = volumeQuota;
+
tst =
AFSVolTransCreate(f_server->serv, volumeId, partition, ITBusy, &ttid);
if (tst) {
}
return rc;
}
+/*
+ * vos_VolumeGet2 - get information about a particular volume.
+ *
+ * PARAMETERS
+ *
+ * IN cellHandle - a previously opened cellHandle that corresponds
+ * to the cell where the volume exists.
+ *
+ * IN serverHandle - a previously opened serverHandle that corresponds
+ * to the server where the volume exists.
+ *
+ * IN callBack - a call back function pointer that may be called to report
+ * status information. Can be null.
+ *
+ * IN partition - the partition where the volume exists.
+ *
+ * IN volumeId - the volume id of the volume to be retrieved.
+ *
+ * OUT pinfo - upon successful completion, contains the information about the
+ * specified volume.
+ *
+ * LOCKS
+ *
+ * No locks are obtained or released by this function
+ *
+ * RETURN CODES
+ *
+ * Returns != 0 upon successful completion.
+ */
+
+int ADMINAPI
+vos_VolumeGet2(const void *cellHandle, const void *serverHandle,
+ vos_MessageCallBack_t callBack, unsigned int partition,
+ unsigned int volumeId, volintInfo* pinfo,
+ afs_status_p st)
+{
+ int rc = 0;
+ afs_status_t tst = 0;
+ file_server_p f_server = (file_server_p) serverHandle;
+ volintInfo *pinfo_=0;
+
+ /*
+ * Validate arguments
+ */
+
+ if (!IsValidServerHandle(f_server, &tst)) {
+ goto fail_vos_VolumeGet2;
+ }
+
+ if (partition > VOLMAXPARTS) {
+ tst = ADMVOSPARTITIONIDTOOLARGE;
+ goto fail_vos_VolumeGet2;
+ }
+
+ if (pinfo == NULL) {
+ tst = ADMVOSVOLUMEPNULL;
+ goto fail_vos_VolumeGet2;
+ }
+
+ /*
+ * Retrieve the information for the volume
+ */
+
+ if (!UV_ListOneVolume(f_server->serv, partition, volumeId, &pinfo_,&tst)) {
+ goto fail_vos_VolumeGet2;
+ }
+
+
+ rc = 1;
+
+ fail_vos_VolumeGet2:
+
+ if (pinfo_ != NULL) {
+ memcpy(pinfo,pinfo_,sizeof(volintInfo));
+ free(pinfo_);
+ }
+
+ if (st != NULL) {
+ *st = tst;
+ }
+ return rc;
+}
+
+/*
+ * vos_ClearVolUpdateCounter - reset volUpdateCounter of a volume to zero
+ *
+ * PARAMETERS
+ *
+ * IN cellHandle - a previously opened cellHandle that corresponds
+ * to the cell where the volume exists.
+ *
+ * IN serverHandle - a previously opened serverHandle that corresponds
+ * to the server where the volume exists.
+ *
+ * IN partition - the partition where the volume exists.
+ *
+ * IN volumeId - the volume id of the volume to be retrieved.
+ *
+ * LOCKS
+ *
+ * No locks are obtained or released by this function
+ *
+ * RETURN CODES
+ *
+ * Returns != 0 upon successful completion.
+ */
+
+int ADMINAPI
+vos_ClearVolUpdateCounter(const void *cellHandle,
+ const void *serverHandle,
+ unsigned int partition,
+ unsigned int volumeId,
+ afs_status_p st)
+{
+ int rc = 0;
+ afs_status_t tst = 0;
+ afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
+ file_server_p f_server = (file_server_p) serverHandle;
+ int ttid = 0;
+ int rcode = 0;
+ struct volintInfo tstatus;
+ int active_trans = 0;
+
+ /*
+ * Verify that the cellHandle is capable of making vos rpc's
+ */
+
+ if (!IsValidCellHandle(c_handle, &tst)) {
+ goto fail_vos_ClearVolUpdateCounter;
+ }
+
+ if (!IsValidServerHandle(f_server, &tst)) {
+ goto fail_vos_ClearVolUpdateCounter;
+ }
+
+ memset((void *)&tstatus, 0, sizeof(tstatus));
+ tstatus.maxquota = -1;
+ tstatus.dayUse = -1;
+ tstatus.creationDate = -1;
+ tstatus.updateDate = -1;
+ tstatus.flags = -1;
+ tstatus.spare0 = -1;
+ tstatus.spare1 = -1;
+ tstatus.spare2 = 0;
+ tstatus.spare3 = -1;
+
+ tst =
+ AFSVolTransCreate(f_server->serv, volumeId, partition, ITBusy, &ttid);
+ if (tst) {
+ goto fail_vos_ClearVolUpdateCounter;
+ }
+ active_trans = 1;
+
+ tst = AFSVolSetInfo(f_server->serv, ttid, &tstatus);
+ if (tst) {
+ goto fail_vos_ClearVolUpdateCounter;
+ }
+ rc = 1;
+
+ fail_vos_ClearVolUpdateCounter:
+
+ if (active_trans) {
+ afs_status_t tst2 = 0;
+ tst2 = AFSVolEndTrans(f_server->serv, ttid, &rcode);
+ if (tst2) {
+ if (tst == 0) {
+ tst = tst2;
+ rc = 0;
+ }
+ }
+ if (rcode) {
+ if (tst == 0) {
+ tst = rcode;
+ rc = 0;
+ }
+ }
+ }
+
+ if (st != NULL) {
+ *st = tst;
+ }
+ return rc;
+}
+
#include <afs/param.h>
#include <afs/afs_Admin.h>
#include <sys/types.h>
+#include <afs/volint.h>
#ifdef AFS_NT40_ENV
#ifndef _MFC_VER
#include <winsock2.h>
unsigned int volumeQuota,
afs_status_p st);
+extern int ADMINAPI vos_VolumeGet2(const void *cellHandle,
+ const void *serverHandle,
+ vos_MessageCallBack_t callBack,
+ unsigned int partition,
+ unsigned int volumeId,
+ volintInfo* pinfo, afs_status_p st);
+
+extern int ADMINAPI vos_ClearVolUpdateCounter(const void *cellHandle,
+ const void *serverHandle,
+ unsigned int partition,
+ unsigned int volumeId,
+ afs_status_p st);
+
#endif /* OPENAFS_VOS_ADMIN_H */
vos_PartitionIdToName @43
vos_VolumeQuotaChange @44
vos_VLDBUnlock @45
-
+ vos_VolumeGet2 @46
+ vos_ClearVolUpdateCounter @47
} /*UV_XListOneVolume */
+/*------------------------------------------------------------------------
+ * EXPORTED UV_ListOneVolume
+ *
+ * Description:
+ * List the volume information for a volume on a particular File
+ * Server and partition.
+ *
+ * Arguments:
+ * server : a handle to the server where the volume resides.
+ * a_partID : Partition for which we want the extended
+ * volume info.
+ * a_volID : Volume ID for which we want the info.
+ * a_resultPP : Ptr to the address of the area containing
+ * the returned volume info.
+ *
+ * Returns:
+ * 0 on success,
+ * Otherise, the return value of AFSVolXListOneVolume.
+ *
+ * Side Effects:
+ * As advertised.
+ *------------------------------------------------------------------------*/
+
+int UV_ListOneVolume(struct rx_connection *server, afs_int32 a_partID,
+ afs_int32 a_volID, struct volintInfo **a_resultPP,
+ afs_status_p st)
+{
+ int rc = 0;
+ afs_status_t tst = 0;
+ volEntries volumeInfo; /*Area for returned info */
+
+ /*
+ * Set the area we're in which we are returning
+ * the info. Setting the val field to a null pointer tells the stub
+ * to allocate space for us.
+ */
+ *a_resultPP = (volintInfo *) 0;
+ volumeInfo.volEntries_val = (volintInfo *) 0;
+ volumeInfo.volEntries_len = 0;
+
+ tst = AFSVolListOneVolume(server, a_partID, a_volID, &volumeInfo);
+
+ if (tst) {
+ goto fail_UV_ListOneVolume;
+ } else {
+ /*
+ * We got the info; pull out the pointer to where the results lie.
+ */
+ *a_resultPP = volumeInfo.volEntries_val;
+ }
+ rc = 1;
+
+ fail_UV_ListOneVolume:
+
+ if (st != NULL) {
+ *st = tst;
+ }
+ return rc;
+}/*UV_ListOneVolume*/
+
/*sync vldb with all the entries on <myQueue> on <aserver> and <apart>*/
static afs_int32
ProcessEntries(afs_cell_handle_p cellHandle, struct qHead *myQueue,
struct volintXInfo **a_resultPP,
afs_status_p st);
+extern int UV_ListOneVolume(struct rx_connection *server, afs_int32 a_partID,
+ afs_int32 a_volID, struct volintInfo **a_resultPP,
+ afs_status_p st);
+
extern int UV_SyncVldb(afs_cell_handle_p cellHandle,
struct rx_connection *server, afs_int32 apart,
int flags, int force, afs_status_p st);
*/
#include <afsconfig.h>
#include <afs/param.h>
+#define MAXINT (~(1<<((sizeof(int)*8)-1)))
RCSID
("$Header$");
vnp->disk.serverModifyTime = now;
}
if (vnp->changed_newTime)
+ {
V_updateDate(vp) = vp->updateTime = now;
+ if(V_volUpCounter(vp)<MAXINT)
+ V_volUpCounter(vp)++;
+ }
/* The vnode has been changed. Write it out to disk */
if (!V_inUse(vp)) {
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("volUpdateCounter = %u\n", V_volUpCounter(vp));
}
/* GetFileInfo
* of measurement; week[6] is 7 days ago */
Date dayUseDate; /* Date the dayUse statistics refer to; the week use stats
* are the preceding 7 days */
- int reserved3[11]; /* Other stats here */
+ unsigned int volUpdateCounter; /*incremented at every update of volume*/
+ int reserved3[10]; /* Other stats here */
/* Server supplied dates */
Date creationDate; /* Creation date for a read/write
#define V_stat_dirSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
#define V_stat_dirDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
#endif /* OPENAFS_VOL_STATS */
+#define V_volUpCounter(vp) ((vp)->header->diskstuff.volUpdateCounter)
/* File offset computations. The offset values in the volume header are
computed with these macros -- when the file is written only!! */
if (!ReadInt32(iodp, (afs_uint32 *) & vol->dayUse))
return VOLSERREAD_DUMPERROR;
break;
+ case 'V':
+ if (!ReadInt32(iodp, (afs_uint32 *) & vol->volUpdateCounter))
+ return VOLSERREAD_DUMPERROR;
+ break;
}
}
iod_ungetc(iodp, tag);
code = DumpInt32(iodp, 'D', V_dayUseDate(vp));
if (!code)
code = DumpInt32(iodp, 'Z', V_dayUse(vp));
+ if (!code)
+ code = DumpInt32(iodp, 'V', V_volUpCounter(vp));
return code;
}
/* if (!code) code = DumpInt32(iodp, 'Z', V_dayUse(vp)); */
FillInt64(addvar,0, 5);
AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
+/* if (!code) code = DumpInt32(iodp, 'V', V_volUpCounter(vp)); */
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
return code;
}
int inService;
int blessed;
char message[1024];
+ afs_int32 volUpdateCounter;
};
afs_int32
case 'Z':
vh.dayUse = ntohl(readvalue(4));
break;
+ case 'V':
+ vh.volUpdateCounter = ntohl(readvalue(4));
+ break;
default:
done = 1;
code = DumpInt32(dumpfd, 'D', V_dayUseDate(vp));
if (!code)
code = DumpInt32(dumpfd, 'Z', V_dayUse(vp));
+ if (!code)
+ code = DumpInt32(dumpfd, 'V', V_volUpCounter(vp));
return code;
}
afs_int32 flags; /* used by the backup system */
afs_int32 spare0; /* Used to hold the minquota value */
afs_int32 spare1; /* Used to hold the weekuse value */
- afs_int32 spare2;
+ afs_int32 spare2; /* Used to hold volUpdateCounter */
afs_int32 spare3;
};
td->creationDate = astatus->creationDate;
if (astatus->updateDate != -1)
td->updateDate = astatus->updateDate;
+ if (astatus->spare2 != -1)
+ td->volUpdateCounter = (unsigned int)astatus->spare2;
VUpdateVolume(&error, tv);
tt->rxCallPtr = (struct rx_call *)0;
if (TRELE(tt))
(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->spare2 = V_volUpCounter(tv);
+ pntr->flags = pntr->spare3 = (long)0;
VDetachVolume(&error, tv); /*free the volume */
tv = (Volume *) 0;
if (error) {
(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->spare2 = V_volUpCounter(tv);
+ pntr->flags = pntr->spare3 = (long)0;
VDetachVolume(&error, tv); /*free the volume */
tv = (Volume *) 0;
if (error) {
/* -clearuse */
info.dayUse = 0;
}
+ if (as->parms[3].items) {
+ /* -clearVolUpCounter */
+ info.spare2 = 0;
+ }
code = UV_SetVolumeInfo(aserver, apart, volid, &info);
if (code)
fprintf(STDERR,
cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
+ cmd_AddParm(ts, "-clearVolUpCounter", CMD_FLAG, CMD_OPTIONAL, "clear volUpdateCounter");
COMMONPARMS;
ts = cmd_CreateSyntax("offline", volOffline, 0, (char *)CMD_HIDDEN);