adm.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:34k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * adm.c - Storage and Transaction Synchrohization Management 
  3.  *         System Administrator of GNU SQL server
  4.  *
  5.  * This file is a part of GNU SQL Server
  6.  *
  7.  * Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  * Developed at the Institute of System Programming 
  9.  * This file is written by Vera Ponomarenko
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify it under
  12.  * the terms of the GNU General Public License as published by the Free
  13.  * Software Foundation; either version 2 of the License, or (at your option)
  14.  * any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful, but WITHOUT
  17.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  19.  * more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License along with
  22.  * this program; if not, write to the Free Software Foundation, Inc.,
  23.  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  * Contacts: gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: adm.c,v 1.248 1997/04/19 17:10:54 kml Exp $ */
  29. #include <setup_os.h>
  30. #ifdef HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif
  33. #include <sys/types.h>
  34. #include <sys/times.h>
  35. #ifdef HAVE_SYS_IPC_H
  36. #include <sys/ipc.h>
  37. #endif
  38. #ifdef HAVE_SYS_MSG_H
  39. #include <sys/msg.h>
  40. #endif
  41. #if STDC_HEADERS
  42. #include <string.h>
  43. #endif
  44. /* for uname */
  45. #if HAVE_UNAME
  46. #include <sys/utsname.h>
  47. #endif
  48. #include <signal.h>
  49. #if HAVE_SYS_WAIT_H
  50. #include <sys/wait.h>
  51. #endif
  52. #if TIME_WITH_SYS_TIME
  53. # include <sys/time.h>
  54. # include <time.h>
  55. #else
  56. # if HAVE_SYS_TIME_H
  57. #  include <sys/time.h>
  58. # else
  59. #  include <time.h>
  60. # endif
  61. #endif
  62. #if HAVE_FCNTL_H 
  63. #include <fcntl.h>
  64. #endif
  65. #include "dispatch.h"
  66. #include "global.h"
  67. #include "rnmtp.h"
  68. #include "pupsi.h"
  69. #include "inpop.h"
  70. #include "expop.h"
  71. #include "adfstr.h"
  72. #include "rcvutl/puprcv.h"
  73. #include "totdecl.h"
  74. #define GDBINIT_FILE ".gdb"
  75. #define EXIT  finit(1)
  76. #define PRINT(x, y) /*printf(x,y);*/
  77. /* maximum of time for waiting exiting of all transactions */
  78. #define KILL_WAIT 10 
  79. #define nul     0xffff
  80. #define EOTLJ   0 /* end of transaction */
  81. #include "strml.h"
  82. struct msg_buf  sbuf;
  83. struct msg_buf  rbuf;
  84. struct des_trn *tabtr = NULL;
  85. #define TRN_SEND_NEED
  86. #include "admdef.h"
  87. #undef TRN_SEND_NEED
  88. #include "gspstr.h"
  89. extern i4_t errno, default_num;
  90. debug_pid_t volatile *debuggers_pids = NULL;
  91. i4_t sbuf_sz, rbuf_sz;
  92. pid_t adm_pid;          /* proc id of administrator                       */
  93. char nocrtr_fl = 0;     /* = 1 if dispatcher may not create a transaction */
  94. char finit_fl  = 0;     /* = 1 if after last transaction finish           */
  95.         /*     dispatcher ought to exit                   */
  96. char fix_lj_fl = 0;     /* = 1 if after last transaction finish           */
  97.         /*     dispatcher ought to fix log journal        */
  98. char *fix_path = NULL;  /* path to fix log journal                        */
  99. key_t keyadm, keylj, keymj, keybf, keymcr, keysn, keysr, *keytrn = NULL;
  100. i4_t   fdlj, fdaf, fdto;
  101. volatile pid_t pidlj = 0, pidmj = 0, pidbf = 0, pidsn = 0, pidsr = 0, pidmcr = 0;
  102. volatile i4_t finit_done = 0;
  103. volatile i4_t children   = 0;
  104. i4_t msgida = -1, msgidl = -1, msgidm = -1, msgidb = -1;
  105. i4_t msgidc = -1, msgids = -1, msgidq = -1;
  106. #define  adfsize sizeof(struct ADF)
  107. struct ADF p2;
  108. u2_t *ext_ids = NULL; /* extent numbers            */
  109. u2_t *trn_ids = NULL; /* transaction numbers       */
  110. i4_t    transaction_number;      /* active transaction number */
  111. i4_t    freext;
  112. i4_t    maxtrans, maxusetran, maxext, maxfrext;
  113. i4_t    sizext; /* extent-size in block      */
  114. u2_t  sizesc; /* scale-size in block       */
  115. i4_t   uidconst;
  116. i4_t   unname;
  117. i4_t   nunname;
  118. i4_t    rfile; /* file-size in blocks for temporary object
  119.    file */
  120. i4_t   uidt;
  121. i4_t   idt;
  122. i4_t   minid;
  123. i4_t    numtr;
  124. i4_t    rjzm, rjzl, mpagem, mpagel;
  125. i4_t   vnlj;
  126. extern void  sig_usr_hnd  __P((i4_t sig_num));
  127. extern i4_t   cp_lj_reg  __P((i4_t to_sz, char *to));
  128. extern void  finit  __P((i4_t err));
  129. static i4_t   ini  __P((void));
  130. static u2_t getext  __P((u2_t));
  131. void  kill_all (i4_t err);
  132. static void
  133. adm_exit(void)
  134. {
  135.   finit(0);
  136. }
  137. void
  138. main (i4_t argc,char *argv[])
  139. {
  140.   struct sigaction act;
  141.   sigset_t set;
  142.   printf ("n   GNU SQL server (version %s on %s)",VERSION,HOST);
  143.   printf ("n   Copyright (c) 1996, 1997 Free Software Foundation, Inc.nn");
  144.   
  145.   fix_adm_port(argv[1]); /* argv[1] is adm rpc program identifier */
  146.   
  147.   adm_pid = getpid();
  148.   
  149.   sigemptyset (&set);
  150.   sigaddset (&set, SIGUSR1);
  151.   sigaddset (&set, SIGCHLD);
  152.   
  153. #if HAVE_ATEXIT
  154.   atexit(adm_exit);
  155. #elif HAVE_ON_EXIT
  156.   on_exit(adm_exit);
  157. #endif
  158.   
  159. #if 0 /*SA_SIGINFO*/
  160.   act.sa_handler   = NULL;
  161.   act.sa_mask      = set;
  162.   act.sa_flags     = SA_SIGINFO;
  163.   act.sa_sigaction = sig_usr_hnd;
  164. #else
  165.   act.sa_handler   = sig_usr_hnd;
  166.   act.sa_mask      = set;
  167.   act.sa_flags     = 0;
  168. #endif
  169.   
  170.   if (sigaction (SIGUSR1, &act, NULL) ||
  171.       sigaction (SIGCHLD, &act, NULL) ||
  172.       sigaction (SIGALRM, &act, NULL)   )
  173.     EXIT;
  174.   
  175.   sbuf_sz = rbuf_sz = BD_PAGESIZE;
  176.   
  177.   setbuf (stdout, NULL);
  178.   
  179.   ini ();
  180.   printf ("n<<<<<  Server is ready >>>>>>n");
  181.   ADM_RPC_START; /* rpcgen generated main */
  182.   /* unreachable */
  183. } /* main */
  184. static u2_t 
  185. getext (u2_t num)
  186. {
  187.   register i4_t i, j;
  188.   char found = 0;
  189.   if (freext != 0)
  190.     for (i = 0; i < maxext; i++)
  191.       if (!(trn_ids[i]) && ext_ids[i] != nul)
  192. {
  193.   trn_ids[i] = num;
  194.           freext--;
  195.           PRINTF(("ADM.getext: freext = %d, fpn = %dn", freext, ext_ids[i]));
  196.   return (ext_ids[i]);
  197. }
  198.   
  199.   for (i = 0; i < maxext; i++) /* new extent is needing */
  200.     if (!(trn_ids[i]) && ext_ids[i] == nul)
  201.       {
  202. found++;
  203. break;
  204.       }
  205.   
  206.   if (!found)
  207.     {
  208.       i = maxext;
  209.       maxext *=2;
  210.       ext_ids = (u2_t *) xrealloc (ext_ids, maxext * sizeof(u2_t));
  211.       trn_ids = (u2_t *) xrealloc (trn_ids, maxext * sizeof(u2_t));
  212.       for (j = i; j < maxext; j++)
  213. {
  214.   ext_ids[j] = nul;
  215.   trn_ids[j] = 0;
  216. }
  217.     }
  218.       
  219.   ext_ids[i] = rfile / BD_PAGESIZE;
  220.   rfile += sizext * BD_PAGESIZE;
  221.   trn_ids[i] = num;
  222.   PRINTF(("ADM.getext: freext = %d, fpn = %d, rfile = %dn",
  223.           freext, ext_ids[i], rfile));
  224.   return (ext_ids[i]);
  225. }
  226. static void 
  227. putext (i4_t exnum, u2_t *mfpn)
  228. {
  229.   register i4_t i, j;
  230.   u2_t fpn;
  231.   
  232.   for (i = 0, fpn = *mfpn; i < exnum; i++, fpn = mfpn[i])
  233.     for (j = 0; j < maxext; j++)
  234.       if (fpn == ext_ids[j] && trn_ids[j])
  235. {
  236.           PRINTF(("ADM.putext: exnum=%d, fpn = %dn",exnum, fpn));
  237.   trn_ids[j] = 0;
  238.   freext++;
  239.   break;
  240. }
  241. }
  242. static void 
  243. iamm (u2_t num) /* I'm modifying transaction */
  244. {
  245.   tabtr[num].uidtr = uidt++;
  246.   if (uidt == idt)
  247.     {
  248.       idt += uidconst;
  249.       p2.uid = idt;
  250.       if (lseek (fdaf, 0, SEEK_SET) < 0)
  251. {
  252.   perror ("ADM.lseek: lseek admfile");
  253.   return;
  254. }
  255.       if (write (fdaf, (char *) &p2, adfsize) != adfsize)
  256. {
  257.   perror ("ADMFILE");
  258.   return;
  259. }
  260.     }
  261. }
  262. static void 
  263. uniqnm (u2_t num)
  264. {
  265.   unname++;
  266.   if(unname == nunname)
  267.     {
  268.       nunname += uidconst;
  269.       p2.unname= unname;
  270.       if(lseek(fdaf,0,SEEK_SET) <0 )
  271.         {
  272.           perror("ADM.lseek: lseek admfile");
  273.           exit(1);
  274.         }
  275.       if(write(fdaf,(char *)&p2,adfsize) !=adfsize)
  276.         {
  277.           perror("ADMFILE");
  278.           exit(1);
  279.         }
  280.     }
  281.   PRINTF (("ADM.uniqnm.e: NUM=%d,UNNAME=%dn", num, (i4_t)unname));
  282. }
  283. /* ? ? write to logic log "end of transaction" mark.
  284.  *    "num" - transaction identifier
  285.  */
  286. static void 
  287. wljetr (u2_t num)
  288. {
  289.   register i4_t i, blsz;
  290.   register char *pnt;
  291.   i4_t uid;
  292.   PRINTF (("ADM.wljet.b: numtr=%d, FIR_TRN_NUM = %d, maxusetran = %dn",
  293.           num, FIR_TRN_NUM, maxusetran));
  294.   t2bpack (num + CONSTTR, sbuf.mtext);
  295.   pnt = sbuf.mtext + sizeof(u2_t) + sizeof(u2_t);
  296.   *pnt++ = EOTLJ;
  297.   for (i = FIR_TRN_NUM, blsz = 1; i <= maxusetran; i++)
  298.     {
  299.       uid = tabtr[i].uidtr;
  300.       if ((uid != 0) && (i != num))
  301. {
  302.           t4bpack (uid, pnt);
  303.           pnt +=sizeof(i4_t);
  304.           blsz += sizeof(i4_t);
  305. }
  306.     }
  307.   sbuf.mtype = PUTOUT;
  308.   t2bpack (blsz, sbuf.mtext + sizeof(u2_t));
  309.   if (msgsnd (msgidl, (MSGBUFP)&sbuf, sizeof(u2_t) + sizeof(u2_t) + blsz, 0) < 0)
  310.     {
  311.       perror ("ADM.msgsnd: LOGJ->PUTOUT");
  312.       return;
  313.     }
  314.   PRINTF (("ADM.wljet.e: recsize=%dn", blsz));
  315. } /* wljetr */
  316. #define NUMTR_DEC 
  317. { numtr--; if (maxusetran==numtr) for(;!(tabtr[maxusetran].idprtr);maxusetran--);}
  318. void 
  319. endotr (i2_t num,i4_t exit_code)
  320. {
  321.   register i4_t i, msgid;
  322.   struct msqid_ds msqidds;
  323.   i4_t all_done, work_ext = 0;
  324.   i4_t pr = 0;
  325.   if(exit_code)
  326.     {
  327.       PRINT ("ADM.endotr: some recovery for trn %d must be heren", num);
  328.       kill_all(-1); /* stops everything and restart services with MCR */
  329.     }
  330.   if (tabtr[num].uidtr == minid)
  331.     { /* if fiinished transaction has minID identifier */
  332.       tabtr[num].uidtr = 0;
  333.       for (i = FIR_TRN_NUM; i <= maxusetran; i++) /* search new minID */
  334.         if (tabtr[i].uidtr != 0)
  335.           {
  336.             minid = tabtr[i].uidtr;
  337.             for (; i <= maxusetran; i++) /* search new minID */
  338.               if (tabtr[i].uidtr < minid)
  339.                 minid = tabtr[i].uidtr;
  340.             pr = 1;
  341.             break;
  342.           }
  343.       if (pr == 0)
  344.         minid = uidt;
  345.       
  346.       for (i = FIR_TRN_NUM; i <= maxusetran; i++) /*sending of min identifier*
  347.                 *of transaction to all    *
  348.            *modifying transactions   */
  349. if (tabtr[i].uidtr != 0)
  350.   {
  351.     t4bpack (minid, sbuf.mtext);
  352.     TRN_SEND (GETMIT, sizeof(i4_t));
  353.   }
  354.     }
  355.   
  356.   if ((msgid = tabtr[num].msgidtrn))
  357.     {
  358.       msgctl (msgid, IPC_RMID, &msqidds);
  359.       tabtr[num].msgidtrn = 0;
  360.       keytrn[num] = 0;
  361.     }
  362.   
  363.   PRINTF (("ADM.endotr: TRN N=%d uniq_name = %d is killedn",
  364.           num, (i4_t)tabtr[num].uidtr));
  365.   tabtr[num].idprtr = 0;
  366.   NUMTR_DEC;
  367.   
  368.   /* RPC-Unregistration of transaction server */
  369.   SVC_UNREG(DEFAULT_TRN +num, 1); /* Number of version of interpretator & *
  370.                                    * compiler must = 1                    */
  371.   
  372.   tabtr[num].cretime = 0;
  373.   /* return all extents NUM-transaction */
  374.   for (i = 0; i < maxext; i++)
  375.     if (trn_ids[i])
  376.       if (trn_ids[i] == num)
  377. {
  378.   trn_ids[i] = 0;
  379.   freext++;
  380. }
  381.       else
  382. work_ext++;
  383.   
  384.   if (nocrtr_fl)
  385.     {
  386.       all_done = 1;
  387.       
  388.       for (i = FIR_TRN_NUM; i <= maxusetran; i++)
  389. if (tabtr[i].idprtr)
  390.   if (tabtr[i].cretime)
  391.     {
  392.       all_done = 0;
  393.       break;
  394.     }
  395.       
  396.       if (all_done)
  397. {
  398.           nocrtr_fl = 0;
  399.   if (fix_lj_fl)
  400.     copylj();
  401.   if (finit_fl)
  402.     finit(0);
  403. }
  404.     }
  405.   transaction_number--;
  406.   if (transaction_number == 0)
  407.     {
  408.       freext = 0;
  409.       rfile = 0;
  410.       ftruncate (fdto, 0);
  411.     }
  412.   PRINT ("ADM.endotr.e: NUM=%dn", num);
  413.   PRINT ("ADM.endotr.e: NUMTR=%dn", numtr);
  414.   PRINT ("ADM.endotr.e: %d extents still in usen", work_ext);
  415. }
  416. static void 
  417. errfu (char c, char tperr)
  418. {
  419.   char pr;
  420.   PRINTF (("ADM.ERRFU.b: c=%cn", c));
  421.   switch (c)
  422.     {
  423.     case 'm':
  424.       pr = MJ_PPS;
  425.       break;
  426.     case 'l':
  427.       pr = LJ_PPS;
  428.       break;
  429.     case 'b':
  430.       pr = BF_PPS;
  431.       break;
  432.     case 's':
  433.       pr = SN_PPS;
  434.       break;
  435.     case 'q':
  436.       pr = SR_PPS;
  437.       break;
  438.     default:
  439.       break;
  440.     }
  441.   /* OUT_ERR(tperr,pr,0); */
  442. }
  443. static void 
  444. copy (void)
  445. {
  446.   char file_name[1024];
  447.   char arr[32];
  448.   PRINTF (("ADM.COPY.b:n"));
  449.   sprintf (arr, "%d", (i4_t)vnlj);
  450.   strcpy (file_name, ARCHIVE);
  451.   strcat (file_name, "/ljour.");
  452.   strcat (file_name, arr);
  453.   
  454.   cp_lj_reg (strlen (file_name), file_name);
  455.   PRINTF (("ADM.COPY.e: %sn", file_name));
  456. }
  457. static void 
  458. nobuf (void)
  459. {
  460.   printf ("ADM.NOBUF: BUF doesn't get buffern");
  461. }
  462. void 
  463. realop (i4_t op, u2_t num, char *b)
  464. {
  465.   u2_t fpn;
  466.   sigset_t set;
  467.   
  468.   PRINT ("ADM.realop: op  = %dn", op )
  469.   /* sleep (2);   @ need to delete @ */
  470.   PRINT ("ADM.realop: NUM = %dn", (i4_t)num)
  471.     
  472.   if (!op)
  473.     return;
  474.   
  475.   PRINT ("ADM.realop: op  = %dn", op )
  476.    sigprocmask (0, NULL, &set);
  477.   PRINT ("ADM.realop: presence flag of SIGUSR1: %dn", sigismember(&set, SIGUSR1)) 
  478.   
  479.   switch (op)
  480.     {
  481.     case RES_READY :
  482.       if (tabtr[num].res_ready == 2) /* it was request from client */
  483. tabtr[num].res_ready = 1;
  484.       break;
  485.     case PUTEXT:
  486.       PRINT ("ADM.realop: before putext: msgidtrn = %dn",
  487.      (i4_t)tabtr[num].msgidtrn)
  488.       putext (t2bunpack (b), (u2_t *) (b + sizeof(u2_t)));
  489.       PRINT ("ADM.realop: after putext: msgidtrn = %dn",
  490.      (i4_t)tabtr[num].msgidtrn)
  491.       break;
  492.     case GETEXT:
  493.       fpn = getext ((num == NUM_SRT) ? 
  494.                     /* process SORT */ t2bunpack (b) : num);
  495.       sbuf.mtype = num + CONSTTR;
  496.       t2bpack (fpn, sbuf.mtext);
  497.       
  498.       PRINT ("ADM.realop: getext: msgidtrn = %dn",
  499.      (i4_t)tabtr[num].msgidtrn);
  500.       PRINT ("ADM.realop: getext: sbuf.mtype = %dn",
  501.      (i4_t)(sbuf.mtype));
  502.   
  503.       if (msgsnd (tabtr[num].msgidtrn, (MSGBUFP)&sbuf, sizeof(u2_t), 0) < 0)
  504. {
  505.   perror ("ADM.msgsnd: Answer to GETEXT");
  506.   return;
  507. }
  508.       break;
  509.     case IAMMOD:
  510.       iamm (num);
  511.       sbuf.mtype = num + CONSTTR;
  512.       t4bpack (tabtr[num].uidtr, sbuf.mtext);
  513.       if (msgsnd (tabtr[num].msgidtrn, (MSGBUFP)&sbuf, sizeof(i4_t), 0) < 0)
  514. {
  515.   perror ("ADM.msgsnd: Answer to IAMMOD");
  516.   return;
  517. }
  518.       break;
  519.     case UNIQNM:
  520.       uniqnm (num);
  521.       sbuf.mtype = num + CONSTTR;
  522.       t4bpack (unname, sbuf.mtext);
  523.       if (msgsnd (tabtr[num].msgidtrn, (MSGBUFP)&sbuf, sizeof(i4_t), 0) < 0)
  524. {
  525.   perror ("ADM.msgsnd: Answer to UNIQNM");
  526.   return;
  527. }
  528.       break;
  529.     case WLJET:
  530.       wljetr (num);
  531.       break;
  532.     case ERRFU:
  533.       errfu (*b, *(b + 1));
  534.       break;
  535.     case COPY:
  536.       copy ();
  537.       break;
  538.     case NOBUF:
  539.       nobuf ();
  540.       break;
  541.     case READY:
  542.       break;
  543.     default:
  544.       break;
  545.     }
  546. }
  547. #define TO_TABTR(pid, msgid)  
  548.   { tabtr[numtr].uidtr = 0;     
  549.     tabtr[numtr].idprtr = pid;          
  550.     tabtr[numtr].res_ready = 0;         
  551.     tabtr[numtr].cretime = time(NULL);  
  552.     tabtr[numtr++].msgidtrn = msgid;    
  553.     maxusetran++; 
  554.   }
  555. #define ARG(num, what) sprintf (args[num], "%d", (i4_t)(what))
  556. static int
  557. logj_fix (void)
  558. {
  559.   sbuf.mtype = BEGFIX;
  560.   if (msgsnd (msgidl, (MSGBUFP)&sbuf, 0, 0) < 0)
  561.     {
  562.       perror ("ADM.msgsnd: LOGJ->FIX");
  563.       return -1;
  564.     }
  565.   if (msgrcv (msgidl, (MSGBUFP)&sbuf, 1, ANSLJ, 0) < 0)
  566.     {
  567.       perror ("ADM.msgrcv: BEGFIX LJ");
  568.       return -1;
  569.     }
  570.   return ((i4_t) *sbuf.mtext);
  571. }
  572. static pid_t
  573. fork_service(char **args,i4_t take_care_of_fail)
  574. {
  575.   pid_t chld;
  576.   
  577. #ifndef NOT_DEBUG
  578.   { 
  579.     char **arg;
  580.     fputs ("##>>>",stderr);
  581.     for(arg=args;*arg;arg++)
  582.       fprintf(stderr,"%s ",*arg);
  583.     fputs ("n",stderr);
  584.   }
  585. #endif
  586.   children++;
  587.   
  588.   chld = fork();
  589.   if (chld < 0) /* if fork failed */
  590.     {
  591.       lperror("fork '%s'",*args);
  592.       if (take_care_of_fail)  
  593.         return chld;          /* return error code          */
  594.       EXIT;
  595.     }
  596.   else if (chld==0)     
  597.     { /* child process -- replace by '*args' */
  598.       execvp (*args, args);
  599.       lperror ("ADM.fork_service: '%s' doesn't exec",*args);
  600.       exit(1);
  601.     }
  602.   return chld;
  603. }
  604. #ifndef NOT_DEBUG
  605. static void
  606. run_debugger (pid_t debuggee, char **args,char *to_debugger,char *x_server)
  607. {
  608.   pid_t  debugger;
  609.   char * prog = *args;
  610.   i4_t    i;
  611.   
  612.   { /* prepare debugger script -- written generally for gdb */
  613.     FILE * fl;
  614.     fl = fopen (GDBINIT_FILE, "w");
  615.     fprintf (fl,
  616.              "attach %dn"                  /* attach at MEET_DEBUGGER     */
  617.              "break exitn"
  618.              "break abortn"
  619.              "break lperrorn"
  620.              "%sn"                         /* set local settings          */
  621.              "signal %dn"                  /* clear wait flag             */
  622.              "finishn"                     /* lperror cathes control here */
  623.              "finishn"                     /* go up to 'main'             */
  624.              ,(i4_t)debuggee
  625.              ,(to_debugger?to_debugger:"")
  626.              ,SIGALRM);
  627.     fclose (fl);
  628.   }
  629.   
  630.   if (!x_server)
  631.     x_server = getenv("DISPLAY");
  632.   if (!x_server)
  633.     x_server = ":0.0";
  634.   args[i=1] = "-display";
  635.   args[++i] = x_server;
  636.   args[++i] = "-bg";
  637.   args[++i] = "Gray";
  638. #if defined(HAVE_DDD)
  639.   args[0] = HAVE_DDD;
  640.   args[++i] = prog;
  641.   args[++i] = "-nx";
  642.   args[++i] = "-command=" GDBINIT_FILE;
  643. #elif defined(HAVE_XXGDB)
  644.   args[0] = HAVE_XXGDB;
  645.   args[++i] = "-nx";
  646.   args[++i] = "-command=" GDBINIT_FILE;
  647.   args[++i] = prog;
  648. #elif  defined(HAVE_XTERM)
  649.   args[0] = HAVE_XTERM;
  650.   args[++i] = "-e";
  651. #if defined(HAVE_GDB)
  652.   args[++i] = HAVE_GDB;
  653. #elif defined(HAVE_DBX) 
  654.   args[++i] = HAVE_DBX;
  655. #else
  656. # error configuraton - !NOT_DEBUG && !HAVE_GDB && !HAVE_DBX 
  657. #endif
  658.   args[++i] = prog;
  659.   args[++i] = "-x";
  660.   args[++i] = GDBINIT_FILE;
  661. #else
  662. # error configuraton - !NOT_DEBUG && !HAVE_XTERM && !HAVE_DDD && !HAVE_XXGDB 
  663. #endif
  664.   args[++i] = NULL;
  665.   debugger = fork_service(args,(to_debugger!=NULL));
  666.   if (debugger>0)
  667.     { /* add new entry to debuggers list */
  668.       debug_pid_t *new_d = xmalloc (sizeof(debug_pid_t));
  669.       new_d->debugger = debugger;
  670.       new_d->to_debug = debuggee;
  671.       new_d->next = debuggers_pids;
  672.       if (debuggers_pids)
  673.         debuggers_pids->prev = new_d;
  674.       debuggers_pids = new_d;
  675.     }
  676. }
  677. #endif /* NOT_DEBUG */
  678. static pid_t
  679. run_chld (i4_t run_gdb,char **args,char *to_debugger,char *x_server)
  680. {
  681.   pid_t  chld;
  682. #ifndef NOT_DEBUG
  683.   if (run_gdb<0)
  684.     {
  685.       i4_t c;
  686.       printf ("DO you want to start gdb for '%s'?",*args);
  687.       do 
  688.         c = getchar();
  689.       while ( c == 'n' );
  690.       if (c != 'y')
  691.         run_gdb = 0;
  692.     }
  693.   if (run_gdb)
  694.     { /* add debugger keyword */
  695.       char **p;
  696.       for ( p = args; *p; p++ );
  697.       *p = "DebugIt";
  698.       *(++p) = NULL;
  699.     }  
  700. #endif
  701.   chld = fork_service(args,(to_debugger!=NULL));
  702. #ifndef NOT_DEBUG
  703.   if (run_gdb && chld > 0)
  704.     run_debugger (chld,args,to_debugger,x_server);
  705. #endif
  706.   
  707.   return chld;
  708. }
  709. static key_t
  710. get_msg_key(void)   /* this function has a complete static copy in strgcr.c */
  711. {
  712.   static key_t k = (key_t)-2;
  713.   if (k==(key_t)-2)
  714. #if HAVE_FTOK
  715.     k = ftok(MJ, 'D');
  716. #else
  717.     k = FIRSTMQN;
  718. #endif
  719.   errno = 0;
  720.   for(;;)
  721.     {
  722.       if ( msgget (k, DEFAULT_ACCESS_RIGHTS) < 0 )
  723.         if (errno == ENOENT)
  724.           return k++;
  725.         else if (errno == ENOSPC)
  726.           return -1;
  727.       k++;
  728.     }
  729. }
  730. static i4_t 
  731. ini (void)
  732. {
  733.   register i4_t i;
  734.   char rep, repmj, *args[20];
  735.   i4_t optbufnum, maxnbuf, maxtact;
  736.   key_t fsegnum;
  737.   char mas[sizeof(i4_t)];
  738.   char argarea[20][20];
  739.   
  740. #define INITARG for(i = 0 ; i < 20; i++) args[i] = argarea[i];
  741.   rep = 0;
  742.   
  743.   
  744.   /*------------OPEN,READ AND WRITE ADMFILE------------------*/
  745.   PRINTF (("ADM.ini: Open, read and write ADMFILE %sn", ADMFILE));
  746.   if ((fdaf = open (ADMFILE, O_RDWR, 0644)) < 0)
  747.     {
  748.       perror ("ADMFILE: open error");
  749.       EXIT;
  750.     }
  751.   if (read (fdaf, (char *) &p2, adfsize) != adfsize)
  752.     {
  753.       perror ("ADMFILE: read error");
  754.       EXIT;
  755.     }
  756.   idt       = p2.uid;
  757.   uidconst  = p2.uidconst;
  758.   nunname   = p2.unname;
  759.   sizext    = p2.sizext / BD_PAGESIZE;
  760.   maxext    = p2.maxext;
  761.   maxfrext  = p2.maxfrext;
  762.   maxtrans  = p2.maxtrans;
  763.   rjzm      = p2.mjred;
  764.   rjzl      = p2.ljred;
  765.   mpagem    = p2.mjmpage;
  766.   mpagel    = p2.ljmpage;
  767.   sizesc    = p2.sizesc;
  768.   optbufnum = p2.optbufnum;
  769.   maxnbuf   = p2.maxnbuf;
  770.   maxtact   = p2.maxtact;
  771.   fsegnum   = p2.fshmsegn;
  772.   PRINTF (("ADM.ini: was reading from ADMFILE:n"));
  773.   PRINTF (("  UID=%d, UIDCONST=%d, MAXTRANS=%d, SIZEXT=%d, MAXEXT=%d, "
  774.   "MAXFREXT=%d, UNNAME=%d, RJZm=%d, RJZl=%d, MPAGEm=%d,"
  775.   " MPAGEl=%d, MAXNBUF=%d,  SIZESC=%dn", 
  776.   (i4_t)idt, (i4_t)uidconst, maxtrans, sizext, maxext, 
  777.   maxfrext, (i4_t)nunname, rjzm, rjzl,
  778.   mpagem, mpagel, maxnbuf, sizesc));
  779.   uidt = idt;
  780.   if (uidt == 0)
  781.     uidt++;
  782.   idt += uidconst;
  783.   p2.uid = idt;
  784.   unname = nunname;
  785.   if (unname == 0)
  786.     unname++;
  787.   nunname += uidconst;
  788.   p2.unname = nunname;
  789.   if (lseek (fdaf, 0, SEEK_SET) < 0)
  790.     {
  791.       perror ("ADM.lseek: lseek admfile");
  792.       EXIT;
  793.     }
  794.   if (write (fdaf, (char *) &p2, adfsize) != adfsize)
  795.     {
  796.       perror ("ADMFILE: write error");
  797.       EXIT;
  798.     }
  799.   
  800.   keyadm = get_msg_key();
  801.   keylj  = get_msg_key();
  802.   keymj  = get_msg_key();
  803.   keybf  = get_msg_key();
  804.   keysn  = get_msg_key();
  805.   keysr  = get_msg_key();
  806.   keymcr = get_msg_key();
  807.   
  808.   /* Getting queue for administraror */
  809.   if ((msgida = msgget (keyadm, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)
  810.     {
  811.       perror ("ADM: Getting queue for adm");
  812.       EXIT;
  813.     }
  814.     
  815.   freext = 0;
  816.   keytrn = (key_t *) xmalloc (maxtrans * sizeof (key_t));
  817.   
  818.   tabtr = (struct des_trn *) xmalloc (maxtrans * sizeof (struct des_trn));
  819.   ext_ids = (u2_t *) xmalloc (maxext * sizeof(u2_t));
  820.   trn_ids = (u2_t *) xmalloc (maxext * sizeof(u2_t)); /* all trn_ids[i] = 0 */
  821.   for (i = 0; i < maxext; i++)
  822.     ext_ids[i] = nul;
  823.   minid = uidt;
  824.   maxusetran = FIR_TRN_NUM;
  825.   numtr = 1;
  826.   
  827. /*---------------INI MICROJ------------------------------*/
  828.   INITARG;
  829.   args[0] = MJ;
  830.   args[1] = MJFILE;
  831.   sprintf (args[2], "%d", rjzm);
  832.   sprintf (args[3], "%d", mpagem);
  833.   sprintf (args[4], "%d", (i4_t)keymj);
  834.   sprintf (args[5], "%d", (i4_t)keylj);
  835.   args[6] = NULL;
  836.   pidmj = run_chld(-1,args,NULL,NULL);
  837. /*---------------INI MICROJ 2 ----------------------------*/
  838.   PRINTF (("ADM.ini: before MSG_INIT ini MJ keymj = %dn", keymj));
  839.   MSG_INIT (msgidm, keymj, "MJ");
  840.   PRINTF (("ADM.ini: after MSG_INIT ini MJn"));
  841.   if (msgrcv (msgidm, (MSGBUFP)&rbuf, 1, ANSMJ, 0) < 0)
  842.     perror ("ADM.msgrcv: INIT MJ");
  843.   repmj = *rbuf.mtext;
  844.   PRINTF (("ADM.ini: INI repmj = %dn", repmj));
  845.   sbuf.mtype = INIMJ;
  846.   if (msgsnd (msgidm, (MSGBUFP)&sbuf, 0, 0) < 0)
  847.     {
  848.       perror ("ADM.msgsnd: MJ->INIMJ");
  849.       exit (1);
  850.     }
  851.   
  852.   /*----------------INI BUFFER----------------------*/
  853.   PRINTF (("ADM.ini: INI BUFFER>n"));
  854.   if ((fdto = creat (SEG0, DEFAULT_ACCESS_RIGHTS)) < 0)
  855.     {
  856.       perror (SEG0);
  857.       EXIT;
  858.     }
  859.   rfile = 0;
  860.   /*vvvvvvvvvvvvvvv  start BUF   vvvvvvvvvvvvvv*/
  861.   INITARG;
  862.   args[0] = BUF;
  863.   args[1] = SEG0;
  864.   ARG (2, keybf);
  865.   ARG (3, keymj);
  866.   ARG (4, optbufnum);
  867.   ARG (5, maxnbuf);
  868.   ARG (6, maxtact);
  869.   ARG (7, maxtrans);
  870.   /* the first numeric name of the   *
  871.    * shared memory segment for PUPSI */
  872.   ARG (8, fsegnum);
  873.   /* BD segments numbers and names */
  874.   ARG (9, 1);
  875.   args[10] = SEG1;
  876.   ARG (11, adm_pid);
  877.   args[12] = NULL;
  878.   pidbf = run_chld(-1,args,NULL,NULL);
  879.   /*^^^^^^^^^^^^^^^^^^ start BUF ^^^^^^^^^^^^^^^^^^^^^*/
  880.   PRINTF (("ADM.ini: INI BUFn"));  
  881.   MSG_INIT (msgidb, keybf, "BUF");
  882.   
  883.   /*-------------OPEN AND INI LOGJ--------------------------*/
  884.   PRINTF (("ADM.ini: Open and INI LOGJn"));
  885.   if ((fdlj = open (LJFILE, O_RDWR, 0644)) < 0)
  886.     {
  887.       perror ("LJ: open");
  888.       EXIT;
  889.     }
  890.   if (read (fdlj, mas, sizeof(i4_t)) != sizeof(i4_t))
  891.     {
  892.       perror ("LJOUR: read error");
  893.       EXIT;
  894.     }
  895.   vnlj = t4bunpack (mas);
  896.   PRINTF (("ADM.ini: VNLJ=%dn", (i4_t)vnlj));
  897.   /*vvvvvvvvvvvvvvv start LJ  vvvvvvvvvvvvvvvvvvvvv*/
  898.   INITARG;
  899.   args[0] = LJ;
  900.   sprintf (args[1], "%d", fdlj);
  901.   sprintf (args[2], "%d", (i4_t)rjzl);
  902.   sprintf (args[3], "%d", (i4_t)mpagel);
  903.   sprintf (args[4], "%d", (i4_t)keylj);
  904.   sprintf (args[5], "%d", (i4_t)keybf);
  905.   sprintf (args[6], "%d", (i4_t)keyadm);
  906.   sprintf (args[7], "%d", (i4_t)keymj);
  907.   args[8] = NULL;
  908.   pidlj = run_chld(-1,args,NULL,NULL);
  909.   /*^^^^^^^^^^^^^^^ start LJ  ^^^^^^^^^^^^^^^^^^^^^*/
  910.   MSG_INIT (msgidl, keylj, "LJ");
  911.   /* LogJournal is the special (with number NUM_LJ) transaction */
  912.   TO_TABTR (pidlj, msgidl);
  913.   PRINTF (("ADM.ini: INI LOGJ donen"));  
  914.  
  915.   
  916.   if (repmj == MJ_PPS)
  917.     {
  918.       /* Memory crash, invoke Memory Crash Recovery Utility */
  919.       PRINTF (("ADM.ini: load MCR MCR_name=%s, MJ_name = %sn", MCR, MJ));
  920.       
  921.       /*vvvvvvvvvvvvvvv start MCR  vvvvvvvvvvvvvvvvvvvvv*/
  922.       INITARG;
  923.       args[0] = MCR;
  924.       args[1] = MJFILE;
  925.       args[2] = LJFILE;
  926.       sprintf (args[3], "%d", (i4_t)keymj);
  927.       sprintf (args[4], "%d", (i4_t)keylj);
  928.       sprintf (args[5], "%d", (i4_t)keybf);
  929.       sprintf (args[6], "%d", (i4_t)keymcr);
  930.       sprintf (args[7], "%d", sizesc);
  931.       args[8] = NULL;
  932.       pidmcr = run_chld(-1,args,NULL,NULL);
  933.       
  934.       /*^^^^^^^^^^^^^^^ start MCR ^^^^^^^^^^^^^^^^^^^^^*/
  935.       MSG_INIT (msgidc, keymcr, "MCR");
  936.       if (msgrcv (msgidc, (MSGBUFP)&rbuf, 1, ANSADM, 0) < 0)
  937.         perror ("ADM.msgrcv: Answer from MCR");
  938.       repmj = *rbuf.mtext;
  939.     }
  940.   logj_fix ();
  941.   /*---------------INI SYNCH-------------------------------*/
  942.   PRINTF (("ADM.ini: INI SYN>n"));
  943.   /*vvvvvvvvvvvvvvv start SYN vvvvvvvvvvvvvvvvvvvvv*/
  944.   INITARG;
  945.   args[0] = SYN;
  946.   ARG (1, keysn);
  947.   ARG (2, keybf);
  948.   args[3] = NULL;
  949.   pidsn = run_chld(-1,args,NULL,NULL);
  950.   /*^^^^^^^^^^^^^^^ start SYN ^^^^^^^^^^^^^^^^^^^^^*/
  951.   MSG_INIT (msgids, keysn, "SYN");
  952.   /*---------------INI SORTER------------------------------*/
  953.   PRINTF (("ADM.ini: INI SORTER>n"));
  954.   /*vvvvvvvvvvvvvvv start SRT vvvvvvvvvvvvvvvvvvvvv*/
  955.   INITARG;
  956.   args[0] = SRT;
  957.   ARG (1,   keysr);
  958.   ARG (2,   keybf);
  959.   ARG (3,   sizext);
  960.   ARG (4,   adm_pid);
  961.   ARG (5,   keyadm);
  962.   args[6] = NULL;
  963.   pidsr = run_chld(-1,args,NULL,NULL);
  964.   /*^^^^^^^^^^^^^^^ start SYN ^^^^^^^^^^^^^^^^^^^^^*/
  965.   MSG_INIT (msgidq, keysr, "SORT");
  966.   
  967.   /* SORTER is the special (with number NUM_SRT) transaction */
  968.   TO_TABTR (pidsr, msgidq);
  969.   transaction_number = 0;
  970.   return (0);
  971. }
  972. static int
  973. rpc_check(i4_t tr_num, rpc_svc_t type)
  974. {
  975.   static struct timeval tv = { 25, 0 };
  976.   CLIENT *cl = (CLIENT *) NULL;
  977.   i4_t    rc = 0,i=0;
  978.   char   *hostname;
  979. #if 0
  980.   struct  utsname unm;
  981.   uname(&unm);
  982.   hostname = unm.nodename;
  983. #else
  984.   hostname = "localhost";
  985. #endif
  986.   
  987.   while (i++<10)
  988.     {
  989.       if (cl == (CLIENT *) NULL)
  990. cl = clnt_create (hostname, DEFAULT_TRN + tr_num, 1, "tcp");
  991.       if ( cl == (CLIENT *) NULL )
  992.         clnt_pcreateerror(hostname);
  993.       else if ( clnt_call(cl, 1000,
  994.   (xdrproc_t) xdr_void, (caddr_t) NULL,
  995.   (xdrproc_t) xdr_long, (caddr_t) &rc,
  996.   tv)
  997. == RPC_SUCCESS)
  998. break;  
  999.       if (tabtr[tr_num].idprtr == 0)
  1000. break;
  1001.       rc = 0;
  1002.       sleep(1);
  1003.     }
  1004.   if (i>10)
  1005.     clnt_perror(cl,hostname);
  1006.   if (cl)
  1007.     clnt_destroy(cl);
  1008.   if(rc>0)
  1009.     {
  1010.       assert( tabtr[tr_num].idprtr == (pid_t)rc);
  1011.     }
  1012.   return (i<=10);
  1013. }
  1014. /* New transaction with interpretator or compiler creating. *
  1015.  * Returns number of it in TABTR or error (< 0).            */
  1016.      
  1017. i4_t 
  1018. creatr (init_arg *arg)
  1019. {
  1020.   static char *svcs[] = SVC_FILES;
  1021.   register i4_t i, j, trnum;
  1022.   pid_t idpr;
  1023.   char *args[20];
  1024.   char  argarea[20][20];
  1025.   PRINTF (("ADM.creatr.b:n"));
  1026.   for(i=0;i<20;i++)
  1027.     args[i] = argarea[i];
  1028.   
  1029.   /* tabtr cleaning & finding free place in it */
  1030.   for (trnum = 0, j = FIR_TRN_NUM; j <= maxusetran; j++)
  1031.     if (!(tabtr[j].cretime) && (!tabtr[j].idprtr) )
  1032.       {
  1033.         trnum = j;
  1034.         break;
  1035.       }
  1036.   
  1037.   if (!trnum) /* there is no free place in tabtr[1..MAXUSETRAN] */
  1038.     {
  1039.       trnum = ++maxusetran;
  1040.       if (numtr == maxtrans)
  1041. {
  1042.   keytrn = (key_t *) xrealloc (keytrn,
  1043.    2 * maxtrans * sizeof (key_t));
  1044.   for (i = maxtrans; i < 2 * maxtrans; i++)
  1045.     keytrn[i] = 0;
  1046.       
  1047.   maxtrans *= 2;
  1048.   tabtr = (struct des_trn *) xrealloc (tabtr, 
  1049.   maxtrans * sizeof (struct des_trn));
  1050. }
  1051.     }
  1052.   {
  1053.     char *debug = 
  1054.       "break compiler_disconnectn"
  1055.       "set   under_dbg=1n";
  1056.     
  1057.     keytrn[trnum] = get_msg_key();
  1058.     assert(arg->type >=0);
  1059.     assert(arg->type < sizeof(svcs)/sizeof(char*));
  1060.     args[0]  = svcs[arg->type];
  1061.     ARG (1,    keytrn[trnum]);
  1062.     ARG (2,    keysn);
  1063.     ARG (3,    keysr);
  1064.     ARG (4,    keylj);
  1065.     ARG (5,    keymj);
  1066.     ARG (6,    keybf);
  1067.     ARG (7,    trnum);
  1068.     ARG (8,    minid);
  1069.     ARG (9,    sizext);
  1070.     ARG (10,   sizesc);
  1071.     ARG (11,   arg->wait_time);
  1072.     ARG (12,   DEFAULT_TRN + trnum);
  1073.     args[13] = arg->user_name;
  1074.     ARG (14,   adm_pid);
  1075.     ARG (15,   keyadm);
  1076.     args[16] = NULL;
  1077.     
  1078.     idpr = run_chld(arg->need_gdb,args,debug,arg->x_server);
  1079.     if (idpr< 0)
  1080.       return -TRN_INIT;
  1081.   }
  1082.   
  1083.   numtr++;
  1084.   tabtr[trnum].uidtr = 0;
  1085.   tabtr[trnum].idprtr = idpr;
  1086.   tabtr[trnum].res_ready = 0;
  1087.   tabtr[trnum].cretime = time(NULL);
  1088.   MSG_INIT (tabtr[trnum].msgidtrn, keytrn[trnum], "TRN");
  1089.   if (!rpc_check(trnum, arg->type))
  1090.     {
  1091.       if (tabtr[trnum].idprtr == idpr) /* if process still not initialized */
  1092.         {                              /* and still exist - kill it        */
  1093.           tabtr[trnum].idprtr = -idpr;
  1094.           kill(idpr,SIGKILL);          
  1095.           keytrn[trnum] = 0;
  1096.         }
  1097.       printf ("ADM.creatr: TRAN creation failedn");
  1098.       return -TRN_INIT;
  1099.     }
  1100.   PRINTF (("ADM.creatr.e: trn number = %dn", trnum));
  1101.   transaction_number++;
  1102.   return (trnum);
  1103. }
  1104. #undef ARG
  1105. void 
  1106. copylj (void)
  1107. {
  1108.   char file_name[1024];
  1109.   char arr[32];
  1110.   register i4_t n, fd;
  1111.   char buf[1024];
  1112.   
  1113.   /*------------------- suspend LJ --------------------------*/
  1114.   
  1115.   n = logj_fix ();
  1116.   /** printf ("ADM.COPYLJ: after LOGJ.FIX fdlj=%dn", fdlj); */
  1117.   /*---------------copying of Logic Log----------------------*/
  1118.  
  1119.   if (fix_path != NULL)
  1120.     {
  1121.       if (lseek (fdlj, 0, SEEK_SET) < 0)
  1122. {
  1123.   perror ("ADM.lseek: lseek ljfile");
  1124.   return;
  1125. }
  1126.       if ((n = read (fdlj, buf, 1024)) == 0)
  1127.         {
  1128.           perror ("LJOUR: read error");
  1129.           EXIT;
  1130.         }
  1131.       vnlj = t4bunpack (buf);
  1132.       sprintf (arr, "%d", (i4_t)vnlj);
  1133.       strcpy (file_name, ARCHIVE);
  1134.       strcat (file_name, "/ljour.");
  1135.       strcat (file_name, arr);
  1136.       if ((fd = creat (file_name, 0640)) < 0)
  1137. {
  1138.   perror (file_name);
  1139.   return;
  1140. }
  1141.       PRINTF (("ADM.COPYLJ: FIX_PATH=%sn", file_name));
  1142.       write (fd, buf, n);
  1143.       while ((n = read (fdlj, buf, 1024)) != 0)
  1144.         {
  1145.           write (fd, buf, n);
  1146.         }
  1147.       close (fd);
  1148.     }
  1149.   /*----------------refreshment of Logic Log---------------------------*/
  1150.   sbuf.mtype = RENEW;
  1151.   t4bpack ((i4_t)fdlj, sbuf.mtext);
  1152.   t4bpack ((i4_t)rjzl, sbuf.mtext + sizeof(i4_t));
  1153.   if (msgsnd (msgidl, (MSGBUFP)&sbuf, 2 * sizeof (i4_t), 0) < 0)
  1154.     {
  1155.       perror ("ADM.msgsnd: LOGJ->RENEW");
  1156.       return;
  1157.     }
  1158.   if (msgrcv (msgidl, (MSGBUFP)&sbuf, 1, ANSLJ, 0) < 0)
  1159.     {
  1160.       perror ("ADM.msgrcv: Answer LOGJ->RENEW");
  1161.       return;
  1162.     }
  1163.   PRINTF (("ADM.COPYLJ.e: fdlj=%dn", fdlj));
  1164.   fix_lj_fl = 0;
  1165. }
  1166. void 
  1167. kill_all (i4_t err)
  1168. {
  1169.   register i4_t i;
  1170.   i4_t error;
  1171.   struct msqid_ds msqidds;
  1172.   static char entered = 0;
  1173.   static i4_t  err_code = 0;
  1174.   
  1175.   if (entered==0)
  1176.     {
  1177.       entered++;
  1178.       err_code = err;
  1179.       
  1180.       if (tabtr)
  1181.         {
  1182.           for (i = FIR_TRN_NUM; i <= maxusetran; i++)
  1183.             if (tabtr[i].idprtr)
  1184.               {
  1185.                 msgctl (tabtr[i].msgidtrn, IPC_RMID, &msqidds);
  1186.                 kill (tabtr[i].idprtr, SIGKILL);
  1187.                 tabtr[i].idprtr = -tabtr[i].idprtr;
  1188.               }
  1189.         }
  1190.       
  1191. #define RMMSG(id) if (id!=-1){msgctl(id,IPC_RMID,&msqidds);id = -1;}
  1192.       RMMSG(msgidl);   /* lj  queue */
  1193.       RMMSG(msgidm);   /* mj  queue */
  1194.       RMMSG(msgidb);   /* buf queue */
  1195.       RMMSG(msgids);   /* syn queue ?*/
  1196.       RMMSG(msgidq);   /* srt queue ?*/
  1197.       RMMSG(msgida);   /* adm queue */
  1198. #undef RMMSG
  1199.       
  1200. #define KILLP(id) if (id){ error = kill(id, SIGKILL); id = -id; }
  1201.       KILLP(pidlj);
  1202.       KILLP(pidmj);
  1203.       KILLP(pidbf);
  1204.       KILLP(pidsn);
  1205.       KILLP(pidsr);
  1206. #undef KILLP
  1207.     }
  1208.   if (children)
  1209.     return; /* let's wait a bit more */
  1210.   
  1211.   err |= err_code;
  1212. #define CLEAR(ptr)  if(ptr) { xfree(ptr); ptr = NULL; }
  1213.   CLEAR(keytrn);
  1214.   CLEAR(ext_ids);
  1215.   CLEAR(trn_ids);
  1216.   CLEAR(tabtr);
  1217.   
  1218. #undef CLEAR
  1219.   printf ("ADM is stoppedn");
  1220.   if(err!=-1)
  1221.     {
  1222.       /* svc_exit(); */
  1223.       exit (err);
  1224.     }
  1225.   entered = finit_done = err_code = 0;
  1226.   ini();
  1227. } /* kill_all */
  1228. void
  1229. finit (i4_t err)
  1230. {
  1231.   i4_t rep, cd, i;
  1232.   
  1233.   /* This function can't use EXIT */
  1234.   
  1235.   if (finit_done)
  1236.     return;
  1237.   
  1238.   if (err < 0)
  1239.     kill_all(-1);
  1240.   finit_done = 1;
  1241.   
  1242.   if (tabtr)
  1243.     {
  1244.       time_t tm;
  1245.       i4_t all_done;
  1246.       
  1247.       for (i = FIR_TRN_NUM; i <= maxusetran; i++)
  1248. if (tabtr[i].idprtr)
  1249.   {
  1250.     TRN_SEND (FINIT, 0);
  1251.   }      
  1252.       tm = time (NULL);
  1253.       do {
  1254. all_done = 1;
  1255. for (i = FIR_TRN_NUM; i <= maxusetran; i++)
  1256.   if (tabtr[i].idprtr)
  1257.     {
  1258.       all_done--;
  1259.       break;
  1260.     }
  1261. if (all_done)
  1262.   break;
  1263. sleep (1);
  1264.       } while (time (NULL) - tm < KILL_WAIT);
  1265.     }
  1266.   
  1267.   PRINTF (("ADM.finit.b: UNNAME=%d n", (i4_t)unname));
  1268.   p2.unname = unname + 1;
  1269.   if (lseek (fdaf, 0, SEEK_SET) < 0)
  1270.     perror ("ADM.lseek: lseek admfile");
  1271.   if (write (fdaf, (char *) &p2, adfsize) != adfsize)
  1272.     perror ("ADMFILE");
  1273.   rep = close (fdaf);
  1274.   fdaf = 0;
  1275.   
  1276.   if (pidlj)
  1277.     logj_fix ();
  1278.   
  1279.   sbuf.mtype = FINIT;
  1280. #if 0
  1281.   if(msgsnd(msgidl,&sbuf,0,0)<0) 
  1282.     { 
  1283.       perror("ADM.msgsnd: LOGJ->FINIT");
  1284.       exit(1); 
  1285.     } 
  1286.   if(msgrcv(msgidl,&rbuf,1,ANSLJ,0)<0) 
  1287.     { 
  1288.       perror("ADM.msgrcv: FINIT LJ"); 
  1289.       exit(1); 
  1290.     } 
  1291. #endif
  1292.   cd = close (fdlj);
  1293.   fdlj = 0;
  1294.   PRINTF (("ADM.finit: after LJ finishn"));
  1295.   if (pidmj)
  1296.     {
  1297.       if (msgsnd (msgidm, (MSGBUFP)&sbuf, 0, 0) < 0)
  1298. perror ("ADM.msgsnd: MJ->FINIT");
  1299.       if (msgrcv (msgidm, (MSGBUFP)&rbuf, 1, ANSMJ, 0) < 0)
  1300. perror ("ADM.msgrcv: FINIT MJ");
  1301.       PRINTF (("ADM.finit: after MJ finishn"));
  1302.     }
  1303.   if (pidbf)
  1304.     {
  1305.       if (msgsnd (msgidb, (MSGBUFP)&sbuf, 0, 0) < 0)
  1306. perror ("ADM.msgsnd: BUF->FINIT");
  1307.       if (msgrcv (msgidb, (MSGBUFP)&rbuf, 1, ANSBUF, 0) < 0)
  1308. perror ("ADM.msgrcv: FINIT BUF");
  1309.       PRINTF (("ADM.finit: after BUF finishn"));
  1310.     }
  1311.   
  1312.   if (pidsn)
  1313.     {
  1314.       if (msgsnd (msgids, (MSGBUFP)&sbuf, 0, 0) < 0)
  1315. perror ("ADM.msgsnd: SYN->FINIT");
  1316.       PRINTF (("ADM.finit: after SYN finishn"));
  1317.     }
  1318.   
  1319.   if (pidsr)
  1320.     {
  1321.       if (msgsnd (msgidq, (MSGBUFP)&sbuf, 0, 0) < 0)
  1322. perror ("ADM.msgsnd: SORT->FINIT");
  1323.       PRINTF (("ADM.finit: after SRT finishn"));
  1324.     }
  1325.   
  1326.   sleep(3); /* let's give to subprocess a chance to stop by itself */
  1327.   printf ("ADM.finit.e:n");
  1328.   kill_all (err); /* kill rest of them */
  1329. } /* finit */
  1330. void
  1331. dyn_change_parameters(void)
  1332. {
  1333.   i4_t fddp, length;
  1334.   struct DGSPARAM dyn_par;
  1335.   char *p;
  1336.   i4_t optbufnum, maxtact;  
  1337.   if ( (fddp = open (DYNPARS, O_RDWR, DEFAULT_ACCESS_RIGHTS)) <0)
  1338.     {
  1339.       perror ("DYNPARS: open error");
  1340.       exit (1);
  1341.     }
  1342.   if (lseek (fddp, 0, SEEK_SET) < 0)
  1343.     { 
  1344.       perror ("DYNPARS.lseek: lseek dynpars");
  1345.       exit (1);
  1346.     }
  1347.   length = sizeof (struct DGSPARAM);      
  1348.   if (read (fddp, (char *)&dyn_par, length) != length) {
  1349.     perror ("DYNPARSE: read error");
  1350.     exit (1);
  1351.   }      
  1352.   close (fddp);
  1353.   unlink (DYNPARS);
  1354.   
  1355.   maxfrext = dyn_par.d_max_free_extents_num;
  1356.   rjzl = dyn_par.d_lj_red_boundary;
  1357.   optbufnum = dyn_par.d_opt_buf_num;
  1358.   maxtact = dyn_par.d_max_tact_num;
  1359.   sbuf.mtype = OPTNUM;
  1360.   p = sbuf.mtext;
  1361.   t4bpack (optbufnum, p);
  1362.   t4bpack (maxtact, p + sizeof(i4_t));
  1363.   if (msgsnd (msgidb, (MSGBUFP)&sbuf, 2 * sizeof(i4_t), 0) < 0)
  1364.     perror ("ADM.msgsnd: BUF->OPTNUM");
  1365.   printf ("ADM.dyn_change_parameters: new parameters has setn");  
  1366. }