Beispiel #1
0
void intern menuevent( VSCREEN *vptr )
/************************************/
{
    register    EVENT                   newevent;
    register    EVENT                   ev;

    newevent = EV_NO_EVENT;

    if ( InitMenuPopupPending ) {
        InitMenuPopupPending = FALSE;
        if( Menu->titles[ Menu->menu - 1].popup != NULL ) {
            newevent = EV_MENU_INITPOPUP;
        }
    }

    if( newevent == EV_NO_EVENT ) {
        if ( uimenuson() && !uimenuisdisabled() ) {
            uipushlist( menu_list );
            if( ( Menu->active == FALSE ) || isdialogue( vptr ) ) {
                ev = getprime( vptr );
            } else {
                ev = getprime( NULL );
            }
            switch( ev ) {
            case EV_SCROLL_PRESS:
                Menu->scroll = TRUE;
                break;
            case EV_SCROLL_RELEASE:
                Menu->scroll = FALSE;
                break;
            case EV_NUM_PRESS:
                Menu->num = TRUE;
                break;
            case EV_NUM_RELEASE:
                Menu->num = FALSE;
                break;
            case EV_CAPS_PRESS:
                Menu->caps = TRUE;
                break;
            case EV_CAPS_RELEASE:
                Menu->caps = FALSE;
                break;
            default:
                newevent = process_menuevent( vptr, ev );
            }
            uipoplist();
        } else {
            newevent = getprime( vptr );
        }
    }

    Event = newevent;
}
int cce_sec_size(gds_file_id *file)
{
	uint4			status;
	int			size;
	short			iosb[4];
	sgmnt_data		sd;
	sgmnt_data_ptr_t	csd = &sd;
	char			expanded_file_name[MAX_FN_LEN];
	struct FAB		fab;
	struct NAM		nam;
	int			buckets;

	fab = cc$rms_fab;
	fab.fab$l_fop = FAB$M_NAM | FAB$M_UFO;
	fab.fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_BIO;
	fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
	fab.fab$l_nam = &nam;
	nam = cc$rms_nam;
	nam.nam$b_ess = MAX_FN_LEN;
	nam.nam$l_esa = expanded_file_name;
	memcpy(nam.nam$t_dvi, file->dvi,file->dvi[0] + 1);
	memcpy(nam.nam$w_fid, file->fid, SIZEOF(file->fid));
	status = sys$open(&fab, 0, 0);
	if (!(status & 1))
		return 0;
	status = sys$qiow(EFN$C_ENF,fab.fab$l_stv, IO$_READVBLK, &iosb[0], 0,0, csd, SIZEOF(sgmnt_data), 1,0,0,0);
	if (!(status & 1))
		return 0;
	buckets = getprime(sd.n_bts);
	size = (LOCK_BLOCK(csd) * DISK_BLOCK_SIZE) + LOCK_SPACE_SIZE(csd) + CACHE_CONTROL_SIZE(csd) + NODE_LOCAL_SPACE(csd)
			+ JNL_SHARE_SIZE(csd);
	sys$dassgn(fab.fab$l_stv);
	return size / OS_PAGELET_SIZE;
}
Beispiel #3
0
void
compute_s (mpz_t s, unsigned long B1)
{
  mpz_t acc[MAX_HEIGHT]; /* To accumulate products of prime powers */
  unsigned int i, j;
  unsigned long pi = 2, pp, maxpp;

  ASSERT_ALWAYS (B1 < MAX_B1_BATCH);

  for (j = 0; j < MAX_HEIGHT; j++)
    mpz_init (acc[j]); /* sets acc[j] to 0 */

  i = 0;
  while (pi <= B1)
    {
      pp = pi;
      maxpp = B1 / pi;
      while (pp <= maxpp)
          pp *= pi;

      if ((i & 1) == 0)
          mpz_set_ui (acc[0], pp);
      else
          mpz_mul_ui (acc[0], acc[0], pp);
			
      j = 0;
      /* We have accumulated i+1 products so far. If bits 0..j of i are all
         set, then i+1 is a multiple of 2^(j+1). */
      while ((i & (1 << j)) != 0)
        {
          /* we use acc[MAX_HEIGHT-1] as 0-sentinel below, thus we need
             j+1 < MAX_HEIGHT-1 */
          ASSERT (j + 1 < MAX_HEIGHT - 1);
          if ((i & (1 << (j + 1))) == 0) /* i+1 is not multiple of 2^(j+2),
                                            thus add[j+1] is "empty" */
            mpz_swap (acc[j+1], acc[j]); /* avoid a copy with mpz_set */
          else
            mpz_mul (acc[j+1], acc[j+1], acc[j]); /* accumulate in acc[j+1] */
          mpz_set_ui (acc[j], 1);
          j++;
        }

      i++;
      pi = getprime (pi);
    }

  for (mpz_set (s, acc[0]), j = 1; mpz_cmp_ui (acc[j], 0) != 0; j++)
    mpz_mul (s, s, acc[j]);
  getprime_clear (); /* free the prime tables, and reinitialize */
  
  for (i = 0; i < MAX_HEIGHT; i++)
      mpz_clear (acc[i]);
}
Beispiel #4
0
int main() {
    getprime();
    while (~scanf("%I64d%I64d", &n, &k)) {
	if (n == 1) printf("1\n");
	else if (k == 2) printf("1\n");
	else if (k > 2) printf("0\n");
	else {
	    printf("%I64d\n", solve());
	}
    }
    return 0;
}
Beispiel #5
0
/* evaluate the Knuth-Schroeppel function, cf Robert D. Silverman,
   "The Multiple Polynomial Quadratic Sieve", Math. of Comp. volume 48,
    number 177, 1987, page 335 */
unsigned long
find_multiplier (mpz_t N, double B)
{
  unsigned long k, bestk = 1;
  double p, f, g, maxf = 0.0;
  mpz_t kN;
  
  mpz_init (kN);
  for (k = 1; k < 100; k = nextprime (k))
    {
      mpz_mul_ui (kN, N, k);
      /* FIXME: Silverman writes "if N = 1 mod 8" but isn't it kN instead? */
      if (mpz_kronecker_ui (kN, 2) == 1 && mpz_fdiv_ui (kN, 8) == 1)
        f = 2.0 * log (2.0);
      else
        f = 0.0;
      for (p = getprime (2.0); p <= B; p = getprime (p))
        {
          if (mpz_kronecker_ui (kN, (unsigned long) p) == 1)
            {
              g = ((k % (unsigned long) p) == 0) ? (1.0 / p) : (2.0 / p);
              f += g * log (p);
            }
        }
      f -= 0.5 * log ((double) k);
      if (f > maxf)
        {
          maxf = f;
          bestk = k;
        }
      getprime (0.0); /* free prime buffer */
    }
  mpz_clear (kN);
  
  return bestk;
}
int main(){
  freopen("in2.txt", "r", stdin);
  char c; int t = 0, n = 1;
  getprime();
  //printf("%.3lf\n", (double)clock()/CLOCKS_PER_SEC);
  while((c=getchar())!=EOF) {
      if(isdigit(c)) t = t*10 + c - '0';
      else if(c=='/') {x[n++] = t;  t = 0;}
      else if(c=='\n') {
          x[n] = t;
          k = n;
          if(x[2] == 0) printf("NO\n");
          else if(x[2] == 1) printf("YES\n");
          else solve();
          n = 1;
          t = 0;
      }
  }           
  return 0;
}
int main() {
   int cases, c, n, i;
   // initialize array
   for (i = 0; i < ARRAY_SIZE; i++){
      primes[i] = 0;
   } // prime array
   primes[0] = 2;
   primes[1] = 3;
   max = primes[1];
   index = 1;
   
   scanf("%d\n", &cases);
   for (c = 0; c < cases; c++){
      scanf("%d\n", &n);
      if (DEBUG){
         fprintf(stderr, "examining %d\n", n);
      }
      printf("%ld\n", getprime(n));
   }
   return 0;
}
Beispiel #8
0
int	mur_forward_multi_proc_init(reg_ctl_list *rctl)
{
	multi_proc_shm_hdr_t	*mp_hdr;	/* Pointer to "multi_proc_shm_hdr_t" structure in shared memory */
	shm_forw_multi_t	*ptr, *ptr_top;
	que_ent_ptr_t		que_head;
	shm_reg_ctl_t		*shm_rctl;
	reg_ctl_list		*rctl_top;

	/* Note: "rctl" is unused. But cannot avoid passing it since "gtm_multi_proc" expects something */
	mp_hdr = multi_proc_shm_hdr;
	mur_shm_hdr = (mur_shm_hdr_t *)((sm_uc_ptr_t)mp_hdr->shm_ret_array + (SIZEOF(void *) * mp_hdr->ntasks));
	mur_shm_hdr->hash_bucket_start = (que_ent_ptr_t)(mur_shm_hdr + 1);
	assert(mur_forw_mp_hash_buckets == getprime(murgbl.reg_total + 32));
	mur_shm_hdr->shm_forw_multi_start = (shm_forw_multi_t *)(mur_shm_hdr->hash_bucket_start + mur_forw_mp_hash_buckets);
	que_head = (que_ent_ptr_t)&mur_shm_hdr->forw_multi_free;
	for (ptr = &mur_shm_hdr->shm_forw_multi_start[0], ptr_top = ptr + murgbl.reg_total; ptr < ptr_top; ptr++)
		insqt((que_ent_ptr_t)&ptr->free_chain, que_head);
	shm_rctl = (shm_reg_ctl_t *)ptr;
	mur_shm_hdr->shm_rctl_start = shm_rctl;
	for (rctl = mur_ctl, rctl_top = mur_ctl + murgbl.reg_total; rctl < rctl_top; rctl++, shm_rctl++)
		shm_rctl->jnlext_shmid = INVALID_SHMID;
	return 0;
}
Beispiel #9
0
static int
pm1_stage1 (mpz_t f, mpres_t a, mpmod_t n, double B1, double *B1done, 
            mpz_t go, int (*stop_asap)(void), char *chkfilename)
{
  double p, q, r, cascade_limit, last_chkpnt_p;
  mpz_t g, d;
  int youpi = ECM_NO_FACTOR_FOUND;
  unsigned int size_n, max_size;
  unsigned int smallbase = 0;
  mul_casc *cascade;
  long last_chkpnt_time;
  const double B0 = sqrt (B1);

  mpz_init (g);
  mpz_init (d);

  size_n = mpz_sizeinbase (n->orig_modulus, 2);
  max_size = L1 * size_n;

  mpres_get_z (g, a, n);
  if (mpz_fits_uint_p (g))
    smallbase = mpz_get_ui (g);

  /* suggestion from Peter Montgomery: start with exponent n-1,
     since any prime divisor of b^m-1 which does not divide any
     algebraic factor of b^m-1 must be of the form km+1 [Williams82].
     Do this only when n is composite, otherwise all tests with prime
     n factor of a Cunningham number will succeed in stage 1.

     Since mpz_probab_prime_p and a^(n-1) mod n require about lg(n) modular
     multiplications, and P-1 perform about B1 modular multiplications,
     to ensure small overhead, use that trick only when lg(n) <= sqrt(B1).
  */
  /* For now, this p^N-1 is left in.  We might want it out at a later time */
  if ((double) size_n <= B0 &&
      mpz_probab_prime_p (n->orig_modulus, PROBAB_PRIME_TESTS) == 0)
    {
      mpz_sub_ui (g, n->orig_modulus, 1);
      mpres_pow (a, a, g, n);
    }
  else
    mpz_set_ui (g, 1);

  /* Set a limit of roughly 10000 * log_10(N) for the primes that are 
     multiplied up in the exponent, i.e. 1M for a 100 digit number, 
     but limit to CASCADE_MAX to avoid problems with stack allocation */
  
  cascade_limit = 3000.0 * (double) size_n;

  if (cascade_limit > CASCADE_MAX)
    cascade_limit = CASCADE_MAX;
  
  if (cascade_limit > B1)
    cascade_limit = B1;

  cascade = mulcascade_init ();
  if (cascade == NULL)
    {
      youpi = ECM_ERROR;
      goto clear_pm1_stage1;
    }

  /* since B0 = sqrt(B1), we can have B0 > cascade_limit only when
     B1 > cascade_limit^2. This cannot happen when cascade_limit=B1,
     thus we need B1 > min(CASCADE_MAX, 3000*sizeinbase(n,2))^2.
     For sizeinbase(n,2) <= CASCADE_MAX/3000 (less than 5017 digits 
     for CASCADE_MAX=5e7) this means B1 > 9e6*sizeinbase(n,2)^2.
     For sizeinbase(n,2) > CASCADE_MAX/3000, this means B1 > CASCADE_MAX^2,
     i.e. B1 > 25e14 for CASCADE_MAX=5e7.
  */

  /* if the user knows that P-1 has a given divisor, he can supply it */
  if (mpz_cmp_ui (go, 1) > 0)
    cascade = mulcascade_mul (cascade, go);
  
  last_chkpnt_time = cputime ();
  last_chkpnt_p = 2.;
  
  /* Fill the multiplication cascade with the product of small stage 1 
     primes */
  /* Add small primes <= MIN(sqrt(B1), cascade_limit) in the appropriate 
     power to the cascade */
  for (p = 2.; p <= MIN(B0, cascade_limit); p = getprime ())
    {
      for (q = 1., r = p; r <= B1; r *= p)
        if (r > *B1done) q *= p;
      cascade = mulcascade_mul_d (cascade, q, d);
    }

  /* If B0 < cascade_limit, we can add some primes > sqrt(B1) with 
     exponent 1 to the cascade */
  for ( ; p <= cascade_limit; p = getprime ())
    if (p > *B1done)
      cascade = mulcascade_mul_d (cascade, p, d);

  /* Now p > cascade_limit, flush cascade and exponentiate */
  mulcascade_get_z (g, cascade);
  mulcascade_free (cascade);
  outputf (OUTPUT_DEVVERBOSE, "Exponent has %u bits\n", 
           mpz_sizeinbase (g, 2));
  
  if (smallbase)
    {
      outputf (OUTPUT_DEVVERBOSE, "Using mpres_ui_pow, base %u\n", smallbase);
      mpres_ui_pow (a, smallbase, g, n);
    }
  else
    {
      mpres_pow (a, a, g, n);
    }
  mpz_set_ui (g, 1);

  /* If B0 > cascade_limit, we need to process the primes 
     cascade_limit < p < B0 in the appropriate exponent yet */
  for ( ; p <= B0; p = getprime ())
    {
      for (q = 1, r = p; r <= B1; r *= p)
        if (r > *B1done) q *= p;
      mpz_mul_d (g, g, q, d);
      if (mpz_sizeinbase (g, 2) >= max_size)
        {
          mpres_pow (a, a, g, n);
          mpz_set_ui (g, 1);
        if (stop_asap != NULL && (*stop_asap) ())
          {
            outputf (OUTPUT_NORMAL, "Interrupted at prime %.0f\n", p);
            if (p > *B1done)
              *B1done = p;
            goto clear_pm1_stage1;
          }
        }
    }

  /* All primes sqrt(B1) < p <= B1 appear in exponent 1. All primes <= B1done
     are already included in exponent of at least 1, so it's save to skip  
     ahead to B1done+1 */
     
  if (*B1done > p)
    {
      getprime_seek ((*B1done) + 1.);
      p = getprime ();
    }

  /* then remaining primes > max(sqrt(B1), cascade_limit) and taken 
     with exponent 1 */
  for (; p <= B1; p = getprime ())
  {
    mpz_mul_d (g, g, p, d);
    if (mpz_sizeinbase (g, 2) >= max_size)
      {
        mpres_pow (a, a, g, n);
        mpz_set_ui (g, 1);
        if (stop_asap != NULL && (*stop_asap) ())
          {
            outputf (OUTPUT_NORMAL, "Interrupted at prime %.0f\n", p);
             if (p > *B1done)
              *B1done = p;
            goto clear_pm1_stage1;
          }
        if (chkfilename != NULL && p > last_chkpnt_p + 10000. &&
            elltime (last_chkpnt_time, cputime ()) > CHKPNT_PERIOD)
          {
            writechkfile (chkfilename, ECM_PM1, p, n, NULL, a, NULL);
            last_chkpnt_p = p;
            last_chkpnt_time = cputime ();
          }
      }
  }

  mpres_pow (a, a, g, n);
  
  /* If stage 1 finished normally, p is the smallest prime >B1 here.
     In that case, set to B1 */
  if (p > B1)
      p = B1;
  
  if (p > *B1done)
    *B1done = p;
  
  mpres_sub_ui (a, a, 1, n);
  mpres_gcd (f, a, n);
  if (mpz_cmp_ui (f, 1) > 0)
    youpi = ECM_FACTOR_FOUND_STEP1;
  mpres_add_ui (a, a, 1, n);

 clear_pm1_stage1:
  if (chkfilename != NULL)
    writechkfile (chkfilename, ECM_PM1, *B1done, n, NULL, a, NULL);
  getprime_clear (); /* free the prime tables, and reinitialize */
  mpz_clear (d);
  mpz_clear (g);

  return youpi;
}
Beispiel #10
0
int main()
{
    int i;
    FILE *fp;
    big K,rid,id,w,a,b,n,q1;
    miracl *mip=mirsys(200,256);
    for (i=0;i<NPRIMES;i++)
    {
        pp[i]=mirvar(0);
        rem[i]=mirvar(0);
    }
    w=mirvar(0);
    n=mirvar(0);
    a=mirvar(0);
    b=mirvar(0);
    p=mirvar(0);
    p1=mirvar(0);     
    q1=mirvar(0);
    K=mirvar(0);
    lim1=mirvar(0);
    lim2=mirvar(0);
    id=mirvar(0);
    rid=mirvar(0);
    order=mirvar(0);

    printf("Enter ID= ");
    innum(rid,stdin);
    getprime("trap1.dat");
    copy(p,n);
    getprime("trap2.dat");
   
    multiply(n,p,n);
    printf("\ncomposite =\n");
    cotnum(n,stdout);

    premult(rid,256,id);   
    while (jack(id,n)!=1)
    { /* bad identity - id=256*rid+i */
        printf("No Discrete Log. for this ID -- incrementing\n");
        incr(id,1,id);
    }

    getprime("trap1.dat");
    copy(p1,q1);
    pollard(id,b);
    getprime("trap2.dat");
    pollard(id,a);

    xgcd(p1,q1,K,K,K); 
    subtract(b,a,w);
    mad(w,K,w,q1,q1,w);
    if(size(w)<0) add_r(w,q1,w);
    subdiv(w,2,w);
    multiply(w,p1,w);
    add_r(w,a,w);

    fp=fopen("secret.dat","w");
    otnum(rid,fp);
    cotnum(w,fp);
    cotnum(n,fp);
    fclose(fp);
    printf("\nDiscrete log (secret key) \n");
    cotnum(w,stdout);
    powltr(PROOT,w,n,id);
    subdiv(id,256,id);
    otstr(id,mip->IOBUFF);
    printf("Check Identity= %s\n",mip->IOBUFF);
    return 0;
}
Beispiel #11
0
/* Input:  P0 is the initial point (sigma)
           n is the number to factor
           B1 is the stage 1 bound
	   B1done: stage 1 was already done up to that limit
	   go: if <> 1, group order to preload
   Output: a is the factor found, or the value at end of stage 1
	   B1done is set to B1 if stage 1 completed normally,
	   or to the largest prime processed if interrupted, but never
	   to a smaller value than B1done was upon function entry.
   Return value: non-zero iff a factor was found.
*/
static int
pp1_stage1 (mpz_t f, mpres_t P0, mpmod_t n, double B1, double *B1done, 
            mpz_t go, int (*stop_asap)(void), char *chkfilename)
{
  double B0, p, q, r, last_chkpnt_p;
  mpz_t g;
  mpres_t P, Q;
  mpres_t R, S, T;
  int youpi = ECM_NO_FACTOR_FOUND;
  unsigned int max_size, size_n;
  long last_chkpnt_time;

  mpz_init (g);
  mpres_init (P, n);
  mpres_init (Q, n);
  mpres_init (R, n);
  mpres_init (S, n);
  mpres_init (T, n);

  B0 = ceil (sqrt (B1));

  size_n = mpz_sizeinbase (n->orig_modulus, 2);
  max_size = L1 * size_n;

  if (mpz_cmp_ui (go, 1) > 0)
    pp1_mul (P0, P0, go, n, P, Q);

  /* suggestion from Peter Montgomery: start with exponent n^2-1,
     as factors of Lucas and Fibonacci number are either +/-1 (mod index),
     and so is n. Therefore, index will appear as a factor
     of n^2-1 and be included in stage 1.
     Do this only when n is composite, otherwise all tests with prime
     n factor of a Cunningham number will succeed in stage 1.

     As in P-1, for small overhead, use that trick only when lg(n) <= sqrt(B1).
  */
  if ((double) size_n <= B0 &&
      mpz_probab_prime_p (n->orig_modulus, PROBAB_PRIME_TESTS) == 0)
    {
      mpz_mul (g, n->orig_modulus, n->orig_modulus);
      mpz_sub_ui (g, g, 1);
      pp1_mul (P0, P0, g, n, P, Q);
    }

  mpz_set_ui (g, 1);

  last_chkpnt_p = 2.;
  last_chkpnt_time = cputime ();
  /* first loop through small primes <= sqrt(B1) */
  for (p = 2.0; p <= B0; p = getprime ())
    {
      for (q = 1, r = p; r <= B1; r *= p)
        if (r > *B1done) q *= p;
      mpz_mul_d (g, g, q, Q);
      if (mpz_sizeinbase (g, 2) >= max_size)
	{
	  pp1_mul (P0, P0, g, n, P, Q);
	  mpz_set_ui (g, 1);
          if (stop_asap != NULL && (*stop_asap) ())
            {
              outputf (OUTPUT_NORMAL, "Interrupted at prime %.0f\n", p);
	      if (p > *B1done)
		  *B1done = p;
              goto clear_and_exit;
            }
	}
    }

  pp1_mul (P0, P0, g, n, P, Q);

#if 1
  /* All primes sqrt(B1) < p <= B1 appear in exponent 1. All primes <= B1done
     are already included in exponent of at least 1, so it's save to skip 
     ahead to B1done+1 */
  
  if (*B1done > p)
    {
      getprime_seek ((*B1done) + 1.);
      p = getprime ();
    }
#endif

  /* then all primes > sqrt(B1) and taken with exponent 1 */
  for (; p <= B1; p = getprime ())
    {
      pp1_mul_prac (P0, (ecm_uint) p, n, P, Q, R, S, T);
  
      if (stop_asap != NULL && (*stop_asap) ())
        {
          outputf (OUTPUT_NORMAL, "Interrupted at prime %.0f\n", p);
	  if (p > *B1done)
	      *B1done = p;
          goto clear_and_exit;
        }
      if (chkfilename != NULL && p > last_chkpnt_p + 10000. &&
          elltime (last_chkpnt_time, cputime ()) > CHKPNT_PERIOD)
        {
          writechkfile (chkfilename, ECM_PP1, p, n, NULL, P0, NULL);
          last_chkpnt_p = p;
          last_chkpnt_time = cputime ();
        }
    }

  /* If stage 1 finished normally, p is the smallest prime >B1 here.
     In that case, set to B1 */
  if (p > B1)
    p = B1;
  
  if (p > *B1done)
    *B1done = p;
  
  mpres_sub_ui (P, P0, 2, n);
  mpres_gcd (f, P, n);
  youpi = mpz_cmp_ui (f, 1);

clear_and_exit:
  if (chkfilename != NULL)
    writechkfile (chkfilename, ECM_PP1, p, n, NULL, P0, NULL);
  getprime_clear (); /* free the prime tables, and reinitialize */
  mpres_clear (Q, n);
  mpres_clear (R, n);
  mpres_clear (S, n);
  mpres_clear (T, n);
  mpz_clear (g);
  mpres_clear (P, n);
  
  return youpi;
}
Beispiel #12
0
void cce_dbdump(void)
{
	uint4	channel, status, flags, pid, real_size, req_size, size, addrs[2], sec_addrs[2];
	int		i, j, k, l;
	gds_file_id	file;
	m_iosb		stat_blk;
	sgmnt_data	*sd;
	unsigned char	mbuff[512], *c, *cptr, *ctop;
	$DESCRIPTOR(d_sec,mbuff);
	static readonly $DESCRIPTOR(d_cmd,"install lis/glo");
	static readonly $DESCRIPTOR(d_mnam,"CCE$DBDUMPMBX");
	static readonly $DESCRIPTOR(d_pnam,"CCE$DBDUMPPRC");
	char		filename[]="SYS$LOGIN:CCE_DBDUMP.DMP", buff[RECORD_SIZE], id_lab[]=" FILE ID:";
	struct FAB	fab;
	struct RAB	rab;
	error_def(ERR_CCEDBDUMP);
	error_def(ERR_CCEDBNODUMP);


	util_out_open(0);
	status = sys$crembx(0, &channel, 512, 0, 0, PSL$C_USER, &d_mnam);
	if (status != SS$_NORMAL)
		sys$exit(status);
	flags = CLI$M_NOWAIT | CLI$M_NOLOGNAM;
	status = lib$spawn(&d_cmd, 0, &d_mnam, &flags, &d_pnam, &pid);
	if (status != SS$_NORMAL)
	{	if (status == SS$_DUPLNAM)
		{	util_out_print("Spawned process CCE$DBDUMPPRC already exists, cannot continue rundown",TRUE);
		}
		sys$exit(status);
	}
	/* the following guess at the dump file size is modeled on the calculation for a section */
	size = DIVIDE_ROUND_UP((SIZEOF(sgmnt_data) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec)
				+ (DEF_LOCK_SIZE / OS_PAGELET_SIZE)
				 + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS)) * SIZEOF(cache_rec) + SIZEOF(cache_que_heads)),
				OS_PAGELET_SIZE);
	size += EXTRA_SPACE;

	fab = cc$rms_fab;
	fab.fab$b_fac = FAB$M_PUT;
	fab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF;
	fab.fab$l_fna = filename;
	fab.fab$b_fns = SIZEOF(filename);
	fab.fab$b_rfm = FAB$C_FIX;
	fab.fab$w_mrs = RECORD_SIZE;
	fab.fab$w_deq = size;
	fab.fab$l_alq = size;
	switch (status = sys$create(&fab))
	{
	case RMS$_NORMAL:
	case RMS$_CREATED:
	case RMS$_SUPERSEDE:
	case RMS$_FILEPURGED:
		break;
	default:
		util_out_print("Error: Cannot create dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
		sys$exit(status);
	}

	rab = cc$rms_rab;
	rab.rab$l_fab = &fab;
	status = sys$connect(&rab);
	if (status != RMS$_NORMAL)
	{	util_out_print("Error: Cannot connect to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
		sys$exit(status);
	}
	rab.rab$w_rsz = SIZEOF(buff);

	for (; ;)
	{	status = sys$qiow (0, channel,IO$_READVBLK ,&stat_blk, 0, 0, mbuff, 512,0,0,0,0);
		if (status != SS$_NORMAL)
		{	sys$exit(status);
			break;
		}
		if (stat_blk.status == SS$_ENDOFFILE)
			break;
		if (stat_blk.status != SS$_NORMAL)
		{	sys$exit(stat_blk.status);
			break;
		}
		if (!memcmp("GT$S",mbuff,4))
		{	for ( c = mbuff; *c > 32 ; c++)
				;
			d_sec.dsc$w_length = c - mbuff;
			flags = SEC$M_GBL | SEC$M_WRT | SEC$M_SYSGBL | SEC$M_PAGFIL | SEC$M_DZRO | SEC$M_PERM;
			addrs[0] = addrs[1] = 0;
			fid_from_sec(&d_sec,&file);

			real_size = cce_sec_size(&file);
			if (real_size == 0)
				real_size = size;
			real_size += 1;

			assert(OS_PAGE_SIZE % OS_PAGELET_SIZE == 0);

			/* Request enough pagelets to ensure enough contiguous pages to contain desired number of pagelets. */
			req_size = ROUND_UP(real_size, OS_PAGE_SIZE);
			lib$get_vm_page(&req_size, &addrs[0]);

			/* addrs will hold addresses of start and end of contiguous block of pagelets for use by $deltva. */
			assert((addrs[0] + (req_size * OS_PAGELET_SIZE) - 1) == addrs[1]);

			/* $get_vm_page returns pagelets; we must align to integral page boundary. */
			/* sec_addrs will contain the starting and ending addresses of the mapped section. */
			sec_addrs[0] = ROUND_UP(addrs[0], OS_PAGE_SIZE);	/* align to first integral page boundary */
			sec_addrs[1] = addrs[0] + (real_size * OS_PAGELET_SIZE);
			sec_addrs[1] = ROUND_UP(addrs[1], OS_PAGE_SIZE) - 1;  /* A(last byte of last page) */

			status = init_sec(sec_addrs, &d_sec, 0, real_size, flags);
			if (status & 1)
			{
				sd = sec_addrs[0];
				memset(buff, 0, RECORD_SIZE);
				memcpy(buff, d_sec.dsc$a_pointer, d_sec.dsc$w_length);
				cptr = &buff[0] + d_sec.dsc$w_length;
				memcpy(cptr,id_lab,SIZEOF(id_lab));
				cptr += SIZEOF(id_lab);
				memcpy(cptr,&file,SIZEOF(file));
				rab.rab$l_rbf = buff;
				status = sys$put(&rab);
				if (status != RMS$_NORMAL)
				{	util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
					util_out_print("Status code is !UL.",TRUE,status);
					break;
				}
				for (c = sd, i = 0; (real_size + EXTRA_SPACE) >= i;
					c += RECORD_SIZE, i += (RECORD_SIZE / DISK_BLOCK_SIZE))
				{
					rab.rab$l_rbf = c;
					status = sys$put(&rab);
					if (status != RMS$_NORMAL)
					{	util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
						util_out_print("Status code is !UL.",TRUE,status);
						break;
					}
				}
				lib$signal(ERR_CCEDBDUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer);
			}else
			{	lib$signal(ERR_CCEDBNODUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer,status,0);
			}
			gtm_deltva(&addrs[0],0,0);
			lib$free_vm_page(&real_size,&addrs[0]);
		}
	}
	sys$exit(SS$_NORMAL);
}
unsigned char mu_cre_file(void)
{
	unsigned char		*inadr[2], *c, exit_stat;
	enum db_acc_method	temp_acc_meth;
	uint4			lcnt, retadr[2];
	int4			blk_init_size, initial_alq, free_blocks;
	gtm_uint64_t		free_blocks_ll, blocks_for_extension;
	char			buff[GLO_NAME_MAXLEN], fn_buff[MAX_FN_LEN];
	unsigned int		status;
	int			free_space;
	struct FAB		*fcb;
	struct NAM		nam;
	gds_file_id		new_id;
	io_status_block_disk	iosb;
	char			node[16];
	short			len;
	struct {
		short	blen;
		short	code;
		char	*buf;
		short	*len;
		int4	terminator;
	} item = {15, SYI$_NODENAME, &node, &len, 0};
	$DESCRIPTOR(desc, buff);

	exit_stat = EXIT_NRM;
/* The following calculations should duplicate the BT_SIZE macro from GDSBT and the LOCK_BLOCK macro from GDSFHEAD.H,
 * but without using a sgmnt_data which is not yet set up at this point
 */

#ifdef GT_CX_DEF
	/* This section needs serious chnages for the fileheader changes in V5 if it is ever resurrected */
	over_head = DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec), DISK_BLOCK_SIZE);
	if (gv_cur_region->dyn.addr->acc_meth == dba_bg)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (gv_cur_region->dyn.addr->global_buffers + getprime(gv_cur_region->dyn.addr->global_buffers) + 1)
				* SIZEOF(bt_rec), DISK_BLOCK_SIZE);
		over_head += gv_cur_region->dyn.addr->lock_space ? gv_cur_region->dyn.addr->lock_space
								 : DEF_LOCK_SIZE / OS_PAGELET_SIZE;
	} else if (gv_cur_region->dyn.addr->acc_meth == dba_mm)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE);
		if (gv_cur_region->dyn.addr->lock_space)
		{
			over_head += gv_cur_region->dyn.addr->lock_space;
			free_space += gv_cur_region->dyn.addr->lock_space;
		} else
		{
			over_head += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
			free_space += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
		}
	}
	free_space *= DISK_BLOCK_SIZE;
#else
	assert(START_VBN_CURRENT > DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE));
	free_space = ((START_VBN_CURRENT - 1) * DISK_BLOCK_SIZE) - SIZEOF_FILE_HDR_DFLT;
#endif
	switch (gv_cur_region->dyn.addr->acc_meth)
	{
		case dba_bg:
		case dba_mm:
			mu_cre_vms_structs(gv_cur_region);
			fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab;
			cs_addrs = &((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs;

			fcb->fab$b_shr &= FAB$M_NIL;	/* No access to this file while it is created */
			fcb->fab$l_nam = &nam;
			nam = cc$rms_nam;
			/* There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
			 * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
			 * manner as every non-bitmap block must have an associated bitmap)
			*/
			fcb->fab$l_alq += DIVIDE_ROUND_UP(fcb->fab$l_alq, BLKS_PER_LMAP - 1);	/* Bitmaps */
			blk_init_size = fcb->fab$l_alq;
			fcb->fab$l_alq *= BLK_SIZE / DISK_BLOCK_SIZE;
			fcb->fab$l_alq += START_VBN_CURRENT - 1;
			initial_alq = fcb->fab$l_alq;
			fcb->fab$w_mrs = 512;				/* no longer a relevent field to us */
			break;
		case dba_usr:
			util_out_print("Database file for region !AD not created; access method is not GDS.", TRUE,
				REG_LEN_STR(gv_cur_region));
			return EXIT_WRN;
		default:
			gtm_putmsg(VARLSTCNT(1) ERR_BADACCMTHD);
			return EXIT_ERR;
	}
	nam.nam$b_ess = SIZEOF(fn_buff);
	nam.nam$l_esa = fn_buff;
	nam.nam$b_nop |= NAM$M_SYNCHK;
	status = sys$parse(fcb, 0, 0);
	if (RMS$_NORMAL != status)
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		return EXIT_ERR;
	}
	if (nam.nam$b_node != 0)
	{
		status = sys$getsyiw(EFN$C_ENF, 0, 0, &item, &iosb, 0, 0);
		if (SS$_NORMAL == status)
			status = iosb.cond;
		if (SS$_NORMAL == status)
		{
			if (len == nam.nam$b_node-2 && !memcmp(nam.nam$l_esa, node, len))
			{
				fcb->fab$l_fna = nam.nam$l_esa + nam.nam$b_node;
				fcb->fab$b_fns = nam.nam$b_esl - nam.nam$b_node;
			}
		} else
		{
			util_out_print("Could not get node for !AD.", TRUE, REG_LEN_STR(gv_cur_region));
			exit_stat = EXIT_WRN;
		}
	}
	assert(gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm);
	nam.nam$l_esa = NULL;
	nam.nam$b_esl = 0;
	status = sys$create(fcb);
	if (status != RMS$_CREATED && status != RMS$_FILEPURGED)
	{
		switch(status)
		{
			case RMS$_FLK:
		 		util_out_print("Database file for region !AD not created; currently locked by another user.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_NORMAL:
		 		util_out_print("Database file for region !AD not created; already exists.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_SUPPORT:
				util_out_print("Database file for region !AD not created; cannot create across network.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_WRN;
				break;
			case RMS$_FUL:
				send_msg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				/* intentionally falling through */
			default:
				gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				exit_stat = EXIT_ERR;
		}
		sys$dassgn(fcb->fab$l_stv);
		return exit_stat;
	}

	memcpy(new_id.dvi, nam.nam$t_dvi, SIZEOF(nam.nam$t_dvi));
	memcpy(new_id.did, nam.nam$w_did, SIZEOF(nam.nam$w_did));
	memcpy(new_id.fid, nam.nam$w_fid, SIZEOF(nam.nam$w_fid));
	global_name("GT$S", &new_id, buff);		/* 2nd parm is actually a gds_file_id * in global_name */
	desc.dsc$w_length = buff[0];			/* By definition, a gds_file_id is dvi,fid,did from nam */
	desc.dsc$a_pointer = &buff[1];
	cs_addrs->db_addrs[0] = cs_addrs->db_addrs[1] = inadr[0] = inadr[1] = inadr;	/* used to determine p0 or p1 allocation */
	status = init_sec(cs_addrs->db_addrs, &desc, fcb->fab$l_stv, (START_VBN_CURRENT - 1),
			  SEC$M_DZRO|SEC$M_GBL|SEC$M_WRT|SEC$M_EXPREG);
	if ((SS$_CREATED != status) && (SS$_NORMAL != status))
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		sys$dassgn(fcb->fab$l_stv);
		return EXIT_ERR;
	}
	cs_data = (sgmnt_data *)cs_addrs->db_addrs[0];
	memset(cs_data, 0, SIZEOF_FILE_HDR_DFLT);
	cs_data->createinprogress = TRUE;
	cs_data->trans_hist.total_blks = (initial_alq - (START_VBN_CURRENT - 1)) / (BLK_SIZE / DISK_BLOCK_SIZE);
	/* assert that total_blks stored in file-header = non-bitmap blocks (initial allocation) + bitmap blocks */
	assert(cs_data->trans_hist.total_blks == gv_cur_region->dyn.addr->allocation +
				DIVIDE_ROUND_UP(gv_cur_region->dyn.addr->allocation, BLKS_PER_LMAP - 1));
	cs_data->start_vbn = START_VBN_CURRENT;
	temp_acc_meth = gv_cur_region->dyn.addr->acc_meth;
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = dba_bg;
	cs_data->extension_size = gv_cur_region->dyn.addr->ext_blk_count;
	mucregini(blk_init_size);
	cs_addrs->hdr->free_space = free_space;
#ifndef GT_CX_DEF
	cs_addrs->hdr->unbacked_cache = TRUE;
#endif
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = temp_acc_meth;
	cs_data->createinprogress = FALSE;
	if (SS$_NORMAL == (status = disk_block_available(fcb->fab$l_stv, &free_blocks)))
	{
		blocks_for_extension = (cs_data->blk_size / DISK_BLOCK_SIZE *
				  (DIVIDE_ROUND_UP(EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size, BLKS_PER_LMAP - 1)
					 + EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size));
		if ((gtm_uint64_t)free_blocks < blocks_for_extension)
		{
			free_blocks_ll = (gtm_uint64_t)free_blocks;
			gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
			send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
		}
	}
	if (SS$_NORMAL == (status = sys$updsec(((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs.db_addrs,
			NULL, PSL$C_USER, 0, efn_immed_wait, &iosb, NULL, 0)))
	{
		status = sys$synch(efn_immed_wait, &iosb);
		if (SS$_NORMAL == status)
			status = iosb.cond;
	} else  if (SS$_NOTMODIFIED == status)
		status = SS$_NORMAL;
	if (SS$_NORMAL == status)
		status = del_sec(SEC$M_GBL, &desc, 0);
	if (SS$_NORMAL == status)
		status = sys$deltva(cs_addrs->db_addrs, retadr, PSL$C_USER);
	if (SS$_NORMAL == status)
		status = sys$dassgn(fcb->fab$l_stv);
	if (SS$_NORMAL == status)
	{
	 	util_out_print("Database file for region !AD created.", TRUE, REG_LEN_STR(gv_cur_region));
		/* the open and close are an attempt to ensure that the file is available, not under the control of an ACP,
		 * before MUPIP exits */
		fcb->fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
		fcb->fab$l_fop = 0;
		for (lcnt = 1;  (60 * MAX_OPEN_RETRY) >= lcnt;  lcnt++)
		{	/* per VMS engineering a delay is expected.  We will wait up to an hour as a
			 * Delete Global Section operation is essentially and inherently asynchronous in nature
			 * and could take an arbitrary amount of time.
			 */
			if (RMS$_FLK != (status = sys$open(fcb, NULL, NULL)))
				break;
			wcs_sleep(lcnt);
		}
		assert(RMS$_NORMAL == status);
		if (RMS$_NORMAL == status)
		{
			status = sys$close(fcb);
			assert(RMS$_NORMAL == status);
		}
		if (RMS$_NORMAL != status)
			exit_stat = EXIT_WRN;
	} else
		exit_stat = EXIT_ERR;
	if (RMS$_NORMAL != status)
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
	if ((MAX_RMS_RECORDSIZE - SIZEOF(shmpool_blk_hdr)) < cs_data->blk_size)
		gtm_putmsg(VARLSTCNT(5) ERR_MUNOSTRMBKUP, 3, fcb->fab$b_fns, fcb->fab$l_fna, 32 * 1024 - DISK_BLOCK_SIZE);
	return exit_stat;
}
Beispiel #14
0
uint4	mur_forward(jnl_tm_t min_broken_time, seq_num min_broken_seqno, seq_num losttn_seqno)
{
	jnl_tm_t		adjusted_resolve_time;
	int			sts, max_procs;
	size_t			shm_size;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	skip_dbtriggers = TRUE;	/* do not want to invoke any triggers for updates done by journal recovery */
	/* In case of mupip journal -recover -backward or -rollback -backward, the forward phase replays the journal records
	 * and creates new journal records. If there is no space to write these journal records, "jnl_file_lost" will eventually
	 * get called. In this case, we want it to issue a runtime error (thereby terminating the journal recovery with an
	 * abnormal exit status, forcing the user to free up more space and reissue the journal recovery) and not turn
	 * journaling off (which would silently let recovery proceed and exit with normal status even though the db might
	 * have integ errors at that point). Use the error_on_jnl_file_lost feature to implement this error triggering.
	 */
	if (mur_options.update)
		TREF(error_on_jnl_file_lost) = JNL_FILE_LOST_ERRORS;
	murgbl.extr_buff = (char *)malloc(murgbl.max_extr_record_length);
	jgbl.dont_reset_gbl_jrec_time = jgbl.forw_phase_recovery = TRUE;
	assert(NULL == jgbl.mur_pini_addr_reset_fnptr);
	jgbl.mur_pini_addr_reset_fnptr = (pini_addr_reset_fnptr)mur_pini_addr_reset;
	mu_gv_stack_init();
	murgbl.consist_jnl_seqno = 0;
	/* Note down passed in values in murgbl global so "mur_forward_play_cur_jrec" function can see it as well */
	murgbl.min_broken_time = min_broken_time;
	murgbl.min_broken_seqno = min_broken_seqno;
	murgbl.losttn_seqno = losttn_seqno;
	/* We play multi-reg TP transactions as multiple single-region TP transactions until the tp_resolve_time.
	 * And then play it as a multi-reg TP transaction. The first phase can be parallelized whereas the second cannot.
	 * So try to play as much as possible using the first phase. Almost always, min_broken_time would be greater than
	 * tp_resolve_time so we can do the first phase until min_broken_time. But there are some cases where min_broken_time
	 * can be 0 (e.g. ZTP broken transactions are detected in mupip_recover.c). Those should be uncommon and so in those
	 * cases, revert to using tp_resolve_time as the transition point between phase1 and phase2.
	 */
	assert((min_broken_time >= jgbl.mur_tp_resolve_time) || !min_broken_time);
	adjusted_resolve_time = (!min_broken_time ? jgbl.mur_tp_resolve_time : min_broken_time);
	murgbl.adjusted_resolve_time = adjusted_resolve_time;	/* needed by "mur_forward_multi_proc" */
	DEBUG_ONLY(jgbl.mur_tp_resolve_time = adjusted_resolve_time);	/* An assert in tp_tend relies on this.
									 * Even in pro, this is a safe change to do but
									 * no one cares about jgbl.mur_tp_resolve_time in
									 * forward phase other than tp_tend so we do nothing.
									 */
	DEBUG_ONLY(murgbl.save_losttn_seqno = losttn_seqno); /* keep save_losttn_seqno in sync at start of mur_forward.
							      * an assert in mur_close_files later checks this did not change.
							      */
	assert(!mur_options.rollback || (murgbl.losttn_seqno <= murgbl.min_broken_seqno));
	max_procs = gtm_mupjnl_parallel;
	if (!max_procs || (max_procs > murgbl.reg_total))
		max_procs = murgbl.reg_total;
	mur_forw_mp_hash_buckets = getprime(murgbl.reg_total + 32);	/* Add 32 to get bigger prime # and in turn better hash */
	assert(mur_forw_mp_hash_buckets);
	shm_size = (size_t)(SIZEOF(mur_shm_hdr_t)
				+ (SIZEOF(que_ent) * mur_forw_mp_hash_buckets)
				+ (SIZEOF(shm_forw_multi_t) * murgbl.reg_total)
				+ (SIZEOF(shm_reg_ctl_t) * murgbl.reg_total));
	sts = gtm_multi_proc((gtm_multi_proc_fnptr_t)&mur_forward_multi_proc, max_procs, max_procs,
				murgbl.ret_array, (void *)mur_ctl, SIZEOF(reg_ctl_list),
				shm_size, (gtm_multi_proc_fnptr_t)&mur_forward_multi_proc_init,
				(gtm_multi_proc_fnptr_t)&mur_forward_multi_proc_finish);
	return (uint4)sts;
}
void cce_cluster(void )
{
	enum db_ver		database;
	char			fn[256];
	struct FAB  		ccpfab;
	struct XABFHC		xab;
	sgmnt_data		*old_data, *dummy_data;
	short			iosb[4];
	unsigned short		fn_len;
	int4			status, size, cluster, space_needed;
	error_def(ERR_CCERDERR);
	error_def(ERR_CCEWRTERR);
	error_def(ERR_CCEDBCL);
	error_def(ERR_CCEDBNTCL);
	error_def(ERR_CCEBADFN);
	error_def(ERR_DBOPNERR);
	error_def(ERR_DBNOTGDS);
	error_def(ERR_BADDBVER);
	error_def(ERR_CCEBGONLY);
	$DESCRIPTOR(cluster_qualifier, "CLUSTER");

	fn_len = SIZEOF(fn);
	if (!cli_get_str("FILE",fn,&fn_len))
	{
		lib$signal(ERR_CCEBADFN);
		return;
	}
	ccpfab = cc$rms_fab;
	ccpfab.fab$l_fna = fn;
	ccpfab.fab$b_fns = fn_len;
	ccpfab.fab$b_fac = FAB$M_BIO | FAB$M_GET | FAB$M_PUT;
	ccpfab.fab$l_fop = FAB$M_UFO;
	xab = cc$rms_xabfhc;
	ccpfab.fab$l_xab = &xab;
	status = sys$open(&ccpfab);
	if (status != RMS$_NORMAL)
	{
		lib$signal(ERR_DBOPNERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status);
		return;
	}
	dummy_data = malloc(ROUND_UP(SIZEOF(sgmnt_data), OS_PAGELET_SIZE));
	status = sys$qiow(EFN$C_ENF, ccpfab.fab$l_stv, IO$_READVBLK, iosb, 0, 0, dummy_data,
			  ROUND_UP(SIZEOF(sgmnt_data), OS_PAGELET_SIZE), 1,0,0,0);
	if (status & 1)
		status = iosb[0];
	if ((status & 1) == 0)
	{
		lib$signal(ERR_CCERDERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status);
		sys$dassgn(ccpfab.fab$l_stv);
		free(dummy_data);
		return;
	}
/*
  Commented out as this is unused code and we are removing the old version database references
  (SE - 4/2005 V5.0)
  if (memcmp(&dummy_data->label[0], GDS_LABEL, GDS_LABEL_SZ))
  {	if (memcmp(&dummy_data->label[0], GDS_LABEL, GDS_LABEL_SZ - 3))
  {	lib$signal (ERR_DBNOTGDS, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna);
  status = sys$dassgn(ccpfab.fab$l_stv);
  assert(status & 1);
  free(dummy_data);
  return;
  }else
  {
  if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V23,2))
  database = v23;
  else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V24,2))
  database = v24;
  else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V25,2))
  database = v25;
  else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V254,2))
  database = v254;
  else
  lib$signal (ERR_BADDBVER, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna);
  }
  }
  else
  database = v255;
*/

	if (dummy_data->acc_meth != dba_bg)
	{
		lib$signal(ERR_CCEBGONLY);
		status = sys$dassgn(ccpfab.fab$l_stv);
		assert(status & 1);
		free(dummy_data);
		return;
	}
	size = (LOCK_BLOCK(dummy_data) * DISK_BLOCK_SIZE) + LOCK_SPACE_SIZE(dummy_data);
	old_data = malloc(size);
	memcpy(old_data, dummy_data, SIZEOF(sgmnt_data));
	cluster = cli$present(&cluster_qualifier);
	if (cluster == CLI$_NEGATED)
		old_data->clustered = FALSE;
	else if (cluster == CLI$_PRESENT)
	{
		old_data->clustered = TRUE;
		old_data->trans_hist.lock_sequence = 0;
	}
	change_fhead_timer("STALE_INTERVAL", old_data->staleness, -50000000, TRUE);
	change_fhead_timer("RESPONSE_INTERVAL",old_data->ccp_response_interval, -600000000, TRUE);
	change_fhead_timer("QUANTUM_INTERVAL", old_data->ccp_quantum_interval, -10000000, FALSE);
	change_fhead_timer("TICK_INTERVAL", old_data->ccp_tick_interval, -1000000, FALSE);
	if (old_data->unbacked_cache)
	{
		space_needed = (old_data->n_bts + getprime(old_data->n_bts) + 1) * SIZEOF(bt_rec);
		if (space_needed > old_data->free_space)
		{
			old_data->n_bts = old_data->free_space/(2*SIZEOF(bt_rec));
			for (;;)
			{
				space_needed = (old_data->n_bts + getprime(old_data->n_bts) + 1) * SIZEOF(bt_rec);
				if (space_needed <= old_data->free_space)
				{
					old_data->bt_buckets = getprime(old_data->n_bts);
					break;
				}
				old_data->n_bts--;
			}
			util_out_open(0);
			util_out_print("Only have space for !UL cache records in clustered file !AD, adjusting file",TRUE,
				       old_data->n_bts, fn_len, fn);
		}
		old_data->free_space -= space_needed;
		old_data->unbacked_cache = FALSE;
	}
	status = dbcx_ref(old_data, ccpfab.fab$l_stv);
	if ((status & 1) == 0)
		lib$signal(ERR_CCEWRTERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status);
	if (cluster != CLI$_ABSENT)
		lib$signal ((old_data->clustered) ? ERR_CCEDBCL : ERR_CCEDBNTCL, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna);
	status = sys$dassgn(ccpfab.fab$l_stv);
	assert(status & 1);
	free(dummy_data);
	free(old_data);
	return;
}
Beispiel #16
0
int4 mupip_set_file(int db_fn_len, char *db_fn)
{
	bool			got_standalone;
	boolean_t		bypass_partial_recov, need_standalone = FALSE;
	char			acc_spec[MAX_ACC_METH_LEN], ver_spec[MAX_DB_VER_LEN], exit_stat, *fn;
	unsigned short		acc_spec_len = MAX_ACC_METH_LEN, ver_spec_len = MAX_DB_VER_LEN;
	int			fd, fn_len;
	int4			status;
	int4			status1;
	int			glbl_buff_status, defer_status, rsrvd_bytes_status,
				extn_count_status, lock_space_status, disk_wait_status;
	int4			new_disk_wait, new_cache_size, new_extn_count, new_lock_space, reserved_bytes, defer_time;
	sgmnt_data_ptr_t	csd;
	tp_region		*rptr, single;
	enum db_acc_method	access, access_new;
	enum db_ver		desired_dbver;
	gd_region		*temp_cur_region;
	char			*errptr, *command = "MUPIP SET VERSION";
	int			save_errno;

	error_def(ERR_DBPREMATEOF);
	error_def(ERR_DBRDERR);
	error_def(ERR_DBRDONLY);
	error_def(ERR_INVACCMETHOD);
	error_def(ERR_MUNOACTION);
	error_def(ERR_RBWRNNOTCHG);
	error_def(ERR_WCERRNOTCHG);
	error_def(ERR_WCWRNNOTCHG);
	error_def(ERR_MMNODYNDWNGRD);

	exit_stat = EXIT_NRM;
	defer_status = cli_present("DEFER_TIME");
	if (defer_status)
		need_standalone = TRUE;
	bypass_partial_recov = cli_present("PARTIAL_RECOV_BYPASS") == CLI_PRESENT;
	if (bypass_partial_recov)
		need_standalone = TRUE;
	if (disk_wait_status = cli_present("WAIT_DISK"))
	{
		if (cli_get_int("WAIT_DISK", &new_disk_wait))
		{
			if (new_disk_wait < 0)
			{
				util_out_print("!UL negative, minimum WAIT_DISK allowed is 0.", TRUE, new_disk_wait);
				return (int4)ERR_WCWRNNOTCHG;
			}
			need_standalone = TRUE;
		} else
		{
			util_out_print("Error getting WAIT_DISK qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (glbl_buff_status = cli_present("GLOBAL_BUFFERS"))
	{
		if (cli_get_int("GLOBAL_BUFFERS", &new_cache_size))
		{
			if (new_cache_size > WC_MAX_BUFFS)
			{
				util_out_print("!UL too large, maximum write cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MAX_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_cache_size < WC_MIN_BUFFS)
			{
				util_out_print("!UL too small, minimum cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MIN_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting GLOBAL BUFFER qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	/* EXTENSION_COUNT does not require standalone access and hence need_standalone will not be set to TRUE for this. */
	if (extn_count_status = cli_present("EXTENSION_COUNT"))
	{
		if (cli_get_int("EXTENSION_COUNT", &new_extn_count))
		{
			if (new_extn_count > MAX_EXTN_COUNT)
			{
				util_out_print("!UL too large, maximum extension count allowed is !UL", TRUE, new_extn_count,
						MAX_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_extn_count < MIN_EXTN_COUNT)
			{
				util_out_print("!UL too small, minimum extension count allowed is !UL", TRUE, new_extn_count,
						MIN_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting EXTENSION COUNT qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (lock_space_status = cli_present("LOCK_SPACE"))
	{
		if (cli_get_int("LOCK_SPACE", &new_lock_space))
		{
			if (new_lock_space > MAX_LOCK_SPACE)
			{
				util_out_print("!UL too large, maximum lock space allowed is !UL", TRUE,
						new_lock_space, MAX_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
			else if (new_lock_space < MIN_LOCK_SPACE)
			{
				util_out_print("!UL too small, minimum lock space allowed is !UL", TRUE,
						new_lock_space, MIN_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting LOCK_SPACE qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (rsrvd_bytes_status = cli_present("RESERVED_BYTES"))
	{
		if (!cli_get_int("RESERVED_BYTES", &reserved_bytes))
		{
			util_out_print("Error getting RESERVED BYTES qualifier value", TRUE);
			return (int4)ERR_RBWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (cli_present("ACCESS_METHOD"))
	{
		cli_get_str("ACCESS_METHOD", acc_spec, &acc_spec_len);
		cli_strupper(acc_spec);
		if (0 == memcmp(acc_spec, "MM", acc_spec_len))
			access = dba_mm;
		else  if (0 == memcmp(acc_spec, "BG", acc_spec_len))
			access = dba_bg;
		else
			mupip_exit(ERR_INVACCMETHOD);
		need_standalone = TRUE;
	} else
		access = n_dba;		/* really want to keep current method,
					    which has not yet been read */
	if (cli_present("VERSION"))
	{
		assert(!need_standalone);
		cli_get_str("VERSION", ver_spec, &ver_spec_len);
		cli_strupper(ver_spec);
		if (0 == memcmp(ver_spec, "V4", ver_spec_len))
			desired_dbver = GDSV4;
		else  if (0 == memcmp(ver_spec, "V5", ver_spec_len))
			desired_dbver = GDSV5;
		else
			GTMASSERT;		/* CLI should prevent us ever getting here */
	} else
		desired_dbver = GDSVLAST;	/* really want to keep version, which has not yet been read */
	if (region)
		rptr = grlist;
	else
	{
		rptr = &single;
		memset(&single, 0, sizeof(single));
	}

	csd = (sgmnt_data *)malloc(ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE));
	in_backup = FALSE;		/* Only want yes/no from mupfndfil, not an address */
	for (;  rptr != NULL;  rptr = rptr->fPtr)
	{
		if (region)
		{
			if (dba_usr == rptr->reg->dyn.addr->acc_meth)
			{
				util_out_print("!/Region !AD is not a GDS access type", TRUE, REG_LEN_STR(rptr->reg));
				exit_stat |= EXIT_WRN;
				continue;
			}
			if (!mupfndfil(rptr->reg, NULL))
				continue;
			fn = (char *)rptr->reg->dyn.addr->fname;
			fn_len = rptr->reg->dyn.addr->fname_len;
		} else
		{
			fn = db_fn;
			fn_len = db_fn_len;
		}
		mu_gv_cur_reg_init();
		strcpy((char *)gv_cur_region->dyn.addr->fname, fn);
		gv_cur_region->dyn.addr->fname_len = fn_len;
		if (!need_standalone)
		{
			gvcst_init(gv_cur_region);
			change_reg();	/* sets cs_addrs and cs_data */
			if (gv_cur_region->read_only)
			{
				gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
				exit_stat |= EXIT_ERR;
				gds_rundown();
				mu_gv_cur_reg_free();
				continue;
			}
			grab_crit(gv_cur_region);
			status = EXIT_NRM;
			access_new = (n_dba == access ? cs_data->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", cs_data->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if (GDSVLAST != desired_dbver)
			{
				if ((dba_mm != access_new) || (GDSV4 != desired_dbver))
					status1 = desired_db_format_set(gv_cur_region, desired_dbver, command);
				else
				{
					status1 = ERR_MMNODYNDWNGRD;
					gtm_putmsg(VARLSTCNT(4) status1, 2, REG_LEN_STR(gv_cur_region));
				}
				if (SS_NORMAL != status1)
				{	/* "desired_db_format_set" would have printed appropriate error messages */
					if (ERR_MUNOACTION != status1)
					{	/* real error occurred while setting the db format. skip to next region */
						status = EXIT_ERR;
					}
				}
			}
			if (EXIT_NRM == status)
			{
				if (extn_count_status)
					cs_data->extension_size = (uint4)new_extn_count;
				wcs_flu(WCSFLU_FLUSH_HDR);
				if (extn_count_status)
					util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, cs_data->extension_size);
				if (GDSVLAST != desired_dbver)
					util_out_print("Database file !AD now has desired DB format !AD", TRUE,
						fn_len, fn, LEN_AND_STR(gtm_dbversion_table[cs_data->desired_db_format]));
			} else
				exit_stat |= status;
			rel_crit(gv_cur_region);
			gds_rundown();
		} else
		{	/* Following part needs standalone access */
			assert(GDSVLAST == desired_dbver);
			got_standalone = mu_rndwn_file(gv_cur_region, TRUE);
			if (FALSE == got_standalone)
				return (int4)ERR_WCERRNOTCHG;
			/* we should open it (for changing) after mu_rndwn_file, since mu_rndwn_file changes the file header too */
			if (-1 == (fd = OPEN(fn, O_RDWR)))
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("open : !AZ", TRUE, errptr);
				exit_stat |= EXIT_ERR;
				db_ipcs_reset(gv_cur_region, FALSE);
				mu_gv_cur_reg_free();
				continue;
			}
			LSEEKREAD(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				PERROR("Error reading header of file");
				errptr = (char *)STRERROR(save_errno);
				util_out_print("read : !AZ", TRUE, errptr);
				util_out_print("Error reading header of file", TRUE);
				util_out_print("Database file !AD not changed:  ", TRUE, fn_len, fn);
				if (-1 != status)
					rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
				else
					rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			}
			if (rsrvd_bytes_status)
			{
				if (reserved_bytes > MAX_RESERVE_B(csd))
				{
					util_out_print("!UL too large, maximum reserved bytes allowed is !UL for database file !AD",
							TRUE, reserved_bytes, MAX_RESERVE_B(csd), fn_len, fn);
					close(fd);
					db_ipcs_reset(gv_cur_region, FALSE);
					return (int4)ERR_RBWRNNOTCHG;
				}
				csd->reserved_bytes = reserved_bytes;
			}
			access_new = (n_dba == access ? csd->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", csd->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if ((n_dba != access) && (csd->acc_meth != access))	/* n_dba is a proxy for no change */
			{
				if (dba_mm == access)
					csd->defer_time = 1;			/* defer defaults to 1 */
				csd->acc_meth = access;
				if (0 == csd->n_bts)
				{
					csd->n_bts = WC_DEF_BUFFS;
					csd->bt_buckets = getprime(csd->n_bts);
				}
			}
			if (glbl_buff_status)
			{
				csd->n_bts = BT_FACTOR(new_cache_size);
				csd->bt_buckets = getprime(csd->n_bts);
				csd->n_wrt_per_flu = 7;
				csd->flush_trigger = FLUSH_FACTOR(csd->n_bts);
			}
			if (disk_wait_status)
				csd->wait_disk_space = new_disk_wait;
			if (extn_count_status)
				csd->extension_size = (uint4)new_extn_count;
			if (lock_space_status)
				csd->lock_space_size = (uint4)new_lock_space * OS_PAGELET_SIZE;
			if (bypass_partial_recov)
			{
				csd->file_corrupt = FALSE;
				util_out_print("Database file !AD now has partial recovery flag set to  !UL(FALSE) ",
						TRUE, fn_len, fn, csd->file_corrupt);
			}
			if (dba_mm == access_new)
			{
				if (CLI_NEGATED == defer_status)
					csd->defer_time = 0;
				else  if (CLI_PRESENT == defer_status)
				{
					if (!cli_get_num("DEFER_TIME", &defer_time))
					{
						util_out_print("Error getting DEFER_TIME qualifier value", TRUE);
						db_ipcs_reset(gv_cur_region, FALSE);
						return (int4)ERR_RBWRNNOTCHG;
					}
					if (-1 > defer_time)
					{
						util_out_print("DEFER_TIME cannot take negative values less than -1", TRUE);
						util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
						exit_stat |= EXIT_WRN;
						db_ipcs_reset(gv_cur_region, FALSE);
						mu_gv_cur_reg_free();
						continue;
					}
					csd->defer_time = defer_time;
				}
				if (csd->blks_to_upgrd)
				{
					util_out_print("MM access method cannot be set if there are blocks to upgrade",	TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (GDSVCURR != csd->desired_db_format)
				{
					util_out_print("MM access method cannot be set in DB compatibility mode",
						TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (JNL_ENABLED(csd) && csd->jnl_before_image)
				{
					util_out_print("MM access method cannot be set with BEFORE image journaling", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				csd->jnl_before_image = FALSE;
			} else
			{
				if (defer_status)
				{
					util_out_print("DEFER cannot be specified with BG access method.", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
			}
			LSEEKWRITE(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("write : !AZ", TRUE, errptr);
				util_out_print("Error writing header of file", TRUE);
				util_out_print("Database file !AD not changed: ", TRUE, fn_len, fn);
				rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
			}
			close(fd);
			/* --------------------- report results ------------------------- */
			if (glbl_buff_status)
				util_out_print("Database file !AD now has !UL global buffers",
						TRUE, fn_len, fn, csd->n_bts);
			if (defer_status && (dba_mm == csd->acc_meth))
				util_out_print("Database file !AD now has defer_time set to !SL",
						TRUE, fn_len, fn, csd->defer_time);
			if (rsrvd_bytes_status)
				util_out_print("Database file !AD now has !UL reserved bytes",
						TRUE, fn_len, fn, csd->reserved_bytes);
			if (extn_count_status)
				util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, csd->extension_size);
			if (lock_space_status)
				util_out_print("Database file !AD now has lock space !UL pages",
						TRUE, fn_len, fn, csd->lock_space_size/OS_PAGELET_SIZE);
			if (disk_wait_status)
				util_out_print("Database file !AD now has wait disk set to !UL seconds",
						TRUE, fn_len, fn, csd->wait_disk_space);
			db_ipcs_reset(gv_cur_region, FALSE);
		} /* end of else part if (!need_standalone) */
		mu_gv_cur_reg_free();
	}
	free(csd);
	assert(!(exit_stat & EXIT_INF));
	return (exit_stat & EXIT_ERR ? (int4)ERR_WCERRNOTCHG :
		(exit_stat & EXIT_WRN ? (int4)ERR_WCWRNNOTCHG : SS_NORMAL));
}