1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * db_log.cc 24*7c478bd9Sstevel@tonic-gate * 25*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 27*7c478bd9Sstevel@tonic-gate */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <malloc.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 37*7c478bd9Sstevel@tonic-gate #include <sysent.h> 38*7c478bd9Sstevel@tonic-gate #endif 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "db_headers.h" 42*7c478bd9Sstevel@tonic-gate #include "db_log.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include "nisdb_mt.h" 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static void 47*7c478bd9Sstevel@tonic-gate delete_log_entry(db_log_entry *lentry) 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate db_query *q; 50*7c478bd9Sstevel@tonic-gate entry_object *obj; 51*7c478bd9Sstevel@tonic-gate if (lentry) { 52*7c478bd9Sstevel@tonic-gate if ((q = lentry->get_query())) { 53*7c478bd9Sstevel@tonic-gate delete q; 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate if ((obj = lentry->get_object())) { 56*7c478bd9Sstevel@tonic-gate free_entry(obj); 57*7c478bd9Sstevel@tonic-gate } 58*7c478bd9Sstevel@tonic-gate delete lentry; 59*7c478bd9Sstevel@tonic-gate } 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /* 63*7c478bd9Sstevel@tonic-gate * Execute given function 'func' on log. 64*7c478bd9Sstevel@tonic-gate * function takes as arguments: pointer to log entry, character pointer to 65*7c478bd9Sstevel@tonic-gate * another argument, and pointer to an integer, which is used as a counter. 66*7c478bd9Sstevel@tonic-gate * 'func' should increment this value for each successful application. 67*7c478bd9Sstevel@tonic-gate * The log is traversed until either 'func' returns FALSE, or when the log 68*7c478bd9Sstevel@tonic-gate * is exhausted. The second argument to 'execute_on_log' is passed as the 69*7c478bd9Sstevel@tonic-gate * second argument to 'func'. The third argument, 'clean' determines whether 70*7c478bd9Sstevel@tonic-gate * the log entry is deleted after the function has been applied. 71*7c478bd9Sstevel@tonic-gate * Returns the number of times that 'func' incremented its third argument. 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate int 74*7c478bd9Sstevel@tonic-gate db_log::execute_on_log(bool_t (*func) (db_log_entry *, char *, int *), 75*7c478bd9Sstevel@tonic-gate char* arg, bool_t clean) 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate db_log_entry *j; 78*7c478bd9Sstevel@tonic-gate int count = 0; 79*7c478bd9Sstevel@tonic-gate bool_t done = FALSE; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate WRITELOCK(this, 0, "w db_log::execute_on_log"); 82*7c478bd9Sstevel@tonic-gate if (open() == TRUE) { // open log 83*7c478bd9Sstevel@tonic-gate while (!done) { 84*7c478bd9Sstevel@tonic-gate j = get(); 85*7c478bd9Sstevel@tonic-gate if (j == NULL) 86*7c478bd9Sstevel@tonic-gate break; 87*7c478bd9Sstevel@tonic-gate if ((*func)(j, arg, &count) == FALSE) done = TRUE; 88*7c478bd9Sstevel@tonic-gate if (clean) delete_log_entry(j); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate sync_log(); 92*7c478bd9Sstevel@tonic-gate close(); 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, count, "wu db_log::execute_on_log"); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate return (count); 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate static bool_t 100*7c478bd9Sstevel@tonic-gate print_log_entry(db_log_entry *j, char * /* dummy */, int *count) 101*7c478bd9Sstevel@tonic-gate { 102*7c478bd9Sstevel@tonic-gate j->print(); 103*7c478bd9Sstevel@tonic-gate ++ *count; 104*7c478bd9Sstevel@tonic-gate return (TRUE); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* Print contents of log file to stdout */ 108*7c478bd9Sstevel@tonic-gate int 109*7c478bd9Sstevel@tonic-gate db_log::print() 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate return (execute_on_log(&(print_log_entry), NULL)); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* Make copy of current log to log pointed to by 'f'. */ 115*7c478bd9Sstevel@tonic-gate int 116*7c478bd9Sstevel@tonic-gate db_log::copy(db_log *f) 117*7c478bd9Sstevel@tonic-gate { 118*7c478bd9Sstevel@tonic-gate db_log_entry *j; 119*7c478bd9Sstevel@tonic-gate int l, ret = 0; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate WRITELOCK(f, -1, "w f db_log::copy"); 122*7c478bd9Sstevel@tonic-gate if ((l = acqnonexcl()) != 0) { 123*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(f, l, "wu f db_log::copy"); 124*7c478bd9Sstevel@tonic-gate return (l); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate for (;;) { 127*7c478bd9Sstevel@tonic-gate j = get(); 128*7c478bd9Sstevel@tonic-gate if (j == NULL) 129*7c478bd9Sstevel@tonic-gate break; 130*7c478bd9Sstevel@tonic-gate if (f->append(j) < 0) { 131*7c478bd9Sstevel@tonic-gate WARNING_M( 132*7c478bd9Sstevel@tonic-gate "db_log::copy: could not append to log file: "); 133*7c478bd9Sstevel@tonic-gate ret = -1; 134*7c478bd9Sstevel@tonic-gate break; 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate delete_log_entry(j); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate if ((l = relnonexcl()) != 0) { 139*7c478bd9Sstevel@tonic-gate ret = l; 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(f, ret, "wu f db_log::copy"); 142*7c478bd9Sstevel@tonic-gate return (ret); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* Rewinds current log */ 146*7c478bd9Sstevel@tonic-gate int 147*7c478bd9Sstevel@tonic-gate db_log::rewind() 148*7c478bd9Sstevel@tonic-gate { 149*7c478bd9Sstevel@tonic-gate return (fseek(file, 0L, 0)); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * Return the next element in current log; return NULL if end of log or error. 154*7c478bd9Sstevel@tonic-gate * Log must have been opened for READ. 155*7c478bd9Sstevel@tonic-gate */ 156*7c478bd9Sstevel@tonic-gate db_log_entry 157*7c478bd9Sstevel@tonic-gate *db_log::get() 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate db_log_entry *j; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate READLOCK(this, NULL, "r db_log::get"); 162*7c478bd9Sstevel@tonic-gate if (mode != PICKLE_READ) { 163*7c478bd9Sstevel@tonic-gate READUNLOCK(this, NULL, "ru db_log::get"); 164*7c478bd9Sstevel@tonic-gate return (NULL); 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate j = new db_log_entry; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate if (j == NULL) { 170*7c478bd9Sstevel@tonic-gate READUNLOCK(this, NULL, "ru db_log::get"); 171*7c478bd9Sstevel@tonic-gate return (NULL); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate if (xdr_db_log_entry(&(xdr), j) == FALSE) { 174*7c478bd9Sstevel@tonic-gate delete_log_entry (j); 175*7c478bd9Sstevel@tonic-gate /* WARNING("Could not sucessfully finish reading log"); */ 176*7c478bd9Sstevel@tonic-gate READUNLOCK(this, NULL, "ru db_log::get"); 177*7c478bd9Sstevel@tonic-gate return (NULL); 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate if (! j->sane()) { 180*7c478bd9Sstevel@tonic-gate WARNING("truncated log entry found"); 181*7c478bd9Sstevel@tonic-gate delete_log_entry(j); 182*7c478bd9Sstevel@tonic-gate j = NULL; 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate READUNLOCK(this, j, "ru db_log::get"); 185*7c478bd9Sstevel@tonic-gate return (j); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate /* Append given log entry to log. */ 189*7c478bd9Sstevel@tonic-gate int 190*7c478bd9Sstevel@tonic-gate db_log::append(db_log_entry *j) 191*7c478bd9Sstevel@tonic-gate { 192*7c478bd9Sstevel@tonic-gate int status; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate WRITELOCK(this, -1, "w db_log::append"); 195*7c478bd9Sstevel@tonic-gate if (mode != PICKLE_APPEND) { 196*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, -1, "wu db_log::append"); 197*7c478bd9Sstevel@tonic-gate return (-1); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate /* xdr returns TRUE if successful, FALSE otherwise */ 201*7c478bd9Sstevel@tonic-gate status = ((xdr_db_log_entry(&(xdr), j)) ? 0 : -1); 202*7c478bd9Sstevel@tonic-gate if (status < 0) { 203*7c478bd9Sstevel@tonic-gate WARNING("db_log: could not write log entry"); 204*7c478bd9Sstevel@tonic-gate } else { 205*7c478bd9Sstevel@tonic-gate syncstate++; 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, status, "wu db_log::append"); 208*7c478bd9Sstevel@tonic-gate return (status); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate int 212*7c478bd9Sstevel@tonic-gate copy_log_file(char *oldname, char *newname) { 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate int from, to, ret = 0; 215*7c478bd9Sstevel@tonic-gate ssize_t size, w, b; 216*7c478bd9Sstevel@tonic-gate char buf[8192]; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate if ((from = open(oldname, O_RDONLY, 0666)) < 0) { 219*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 220*7c478bd9Sstevel@tonic-gate return (0); 221*7c478bd9Sstevel@tonic-gate } else { 222*7c478bd9Sstevel@tonic-gate return (errno); 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate if ((to = open(newname, O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0) { 226*7c478bd9Sstevel@tonic-gate ret = errno; 227*7c478bd9Sstevel@tonic-gate (void) close(from); 228*7c478bd9Sstevel@tonic-gate return (ret); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate while ((size = read(from, buf, sizeof (buf))) > 0) { 232*7c478bd9Sstevel@tonic-gate b = 0; 233*7c478bd9Sstevel@tonic-gate while (size > 0) { 234*7c478bd9Sstevel@tonic-gate w = write(to, &buf[b], size); 235*7c478bd9Sstevel@tonic-gate if (w < 0) { 236*7c478bd9Sstevel@tonic-gate size == -1; 237*7c478bd9Sstevel@tonic-gate break; 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate size -= w; 240*7c478bd9Sstevel@tonic-gate b += w; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate if (size != 0) { 243*7c478bd9Sstevel@tonic-gate ret = errno; 244*7c478bd9Sstevel@tonic-gate break; 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate (void) close(from); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate if (ret != 0) { 251*7c478bd9Sstevel@tonic-gate errno = ret; 252*7c478bd9Sstevel@tonic-gate WARNING_M("db_log: error copying log file") 253*7c478bd9Sstevel@tonic-gate (void) close(to); 254*7c478bd9Sstevel@tonic-gate return (ret); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate if (fsync(to) != 0) { 258*7c478bd9Sstevel@tonic-gate ret = errno; 259*7c478bd9Sstevel@tonic-gate WARNING_M("db_log: error syncing log file"); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate (void) close(to); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate return (ret); 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate /* 269*7c478bd9Sstevel@tonic-gate * Return value is expected to be the usual C convention of non-zero 270*7c478bd9Sstevel@tonic-gate * for success, 0 for failure. 271*7c478bd9Sstevel@tonic-gate */ 272*7c478bd9Sstevel@tonic-gate int 273*7c478bd9Sstevel@tonic-gate db_log::sync_log() 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate int status, err; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate WRITELOCK(this, -1, "w db_log::sync_log"); 278*7c478bd9Sstevel@tonic-gate status = fflush(file); 279*7c478bd9Sstevel@tonic-gate if (status < 0) { 280*7c478bd9Sstevel@tonic-gate WARNING("db_log: could not flush log entry to disk"); 281*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, status, "wu db_log::sync_log"); 282*7c478bd9Sstevel@tonic-gate return (status); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate status = fsync(fileno(file)); 286*7c478bd9Sstevel@tonic-gate if (status < 0) { 287*7c478bd9Sstevel@tonic-gate WARNING("db_log: could not sync log entry to disk"); 288*7c478bd9Sstevel@tonic-gate } else if (tmplog != 0) { 289*7c478bd9Sstevel@tonic-gate if (syncstate == 0) { 290*7c478bd9Sstevel@tonic-gate /* Log already stable; nothing to do */ 291*7c478bd9Sstevel@tonic-gate err = 0; 292*7c478bd9Sstevel@tonic-gate } else if ((err = copy_log_file(tmplog, stablelog)) == 0) { 293*7c478bd9Sstevel@tonic-gate if (rename(stablelog, oldlog) != 0) { 294*7c478bd9Sstevel@tonic-gate WARNING_M("db_log: could not mv stable log"); 295*7c478bd9Sstevel@tonic-gate } else { 296*7c478bd9Sstevel@tonic-gate syncstate = 0; 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate } else { 299*7c478bd9Sstevel@tonic-gate errno = err; 300*7c478bd9Sstevel@tonic-gate WARNING_M("db_log: could not stabilize log"); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate status = (err == 0); 303*7c478bd9Sstevel@tonic-gate } else { 304*7c478bd9Sstevel@tonic-gate /* 305*7c478bd9Sstevel@tonic-gate * Successful sync of file, but no tmplog to sync 306*7c478bd9Sstevel@tonic-gate * so we make sure we return 'success'. 307*7c478bd9Sstevel@tonic-gate */ 308*7c478bd9Sstevel@tonic-gate status = 1; 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, status, "wu db_log::sync_log"); 311*7c478bd9Sstevel@tonic-gate return (status); 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate int 315*7c478bd9Sstevel@tonic-gate db_log::close() { 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate int ret; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate WRITELOCK(this, -1, "w db_log::close"); 320*7c478bd9Sstevel@tonic-gate if (mode != PICKLE_READ && oldlog != 0) { 321*7c478bd9Sstevel@tonic-gate if (syncstate != 0) { 322*7c478bd9Sstevel@tonic-gate WARNING("db_log: closing unstable tmp log"); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate filename = oldlog; 325*7c478bd9Sstevel@tonic-gate oldlog = 0; 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate ret = pickle_file::close(); 329*7c478bd9Sstevel@tonic-gate if (tmplog != 0) { 330*7c478bd9Sstevel@tonic-gate (void) unlink(tmplog); 331*7c478bd9Sstevel@tonic-gate delete tmplog; 332*7c478bd9Sstevel@tonic-gate tmplog = 0; 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate if (stablelog != 0) { 335*7c478bd9Sstevel@tonic-gate delete stablelog; 336*7c478bd9Sstevel@tonic-gate stablelog = 0; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, ret, "wu db_log::close"); 339*7c478bd9Sstevel@tonic-gate return (ret); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate bool_t 343*7c478bd9Sstevel@tonic-gate db_log::open(void) { 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate int len, cpstat; 346*7c478bd9Sstevel@tonic-gate bool_t ret; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate WRITELOCK(this, FALSE, "w db_log::open"); 349*7c478bd9Sstevel@tonic-gate if (mode == PICKLE_READ || (!copylog)) { 350*7c478bd9Sstevel@tonic-gate ret = pickle_file::open(); 351*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, ret, "wu db_log::open"); 352*7c478bd9Sstevel@tonic-gate return (ret); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate len = strlen(filename); 356*7c478bd9Sstevel@tonic-gate tmplog = new char[len + sizeof (".tmp")]; 357*7c478bd9Sstevel@tonic-gate if (tmplog == 0) { 358*7c478bd9Sstevel@tonic-gate WARNING("db_log: could not allocate tmp log name"); 359*7c478bd9Sstevel@tonic-gate ret = pickle_file::open(); 360*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, ret, "wu db_log::open"); 361*7c478bd9Sstevel@tonic-gate return (ret); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate stablelog = new char[len + sizeof (".stable")]; 364*7c478bd9Sstevel@tonic-gate if (stablelog == 0) { 365*7c478bd9Sstevel@tonic-gate WARNING("db_log: could not allocate stable log name"); 366*7c478bd9Sstevel@tonic-gate delete tmplog; 367*7c478bd9Sstevel@tonic-gate tmplog = 0; 368*7c478bd9Sstevel@tonic-gate ret = pickle_file::open(); 369*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, ret, "wu db_log::open"); 370*7c478bd9Sstevel@tonic-gate return (ret); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate sprintf(tmplog, "%s.tmp", filename); 373*7c478bd9Sstevel@tonic-gate sprintf(stablelog, "%s.stable", filename); 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate if ((cpstat = copy_log_file(filename, tmplog)) == 0) { 376*7c478bd9Sstevel@tonic-gate oldlog = filename; 377*7c478bd9Sstevel@tonic-gate filename = tmplog; 378*7c478bd9Sstevel@tonic-gate } else { 379*7c478bd9Sstevel@tonic-gate syslog(LOG_WARNING, 380*7c478bd9Sstevel@tonic-gate "db_log: Error copying \"%s\" to \"%s\": %s", 381*7c478bd9Sstevel@tonic-gate filename, tmplog, strerror(cpstat)); 382*7c478bd9Sstevel@tonic-gate delete tmplog; 383*7c478bd9Sstevel@tonic-gate tmplog = 0; 384*7c478bd9Sstevel@tonic-gate delete stablelog; 385*7c478bd9Sstevel@tonic-gate stablelog = 0; 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate ret = pickle_file::open(); 389*7c478bd9Sstevel@tonic-gate WRITEUNLOCK(this, ret, "wu db_log::open"); 390*7c478bd9Sstevel@tonic-gate return (ret); 391*7c478bd9Sstevel@tonic-gate } 392