#endif /* DJGPP */
if (serversp == NULL) {
- osi_Log1(afsd_logp, "cm_ConnByMServers returning 0x%x", CM_ERROR_NOSUCHVOLUME);
- return CM_ERROR_NOSUCHVOLUME;
+ osi_Log1(afsd_logp, "cm_ConnByMServers returning 0x%x", CM_ERROR_ALLDOWN);
+ return CM_ERROR_ALLDOWN;
}
*connpp = NULL;
return 0;
}
+
+
+static long
+cm_CheckServersStatus(cm_serverRef_t *serversp)
+{
+ long code = 0;
+ cm_serverRef_t *tsrp;
+ cm_server_t *tsp;
+ int someBusy = 0, someOffline = 0, allOffline = 1, allBusy = 1, allDown = 1;
+
+ if (serversp == NULL) {
+ osi_Log1(afsd_logp, "cm_CheckServersStatus returning 0x%x", CM_ERROR_ALLDOWN);
+ return CM_ERROR_ALLDOWN;
+ }
+
+ lock_ObtainRead(&cm_serverLock);
+ for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
+ if (tsp = tsrp->server) {
+ cm_GetServerNoLock(tsp);
+ lock_ReleaseRead(&cm_serverLock);
+ if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
+ allDown = 0;
+ if (tsrp->status == busy) {
+ allOffline = 0;
+ someBusy = 1;
+ } else if (tsrp->status == offline) {
+ allBusy = 0;
+ someOffline = 1;
+ } else {
+ allOffline = 0;
+ allBusy = 0;
+ cm_PutServer(tsp);
+ goto done;
+ }
+ }
+ lock_ObtainRead(&cm_serverLock);
+ cm_PutServerNoLock(tsp);
+ }
+ }
+ lock_ReleaseRead(&cm_serverLock);
+
+ if (allDown)
+ code = CM_ERROR_ALLDOWN;
+ else if (allBusy)
+ code = CM_ERROR_ALLBUSY;
+ else if (allOffline || (someBusy && someOffline))
+ code = CM_ERROR_ALLOFFLINE;
+
+ done:
+ osi_Log1(afsd_logp, "cm_CheckServersStatus returning 0x%x", code);
+ return code;
+}
+
+
+long cm_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ long code;
+ cm_scache_t *scp;
+ cm_cell_t *cellp;
+ cm_volume_t *tvp;
+ cm_serverRef_t **tsrpp;
+ unsigned long volume;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
+ if (code)
+ return code;
+
+ volume = scp->fid.volume;
+
+ cellp = cm_FindCellByID(scp->fid.cell);
+
+ cm_ReleaseSCache(scp);
+
+ if (!cellp)
+ return CM_ERROR_NOSUCHCELL;
+
+ code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp);
+ if (code)
+ return code;
+
+ lock_ObtainMutex(&tvp->mx);
+ tsrpp = cm_GetVolServers(tvp, volume);
+ code = cm_CheckServersStatus(*tsrpp);
+ cm_FreeServerList(tsrpp);
+ lock_ReleaseMutex(&tvp->mx);
+ cm_PutVolume(tvp);
+ return 0;
+}
+
+
extern long cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp);
+extern long cm_IoctlPathAvailability(struct smb_ioctl * ioctlp, struct cm_user *userp);
+
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */
static int
PrintStatus(VolumeStatus *status, char *name, char *motd, char *offmsg)
{
- printf("Volume status for vid = %u named %s\n",status->Vid, name);
+ printf("Volume status for vid = %u named %s is\n",status->Vid, name);
if (*offmsg != 0)
printf("Current offline message is %s\n",offmsg);
if (*motd != 0)
else
printf("unlimited\n");
printf("Current blocks used are %d\n",status->BlocksInUse);
- printf("The partition has %d blocks available out of %d\n\n",
+ printf("The partition has %d blocks available out of %d\n",
status->PartBlocksAvail, status->PartMaxBlocks);
return 0;
}
struct cmd_item *ti;
struct VolumeStatus *status;
char *name, *offmsg, *motd;
+ long online_state;
int error = 0;
SetDotDefault(&as->parms[0].items);
pr_SIdToName(owner[0], oname);
printf("Owner %s (%u) Group %u\n", oname, owner[0], owner[1]);
}
-
+
blob.out = space;
blob.out_size = MAXSIZE;
code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
- if (code) {
- Die(errno, ti->data);
- error = 1;
- continue;
- }
- status = (VolumeStatus *)space;
- name = (char *)status + sizeof(*status);
- offmsg = name + strlen(name) + 1;
- motd = offmsg + strlen(offmsg) + 1;
+ if (code == 0) {
+ status = (VolumeStatus *)space;
+ name = (char *)status + sizeof(*status);
+ offmsg = name + strlen(name) + 1;
+ motd = offmsg + strlen(offmsg) + 1;
- PrintStatus(status, name, motd, offmsg);
+ PrintStatus(status, name, motd, offmsg);
+ } else {
+ Die(errno, ti->data);
+ }
+ online_state = pioctl(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
+ switch (online_state) {
+ case 0:
+ printf("Volume is online\n");
+ break;
+ case CM_ERROR_ALLOFFLINE:
+ printf("Volume offline\n");
+ break;
+ case CM_ERROR_ALLDOWN:
+ printf("All Volume servers are down\n");
+ break;
+ case CM_ERROR_ALLBUSY:
+ printf("All volume servers are busy\n");
+ break;
+ default:
+ Die(online_state, ti->data);
+ }
+ printf("\n");
}
return error;
}
#define VIOC_RXSTAT_PROC 0x2e
#define VIOC_RXSTAT_PEER 0x2f
#define VIOC_UUIDCTL 0x30
+#define VIOC_PATH_AVAILABILITY 0x31
#endif /* __SMB_IOCONS_H_ENV_ */
smb_ioctlProcsp[VIOC_RXSTAT_PROC] = cm_IoctlRxStatProcess;
smb_ioctlProcsp[VIOC_RXSTAT_PEER] = cm_IoctlRxStatPeer;
smb_ioctlProcsp[VIOC_UUIDCTL] = cm_IoctlUUIDControl;
+ smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability;
}
/* called to make a fid structure into an IOCTL fid structure */