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

SQL Server

开发平台:

Unix_Linux

  1. /*  memcr.c  - Memory Crash Recovery Utility
  2.  *             Kernel of GNU SQL-server. Recovery utilities    
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by  Vera Ponomarenko
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contacts:   gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: memcr.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  28. #include "setup_os.h"
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <sys/uio.h>
  32. #if HAVE_UNISTD_H 
  33. #include <unistd.h>
  34. #endif
  35. #if HAVE_FCNTL_H 
  36. #include <fcntl.h>
  37. #endif
  38. #include <sys/ipc.h>
  39. #include <sys/msg.h>
  40. #include <assert.h>
  41. #include "destrn.h"
  42. #include "strml.h"
  43. #include "admdef.h"
  44. #include "adfstr.h"
  45. #include "fdclrcv.h"
  46. #include "xmem.h"
  47. key_t keylj, keymj, keybf, keymcr;
  48. i4_t msqidmcr, msqidl, msqidm, msqidb;
  49. i4_t fdmj, fdcurlj;
  50. u2_t trnum;
  51. extern CPNM curcpn;
  52. char **scptab;
  53. extern i2_t maxscan;
  54. unsigned ljmsize;
  55. u2_t S_SC_S;
  56. char mjpage[RPAGE], ljpage[RPAGE];
  57. i4_t minidnt;
  58. extern struct ADREC bllj;
  59. extern i4_t idtr;
  60. extern struct ADBL adlj;
  61. struct ldesind **TAB_IFAM;
  62. i4_t TIFAM_SZ;
  63. static int
  64. mrllb_tr(i4_t cidtr, struct ADBL adfix, struct ADBL cadlj, u2_t blsz, char *a,
  65.          char type)
  66. {
  67.   i4_t newidtr;
  68.   idtr = cidtr;
  69.   if (cadlj.npage <= adfix.npage && cadlj.cm <= adfix.cm)
  70.     {
  71.       cadlj.npage = t2bunpack (a);
  72.       a += size2b;
  73.       cadlj.cm = t2bunpack (a);
  74.       a += size2b;
  75.       backactn (blsz, a, type);
  76.     }
  77.   while (cadlj.npage >= adfix.npage || cadlj.cm > adfix.cm)
  78.     {
  79.       rcv_LJ_GETREC (&bllj, &cadlj);
  80.       a = bllj.block;
  81.       type = *a++;
  82.       if (type == GRLBLJ)
  83. continue;
  84.       if (type == EOTLJ)
  85. {
  86.   getmint (a, bllj.razm - size1b);
  87.   continue;
  88. }
  89.       newidtr = t4bunpack (a);
  90.       a += size4b;
  91.       cadlj.npage = t2bunpack (a);
  92.       a += size2b;
  93.       cadlj.cm = t2bunpack (a);
  94.       if (cadlj.cm == 0)
  95. return (0);
  96.     }
  97.   r_tr (cadlj);
  98.   return (0);
  99. }
  100. static void
  101. mrollb_nftr(struct ADBL adfix, struct ADBL adstart, char *nftr, u2_t n)
  102. {
  103.   register u2_t i, NFTRANS, blsz;
  104.   register char *a, type;
  105.   struct ADBL cadlj;
  106.   i4_t cidtr, newidtr;
  107.   char *pnt, mas[RPAGE];
  108.   NFTRANS = n / size4b;
  109.   for (i = 0; i < NFTRANS; i++, nftr += size4b)
  110.     {
  111.       cidtr = t4bunpack (nftr);
  112.       newidtr = cidtr;
  113.       do
  114. {
  115.   cadlj = adstart;
  116.   blsz = LJ_prev (fdcurlj, &cadlj, &pnt, mas);
  117.   a = pnt;
  118.   type = *a++;
  119.   if (type == EOTLJ)
  120.     {
  121.       getmint (a, blsz - size1b);
  122.       continue;
  123.     }
  124.   newidtr = t4bunpack (a);
  125.   a += size4b;
  126. }
  127.       while (newidtr != cidtr);
  128.       mrllb_tr (cidtr, adfix, cadlj, blsz, a, type);
  129.     }
  130. }
  131. #define GET_OFFBEG()     
  132. {                             
  133.   if (N == 1)                 
  134.     offbeg = RTPAGE + RTJOUR; 
  135.   else                        
  136.     offbeg = RTPAGE;          
  137. }
  138. static int
  139. MJ_prev (i4_t fd, struct ADBL *adj, char **pnt, char *mas)
  140. {
  141.   u2_t N, offbeg, n, blsz, n1;
  142.   char *end_of_record;
  143.   N = adj->npage;
  144.   n = adj->cm;
  145.   GET_OFFBEG();
  146.   if (n == offbeg && N == 1)
  147.     {
  148.       *pnt = mjpage + RTPAGE;
  149.       return (0);
  150.     }
  151.   n -= offbeg;
  152.   if (n < RTBLK)
  153.     { /* the endtop-block places in two pages*/
  154.       char buff[size2b];
  155.       n1 = RTBLK - n;
  156.       bcopy (mjpage + RTPAGE, buff + n1, n);
  157.       N--;
  158.       read_page (fd, N, mjpage);
  159.       bcopy (mjpage + RPAGE - n1, buff, n1);
  160.       blsz = t2bunpack (buff);
  161.       end_of_record = mjpage + RPAGE - n1;
  162.       GET_OFFBEG();
  163.       n = RPAGE - offbeg - n1;
  164.     }
  165.   else
  166.     { /* the top-block places in (N)-page */
  167.       end_of_record = mjpage + offbeg + n - RTBLK;
  168.       blsz = t2bunpack (end_of_record);
  169.       n -= RTBLK;
  170.       if (n == 0)
  171.         {
  172.           N--;
  173.           read_page (fd, N, mjpage);
  174.           GET_OFFBEG();
  175.           n = RPAGE - offbeg;
  176.           end_of_record = mjpage + RPAGE;
  177.         }
  178.     }
  179.   assert (blsz < RPAGE);
  180.   if (n < blsz)
  181.     {               /* block-record places in two page */
  182.       n1 = blsz - n;
  183.       bcopy (mjpage + RTPAGE, mas + n1, n);
  184.       N--;
  185.       read_page (fd, N, mjpage);
  186.       GET_OFFBEG();
  187.       bcopy (mjpage + RPAGE - n1, mas, n1);
  188.       *pnt = mas;
  189.       n = RPAGE - offbeg - n1;
  190.     }
  191.   else
  192.     {
  193.        *pnt = end_of_record - blsz;
  194.        n -= blsz;
  195.        if (n == 0 && N != 1)
  196.          {
  197.            bcopy (*pnt, mas, blsz);
  198.            *pnt = mas;
  199.            N--;
  200.            read_page (fd, N, mjpage);
  201.            GET_OFFBEG();
  202.            n = RPAGE - offbeg;
  203.          }
  204.     }
  205.   adj->npage = N;
  206.   adj->cm = n + offbeg;
  207.   return (blsz);
  208. }
  209. static void
  210. get_last_page (i4_t fd, char *jpage, u2_t *pn)
  211. {     /* Search the last page of a journal */
  212.   i4_t PCP, RFILE;
  213.   u2_t N;
  214.   i4_t NV;
  215.   struct stat buf;
  216.   if (fstat (fd, &buf) < 0)
  217.     {
  218.       perror ("MCR.get_last_page: fstat");
  219.       exit (1);
  220.     }
  221.   RFILE = buf.st_size / (RPAGE);
  222.   N = *pn;
  223.   read_page (fd, N, jpage);
  224.   NV = t4bunpack (jpage);
  225.   while (N != RFILE)
  226.     {
  227.       PCP = *(jpage + size4b + size2b);
  228.       if (PCP == SIGN_NOCONT)
  229. break;
  230.       read_page (fd, ++N, jpage);
  231.       if (NV != t4bunpack (jpage))
  232. {
  233.   read_page (fd, --N, jpage);
  234.   break;
  235. }
  236.     }
  237.   *pn = N;
  238. }
  239. static struct ADBL 
  240. recov_mj (char *mj_name)
  241. {
  242.   register char *a, *b, *d, *asp, *beg;
  243.   struct ADBL adfix, cadmj;
  244.   i4_t idm, cidm;
  245.   u2_t sn, pn, fs, off, blsz, prevpn, size;
  246.   i2_t shsize;
  247.   char *pnt, type, prmod;
  248.   char mas[RPAGE];
  249.   struct A pg;
  250.   if ((fdmj = open (mj_name, O_RDWR, 0644)) < 0)
  251.     {
  252.       perror ("MCR: open current MJ");
  253.       exit (1);
  254.     }
  255.   pn = 1;
  256.   get_last_page (fdmj, mjpage, &pn);
  257.   cadmj.npage = pn;
  258.   cadmj.cm = t2bunpack (mjpage + size4b);
  259.   asp = NULL;
  260.   for (prevpn = (u2_t) ~ 0, prmod = 'n'; (blsz = MJ_prev (fdmj, &cadmj, &pnt, mas)) > 0;)
  261.     {
  262.       a = pnt;
  263.       while (blsz != 0)
  264. {
  265.   a += adjsize;
  266.   type = *a++;
  267.           assert (type == OLD || type == SHF || type == COMBR || type == COMBL);
  268.   idm = t4bunpack (a);
  269.   a += size4b;
  270.   sn = t2bunpack (a);
  271.           assert (sn != 0);
  272.   a += size2b;
  273.   pn = t2bunpack (a);
  274.   a += size2b;
  275.   if (pn != prevpn)
  276.     {
  277.       if (prevpn != (u2_t) ~ 0)
  278. putpg (&pg, prmod);
  279.       asp = getpg (&pg, sn, pn, 'x');
  280.       prmod = 'n';
  281.       prevpn = pn;
  282.     }
  283.   cidm = ((struct p_head *) asp)->idmod;
  284.   if (idm <= cidm)
  285.     prmod = 'm';
  286.   off = t2bunpack (a);
  287.   a += size2b;
  288.   fs = t2bunpack (a);
  289.   a += size2b;
  290.   size = adjsize + 1 + size4b + 4 * size2b;
  291.   if (type == OLD)
  292.     {
  293.       if (idm <= cidm)
  294.                 bcopy (a, asp + off, fs);
  295.               a += fs;
  296.       size += fs;
  297.     }
  298.   else
  299.     {
  300.       size += size2b;
  301.               shsize = t2bunpack (a);
  302.               a += size2b;
  303.               if (type == SHF)
  304.                 {
  305.                   if (idm <= cidm)
  306.                     {
  307.                       beg = asp + off;
  308.                       if (shsize < 0)
  309.                         {
  310.                           shsize = -shsize;
  311.                           bcopy (beg + shsize, beg, fs);
  312.                         }
  313.                       else
  314.                         {
  315.                           for (b = beg + fs - 1, d = b - shsize; fs != 0; fs--)
  316.                             *b-- = *d--;
  317.                         }
  318.                     }
  319.                 }
  320.       else 
  321. {
  322.   if (idm <= cidm)
  323.     {
  324.                       beg = asp + off;
  325.                       if (type == COMBR)
  326.                         {
  327.                           b = beg - fs;
  328.                           bcopy (b - shsize, b, fs);
  329.                         }
  330.                       else
  331.                         {
  332.                           for (b = beg + fs - 1, d = b + shsize; fs != 0; fs--)
  333.                             *d-- = *b--;
  334.                         }
  335.                       bcopy (a, beg, shsize);
  336.     }
  337.                   size += shsize;
  338.                   a += shsize;
  339. }
  340.     }
  341.   blsz -= size;
  342. }
  343.     }
  344.   if (prevpn != (u2_t) ~ 0)
  345.     putpg (&pg, prmod);
  346.   bcopy (pnt, (char *) &adfix, adjsize);
  347.   close (fdmj);
  348.   return (adfix);
  349. }
  350. static void
  351. ini_mcru (void)
  352. {
  353.   struct ADF adf;
  354.   i4_t fdaf;
  355.     /* Getting queue for MCR */
  356.   if ((msqidmcr = msgget (keymcr, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)
  357.     {
  358.       perror ("ADM: Getting queue for MCR");
  359.       exit (1);
  360.     }
  361.   if ((msqidm = msgget (keymj, DEFAULT_ACCESS_RIGHTS)) < 0)
  362.     {
  363.       perror ("MCR.msgget: Get queue for MJ");
  364.       exit (1);
  365.     }
  366.   if ((msqidl = msgget (keylj, DEFAULT_ACCESS_RIGHTS)) < 0)
  367.     {
  368.       perror ("MCR.msgget: Get queue for LJ");
  369.       exit (1);
  370.     }
  371.   if ((msqidb = msgget (keybf, DEFAULT_ACCESS_RIGHTS)) < 0)
  372.     {
  373.       perror ("MCR.ini_mcru.msgget: Get queue for BUF");
  374.       exit (1);
  375.     }
  376.   if ((fdaf = open (ADMFILE, O_RDWR, 0644)) < 0)
  377.     {
  378.       perror ("ADMFILE: open error");
  379.       exit (1);
  380.     }
  381.   if (read (fdaf, (char *) &adf, sizeof (struct ADF)) != sizeof (struct ADF))
  382.     {
  383.       perror ("ADMFILE: read error");
  384.       exit (1);
  385.     }
  386.   minidnt = 1;
  387.   close (fdaf);
  388. }
  389. static void
  390. mfrwrd_mtn (struct ADBL cadlj, struct ADBL last_adlj, char *idtr_pnt, u2_t n)
  391. {
  392.   char *a, type, *cur_idtr_pnt, *eo_idtr_pnt;
  393.   u2_t blsz;
  394.   i4_t cidtr;
  395.   char *pnt, mas[RPAGE];
  396.   eo_idtr_pnt = idtr_pnt + n;
  397.   while (cadlj.npage != last_adlj.npage || cadlj.cm != last_adlj.cm)
  398.     {
  399.       blsz = LJ_next (fdcurlj, &cadlj, &pnt, mas);
  400.       a = pnt;
  401.       type = *a++;
  402.       if (type == CPRLJ)
  403.         continue;
  404.       if (type == EOTLJ)
  405. {
  406.   getmint (a, blsz - size1b);
  407.   continue;
  408. }
  409.       idtr = t4bunpack (a);
  410.       for (cur_idtr_pnt = idtr_pnt; cur_idtr_pnt < eo_idtr_pnt; cur_idtr_pnt += size4b)
  411.         {
  412.           cidtr = t4bunpack (cur_idtr_pnt);
  413.           if (cidtr == idtr)
  414.             goto end;
  415.         }
  416.       forward_action (a + size4b, type, blsz - ljmsize);
  417.     end:;
  418.     }
  419. }
  420. int
  421. main (i4_t argc, char **argv)
  422. {
  423.   register char *a;
  424.   u2_t n, blsz;
  425.   struct ADBL cadlj, ladlj, adfix;
  426.   char type, *pnt, mas[RPAGE];
  427.   i4_t preot = 0, repl;
  428.   u2_t pn, s_sc_s;
  429.   struct msg_buf sbuf;
  430.   MEET_DEBUGGER;
  431.   
  432.   setbuf (stdout, NULL);
  433.   fprintf (stderr, "MCR.main.b: Memory Crash Recovery Utility is runningn");
  434.   sscanf (argv[3], "%d", &keymj);
  435.   sscanf (argv[4], "%d", &keylj);
  436.   sscanf (argv[5], "%d", &keybf);
  437.   sscanf (argv[6], "%d", &keymcr);
  438.   {
  439.     i4_t x;
  440.     sscanf (argv[7], "%d", &x);
  441.     s_sc_s=x;
  442.   }
  443.   trnum = CONSTTR;
  444.   S_SC_S = s_sc_s;
  445.   
  446.   TIFAM_SZ = 2;
  447.   TAB_IFAM = (struct ldesind **) xmalloc (TIFAM_SZ * sizeof (struct ldesind **));
  448.   TAB_IFAM[0] = NULL;
  449.   TAB_IFAM[1] = NULL;
  450.   tab_difam (1);
  451.   ljmsize = size1b + size4b + 2 * size2b + 2 * size2b + size2b + size4b + 2 * size2b;
  452.   scptab = (char **) xmalloc (chpsize * maxscan);
  453.   for (n = 0; (i2_t) n < maxscan; n++)
  454.     scptab[n] = NULL;
  455.   
  456. /*------------Recovery by MICROJ------------------*/
  457.   ini_mcru ();
  458.   adfix = recov_mj (argv[1]);
  459.   if (adfix.cm == 0)
  460.     goto end;
  461. /*------------Recovery by LOGJ------------------*/
  462. /* The search of the last EOTLJ from the end of LJ */
  463. /* If EOTLJ is after adfix, rollback unfinished transactions */
  464.   if ((fdcurlj = open (argv[2], O_RDWR, 0644)) < 0)
  465.     {
  466.       perror ("MCR: open current LJ");
  467.       exit (1);
  468.     }
  469.   pn = adfix.npage;
  470.   get_last_page (fdcurlj, ljpage, &pn);
  471.   adlj.npage = pn;
  472.   adlj.cm = t2bunpack (ljpage + size4b);
  473.   cadlj = adlj;
  474.   while ( cadlj.npage != adfix.npage || cadlj.cm != adfix.cm)
  475.     {
  476.       blsz = LJ_prev (fdcurlj, &cadlj, &pnt, mas);
  477.       a = pnt;
  478.       type = *a++;
  479.       if (type == EOTLJ)
  480. {
  481.   preot = 1;
  482.   ladlj = cadlj;
  483.   getmint (a, blsz - size1b);
  484.   n = blsz - size1b;
  485.   mrollb_nftr (adfix, cadlj, a, n);
  486.           mfrwrd_mtn (adfix, ladlj, a, n);
  487.   break;
  488. }
  489.     }
  490.   if (preot == 0)
  491.     ladlj = bmtn_feot (fdcurlj, adfix);
  492.   rcv_wmlj (&ladlj); /* The record about global rollback */
  493.   rcv_ini_lj ();
  494.   repl = LOGJ_FIX ();
  495.   dubl_segs ();
  496. end:
  497.   /*  ini_mj (argv[1]);*/
  498.   sbuf.mtype = ANSADM;
  499.   sbuf.mtext[0] = 0;
  500.   if (msgsnd (msqidmcr, (MSGBUFP)&sbuf, 1, 0) < 0)
  501.     {
  502.       perror ("MCR.msgsnd: Answer ADM");
  503.       exit (1);
  504.     }
  505.   fprintf (stderr, "MCR: Memory Crash Recovery has finished successfullyn");
  506.   sleep (1);
  507.   return 0;
  508. }