16 #include "../daemon/XmemDaemon.h"
18 static XmemNodeId all_nodes
= 0;
19 static XmemTableId all_tables
= 0;
21 static XmemTableId ctid
= XmemTableId_01
;
23 static int timeout
= 1000; /* 10 Seconds */
25 static char *ENames
[XmemEventMASKS
] = {
36 static char *IOENames
[XmemIoERRORS
] = {
43 static char *InitMess
[XmemInitMessageMESSAGES
] = {
48 static char *MSNames
[XmemMessageTypeCOUNT
] = {
55 static XdEventLogEntries
*event_log
= NULL
;
57 /* ========================================================= */
58 /* Callback routins to handle events */
60 void callback(XmemCallbackStruct
*cbs
) {
62 unsigned long msk
, emsk
, data
;
66 for (i
=0; i
<XmemEventMASKS
; i
++) {
68 if (cbs
->Mask
& msk
) {
70 if ((msk
& XmemEventMaskSOFTWARE
) && (cbs
->Data
== XmemErrorSUCCESS
)) {
71 printf("Information: ");
73 printf("%s: ",ENames
[i
]);
75 switch ((XmemEventMask
) msk
) {
77 case XmemEventMaskTIMEOUT
:
81 case XmemEventMaskSEND_TABLE
:
83 XmemGetTableName(cbs
->Table
),
84 XmemGetNodeName(cbs
->Node
));
87 case XmemEventMaskUSER
:
88 printf("0x%X (%d) From:%s\n",
91 XmemGetNodeName(cbs
->Node
));
94 case XmemEventMaskTABLE_UPDATE
:
96 XmemGetTableName(cbs
->Table
),
97 XmemGetNodeName(cbs
->Node
));
100 case XmemEventMaskINITIALIZED
:
101 printf("%s Message:0x%X (%d/",
102 XmemGetNodeName(cbs
->Node
),
105 if (data
< XmemInitMessageMESSAGES
)
106 printf("%s)\n",InitMess
[data
]);
108 printf("%s)\n",InitMess
[XmemInitMessageUSER_DEFINED
]);
111 case XmemEventMaskIO
:
113 for (j
=0; j
<XmemIoERRORS
; j
++) {
115 if (emsk
& data
) printf("%s ",IOENames
[j
]);
120 case XmemEventMaskKILL
:
124 case XmemEventMaskSYSTEM
:
126 strerror((int) data
),
130 case XmemEventMaskSOFTWARE
:
131 if (data
!= XmemErrorSUCCESS
) {
133 XmemErrorToString((XmemError
) data
));
141 /* ========================================================= */
142 /* Convert time to a standard string routine. */
143 /* Result is a pointer to a static string. */
144 /* the format is: Thu-18/Jan/2001 08:25:14 */
145 /* day-dd/mon/yyyy hh:mm:ss */
147 char *TimeToStr(time_t tod
) {
149 static char tbuf
[128];
152 char *yr
, *ti
, *md
, *mn
, *dy
;
154 bzero((void *) tbuf
, 128);
155 bzero((void *) tmp
, 128);
159 tmp
[ 3] = 0; dy
= &(tmp
[0]);
160 tmp
[ 7] = 0; mn
= &(tmp
[4]);
161 tmp
[10] = 0; md
= &(tmp
[8]); if (md
[0] == ' ') md
[0] = '0';
162 tmp
[19] = 0; ti
= &(tmp
[11]);
163 tmp
[24] = 0; yr
= &(tmp
[20]);
164 sprintf (tbuf
, "%s-%s/%s/%s %s" , dy
, md
, mn
, yr
, ti
);
166 } else sprintf (tbuf
, "--- Zero ---");
170 /* ========================================================= */
171 /* Get the event log table in shared memory */
173 XdEventLogEntries
*GetEventLogTable() {
178 static XdEventLogEntries
*result
= NULL
;
180 if (result
) return result
;
182 smemky
= XmemGetKey(EVENT_LOG_NAME
);
183 smemid
= shmget(smemky
,sizeof(XdEventLogEntries
),0666);
185 if (errno
== ENOENT
) {
186 smemid
= shmget(smemky
,sizeof(XdEventLogEntries
),IPC_CREAT
| 0666);
188 result
= (XdEventLogEntries
*) shmat(smemid
,(char *) 0,0);
189 if ((int) result
!= -1) {
190 bzero((void *) result
, sizeof(XdEventLogEntries
));
196 result
= (XdEventLogEntries
*) shmat(smemid
,(char *) 0,0);
197 if ((int) result
!= -1) return result
;
199 XmemErrorCallback(XmemErrorSYSTEM
,errno
);
203 /* ========================================================= */
204 /* Print out a callback structure */
206 char *CallbackToStr(XmemCallbackStruct
*cbs
) {
208 static char str
[128];
211 bzero((void *) str
, 128);
213 case XmemEventMaskTIMEOUT
:
214 sprintf(str
,"Timeout");
217 case XmemEventMaskUSER
:
218 sprintf(str
,"User event:%d From node:%s",(int) cbs
->Data
,XmemGetNodeName(cbs
->Node
));
221 case XmemEventMaskSEND_TABLE
:
222 sprintf(str
,"Send table:%s From node:%s",XmemGetTableName(cbs
->Table
),XmemGetNodeName(cbs
->Node
));
225 case XmemEventMaskTABLE_UPDATE
:
226 sprintf(str
,"Update table:%s From node:%s",XmemGetTableName(cbs
->Table
),XmemGetNodeName(cbs
->Node
));
229 case XmemEventMaskINITIALIZED
:
230 sprintf(str
,"Initialized:%d From node:%s",(int) cbs
->Data
,XmemGetNodeName(cbs
->Node
));
233 case XmemEventMaskKILL
:
234 sprintf(str
,"Kill daemon received");
237 case XmemEventMaskIO
:
238 sprintf(str
,"IO error:%s",XmemErrorToString(cbs
->Data
));
241 case XmemEventMaskSYSTEM
:
242 sprintf(str
,"System error:%d",(int) cbs
->Data
);
245 case XmemEventMaskSOFTWARE
:
246 if (cbs
->Data
== XmemErrorSUCCESS
) {
247 sprintf(str
,"Information:");
249 sprintf(str
,"Software error:%s",XmemErrorToString(cbs
->Data
));
260 /* ========================================================= */
261 /* Register callback, arg is the event mask */
263 int RegisterCallback(int arg
) {
274 if (at
== Operator
) {
275 if (v
->OId
== OprNOOP
) {
280 printf("Possible events are:\n");
282 for (i
=0; i
<XmemEventMASKS
; i
++) {
284 printf("Event:0x%03X: %s\n",(int) msk
, ENames
[i
]);
293 emsk
= (XmemEventMask
) v
->Number
;
295 emsk
= XmemGetRegisteredEvents();
297 for (i
=0; i
<XmemEventMASKS
; i
++) {
300 printf("Registered:0x%03X: %s\n",(int) msk
, ENames
[i
]);
302 } else printf("Registered: No events\n");
306 err
= XmemRegisterCallback(callback
,emsk
);
307 if (err
!= XmemErrorSUCCESS
)
308 printf("XmemRegisterCallback: Error:%s\n",XmemErrorToString(err
));
310 if (emsk
) printf("XmemRegisterCallback: Registered:0x%X OK\n",(int) emsk
);
311 else printf("XmemRegisterCallback: Unregistered all OK\n");
315 /* ========================================================= */
316 /* Call XmemGetAllNodeIds and print list */
318 int GetAllNodeIds(int arg
) {
321 unsigned long msk
, nid
;
323 all_nodes
= XmemGetAllNodeIds();
324 printf("NodeIdMask:0x%02X\n",(int) all_nodes
);
325 for (i
=0; i
<XmemMAX_NODES
; i
++) {
327 if (all_nodes
& msk
) printf("NodeId:0x%02X: NodeName:%s\n",
329 XmemGetNodeName((XmemNodeId
) msk
));
335 printf("This node has Id: 0x%02X NodeName:%s\n",
337 XmemGetNodeName((XmemNodeId
) nid
));
339 i
= XmemCheckForWarmStart();
340 if (i
) printf("This is a WARM start\n");
341 else printf("This is a COLD start\n");
345 /* ========================================================= */
346 /* Get the name od a node from its Id */
348 int GetNodeName(int arg
) {
351 unsigned long nid
, msk
;
362 } else nid
= XmemGetAllNodeIds();
364 for (i
=0; i
<XmemMAX_NODES
; i
++) {
367 printf("NodeId:0x%02X NodeName:%s\n",(int) msk
, XmemGetNodeName((XmemNodeId
) msk
));
372 /* ========================================================= */
373 /* Get the ID of a node from its name */
375 int GetNodeId(int arg
) {
384 printf("%s has ID:0x%X\n",
386 XmemGetNodeId(v
->Text
));
387 } else printf("No node name supplied\n");
391 /* ========================================================= */
392 /* Get the complete list of all defined tables */
394 int GetAllTableIds(int arg
) {
398 all_tables
= XmemGetAllTableIds();
399 printf("TableIds:0x%08X\n",(int) all_tables
);
400 for (i
=0; i
<XmemMAX_TABLES
; i
++) {
402 if (msk
& all_tables
)
403 printf("TableId:0x%08X: TableName:%s\n",
405 XmemGetTableName((XmemTableId
) msk
));
410 /* ========================================================= */
411 /* Get the name of a table from its ID */
413 int GetTableName(int arg
) {
416 unsigned long tid
, msk
;
427 } else tid
= XmemGetAllTableIds();
429 for (i
=0; i
<XmemMAX_TABLES
; i
++) {
432 printf("TableId:0x%08X TableName:%s\n",(int) msk
, XmemGetTableName((XmemTableId
) msk
));
437 /* ========================================================= */
438 /* Get the ID of a table from its name */
440 int GetTableId(int arg
) {
449 printf("%s has ID:0x%X\n",
451 XmemGetTableId(v
->Text
));
452 } else printf("No table name supplied\n");
456 /* ========================================================= */
457 /* Get the description of a table from its ID */
459 int GetTableDesc(int arg
) {
462 unsigned long tid
, nid
, msk
, user
, longs
;
473 } else tid
= XmemGetAllTableIds();
475 for (i
=0; i
<XmemMAX_TABLES
; i
++) {
478 XmemGetTableDesc(msk
,(unsigned long *) &longs
,(XmemNodeId
*) &nid
, &user
);
479 printf("0x%08X:%s L:0x%04X[%03d] B:0x%06X[%03d] N:0x%02X U:0x%X\n",
481 XmemGetTableName((XmemTableId
) msk
),
484 (int) longs
*sizeof(long),
485 (int) longs
*sizeof(long),
493 /* ========================================================= */
494 /* Wait for an event. Arg contains optional timeout */
509 printf("Wait:EventMask:0x%X\n",XmemWait(timeout
));
513 /* ========================================================= */
514 /* Non blocking event poll */
519 if (XmemPoll() == 0) printf("Poll:No events on queue\n");
523 /* ========================================================= */
524 /* Send table from shared memory */
526 int SendTable(int arg
) {
529 unsigned long tid
, nid
, user
, longs
;
544 table
= XmemGetSharedMemory(tid
);
547 err
= XmemGetTableDesc(tid
,&longs
,(XmemNodeId
*) &nid
, &user
);
548 if (err
!= XmemErrorSUCCESS
) return arg
;
549 err
= XmemSendTable(tid
,table
,longs
,0,1);
550 if (err
== XmemErrorSUCCESS
) printf("Sent:%s from shmem OK\n",
551 XmemGetTableName(tid
));
552 else printf("Error:Table NOT sent:%s\n",
553 XmemErrorToString(err
));
556 printf("Can't get shared memory segment\n");
560 /* ========================================================= */
561 /* Recieve table and update shared memory */
563 int RecvTable(int arg
) {
566 unsigned long tid
, nid
, user
, longs
;
581 table
= XmemGetSharedMemory(tid
);
584 err
= XmemGetTableDesc(tid
,&longs
,(XmemNodeId
*) &nid
, &user
);
585 if (err
!= XmemErrorSUCCESS
) return arg
;
586 err
= XmemRecvTable(tid
,table
,longs
,0);
587 if (err
== XmemErrorSUCCESS
) printf("Received:%s in shmem OK\n",
588 XmemGetTableName(tid
));
589 else printf("Error:Table NOT received:%s\n",
590 XmemErrorToString(err
));
593 printf("Error:Can't get shared memory segment\n");
597 /* ========================================================= */
600 int SendMessage(int arg
) {
604 unsigned long dta
, nid
;
605 XmemMessageType mtyp
;
613 if (at
== Operator
) {
614 if (v
->OId
== OprNOOP
) {
617 for (i
=0; i
<XmemMessageTypeCOUNT
; i
++) {
618 printf("%d:%s\t",i
,MSNames
[i
]);
619 switch ((XmemMessageType
) i
) {
620 case XmemMessageTypeTABLE_UPDATE
:
621 case XmemMessageTypeSEND_TABLE
:
622 printf("<NdIdMask><TbIdMask>");
625 case XmemMessageTypeUSER
:
626 printf("<NdIdMask><Data>");
629 case XmemMessageTypeINITIALIZE_ME
:
630 printf("<NdIdMask><Sub:");
631 for (j
=0; j
<XmemInitMessageMESSAGES
; j
++) {
632 printf("%d:%s ",j
,InitMess
[j
]);
634 printf("[Or greater]>");
637 case XmemMessageTypeKILL
:
638 printf("<NdIdMask>");
654 if (mtyp
>= XmemMessageTypeCOUNT
) {
655 printf("Illegal message type: %d Range is [0..%d]\n",
657 (int) XmemMessageTypeCOUNT
-1);
661 printf("Error:No message specified\n");
669 if (nid
== 0) nid
= XmemALL_NODES
;
682 mess
.MessageType
= mtyp
;
684 err
= XmemSendMessage(nid
,&mess
);
685 if (err
== XmemErrorSUCCESS
) printf("Message:%s %d %d sent OK\n",
689 else printf("Error:Message NOT sent:%s\n",
690 XmemErrorToString(err
));
694 /* ========================================================= */
695 /* Check for table updates */
697 int CheckTables(int arg
) {
703 tid
= XmemCheckTables();
705 printf("Updated: TableIdMask:0x%08X\n",(int) tid
);
706 for (i
=0; i
<XmemMAX_TABLES
; i
++) {
709 printf("Updated: TableId:0x%08X TableName:%s\n",
711 XmemGetTableName((XmemTableId
) msk
));
715 printf("Updated: 0 => No table updates since last call\n");
719 /* ========================================================= */
720 /* Save a table to disc */
722 int SaveTable(int arg
) {
726 XmemNodeId nodes
, nid
;
728 unsigned long user
, longs
;
740 err
= XmemGetTableDesc(tid
,&longs
,&nodes
,&user
);
741 if (err
!= XmemErrorSUCCESS
) {
742 printf("Error:Can't get Id:0x%08x table description:%s\n",
744 XmemErrorToString(err
));
750 err
= XmemWriteTableFile(tid
);
751 if (err
!= XmemErrorSUCCESS
) printf("Error:Can't write table to disc:%s\n",
752 XmemErrorToString(err
));
753 else printf("Saved:%s to disc: OK\n",
754 XmemGetTableName(tid
));
755 } else printf("Error:No write-access: File belongs to another node\n");
759 /* ========================================================= */
760 /* Load a table from disc */
762 int LoadTable(int arg
) {
766 XmemNodeId nodes
, nid
;
768 unsigned long user
, longs
;
779 err
= XmemGetTableDesc(tid
,&longs
,&nodes
,&user
);
780 if (err
!= XmemErrorSUCCESS
) {
781 printf("Error:Can't get Id:0x%08x table description:%s\n",
783 XmemErrorToString(err
));
789 err
= XmemReadTableFile(tid
);
790 if (err
!= XmemErrorSUCCESS
) printf("Error:Can't read table from disc:%s\n",
791 XmemErrorToString(err
));
792 else printf("Loaded:%s from disc: OK\n",
793 XmemGetTableName(tid
));
794 } else printf("Error:This node should receive the table from memory, not disc\n");
798 /*****************************************************************/
800 void EditMemory(char *name
, unsigned long *table
, unsigned long longs
, int flag
) {
802 unsigned long addr
, data
, nadr
;
803 char c
, *cp
, str
[128];
806 printf("EditMemory: ?:Comment /:Open CR:Next .:Exit x:Hex d:Dec s:String\n\n");
817 if (c
=='\n') printf("Addr:0x%04x: 0x%04x ",(int) addr
,(int) table
[addr
]);
819 if (c
=='\n') printf("Addr:%04d: %5d ",(int) addr
,(int) table
[addr
]);
822 c
= (char) getchar();
825 bzero((void *) str
, 128); n
= 0;
826 while ((c
!= '\n') && (n
< 128)) c
= str
[n
++] = (char) getchar();
827 nadr
= strtoul(str
,&cp
,radix
);
828 if (cp
!= str
) addr
= nadr
;
831 else if (c
== 'x') { radix
= 16; addr
--; continue; }
832 else if (c
== 'd') { radix
= 10; addr
--; continue; }
833 else if (c
== '.') { c
= getchar(); printf("\n"); break; }
834 else if (c
== 'q') { c
= getchar(); printf("\n"); break; }
836 cnt
= 0; cp
= (char *) &(table
[addr
]);
837 while ((c
= (char) getchar()) != '\n') {
840 if (cnt
++ > 32) break;
843 cnt
= 0; cp
= (char *) &(table
[addr
]);
844 while (isascii((int) *cp
)) {
846 if ((*cp
== '\0') || (*cp
== '\n') || (cnt
++ > 32)) break;
851 } else if (c
== '\n') {
859 bzero((void *) str
, 128); n
= 0;
861 while ((c
!= '\n') && (n
< 128)) c
= str
[n
++] = (char) getchar();
862 data
= strtoul(str
,&cp
,radix
);
864 if (flag
) table
[addr
] = data
;
871 /* ========================================================= */
872 /* Edit shared memory */
874 int EditSharedMemory(int arg
) {
878 XmemNodeId nodes
, nid
;
880 unsigned long user
, longs
;
882 unsigned long *table
;
894 table
= XmemGetSharedMemory(tid
);
897 err
= XmemGetTableDesc(tid
,&longs
,&nodes
,&user
);
898 if (err
!= XmemErrorSUCCESS
) {
899 printf("Error:Can't get Id:0x%08x table description:%s\n",
901 XmemErrorToString(err
));
905 name
= XmemGetTableName(tid
);
907 printf("Editing: %s in RW mode: FULL-ACCESS\n",name
);
908 EditMemory(name
,table
,longs
,1);
910 printf("Editing: %s in RO mode: No WRITE-ACCESS\n",name
);
911 EditMemory(name
,table
,longs
,0);
917 /* ========================================================= */
918 /* Show what in the shared memory segment */
920 int ShowDaemonEventLog(int arg
) {
922 XdEventLogEntry
*evp
;
926 event_log
= GetEventLogTable();
928 if (event_log
->NextEntry
) {
929 for (i
=0; i
<event_log
->NextEntry
; i
++) {
930 evp
= &(event_log
->Entries
[i
]);
931 printf("%02d: %s ",i
,TimeToStr(evp
->Time
));
932 printf("%s: ",CallbackToStr(&(evp
->CbEvent
)));
933 if (evp
->Text
) printf("%s",(char *) &(evp
->Text
[0]));
936 } else printf("Empty: No logged events in memory\n");
941 /* ========================================================= */
942 /* Print out the file for a node */
944 int ShowDaemonEventHistory(int arg
) {
948 XdEventLogEntries elog
;
949 XdEventLogEntry
*evp
;
964 elg
= XmemGetFile(EVENT_LOG
);
967 bzero((void *) &elog
, sizeof(XdEventLogEntries
));
968 cnt
= fread(&elog
, sizeof(XdEventLogEntries
), 1, fp
);
970 perror("ShowDaemonEventHistory");
971 fprintf(stderr
,"ShowDaemonEventHistory: Error: Can't READ:%s\n",elg
);
976 perror("ShowDaemonEventHistory");
977 fprintf(stderr
,"ShowDaemonEventHistory: Error: Can't OPEN:%s for READ\n",elg
);
982 printf("Showing file:%s\n",elg
);
983 for (i
=0; i
<elog
.NextEntry
; i
++) {
984 evp
= &(elog
.Entries
[i
]);
985 printf("%02d: %s ",i
,TimeToStr(evp
->Time
));
986 printf("%s: ",CallbackToStr(&(evp
->CbEvent
)));
987 if (evp
->Text
) printf("%s",(char *) &(evp
->Text
[0]));
993 /* ========================================================= */
994 /* Wipe errors out */
996 int ClearDaemonEventLog(int arg
) {
1000 event_log
= GetEventLogTable();
1002 bzero((void *) event_log
, sizeof(XdEventLogEntries
));
1003 printf("ClearDaemonEventLog: Done OK\n");
1009 /* ========================================================= */
1011 int KillDaemon(int arg
) {
1023 if (at
== Numeric
) {
1026 if (nid
== 0) nid
= XmemALL_NODES
;
1028 mes
.MessageType
= XmemMessageTypeKILL
;
1029 mes
.Data
= XmemWhoAmI();
1030 err
= XmemSendMessage(nid
,&mes
);
1031 if (err
== XmemErrorSUCCESS
) printf("Sent KILL to nodes: 0x%02X\n",(int) nid
);
1032 else printf("KillDaemon: Error: %s\n",XmemErrorToString(err
));
1036 /* ========================================================= */
1045 mes
.MessageType
= XmemMessageTypeINITIALIZE_ME
;
1046 mes
.Data
= XmemInitMessageRESET
;
1047 err
= XmemSendMessage(XmemALL_NODES
,&mes
);
1048 if (err
== XmemErrorSUCCESS
) printf("Sent Initialize to all nodes");
1049 else printf("Init: Error: %s\n",XmemErrorToString(err
));