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; }
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]); }
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; }
/* 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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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)); }