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

SQL Server

开发平台:

Unix_Linux

  1. /*  strgcr.c  - Storage 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: strgcr.c,v 1.247 1997/03/31 12:24:55 kml Exp $ */
  28. #include "setup_os.h"
  29. #include "xmem.h"
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <signal.h>
  33. #if HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #include <assert.h>
  37. #if HAVE_DIRENT_H
  38. # include <dirent.h>
  39. # define NAMLEN(dirent) strlen((dirent)->d_name)
  40. #else
  41. # define dirent direct
  42. # define NAMLEN(dirent) (dirent)->d_namlen
  43. # if HAVE_SYS_NDIR_H
  44. #  include <sys/ndir.h>
  45. # endif
  46. # if HAVE_SYS_DIR_H
  47. #  include <sys/dir.h>
  48. # endif
  49. # if HAVE_NDIR_H
  50. #  include <ndir.h>
  51. # endif
  52. #endif
  53. #if HAVE_FCNTL_H
  54. #include <fcntl.h>
  55. #endif
  56. #include <sys/ipc.h>
  57. #include <sys/msg.h>
  58. #include <sys/shm.h>
  59. #if HAVE_SYS_WAIT_H
  60. # include <sys/wait.h>
  61. #endif
  62. #ifndef WEXITSTATUS
  63. # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
  64. #endif
  65. #ifndef WIFEXITED
  66. # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
  67. #endif
  68. #include "destrn.h"
  69. #include "strml.h"
  70. #include "puprcv.h"
  71. #include "fdclrcv.h"
  72. #include "f1f2decl.h"
  73. #include "admdef.h"
  74. #include "adfstr.h"
  75. /**************************************************************/
  76. #define  adfsize sizeof(struct ADF)
  77. i4_t fdcurlj;
  78. i4_t fd_lj;
  79. i4_t msqidscr, msqidl, msqidm, msqidb;
  80. pid_t pidlj, pidmj, pidbf;
  81. key_t keyscr, keylj, keymj, keybf;
  82. u2_t RJZm, RJZl, MPAGEm, MPAGEl;
  83. i4_t OPTBUFNUM, MAXNBUF, MAXTACT;
  84. key_t FSEGNUM;
  85. i4_t MAXTRANS;
  86. pid_t strcr_pid;
  87. u2_t trnum;
  88. extern CPNM curcpn;
  89. char **scptab;
  90. extern i2_t maxscan;
  91. unsigned ljmsize;
  92. u2_t S_SC_S;
  93. i4_t minidnt;
  94. struct ldesind **TAB_IFAM;
  95. i4_t TIFAM_SZ;
  96. #define ARG(num, what) argum = (i4_t)(what);            
  97.                        sprintf (args[num], "%d", argum)
  98. static void
  99. ini_pupsi (void)
  100. {
  101.   char *args[20], mch[20][20];
  102.   i4_t fdto, i;
  103.   i4_t argum;  
  104.   for (i = 0; i < 20; i++)
  105.     args[i] = mch[i];
  106. /*---------------INI MICROJ------------------------------*/
  107.   if ((pidmj = fork ())< 0)
  108.     {
  109.       perror ("fork MJ");
  110.       exit (1);
  111.     }
  112.   if (pidmj == 0)
  113.     {
  114.       args[0] = MJ;
  115.       args[1] = MJFILE;
  116.       sprintf (args[2], "%d", (i4_t)RJZm);
  117.       sprintf (args[3], "%d", (i4_t)MPAGEm);
  118.       sprintf (args[4], "%d", (i4_t)keymj);
  119.       sprintf (args[5], "%d", (i4_t)keylj);
  120.       args[6] = NULL;
  121.       execvp (*args, args);
  122.       perror ("SCR.INI: MJ doesn't exec");
  123.       exit (1);
  124.     }
  125.   MSG_INIT (msqidm, keymj, "MJ");
  126.   
  127. /*----------------INI BUFFER----------------------*/
  128.   if ((fdto = creat (SEG0, DEFAULT_ACCESS_RIGHTS)) < 0)
  129.     {
  130.       perror (SEG0);
  131.       exit (1);
  132.     }
  133.   if ((pidbf = fork ())< 0)
  134.     {
  135.       perror ("fork BUF");
  136.       exit (1);
  137.     }
  138.   if (pidbf == 0)
  139.     {
  140.       struct dirent *dir;
  141.       DIR *dp;
  142.       i4_t seg_num;
  143.       char name_BD_seg[1024];
  144.       args[0] = BUF;
  145.       args[1] = SEG0;
  146.       ARG (2, keybf);
  147.       ARG (3, keymj);
  148.       ARG (4, OPTBUFNUM);
  149.       ARG (5, MAXNBUF);
  150.       ARG (6, MAXTACT);
  151.       ARG (7, MAXTRANS);
  152.       /* the first numeric name of the shared memory segment for PUPSI */
  153.       ARG (8, FSEGNUM);
  154.       /* BD segments numbers and names */
  155.       if ((dp = opendir (DIR_SEGS)) == NULL)
  156. {
  157.   fprintf (stderr, "SCR: %s cannot openn", DIR_SEGS);
  158.   exit (1);
  159. }
  160.       dir = readdir (dp);
  161.       dir = readdir (dp);
  162.       for (i = 9; (dir = readdir (dp)) != NULL; i += 2)
  163. {
  164.   if (dir->d_ino == 0)
  165.     continue;
  166.   args[i] = dir->d_name + 3;
  167.           seg_num = atoi (args[i]);
  168.           ARG (i, seg_num);
  169.   sprintf (args[i + 1], "%s/%s", DIR_SEGS, dir->d_name);
  170.           printf ("SCR.ini_pupsi: name = %s, segnum = %dn", args[i + 1], seg_num);
  171. }
  172.       printf ("SCR.ini_pupsi: i = %dn", i);    
  173.       if (i == 9)           /* no at all segments */
  174.         {
  175.           strcpy (name_BD_seg, DIR_SEGS);
  176.           strcat (name_BD_seg, "/seg1");
  177.           ini_BD_seg (name_BD_seg, S_SC_S);
  178.           sprintf (args[9], "%d", 1);
  179.           args[10] = name_BD_seg;
  180.           i += 2;
  181.         }
  182.       closedir (dp);
  183.       sprintf (args[i], "%d", (i4_t)strcr_pid);
  184.       args[i + 1] = NULL;
  185.       execvp (*args, args);
  186.       perror ("SCR.INI: BUF doesn't exec");
  187.       exit (1);
  188.     }
  189.   MSG_INIT (msqidb, keybf, "BUF");
  190.   
  191. /*-------------OPEN/INI LOGJ--------------------------*/
  192.   if ((fd_lj = open (LJFILE, O_RDWR, 0644)) < 0)
  193.     {
  194.       ini_lj (LJFILE);
  195.       if ((fd_lj = open (LJFILE, O_RDWR, 0644)) < 0)
  196.         {      
  197.           perror ("LJ: open");
  198.           exit (1);
  199.         }
  200.     }
  201.   if ((pidlj = fork ())< 0)
  202.     {
  203.       perror ("fork LJ");
  204.       exit (1);
  205.     }
  206.   if (pidlj == 0)
  207.     {
  208.       args[0] = LJ;
  209.       sprintf (args[1], "%d", fd_lj);
  210.       sprintf (args[2], "%d", (i4_t)RJZl);
  211.       sprintf (args[3], "%d", (i4_t)MPAGEl);
  212.       sprintf (args[4], "%d", (i4_t)keylj);
  213.       sprintf (args[5], "%d", (i4_t)keybf);
  214.       sprintf (args[6], "%d", (i4_t)keyscr);      
  215.       args[7] = NULL;
  216.       execvp (*args, args);
  217.       perror ("SCR.INI: LJ doesn't exec");
  218.       exit (1);
  219.     }
  220.   MSG_INIT (msqidl, keylj, "LJ");
  221. }
  222. static int
  223. fin_pupsi (void)
  224. {
  225.   i4_t rep, repm, repb, repl, cd, i;
  226.   struct msg_buf sbuf, rbuf;
  227.   struct msqid_ds msqidds;
  228.   repl = LOGJ_FIX ();
  229.   cd = close (fdcurlj);
  230.   sbuf.mtype = FINIT;
  231.   if (msgsnd (msqidm, (void *) &sbuf, 0, 0) < 0)
  232.     {
  233.       perror ("SCR.msgsnd: MJ->FINIT");
  234.       exit (1);
  235.     }
  236.   if (msgrcv (msqidm, (void *) &rbuf, 1, ANSMJ, 0) < 0)
  237.     {
  238.       perror ("SCR.msgrcv: FINIT MJ");
  239.       exit (1);
  240.     }
  241.   repm = *rbuf.mtext;
  242.   if (msgsnd (msqidb, (void *) &sbuf, 0, 0) < 0)
  243.     {
  244.       perror ("SCR.msgsnd: BUF->FINIT");
  245.       exit (1);
  246.     }
  247.   if (msgrcv (msqidb, (void *) &rbuf, 1, ANSBUF, 0) < 0)
  248.     {
  249.       perror ("SCR.msgrcv: FINIT BUF");
  250.       exit (1);
  251.     }
  252.   repb = *rbuf.mtext;
  253.   i = msgctl (msqidl, IPC_RMID, &msqidds);
  254.   i = msgctl (msqidm, IPC_RMID, &msqidds);
  255.   i = msgctl (msqidb, IPC_RMID, &msqidds);
  256.   if (cd == 0 && repm == 0 && repb == 0 && repl == 0)
  257.     rep = 0;
  258.   else
  259.     rep = -1;
  260.   kill (pidlj, SIGKILL);
  261.   kill (pidmj, SIGKILL);
  262.   kill (pidbf, SIGKILL);
  263.   return (rep);
  264. }
  265. static void
  266. open_cur_lj (char *file_name)
  267. {
  268.   if ( (fdcurlj = open (file_name, O_RDWR, 0644)) < 0)
  269.     {
  270.       printf ("current LJ: open %s", file_name);
  271.       perror ("current LJ: open");
  272.       exit (1);
  273.     }
  274.   printf ("current LJ  %s  fdcurlj = %dn", file_name, fdcurlj);  
  275. }
  276. static key_t
  277. get_msg_key(void)   /* this function has a complete static copy in adm.c */
  278. {
  279.   static key_t k = (key_t)-2;
  280.   if (k==(key_t)-2)
  281. #if HAVE_FTOK
  282.     k = ftok(MJ, (getpid()&0xff));
  283. #else
  284.     k = FIRSTMQN;
  285. #endif
  286.   errno = 0;
  287.   for(;;)
  288.     {
  289.       if ( msgget (k, DEFAULT_ACCESS_RIGHTS) < 0 )
  290.         if (errno == ENOENT)
  291.           return k++;
  292.         else if (errno == ENOSPC)
  293.           return -1;
  294.       k++;
  295.     }
  296. }
  297. void
  298. main (void)
  299. {
  300.   struct ADBL cadlj, ladlj;
  301.   char *dname;
  302.   i4_t fdaf, segnum, n;
  303.   struct ADF p2;
  304.   DIR *dp;
  305.   struct dirent *dir;
  306.   struct msqid_ds msqidds;
  307.   char name[1024];
  308.   setbuf (stdout, NULL);
  309.   
  310.   ljmsize = size1b + size4b + 2 * size2b + 2 * size2b + size2b + size4b + 2 * size2b;
  311.   scptab = (char **) xmalloc (chpsize * maxscan);
  312.   for (n = 0; n < maxscan; n++)
  313.     scptab[n] = NULL;
  314.   trnum = CONSTTR;
  315.   strcr_pid = getpid();
  316. /*------------- Copy BD's segments ---------------*/
  317.   if ((segnum = dir_copy (DIR_REP_SEGS, DIR_SEGS)) < 0)
  318.     fprintf (stderr, "SCR: Can't copy SEGSn");
  319. /*------------OPEN AND READ ADMFILE------------------*/
  320.   if ((fdaf = open (ADMFILE, O_RDWR, 0644)) < 0)
  321.     {
  322.       ini_adm_file (ADMFILE);
  323.       if ((fdaf = open (ADMFILE, O_RDWR, 0644)) < 0)
  324.         {      
  325.           perror ("ADMFILE: open error");
  326.           exit (1);
  327.         }
  328.     }
  329.   if (read (fdaf, (char *) &p2, adfsize) != adfsize)
  330.     {
  331.       perror ("ADMFILE: read error");
  332.       exit (1);
  333.     }
  334.   minidnt = 1;
  335.   MAXTRANS = p2.maxtrans;
  336.   RJZm = p2.mjred;
  337.   RJZl = p2.ljred;
  338.   MPAGEm = p2.mjmpage;
  339.   MPAGEl = p2.ljmpage;
  340.   S_SC_S = p2.sizesc;
  341.   OPTBUFNUM = p2.optbufnum;
  342.   MAXNBUF = p2.maxnbuf;
  343.   MAXTACT = p2.maxtact;
  344.   FSEGNUM = p2.fshmsegn;
  345.   
  346.   TIFAM_SZ = 2;
  347.   TAB_IFAM = (struct ldesind **) xmalloc (TIFAM_SZ * sizeof (struct ldesind **));
  348.   TAB_IFAM[0] = NULL;
  349.   TAB_IFAM[1] = NULL;
  350.   tab_difam (1);
  351.   
  352.   keyscr  = get_msg_key();  
  353.   keylj   = get_msg_key();
  354.   keymj   = get_msg_key();
  355.   keybf   = get_msg_key();
  356.   /* Getting queue for rcvsc */
  357.   if ((msqidscr = msgget (keyscr, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)
  358.     {
  359.       perror ("SCR: Getting queue for rcvsc");
  360.       exit (1);
  361.     }  
  362. /*------------Recovery by LJ's repository------------------*/
  363.   if ((dp = opendir (DIR_REP_LJS)) == NULL)
  364.     {
  365.       fprintf (stderr, "SCR: %s cannot openn", DIR_REP_LJS);
  366.       exit (1);
  367.     }
  368.   dir = readdir (dp);
  369.   dir = readdir (dp);
  370.   while ((dir = readdir (dp)) != NULL)
  371.     {
  372.       if (dir->d_ino == 0)
  373. continue;
  374.       dname = dir->d_name;
  375.       copy (dname, DIR_REP_LJS, DIR_JOUR);
  376.       ini_pupsi ();
  377.       strcpy (name, DIR_JOUR);
  378.       strcat (name, "/");
  379.       strcat (name, dname);
  380.       open_cur_lj (name);
  381.       cadlj = frwdmtn ();
  382.       fin_pupsi ();
  383.       dubl_segs ();
  384.       if (unlink (name) < 0)
  385. {
  386.   fprintf (stderr, "SCR: %s cannot deleten", name);
  387.   exit (1);
  388. }
  389.     }
  390.   closedir (dp);
  391.   ini_pupsi ();
  392.   fdcurlj = fd_lj;
  393.   cadlj = frwdmtn ();
  394.   ladlj = bmtn_feot (fdcurlj, cadlj);
  395.   close (fdaf);
  396.   rcv_wmlj (&ladlj); /* The record about global rollback */
  397.   fin_pupsi ();
  398.   dubl_segs ();
  399.   msgctl (msqidscr, IPC_RMID, &msqidds);  
  400.   fprintf (stderr, "SCR: Storage Crash Recovery has finished successfullyn");
  401. }