⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memcr.c

📁 免费的Sql数据库系统
💻 C
字号:
/*  memcr.c  - Memory Crash Recovery Utility *             Kernel of GNU SQL-server. Recovery utilities     * *  This file is a part of GNU SQL Server * *  Copyright (c) 1996, 1997, Free Software Foundation, Inc *  Developed at the Institute of System Programming *  This file is written by  Vera Ponomarenko * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *  Contacts:   gss@ispras.ru * *//* $Id: memcr.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */#include "setup_os.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/uio.h>#if HAVE_UNISTD_H #include <unistd.h>#endif#if HAVE_FCNTL_H #include <fcntl.h>#endif#include <sys/ipc.h>#include <sys/msg.h>#include <assert.h>#include "destrn.h"#include "strml.h"#include "admdef.h"#include "adfstr.h"#include "fdclrcv.h"#include "xmem.h"key_t keylj, keymj, keybf, keymcr;i4_t msqidmcr, msqidl, msqidm, msqidb;i4_t fdmj, fdcurlj;u2_t trnum;extern CPNM curcpn;char **scptab;extern i2_t maxscan;unsigned ljmsize;u2_t S_SC_S;char mjpage[RPAGE], ljpage[RPAGE];i4_t minidnt;extern struct ADREC bllj;extern i4_t idtr;extern struct ADBL adlj;struct ldesind **TAB_IFAM;i4_t TIFAM_SZ;static intmrllb_tr(i4_t cidtr, struct ADBL adfix, struct ADBL cadlj, u2_t blsz, char *a,         char type){  i4_t newidtr;  idtr = cidtr;  if (cadlj.npage <= adfix.npage && cadlj.cm <= adfix.cm)    {      cadlj.npage = t2bunpack (a);      a += size2b;      cadlj.cm = t2bunpack (a);      a += size2b;      backactn (blsz, a, type);    }  while (cadlj.npage >= adfix.npage || cadlj.cm > adfix.cm)    {      rcv_LJ_GETREC (&bllj, &cadlj);      a = bllj.block;      type = *a++;      if (type == GRLBLJ)	continue;      if (type == EOTLJ)	{	  getmint (a, bllj.razm - size1b);	  continue;	}      newidtr = t4bunpack (a);      a += size4b;      cadlj.npage = t2bunpack (a);      a += size2b;      cadlj.cm = t2bunpack (a);      if (cadlj.cm == 0)	return (0);    }  r_tr (cadlj);  return (0);}static voidmrollb_nftr(struct ADBL adfix, struct ADBL adstart, char *nftr, u2_t n){  register u2_t i, NFTRANS, blsz;  register char *a, type;  struct ADBL cadlj;  i4_t cidtr, newidtr;  char *pnt, mas[RPAGE];  NFTRANS = n / size4b;  for (i = 0; i < NFTRANS; i++, nftr += size4b)    {      cidtr = t4bunpack (nftr);      newidtr = cidtr;      do	{	  cadlj = adstart;	  blsz = LJ_prev (fdcurlj, &cadlj, &pnt, mas);	  a = pnt;	  type = *a++;	  if (type == EOTLJ)	    {	      getmint (a, blsz - size1b);	      continue;	    }	  newidtr = t4bunpack (a);	  a += size4b;	}      while (newidtr != cidtr);      mrllb_tr (cidtr, adfix, cadlj, blsz, a, type);    }}#define GET_OFFBEG()     \{                             \  if (N == 1)                 \    offbeg = RTPAGE + RTJOUR; \  else                        \    offbeg = RTPAGE;          \}static intMJ_prev (i4_t fd, struct ADBL *adj, char **pnt, char *mas){  u2_t N, offbeg, n, blsz, n1;  char *end_of_record;  N = adj->npage;  n = adj->cm;  GET_OFFBEG();  if (n == offbeg && N == 1)    {      *pnt = mjpage + RTPAGE;      return (0);    }  n -= offbeg;  if (n < RTBLK)    {				/* the endtop-block places in two pages*/      char buff[size2b];      n1 = RTBLK - n;      bcopy (mjpage + RTPAGE, buff + n1, n);      N--;      read_page (fd, N, mjpage);      bcopy (mjpage + RPAGE - n1, buff, n1);      blsz = t2bunpack (buff);      end_of_record = mjpage + RPAGE - n1;      GET_OFFBEG();      n = RPAGE - offbeg - n1;    }  else    {				/* the top-block places in (N)-page */      end_of_record = mjpage + offbeg + n - RTBLK;      blsz = t2bunpack (end_of_record);      n -= RTBLK;      if (n == 0)        {          N--;          read_page (fd, N, mjpage);          GET_OFFBEG();          n = RPAGE - offbeg;          end_of_record = mjpage + RPAGE;        }    }  assert (blsz < RPAGE);  if (n < blsz)    {               /* block-record places in two page */      n1 = blsz - n;      bcopy (mjpage + RTPAGE, mas + n1, n);      N--;      read_page (fd, N, mjpage);      GET_OFFBEG();      bcopy (mjpage + RPAGE - n1, mas, n1);      *pnt = mas;      n = RPAGE - offbeg - n1;    }  else    {       *pnt = end_of_record - blsz;       n -= blsz;       if (n == 0 && N != 1)         {           bcopy (*pnt, mas, blsz);           *pnt = mas;           N--;           read_page (fd, N, mjpage);           GET_OFFBEG();           n = RPAGE - offbeg;         }    }  adj->npage = N;  adj->cm = n + offbeg;  return (blsz);}static voidget_last_page (i4_t fd, char *jpage, u2_t *pn)	{     /* Search the last page of a journal */  i4_t PCP, RFILE;  u2_t N;  i4_t NV;  struct stat buf;  if (fstat (fd, &buf) < 0)    {      perror ("MCR.get_last_page: fstat");      exit (1);    }  RFILE = buf.st_size / (RPAGE);  N = *pn;  read_page (fd, N, jpage);  NV = t4bunpack (jpage);  while (N != RFILE)    {      PCP = *(jpage + size4b + size2b);      if (PCP == SIGN_NOCONT)	break;      read_page (fd, ++N, jpage);      if (NV != t4bunpack (jpage))	{	  read_page (fd, --N, jpage);	  break;	}    }  *pn = N;}static struct ADBL recov_mj (char *mj_name){  register char *a, *b, *d, *asp, *beg;  struct ADBL adfix, cadmj;  i4_t idm, cidm;  u2_t sn, pn, fs, off, blsz, prevpn, size;  i2_t shsize;  char *pnt, type, prmod;  char mas[RPAGE];  struct A pg;  if ((fdmj = open (mj_name, O_RDWR, 0644)) < 0)    {      perror ("MCR: open current MJ");      exit (1);    }  pn = 1;  get_last_page (fdmj, mjpage, &pn);  cadmj.npage = pn;  cadmj.cm = t2bunpack (mjpage + size4b);  asp = NULL;  for (prevpn = (u2_t) ~ 0, prmod = 'n'; (blsz = MJ_prev (fdmj, &cadmj, &pnt, mas)) > 0;)    {      a = pnt;      while (blsz != 0)	{	  a += adjsize;	  type = *a++;          assert (type == OLD || type == SHF || type == COMBR || type == COMBL);	  idm = t4bunpack (a);	  a += size4b;	  sn = t2bunpack (a);          assert (sn != 0);	  a += size2b;	  pn = t2bunpack (a);	  a += size2b;	  if (pn != prevpn)	    {	      if (prevpn != (u2_t) ~ 0)		putpg (&pg, prmod);	      asp = getpg (&pg, sn, pn, 'x');	      prmod = 'n';	      prevpn = pn;	    }	  cidm = ((struct p_head *) asp)->idmod;	  if (idm <= cidm)	    prmod = 'm';	  off = t2bunpack (a);	  a += size2b;	  fs = t2bunpack (a);	  a += size2b;	  size = adjsize + 1 + size4b + 4 * size2b;	  if (type == OLD)	    {	      if (idm <= cidm)                bcopy (a, asp + off, fs);              a += fs;	      size += fs;	    }	  else	    {	      size += size2b;              shsize = t2bunpack (a);              a += size2b;              if (type == SHF)                {                  if (idm <= cidm)                    {                      beg = asp + off;                      if (shsize < 0)                        {                          shsize = -shsize;                          bcopy (beg + shsize, beg, fs);                        }                      else                        {                          for (b = beg + fs - 1, d = b - shsize; fs != 0; fs--)                            *b-- = *d--;                        }                    }                }	      else 		{		  if (idm <= cidm)		    {                      beg = asp + off;                      if (type == COMBR)                        {                          b = beg - fs;                          bcopy (b - shsize, b, fs);                        }                      else                        {                          for (b = beg + fs - 1, d = b + shsize; fs != 0; fs--)                            *d-- = *b--;                        }                      bcopy (a, beg, shsize);		    }                  size += shsize;                  a += shsize;		}	    }	  blsz -= size;	}    }  if (prevpn != (u2_t) ~ 0)    putpg (&pg, prmod);  bcopy (pnt, (char *) &adfix, adjsize);  close (fdmj);  return (adfix);}static voidini_mcru (void){  struct ADF adf;  i4_t fdaf;    /* Getting queue for MCR */  if ((msqidmcr = msgget (keymcr, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)    {      perror ("ADM: Getting queue for MCR");      exit (1);    }  if ((msqidm = msgget (keymj, DEFAULT_ACCESS_RIGHTS)) < 0)    {      perror ("MCR.msgget: Get queue for MJ");      exit (1);    }  if ((msqidl = msgget (keylj, DEFAULT_ACCESS_RIGHTS)) < 0)    {      perror ("MCR.msgget: Get queue for LJ");      exit (1);    }  if ((msqidb = msgget (keybf, DEFAULT_ACCESS_RIGHTS)) < 0)    {      perror ("MCR.ini_mcru.msgget: Get queue for BUF");      exit (1);    }  if ((fdaf = open (ADMFILE, O_RDWR, 0644)) < 0)    {      perror ("ADMFILE: open error");      exit (1);    }  if (read (fdaf, (char *) &adf, sizeof (struct ADF)) != sizeof (struct ADF))    {      perror ("ADMFILE: read error");      exit (1);    }  minidnt = 1;  close (fdaf);}static voidmfrwrd_mtn (struct ADBL cadlj, struct ADBL last_adlj, char *idtr_pnt, u2_t n){  char *a, type, *cur_idtr_pnt, *eo_idtr_pnt;  u2_t blsz;  i4_t cidtr;  char *pnt, mas[RPAGE];  eo_idtr_pnt = idtr_pnt + n;  while (cadlj.npage != last_adlj.npage || cadlj.cm != last_adlj.cm)    {      blsz = LJ_next (fdcurlj, &cadlj, &pnt, mas);      a = pnt;      type = *a++;      if (type == CPRLJ)        continue;      if (type == EOTLJ)	{	  getmint (a, blsz - size1b);	  continue;	}      idtr = t4bunpack (a);      for (cur_idtr_pnt = idtr_pnt; cur_idtr_pnt < eo_idtr_pnt; cur_idtr_pnt += size4b)        {          cidtr = t4bunpack (cur_idtr_pnt);          if (cidtr == idtr)            goto end;        }      forward_action (a + size4b, type, blsz - ljmsize);    end:;    }}intmain (i4_t argc, char **argv){  register char *a;  u2_t n, blsz;  struct ADBL cadlj, ladlj, adfix;  char type, *pnt, mas[RPAGE];  i4_t preot = 0, repl;  u2_t pn, s_sc_s;  struct msg_buf sbuf;  MEET_DEBUGGER;    setbuf (stdout, NULL);  fprintf (stderr, "MCR.main.b: Memory Crash Recovery Utility is running\n");  sscanf (argv[3], "%d", &keymj);  sscanf (argv[4], "%d", &keylj);  sscanf (argv[5], "%d", &keybf);  sscanf (argv[6], "%d", &keymcr);  {    i4_t x;    sscanf (argv[7], "%d", &x);    s_sc_s=x;  }  trnum = CONSTTR;  S_SC_S = s_sc_s;    TIFAM_SZ = 2;  TAB_IFAM = (struct ldesind **) xmalloc (TIFAM_SZ * sizeof (struct ldesind **));  TAB_IFAM[0] = NULL;  TAB_IFAM[1] = NULL;  tab_difam (1);  ljmsize = size1b + size4b + 2 * size2b + 2 * size2b + size2b + size4b + 2 * size2b;  scptab = (char **) xmalloc (chpsize * maxscan);  for (n = 0; (i2_t) n < maxscan; n++)    scptab[n] = NULL;  /*------------Recovery by MICROJ------------------*/  ini_mcru ();  adfix = recov_mj (argv[1]);  if (adfix.cm == 0)    goto end;/*------------Recovery by LOGJ------------------*//* The search of the last EOTLJ from the end of LJ *//* If EOTLJ is after adfix, rollback unfinished transactions */  if ((fdcurlj = open (argv[2], O_RDWR, 0644)) < 0)    {      perror ("MCR: open current LJ");      exit (1);    }  pn = adfix.npage;  get_last_page (fdcurlj, ljpage, &pn);  adlj.npage = pn;  adlj.cm = t2bunpack (ljpage + size4b);  cadlj = adlj;  while ( cadlj.npage != adfix.npage || cadlj.cm != adfix.cm)    {      blsz = LJ_prev (fdcurlj, &cadlj, &pnt, mas);      a = pnt;      type = *a++;      if (type == EOTLJ)	{	  preot = 1;	  ladlj = cadlj;	  getmint (a, blsz - size1b);	  n = blsz - size1b;	  mrollb_nftr (adfix, cadlj, a, n);          mfrwrd_mtn (adfix, ladlj, a, n);	  break;	}    }  if (preot == 0)    ladlj = bmtn_feot (fdcurlj, adfix);  rcv_wmlj (&ladlj);		/* The record about global rollback */  rcv_ini_lj ();  repl = LOGJ_FIX ();  dubl_segs ();end:  /*  ini_mj (argv[1]);*/  sbuf.mtype = ANSADM;  sbuf.mtext[0] = 0;  if (msgsnd (msqidmcr, (MSGBUFP)&sbuf, 1, 0) < 0)    {      perror ("MCR.msgsnd: Answer ADM");      exit (1);    }  fprintf (stderr, "MCR: Memory Crash Recovery has finished successfully\n");  sleep (1);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -