From 0f78f3fe78e859d9f0d3f0d3e13fcd28085dd427 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 14 Nov 2006 08:12:06 +0000 Subject: [PATCH] Work on bug #550: Avoid exit. In particular the mfile/cfile/bfile has been refactored quite a bit. Remaining exit uses zebra_exit. Removed redundant apitest.c. --- bfile/bfile.c | 61 +++++++--- bfile/cfile.c | 70 +++++++---- bfile/cfile.h | 4 +- bfile/commit.c | 104 +++++++++++------ bfile/mfile.c | 94 +++++---------- bfile/mfile.h | 76 ++++++++---- dict/dclose.c | 7 +- dict/dopen.c | 7 +- include/idzebra/api.h | 20 +--- include/idzebra/bfile.h | 29 +++-- include/idzebra/util.h | 23 +++- index/Makefile.am | 5 +- index/apitest.c | 297 ----------------------------------------------- index/extract.c | 10 +- index/recindex.c | 3 +- index/zebraapi.c | 130 +++++++++++---------- index/zinfo.c | 5 +- isamb/isamb.c | 22 +++- isamc/isamc.c | 70 ++++++----- rset/rstemp.c | 16 +-- util/Makefile.am | 5 +- util/exit.c | 39 +++++++ win/makefile | 3 +- 23 files changed, 497 insertions(+), 603 deletions(-) delete mode 100644 index/apitest.c create mode 100644 util/exit.c diff --git a/bfile/bfile.c b/bfile/bfile.c index 7fb6a8c..1f6f49d 100644 --- a/bfile/bfile.c +++ b/bfile/bfile.c @@ -1,4 +1,4 @@ -/* $Id: bfile.c,v 1.51 2006-11-08 22:08:27 adam Exp $ +/* $Id: bfile.c,v 1.52 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -98,7 +98,8 @@ static FILE *open_cache(BFiles bfs, const char *flags) static void unlink_cache(BFiles bfs) { - unlink(bfs->cache_fname); + if (bfs->cache_fname) + unlink(bfs->cache_fname); } ZEBRA_RES bf_cache(BFiles bfs, const char *spec) @@ -127,19 +128,35 @@ ZEBRA_RES bf_cache(BFiles bfs, const char *spec) return ZEBRA_OK; } -int bf_close(BFile bf) +int bf_close2(BFile bf) { + int ret = 0; zebra_lock_rdwr_destroy(&bf->rdwr_lock); if (bf->cf) - cf_close(bf->cf); + { + if (cf_close(bf->cf)) + ret = -1; + } if (bf->mf) - mf_close(bf->mf); + { + if (mf_close(bf->mf)) + ret = -1; + } xfree(bf->alloc_buf); xfree(bf->magic); xfree(bf); - return 0; + return ret; +} + +void bf_close(BFile bf) +{ + if (bf_close2(bf)) + { + zebra_exit("bf_close"); + } } + #define HEADER_SIZE 256 BFile bf_xopen(BFiles bfs, const char *name, int block_size, int wrflag, @@ -238,7 +255,7 @@ int bf_xclose(BFile bf, int version, const char *more_info) break; } } - return bf_close(bf); + return bf_close2(bf); } BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag) @@ -305,7 +322,7 @@ int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf) if (ret == -1) { - exit(1); + zebra_exit("bf_read"); } return ret; } @@ -332,7 +349,7 @@ int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf) if (ret == -1) { - exit(1); + zebra_exit("bf_write"); } return ret; } @@ -371,7 +388,7 @@ void bf_reset(BFiles bfs) unlink_cache(bfs); } -void bf_commitExec(BFiles bfs) +int bf_commitExec(BFiles bfs) { FILE *inf; int block_size; @@ -379,24 +396,40 @@ void bf_commitExec(BFiles bfs) MFile mf; CFile cf; int first_time; + int r = 0; assert(bfs->commit_area); if (!(inf = open_cache(bfs, "rb"))) { yaz_log(YLOG_LOG, "No commit file"); - return ; + return -1; } while (fscanf(inf, "%s %d", path, &block_size) == 2) { mf = mf_open(bfs->register_area, path, block_size, 1); + if (!mf) + { + r = -1; + break; + } cf = cf_open(mf, bfs->commit_area, path, block_size, 0, &first_time); + if (!cf) + { + mf_close(mf); + r = -1; + break; + } - cf_commit(cf); + r = cf_commit(cf); cf_close(cf); mf_close(mf); + + if (r) + break; } fclose(inf); + return r; } void bf_commitClean(BFiles bfs, const char *spec) @@ -432,11 +465,11 @@ int bf_alloc(BFile bf, int no, zint *blocks) memset(buf, '\0', sizeof(buf)); blocks[i] = bf->free_list; - if (!bf_read(bf, bf->free_list, 0, sizeof(buf), buf)) + if (bf_read(bf, bf->free_list, 0, sizeof(buf), buf) != 1) { yaz_log(YLOG_WARN, "Bad freelist entry " ZINT_FORMAT, bf->free_list); - exit(1); + return -1; } zebra_zint_decode(&cp, &bf->free_list); } diff --git a/bfile/cfile.c b/bfile/cfile.c index f84d395..4774072 100644 --- a/bfile/cfile.c +++ b/bfile/cfile.c @@ -1,4 +1,4 @@ -/* $Id: cfile.c,v 1.38 2006-11-08 22:08:27 adam Exp $ +/* $Id: cfile.c,v 1.39 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -83,6 +83,9 @@ CFile cf_open(MFile mf, MFile_area area, const char *fname, CFile cf = (CFile) xmalloc(sizeof(*cf)); int hash_bytes; + /* avoid valgrind warnings, but set to something nasty */ + memset(cf, 'Z', sizeof(*cf)); + yaz_log(YLOG_DEBUG, "cf: open %s %s", cf->rmf->name, wflag ? "rdwr" : "rd"); @@ -110,14 +113,12 @@ CFile cf_open(MFile mf, MFile_area area, const char *fname, sprintf(path, "%s-b", fname); if (!(cf->block_mf = mf_open(area, path, block_size, wflag))) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path); cf_close(cf); return 0; } sprintf(path, "%s-i", fname); if (!(cf->hash_mf = mf_open(area, path, HASH_BSIZE, wflag))) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path); cf_close(cf); return 0; } @@ -207,9 +208,10 @@ static void release_bucket(CFile cf, struct CFile_hash_bucket *p) xfree(p); } -static void flush_bucket(CFile cf, int no_to_flush) +static int flush_bucket(CFile cf, int no_to_flush) { int i; + int ret = 0; struct CFile_hash_bucket *p; for (i = 0; i != no_to_flush; i++) @@ -219,11 +221,16 @@ static void flush_bucket(CFile cf, int no_to_flush) break; if (p->dirty) { - mf_write(cf->hash_mf, p->ph.this_bucket, 0, 0, &p->ph); + if (ret == 0) + { + if (mf_write(cf->hash_mf, p->ph.this_bucket, 0, 0, &p->ph)) + ret = -1; + } cf->dirty = 1; } release_bucket(cf, p); } + return ret; } static struct CFile_hash_bucket *alloc_bucket(CFile cf, zint block_no, int hno) @@ -231,7 +238,10 @@ static struct CFile_hash_bucket *alloc_bucket(CFile cf, zint block_no, int hno) struct CFile_hash_bucket *p, **pp; if (cf->bucket_in_memory == cf->max_bucket_in_memory) - flush_bucket(cf, 1); + { + if (flush_bucket(cf, 1)) + return 0; + } assert(cf->bucket_in_memory < cf->max_bucket_in_memory); ++(cf->bucket_in_memory); p = (struct CFile_hash_bucket *) xmalloc(sizeof(*p)); @@ -258,10 +268,12 @@ static struct CFile_hash_bucket *get_bucket(CFile cf, zint block_no, int hno) struct CFile_hash_bucket *p; p = alloc_bucket(cf, block_no, hno); + if (!p) + return 0; p->dirty = 0; - if (!mf_read(cf->hash_mf, block_no, 0, 0, &p->ph)) + if (mf_read(cf->hash_mf, block_no, 0, 0, &p->ph) != 1) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "read get_bucket"); + yaz_log(YLOG_FATAL, "read get_bucket"); release_bucket(cf, p); return 0; } @@ -277,6 +289,8 @@ static struct CFile_hash_bucket *new_bucket(CFile cf, zint *block_nop, int hno) block_no = *block_nop = cf->head.next_bucket++; p = alloc_bucket(cf, block_no, hno); + if (!p) + return 0; p->dirty = 1; for (i = 0; ihash_mf, hno+cf->head.next_bucket, off, sizeof(zint), vno); + if (mf_read(cf->hash_mf, hno+cf->head.next_bucket, off, sizeof(zint), vno) + == -1) + return -1; if (*vno) return 1; return 0; @@ -376,14 +392,14 @@ static int cf_moveto_flat(CFile cf) int j; zint i; - yaz_log(YLOG_LOG, "cf: Moving to flat shadow: %s", cf->rmf->name); yaz_log(YLOG_DEBUG, "cf: Moving to flat shadow: %s", cf->rmf->name); yaz_log(YLOG_DEBUG, "cf: hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT " total=" ZINT_FORMAT, cf->no_hits, cf->no_miss, cf->bucket_in_memory, cf->head.next_bucket - cf->head.first_bucket); assert(cf->head.state == 1); - flush_bucket(cf, -1); + if (flush_bucket(cf, -1)) + return -1; assert(cf->bucket_in_memory == 0); p = (struct CFile_hash_bucket *) xmalloc(sizeof(*p)); for (i = cf->head.first_bucket; i < cf->head.next_bucket; i++) @@ -489,6 +505,9 @@ static zint cf_new_hash(CFile cf, zint no) if (hbprev) hbprev->dirty = 1; hb = new_bucket(cf, bucketpp, hno); + if (!hb) + return 0; + hb->ph.no[0] = no; hb->ph.vno[0] = vno; return vno; @@ -528,14 +547,20 @@ int cf_read(CFile cf, zint no, int offset, int nbytes, void *buf) zebra_mutex_lock(&cf->mutex); ret = cf_lookup(cf, no, &block); zebra_mutex_unlock(&cf->mutex); - if (ret != 1) + if (ret == -1) + { + /* error */ + yaz_log(YLOG_FATAL, "cf_lookup failed"); + return -1; + } + else if (ret == 0) { - /* block could not be read or error */ + /* block could not be read */ return ret; } - if (mf_read(cf->block_mf, block, offset, nbytes, buf) != 1) + else if (mf_read(cf->block_mf, block, offset, nbytes, buf) != 1) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "cf_read no=" ZINT_FORMAT " block=" ZINT_FORMAT, no, block); + yaz_log(YLOG_FATAL|YLOG_ERRNO, "mf_read no=" ZINT_FORMAT " block=" ZINT_FORMAT, no, block); return -1; } return 1; @@ -575,7 +600,8 @@ int cf_write(CFile cf, zint no, int offset, int nbytes, const void *buf) } if (offset || nbytes) { - mf_read(cf->rmf, no, 0, 0, cf->iobuf); + if (mf_read(cf->rmf, no, 0, 0, cf->iobuf) == -1) + return -1; memcpy(cf->iobuf + offset, buf, nbytes); buf = cf->iobuf; offset = 0; @@ -588,17 +614,21 @@ int cf_write(CFile cf, zint no, int offset, int nbytes, const void *buf) int cf_close(CFile cf) { + int ret = 0; yaz_log(YLOG_DEBUG, "cf: close hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT " total=" ZINT_FORMAT, cf->no_hits, cf->no_miss, cf->bucket_in_memory, cf->head.next_bucket - cf->head.first_bucket); - flush_bucket(cf, -1); + if (flush_bucket(cf, -1)) + ret = -1; if (cf->hash_mf) { if (cf->dirty) { - mf_write(cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head); - write_head(cf); + if (mf_write(cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head)) + ret = -1; + if (write_head(cf)) + ret = -1; } mf_close(cf->hash_mf); } @@ -609,7 +639,7 @@ int cf_close(CFile cf) xfree(cf->iobuf); zebra_mutex_destroy(&cf->mutex); xfree(cf); - return 0; + return ret; } /* diff --git a/bfile/cfile.h b/bfile/cfile.h index c027e9d..7aa1b80 100644 --- a/bfile/cfile.h +++ b/bfile/cfile.h @@ -1,4 +1,4 @@ -/* $Id: cfile.h,v 1.20 2006-10-09 22:10:00 adam Exp $ +/* $Id: cfile.h,v 1.21 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -80,7 +80,7 @@ CFile cf_open (MFile mf, MFile_area area, const char *fname, int block_size, int wflag, int *firstp); int cf_read (CFile cf, zint no, int offset, int nbytes, void *buf); int cf_write (CFile cf, zint no, int offset, int nbytes, const void *buf); -void cf_commit (CFile cf); +int cf_commit (CFile cf) ZEBRA_GCC_ATTR((warn_unused_result)); YAZ_END_CDECL diff --git a/bfile/commit.c b/bfile/commit.c index 9fda156..782ca55 100644 --- a/bfile/commit.c +++ b/bfile/commit.c @@ -1,4 +1,4 @@ -/* $Id: commit.c,v 1.29 2006-10-09 22:10:00 adam Exp $ +/* $Id: commit.c,v 1.30 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -72,7 +72,7 @@ static int map_cache_cmp_to (const void *p1, const void *p2) ((struct map_cache_entity*) p2)->to; } -static void map_cache_flush (struct map_cache *m_p) +static int map_cache_flush (struct map_cache *m_p) { int i; @@ -85,7 +85,7 @@ static void map_cache_flush (struct map_cache *m_p) { yaz_log (YLOG_FATAL, "read commit block at position %d", m_p->map[i].from); - exit (1); + return -1; } m_p->map[i].from = i; } @@ -97,17 +97,19 @@ static void map_cache_flush (struct map_cache *m_p) m_p->buf + m_p->map[i].from * m_p->cf->head.block_size); } m_p->no = 0; + return 0; } -static void map_cache_del (struct map_cache *m_p) +static int map_cache_del(struct map_cache *m_p) { - map_cache_flush (m_p); + int r = map_cache_flush (m_p); xfree (m_p->map); xfree (m_p->buf); xfree (m_p); + return r; } -static void map_cache_add (struct map_cache *m_p, int from, int to) +static int map_cache_add(struct map_cache *m_p, int from, int to) { int i = m_p->no; @@ -115,14 +117,16 @@ static void map_cache_add (struct map_cache *m_p, int from, int to) m_p->map[i].to = to; m_p->no = ++i; if (i == m_p->max) - map_cache_flush (m_p); + return map_cache_flush (m_p); + return 0; } /* CF_OPTIMIZE_COMMIT */ #endif -static void cf_commit_hash (CFile cf) +static int cf_commit_hash (CFile cf) { + int r = 0; int i; zint bucket_no; int hash_bytes; @@ -140,36 +144,51 @@ static void cf_commit_hash (CFile cf) bucket_no = cf->head.first_bucket; for (; bucket_no < cf->head.next_bucket; bucket_no++) { - if (!mf_read (cf->hash_mf, bucket_no, 0, 0, p)) + if (mf_read (cf->hash_mf, bucket_no, 0, 0, p) != 1) { yaz_log (YLOG_FATAL, "read commit hash"); - exit (1); + r = -1; + goto out; } for (i = 0; ivno[i]; i++) { #if CF_OPTIMIZE_COMMIT - map_cache_add (m_p, p->vno[i], p->no[i]); + if (map_cache_add(m_p, p->vno[i], p->no[i])) + { + r = -1; + goto out; + } #else - if (!mf_read (cf->block_mf, p->vno[i], 0, 0, cf->iobuf)) + if (mf_read (cf->block_mf, p->vno[i], 0, 0, cf->iobuf) != 1) { yaz_log (YLOG_FATAL, "read commit block"); - exit (1); + r = -1; + goto out; + } + if (mf_write (cf->rmf, p->no[i], 0, 0, cf->iobuf)) + { + yaz_log (YLOG_FATAL, "write commit block"); + r = -1; + goto out; } - mf_write (cf->rmf, p->no[i], 0, 0, cf->iobuf); #endif } } + out: #if CF_OPTIMIZE_COMMIT - map_cache_del (m_p); + if (map_cache_del(m_p)) + r = -1; #endif - xfree (p); + xfree(p); + return r; } -static void cf_commit_flat (CFile cf) +static int cf_commit_flat(CFile cf) { zint *fp; zint hno; int i; + int r = 0; zint vno = 0; #if CF_OPTIMIZE_COMMIT @@ -189,49 +208,66 @@ static void cf_commit_flat (CFile cf) hno != cf->head.flat_bucket-1) { yaz_log (YLOG_FATAL, "read index block hno=" ZINT_FORMAT - " (" ZINT_FORMAT "-" ZINT_FORMAT ") commit", - hno, cf->head.next_bucket, cf->head.flat_bucket-1); + " (" ZINT_FORMAT "-" ZINT_FORMAT ") commit", + hno, cf->head.next_bucket, cf->head.flat_bucket-1); + r = -1; + goto out; } for (i = 0; i < (int) (HASH_BSIZE/sizeof(zint)); i++) { if (fp[i]) { #if CF_OPTIMIZE_COMMIT - map_cache_add (m_p, fp[i], vno); + if (map_cache_add(m_p, fp[i], vno)) + { + r = -1; + goto out; + } #else if (!mf_read (cf->block_mf, fp[i], 0, 0, cf->iobuf)) { yaz_log (YLOG_FATAL, "read data block hno=" ZINT_FORMAT " (" ZINT_FORMAT "-" ZINT_FORMAT ") " - "i=%d commit block at " ZINT_FORMAT " (->" ZINT_FORMAT")", - hno, cf->head.next_bucket, cf->head.flat_bucket-1, - i, fp[i], vno); - exit (1); + "i=%d commit block at " ZINT_FORMAT " (->" ZINT_FORMAT")", + hno, cf->head.next_bucket, cf->head.flat_bucket-1, + i, fp[i], vno); + r = -1; + goto out; + } + if (mf_write (cf->rmf, vno, 0, 0, cf->iobuf) != 1) + { + r = -1; + goto out; } - mf_write (cf->rmf, vno, 0, 0, cf->iobuf); - #endif } vno++; } } + out: #if CF_OPTIMIZE_COMMIT - map_cache_del (m_p); + if (map_cache_del(m_p)) + r = -1; #endif - xfree (fp); + xfree(fp); + return r; } -void cf_commit (CFile cf) +int cf_commit (CFile cf) { - if (cf->bucket_in_memory) { - yaz_log (YLOG_FATAL, "Cannot commit potential dirty cache"); - exit (1); + yaz_log(YLOG_FATAL, "cf_commit: dirty cache"); + return -1; } if (cf->head.state == 1) - cf_commit_hash (cf); + return cf_commit_hash (cf); else if (cf->head.state == 2) - cf_commit_flat (cf); + return cf_commit_flat (cf); + else + { + yaz_log(YLOG_FATAL, "cf_commit: bad state=%d", cf->head.state); + return -1; + } } /* diff --git a/bfile/mfile.c b/bfile/mfile.c index 9d8a3fb..b55dc2e 100644 --- a/bfile/mfile.c +++ b/bfile/mfile.c @@ -1,4 +1,4 @@ -/* $Id: mfile.c,v 1.70 2006-11-08 22:08:27 adam Exp $ +/* $Id: mfile.c,v 1.71 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -192,12 +192,6 @@ static int cmp_part_file(const void *p1, const void *p2) return 0; } -/** \brief creates a metafile area - \param name of area (does not show up on disk - purely for notation) - \param spec area specification (e.g. "/a:1G dir /b:2000M" - \param base base directory (NULL for no base) - \returns metafile area handle or NULL if error occurs -*/ MFile_area mf_init(const char *name, const char *spec, const char *base) { MFile_area ma = (MFile_area) xmalloc(sizeof(*ma)); @@ -216,6 +210,7 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) if (scan_areadef(ma, spec, base) < 0) { yaz_log(YLOG_WARN, "Failed to access description of '%s'", name); + mf_destroy(ma); return 0; } /* look at each directory */ @@ -224,7 +219,8 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) if (!(dd = opendir(dirp->name))) { yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to open directory %s", - dirp->name); + dirp->name); + mf_destroy(ma); return 0; } /* look at each file */ @@ -273,12 +269,17 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to access %s", dent->d_name); + closedir(dd); + mf_destroy(ma); return 0; } if ((part_f->bytes = mfile_seek(fd, 0, SEEK_END)) < 0) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to seek in %s", dent->d_name); + close(fd); + closedir(dd); + mf_destroy(ma); return 0; } #ifndef WIN32 @@ -300,9 +301,6 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) return ma; } -/** \brief destroys metafile area handle - \param ma metafile area handle -*/ void mf_destroy(MFile_area ma) { mf_dir *dp; @@ -320,10 +318,6 @@ void mf_destroy(MFile_area ma) xfree(ma); } -/** \brief reset all files in a metafile area (optionally delete them as well) - \param ma metafile area - \param unlink_flag if unlink_flag=1 all files are removed from FS -*/ void mf_reset(MFile_area ma, int unlink_flag) { meta_file *meta_f; @@ -351,13 +345,6 @@ void mf_reset(MFile_area ma, int unlink_flag) ma->mfiles = 0; } -/** \brief opens metafile - \param ma metafile area handle - \param name pseudo filename (name*.mf) - \param block_size block size for this file - \param wflag write flag, 0=read, 1=write&read - \returns metafile handle, or NULL for error (could not be opened) - */ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) { meta_file *mnew; @@ -394,7 +381,8 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) mnew->min_bytes_creat; dp = dp->next); if (!dp) { - yaz_log(YLOG_FATAL, "Insufficient space for new mfile."); + yaz_log(YLOG_FATAL, "Insufficient space for file %s", name); + xfree(mnew); return 0; } mnew->files[0].dir = dp; @@ -434,10 +422,6 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) return mnew; } -/** \brief closes metafile - \param mf metafile handle - \retval 0 OK -*/ int mf_close(MFile mf) { int i; @@ -459,16 +443,6 @@ int mf_close(MFile mf) return 0; } -/** \brief reads block from metafile - \param mf metafile handle - \param no block position - \param offset offset within block - \param nbytes no of bytes to read (0 for whole block) - \param buf content (filled with data if OK) - \retval 0 block partially read - \retval 1 block fully read - \retval -1 block could not be read due to error - */ int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf) { zint rd; @@ -502,18 +476,9 @@ int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf) return 1; } - -/** \brief writes block to metafile - \param mf metafile handle - \param no block position - \param offset offset within block - \param nbytes no of bytes to write (0 for whole block) - \param buf content to be written - \retval 0 block written - \retval -1 error (block not written) - */ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) { + int ret = 0; zint ps; zint nblocks; int towrite; @@ -524,8 +489,9 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) zebra_mutex_lock(&mf->mutex); if ((ps = file_position(mf, no, offset)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (1)", mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (1)", mf->name); + ret = -1; + goto out; } /* file needs to grow */ while (ps >= mf->files[mf->cur_file].blocks) @@ -546,16 +512,18 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) (mf->cur_file ? mf->files[mf->cur_file-1].top : 0) + mf->files[mf->cur_file].blocks + nblocks - 1, 0)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (2)", + yaz_log(YLOG_FATAL, "mf_write: %s error (2)", mf->name); - return -1; + ret = -1; + goto out; } yaz_log(YLOG_DEBUG, "ps = " ZINT_FORMAT, ps); if (write(mf->files[mf->cur_file].fd, &dummych, 1) < 1) { - yaz_log(YLOG_ERRNO|YLOG_FATAL, "mf_write %s internal error (3)", + yaz_log(YLOG_ERRNO|YLOG_FATAL, "mf_write: %s error (3)", mf->name); - return -1; + ret = -1; + goto out; } mf->files[mf->cur_file].blocks += nblocks; mf->files[mf->cur_file].bytes += nblocks * mf->blocksize; @@ -568,12 +536,13 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) dp->avail_bytes < needed; dp = dp->next); if (!dp) { - yaz_log(YLOG_FATAL, "Cannot allocate more space for %s", - mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (4) no more space", + mf->name); + ret = -1; + goto out; } mf->files[mf->cur_file].top = (mf->cur_file ? - mf->files[mf->cur_file-1].top : -1) + + mf->files[mf->cur_file-1].top : -1) + mf->files[mf->cur_file].blocks; mf->files[++(mf->cur_file)].top = -1; mf->files[mf->cur_file].dir = dp; @@ -589,9 +558,9 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) /* open new file and position at beginning */ if ((ps = file_position(mf, no, offset)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (4)", - mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (5)", mf->name); + ret = -1; + goto out; } } else @@ -609,10 +578,11 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Write failed for file %s part %d", mf->name, mf->cur_file); - return -1; + ret = -1; } + out: zebra_mutex_unlock(&mf->mutex); - return 0; + return ret; } /** \brief metafile area statistics diff --git a/bfile/mfile.h b/bfile/mfile.h index de79cd3..2c7deb6 100644 --- a/bfile/mfile.h +++ b/bfile/mfile.h @@ -1,4 +1,4 @@ -/* $Id: mfile.h,v 1.8 2006-11-08 22:06:50 adam Exp $ +/* $Id: mfile.h,v 1.9 2006-11-14 08:12:06 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -20,8 +20,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - #ifndef MFILE_H #define MFILE_H @@ -103,33 +101,65 @@ typedef struct MFile_area_struct Zebra_mutex mutex; } MFile_area_struct; -/* - * Open an area, cotaining metafiles in directories. - */ -MFile_area mf_init(const char *name, const char *spec, const char *base); +/** \brief creates a metafile area + \param name of area (does not show up on disk - purely for notation) + \param spec area specification (e.g. "/a:1G dir /b:2000M" + \param base base directory (NULL for no base) + \returns metafile area handle or NULL if error occurs +*/ +MFile_area mf_init(const char *name, const char *spec, const char *base) + ZEBRA_GCC_ATTR((warn_unused_result)); -/* - * Release an area. - */ +/** \brief destroys metafile area handle + \param ma metafile area handle +*/ void mf_destroy(MFile_area ma); -/* - * Open a metafile. - */ -MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag); - -/* - * Close a metafile. +/** \brief opens metafile + \param ma metafile area handle + \param name pseudo filename (name*.mf) + \param block_size block size for this file + \param wflag write flag, 0=read, 1=write&read + \returns metafile handle, or NULL for error (could not be opened) */ +MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) + ZEBRA_GCC_ATTR((warn_unused_result)); + +/** \brief closes metafile + \param mf metafile handle + \retval 0 OK +*/ int mf_close(MFile mf); -int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf); - -int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf); - -/* - * Destroy all metafiles. No files may be opened. +/** \brief reads block from metafile + \param mf metafile handle + \param no block position + \param offset offset within block + \param nbytes no of bytes to read (0 for whole block) + \param buf content (filled with data if OK) + \retval 0 block partially read + \retval 1 block fully read + \retval -1 block could not be read due to error */ +int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf) + ZEBRA_GCC_ATTR((warn_unused_result)); + +/** \brief writes block to metafile + \param mf metafile handle + \param no block position + \param offset offset within block + \param nbytes no of bytes to write (0 for whole block) + \param buf content to be written + \retval 0 block written + \retval -1 error (block not written) +*/ +int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) + ZEBRA_GCC_ATTR((warn_unused_result)); + +/** \brief reset all files in a metafile area (optionally delete them as well) + \param ma metafile area + \param unlink_flag if unlink_flag=1 all files are removed from FS +*/ void mf_reset(MFile_area ma, int unlink_flag); /* \brief gets statistics about directory in metafile area diff --git a/dict/dclose.c b/dict/dclose.c index 6b970e2..98c9924 100644 --- a/dict/dclose.c +++ b/dict/dclose.c @@ -1,4 +1,4 @@ -/* $Id: dclose.c,v 1.10 2006-08-14 10:40:09 adam Exp $ +/* $Id: dclose.c,v 1.11 2006-11-14 08:12:07 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -31,15 +31,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA int dict_bf_close (Dict_BFile dbf) { - int i; dict_bf_flush_blocks (dbf, -1); xfree (dbf->all_blocks); xfree (dbf->all_data); xfree (dbf->hash_array); - i = bf_close (dbf->bf); + bf_close(dbf->bf); xfree (dbf); - return i; + return 0; } /* * Local variables: diff --git a/dict/dopen.c b/dict/dopen.c index 2062ecf..315857f 100644 --- a/dict/dopen.c +++ b/dict/dopen.c @@ -1,4 +1,4 @@ -/* $Id: dopen.c,v 1.14 2006-08-14 10:40:09 adam Exp $ +/* $Id: dopen.c,v 1.15 2006-11-14 08:12:07 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -80,7 +80,10 @@ Dict_BFile dict_bf_open (BFiles bfs, const char *name, int block_size, dbf = (Dict_BFile) xmalloc (sizeof(*dbf)); dbf->bf = bf_open (bfs, name, block_size, rw); if (!dbf->bf) - return NULL; + { + xfree(dbf); + return 0; + } common_init (dbf, block_size, cache); return dbf; } diff --git a/include/idzebra/api.h b/include/idzebra/api.h index 429bf09..d01ce21 100644 --- a/include/idzebra/api.h +++ b/include/idzebra/api.h @@ -1,4 +1,4 @@ -/* $Id: api.h,v 1.39 2006-08-22 13:59:02 adam Exp $ +/* $Id: api.h,v 1.40 2006-11-14 08:12:07 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -39,24 +39,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA YAZ_BEGIN_CDECL -/** - expand GCC_ATTRIBUTE if GCC is in use. See : - http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html - - To see gcc pre-defines for c: - gcc -E -dM -x c /dev/null -*/ - -#ifdef __GNUC__ -#if __GNUC__ >= 4 -#define ZEBRA_GCC_ATTR(x) __attribute__ (x) -#endif -#endif - -#ifndef ZEBRA_GCC_ATTR -#define ZEBRA_GCC_ATTR(x) -#endif - typedef struct { zint processed; zint inserted; diff --git a/include/idzebra/bfile.h b/include/idzebra/bfile.h index de1acc6..6369f4c 100644 --- a/include/idzebra/bfile.h +++ b/include/idzebra/bfile.h @@ -1,4 +1,4 @@ -/* $Id: bfile.h,v 1.11 2006-11-08 22:08:26 adam Exp $ +/* $Id: bfile.h,v 1.12 2006-11-14 08:12:07 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -60,32 +60,40 @@ BFiles bfs_create (const char *spec, const char *base); */ void bfs_destroy (BFiles bfiles); +/** \brief closes a Block file (may call exit) + \param bf block file + */ +YAZ_EXPORT +void bf_close(BFile bf); + /** \brief closes a Block file \param bf block file + \retval 0 success + \retval -1 failure */ YAZ_EXPORT -int bf_close (BFile bf); +int bf_close2(BFile bf); /** \brief closes an extended Block file handle.. \param bf extended block file opened with bf_xopen \param version version to be put in a file \param more_info more information to be stored in file (header) - \retval 0 succes + \retval 0 success \retval -1 failure (can never happen as the code is now) */ YAZ_EXPORT -int bf_xclose (BFile bf, int version, const char *more_info); +int bf_xclose(BFile bf, int version, const char *more_info); /** \brief opens and returns a Block file handle \param bfs block files \param name filename \param block_size block size in bytes \param wflag 1=opened for read&write, 0=read only - \retval 0 succes + \retval 0 success \retval -1 failure (can never happen as the code is now) */ YAZ_EXPORT -BFile bf_open (BFiles bfs, const char *name, int block_size, int wflag); +BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag); /** \brief opens and returns an extended Block file handle \param bfs block files @@ -124,7 +132,8 @@ int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf); \retval -1 error */ YAZ_EXPORT -int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf); +int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf) + ZEBRA_GCC_ATTR((warn_unused_result)); /** \brief writes block of bytes to file (may call exit) @@ -155,8 +164,8 @@ int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf); if write failed. */ YAZ_EXPORT -int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf); - +int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf) + ZEBRA_GCC_ATTR((warn_unused_result)); /** \brief enables or disables shadow for block files \param bfs block files @@ -179,7 +188,7 @@ int bf_commitExists (BFiles bfs); \param bfs block files */ YAZ_EXPORT -void bf_commitExec (BFiles bfs); +int bf_commitExec (BFiles bfs) ZEBRA_GCC_ATTR((warn_unused_result)); /** \brief Cleans shadow files (remove them) \param bfs block files diff --git a/include/idzebra/util.h b/include/idzebra/util.h index 2abf9cf..1e35164 100644 --- a/include/idzebra/util.h +++ b/include/idzebra/util.h @@ -1,4 +1,4 @@ -/* $Id: util.h,v 1.9 2006-10-10 14:45:42 adam Exp $ +/* $Id: util.h,v 1.10 2006-11-14 08:12:07 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -28,6 +28,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include +/** + expand GCC_ATTRIBUTE if GCC is in use. See : + http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + + To see gcc pre-defines for c: + gcc -E -dM -x c /dev/null +*/ + +#ifdef __GNUC__ +#if __GNUC__ >= 4 +#define ZEBRA_GCC_ATTR(x) __attribute__ (x) +#endif +#endif + +#ifndef ZEBRA_GCC_ATTR +#define ZEBRA_GCC_ATTR(x) +#endif + /* check that we don't have all too old yaz */ #ifndef YLOG_ERRNO #error Need a modern yaz with YLOG_ defines @@ -84,6 +102,9 @@ void zebra_zint_encode(char **dst, zint pos); YAZ_EXPORT void zebra_zint_decode(const char **src, zint *pos); +YAZ_EXPORT +void zebra_exit(const char *msg); + YAZ_END_CDECL #define CAST_ZINT_TO_INT(x) (int)(x) diff --git a/index/Makefile.am b/index/Makefile.am index a9e9493..2430a4b 100644 --- a/index/Makefile.am +++ b/index/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.57 2006-11-06 20:48:43 adam Exp $ +## $Id: Makefile.am,v 1.58 2006-11-14 08:12:08 adam Exp $ aux_libs = \ ../rset/libidzebra-rset.la \ @@ -15,7 +15,7 @@ aux_libs = \ # Should also match the libidzebra_..._la lines..! zebralib = libidzebra-2.0.la -noinst_PROGRAMS = apitest kdump zebrash +noinst_PROGRAMS = kdump zebrash modlibdir=$(libdir)/$(PACKAGE)$(PACKAGE_SUFFIX)/modules @@ -95,7 +95,6 @@ bin_PROGRAMS = zebraidx zebrasrv zebraidx_SOURCES = zebraidx.c zebrasrv_SOURCES = zebrasrv.c zebrash_SOURCES = zebrash.c -apitest_SOURCES = apitest.c kdump_SOURCES = kdump.c AM_CPPFLAGS = -I$(srcdir)/../include $(YAZINC) \ diff --git a/index/apitest.c b/index/apitest.c deleted file mode 100644 index 8490a9d..0000000 --- a/index/apitest.c +++ /dev/null @@ -1,297 +0,0 @@ -/* $Id: apitest.c,v 1.26 2006-08-14 10:40:15 adam Exp $ - Copyright (C) 1995-2006 - Index Data ApS - -This file is part of the Zebra server. - -Zebra is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -Zebra is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include -#include - -#include -#include -#include - -/* Small routine to display GRS-1 record variants ... */ -/* Copied verbatim from yaz/client/client.c */ -static void display_variant(Z_Variant *v, int level) -{ - int i; - - for (i = 0; i < v->num_triples; i++) - { - printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass, - *v->triples[i]->type); - if (v->triples[i]->which == Z_Triple_internationalString) - printf(",value=%s\n", v->triples[i]->value.internationalString); - else - printf("\n"); - } -} - -/* Small routine to display a GRS-1 record ... */ -/* Copied verbatim from yaz/client/client.c */ -static void display_grs1(Z_GenericRecord *r, int level) -{ - int i; - - if (!r) - return; - for (i = 0; i < r->num_elements; i++) - { - Z_TaggedElement *t; - - printf("%*s", level * 4, ""); - t = r->elements[i]; - printf("("); - if (t->tagType) - printf("%d,", *t->tagType); - else - printf("?,"); - if (t->tagValue->which == Z_StringOrNumeric_numeric) - printf("%d) ", *t->tagValue->u.numeric); - else - printf("%s) ", t->tagValue->u.string); - if (t->content->which == Z_ElementData_subtree) - { - printf("\n"); - display_grs1(t->content->u.subtree, level+1); - } - else if (t->content->which == Z_ElementData_string) - printf("%s\n", t->content->u.string); - else if (t->content->which == Z_ElementData_numeric) - printf("%d\n", *t->content->u.numeric); - else if (t->content->which == Z_ElementData_oid) - { - int *ip = t->content->u.oid; - oident *oent; - - if ((oent = oid_getentbyoid(t->content->u.oid))) - printf("OID: %s\n", oent->desc); - else - { - printf("{"); - while (ip && *ip >= 0) - printf(" %d", *(ip++)); - printf(" }\n"); - } - } - else if (t->content->which == Z_ElementData_noDataRequested) - printf("[No data requested]\n"); - else if (t->content->which == Z_ElementData_elementEmpty) - printf("[Element empty]\n"); - else if (t->content->which == Z_ElementData_elementNotThere) - printf("[Element not there]\n"); - else - printf("??????\n"); - if (t->appliedVariant) - display_variant(t->appliedVariant, level+1); - if (t->metaData && t->metaData->supportedVariants) - { - int c; - - printf("%*s---- variant list\n", (level+1)*4, ""); - for (c = 0; c < t->metaData->num_supportedVariants; c++) - { - printf("%*svariant #%d\n", (level+1)*4, "", c); - display_variant(t->metaData->supportedVariants[c], level + 2); - } - } - } -} - -/* Small test main to illustrate the use of the C api */ -int main (int argc, char **argv) -{ - /* odr is a handle to memory assocated with RETURNED data from - various functions */ - ODR odr_input, odr_output; - - /* zs is our Zebra Service - decribes whole server */ - ZebraService zs; - - /* zh is our Zebra Handle - describes database session */ - ZebraHandle zh; - - /* the database we specify in our example */ - const char *base = "Default"; - int argno; - - nmem_init (); - - yaz_log_init_file("apitest.log"); - - odr_input = odr_createmem (ODR_DECODE); - odr_output = odr_createmem (ODR_ENCODE); - - zs = zebra_start ("zebra.cfg"); - if (!zs) - { - printf ("zebra_start failed; missing zebra.cfg?\n"); - exit (1); - } - /* open Zebra */ - zh = zebra_open (zs, 0); - if (!zh) - { - printf ("zebras_open failed\n"); - exit (1); - } - if (zebra_select_databases (zh, 1, &base) != ZEBRA_OK) - { - printf ("zebra_select_databases failed\n"); - exit (1); - } - /* Each argument to main will be a query */ - for (argno = 1; argno < argc; argno++) - { - /* parse the query and generate an RPN structure */ - Z_RPNQuery *query = p_query_rpn (odr_input, PROTO_Z3950, argv[argno]); - char setname[64]; - int errCode; - int i; - zint hits; - char *errString; - ZebraRetrievalRecord *records; - int noOfRecordsToFetch; - - /* bad query? */ - if (!query) - { - yaz_log (YLOG_WARN, "bad query %s\n", argv[argno]); - odr_reset (odr_input); - continue; - } - else - { - char out_str[100]; - int r; -#if 1 - r = zebra_string_norm (zh, 'w', - argv[argno], strlen(argv[argno]), - out_str, sizeof(out_str)); - if (r >= 0) - { - printf ("norm: '%s'\n", out_str); - } - else - { - printf ("norm fail: %d\n", r); - } -#endif - - } - /* result set name will be called 1,2, etc */ - sprintf (setname, "%d", argno); - - /* fire up the search */ - zebra_search_RPN (zh, odr_input, query, setname, &hits); - - /* status ... */ - zebra_result (zh, &errCode, &errString); - - /* error? */ - if (errCode) - { - printf ("Zebra Search Error %d %s\n", - errCode, errString); - continue; - } - /* ok ... */ - printf ("Zebra Search gave " ZINT_FORMAT " hits\n", hits); - - /* Deterimine number of records to fetch ... */ - if (hits > 10) - noOfRecordsToFetch = 10; - else - noOfRecordsToFetch = hits; - - /* reset our memory - we've finished dealing with search */ - odr_reset (odr_input); - odr_reset (odr_output); - - /* prepare to fetch ... */ - records = odr_malloc (odr_input, sizeof(*records) * noOfRecordsToFetch); - /* specify position of each record to fetch */ - /* first one is numbered 1 and NOT 0 */ - for (i = 0; ireg->key_file_no); prevcp = cp = (zh->reg->key_buf)[zh->reg->ptr_top - ptr_i]; @@ -1231,7 +1231,7 @@ void extract_flushWriteKeys (ZebraHandle zh, int final) if (!(outf = fopen (out_fname, "wb"))) { yaz_log (YLOG_FATAL|YLOG_ERRNO, "fopen %s", out_fname); - exit (1); + zebra_exit("extract_flushWriteKeys"); } yaz_log (YLOG_LOG, "writing section %d", key_file_no); i = ptr_i; @@ -1264,7 +1264,7 @@ void extract_flushWriteKeys (ZebraHandle zh, int final) if (fclose (outf)) { yaz_log (YLOG_FATAL|YLOG_ERRNO, "fclose %s", out_fname); - exit (1); + zebra_exit("extract_flushWriteKeys"); } yaz_log (YLOG_LOG, "finished section %d", zh->reg->key_file_no); zh->reg->ptr_i = 0; @@ -1631,7 +1631,7 @@ static void encode_key_write (char *k, struct encode_info *i, FILE *outf) if (fwrite (i->buf, bp - i->buf, 1, outf) != 1) { yaz_log (YLOG_FATAL|YLOG_ERRNO, "fwrite"); - exit (1); + zebra_exit("encode_key_write"); } #if 0 diff --git a/index/recindex.c b/index/recindex.c index 69237da..3280dfc 100644 --- a/index/recindex.c +++ b/index/recindex.c @@ -1,4 +1,4 @@ -/* $Id: recindex.c,v 1.52 2006-09-15 10:45:13 adam Exp $ +/* $Id: recindex.c,v 1.53 2006-11-14 08:12:08 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -352,6 +352,7 @@ Records rec_open(BFiles bfs, int rw, int compression_method) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "bf_open %s", p->data_fname[i]); ret = ZEBRA_FAIL; + break; } } p->cache_max = 400; diff --git a/index/zebraapi.c b/index/zebraapi.c index efbb919..0ff27a1 100644 --- a/index/zebraapi.c +++ b/index/zebraapi.c @@ -1,4 +1,4 @@ -/* $Id: zebraapi.c,v 1.230 2006-10-12 13:06:00 adam Exp $ +/* $Id: zebraapi.c,v 1.231 2006-11-14 08:12:08 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -1564,6 +1564,16 @@ int zebra_string_norm (ZebraHandle zh, unsigned reg_id, return wrbuf_len(wrbuf); } +/** \brief set register state (state*.LCK) + \param zh Zebra handle + \param val state + \param seqno sequence number + + val is one of: + d=writing to shadow(dirty) + o=no writing, + c=commit +*/ static void zebra_set_state (ZebraHandle zh, int val, int seqno) { char state_fname[256]; @@ -1673,7 +1683,6 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw) assert (zh->res); if (rw) { - int pass; int seqno = 0; char val = '?'; const char *rval = 0; @@ -1709,51 +1718,40 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw) if (zh->shadow_enable) rval = res_get (zh->res, "shadow"); - for (pass = 0; pass < 2; pass++) + if (rval) { - if (rval) - { - zebra_lock_r (zh->lock_normal); - zebra_lock_w (zh->lock_shadow); - } - else + zebra_lock_r(zh->lock_normal); + zebra_lock_w(zh->lock_shadow); + } + else + { + zebra_lock_w(zh->lock_normal); + zebra_lock_w(zh->lock_shadow); + } + zebra_get_state (zh, &val, &seqno); + if (val != 'o') + { + /* either we didn't finish commit or shadow is dirty */ + zebra_unlock (zh->lock_shadow); + zebra_unlock (zh->lock_normal); + if (zebra_commit (zh)) { - zebra_lock_w (zh->lock_normal); - zebra_lock_w (zh->lock_shadow); + zh->trans_no--; + zh->trans_w_no = 0; + return ZEBRA_FAIL; } - - zebra_get_state (zh, &val, &seqno); - if (val == 'c') + if (rval) { - yaz_log (YLOG_WARN, "previous transaction didn't finish commit"); - zebra_unlock (zh->lock_shadow); - zebra_unlock (zh->lock_normal); - zebra_commit (zh); - continue; + zebra_lock_r(zh->lock_normal); + zebra_lock_w(zh->lock_shadow); } - else if (val == 'd') + else { - if (rval) - { - BFiles bfs = bfs_create (res_get (zh->res, "shadow"), - zh->path_reg); - yaz_log (YLOG_WARN, "previous transaction didn't reach commit"); - bf_commitClean (bfs, rval); - bfs_destroy (bfs); - } - else - { - yaz_log (YLOG_WARN, "your previous transaction didn't finish"); - } + zebra_lock_w(zh->lock_normal); + zebra_lock_w(zh->lock_shadow); } - break; - } - if (pass == 2) - { - yaz_log (YLOG_FATAL, "zebra_begin_trans couldn't finish commit"); - abort(); - return ZEBRA_FAIL; } + zebra_set_state (zh, 'd', seqno); zh->reg = zebra_register_open(zh->service, zh->reg_name, @@ -1988,6 +1986,8 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only) char val; const char *rval; BFiles bfs; + ZEBRA_RES res = ZEBRA_OK; + ASSERTZH; zebra_select_default_database(zh); @@ -1996,24 +1996,24 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only) zh->errCode = YAZ_BIB1_DATABASE_UNAVAILABLE; return ZEBRA_FAIL; } - rval = res_get (zh->res, "shadow"); + rval = res_get(zh->res, "shadow"); if (!rval) { yaz_log (YLOG_WARN, "Cannot perform commit - No shadow area defined"); return ZEBRA_OK; } - zebra_lock_w (zh->lock_normal); - zebra_lock_r (zh->lock_shadow); + zebra_lock_w(zh->lock_normal); + zebra_lock_r(zh->lock_shadow); - bfs = bfs_create (res_get (zh->res, "register"), zh->path_reg); + bfs = bfs_create(res_get (zh->res, "register"), zh->path_reg); if (!bfs) { zebra_unlock(zh->lock_shadow); zebra_unlock(zh->lock_normal); return ZEBRA_FAIL; } - zebra_get_state (zh, &val, &seqno); + zebra_get_state(zh, &val, &seqno); if (val == 'd') { @@ -2026,33 +2026,43 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only) if (bf_commitExists (bfs)) { if (clean_only) - zebra_set_state (zh, 'd', seqno); + zebra_set_state(zh, 'd', seqno); else { - zebra_set_state (zh, 'c', seqno); + zebra_set_state(zh, 'c', seqno); - yaz_log (YLOG_DEBUG, "commit start"); - bf_commitExec (bfs); + yaz_log(YLOG_DEBUG, "commit start"); + if (bf_commitExec (bfs)) + res = ZEBRA_FAIL; + } + if (res == ZEBRA_OK) + { + seqno++; + zebra_set_state(zh, 'o', seqno); + + zebra_unlock(zh->lock_shadow); + zebra_unlock(zh->lock_normal); + + zebra_lock_w(zh->lock_shadow); + bf_commitClean(bfs, rval); + zebra_unlock(zh->lock_shadow); + } + else + { + zebra_unlock(zh->lock_shadow); + zebra_unlock(zh->lock_normal); + yaz_log(YLOG_WARN, "zebra_commit: failed"); } - seqno++; - zebra_set_state (zh, 'o', seqno); - - zebra_unlock (zh->lock_shadow); - zebra_unlock (zh->lock_normal); - - zebra_lock_w(zh->lock_shadow); - bf_commitClean (bfs, rval); - zebra_unlock (zh->lock_shadow); } else { zebra_unlock(zh->lock_shadow); zebra_unlock(zh->lock_normal); - yaz_log (log_level, "nothing to commit"); + yaz_log(log_level, "nothing to commit"); } - bfs_destroy (bfs); + bfs_destroy(bfs); - return ZEBRA_OK; + return res; } ZEBRA_RES zebra_clean(ZebraHandle zh) diff --git a/index/zinfo.c b/index/zinfo.c index 817f104..9d5bb3d 100644 --- a/index/zinfo.c +++ b/index/zinfo.c @@ -1,4 +1,4 @@ -/* $Id: zinfo.c,v 1.70 2006-09-20 10:51:25 adam Exp $ +/* $Id: zinfo.c,v 1.71 2006-11-14 08:12:08 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -855,8 +855,7 @@ static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n, if (!c) { data1_pr_tree (zei->dh, n, stdout); - exit (0); - assert (c); + zebra_exit("zebraExplain_updateAccessInfo"); } if ((p = accessInfo->attributeSetIds)) diff --git a/isamb/isamb.c b/isamb/isamb.c index dd2f84a..8e464ba 100644 --- a/isamb/isamb.c +++ b/isamb/isamb.c @@ -1,4 +1,4 @@ -/* $Id: isamb.c,v 1.84 2006-09-26 12:56:33 adam Exp $ +/* $Id: isamb.c,v 1.85 2006-11-14 08:12:08 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -199,12 +199,19 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method, assert(cache == 0); isamb->file = xmalloc(sizeof(*isamb->file) * isamb->no_cat); + + for (i = 0; i < isamb->no_cat; i++) + { + isamb->file[i].bf = 0; + isamb->file[i].head_dirty = 0; + isamb->file[i].cache_entries = 0; + } + for (i = 0; i < isamb->no_cat; i++) { char fname[DST_BUF_SIZE]; char hbuf[DST_BUF_SIZE]; - isamb->file[i].cache_entries = 0; - isamb->file[i].head_dirty = 0; + sprintf(fname, "%s%c", name, i+'A'); if (cache) isamb->file[i].bf = bf_open(bfs, fname, ISAMB_CACHE_ENTRY_SIZE, @@ -212,6 +219,12 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method, else isamb->file[i].bf = bf_open(bfs, fname, b_size, writeflag); + if (!isamb->file[i].bf) + { + isamb_close(isamb); + return 0; + } + /* fill-in default values (for empty isamb) */ isamb->file[i].head.first_block = ISAMB_CACHE_ENTRY_SIZE/b_size+1; isamb->file[i].head.last_block = isamb->file[i].head.first_block; @@ -414,7 +427,8 @@ void isamb_close (ISAMB isamb) bf_write(isamb->file[i].bf, pos, 0, 0, hbuf + pos*b_size); } } - bf_close (isamb->file[i].bf); + if (isamb->file[i].bf) + bf_close (isamb->file[i].bf); } xfree(isamb->file); xfree(isamb->method); diff --git a/isamc/isamc.c b/isamc/isamc.c index 8ba7a6c..aec8da4 100644 --- a/isamc/isamc.c +++ b/isamc/isamc.c @@ -1,4 +1,4 @@ -/* $Id: isamc.c,v 1.32 2006-08-14 10:40:19 adam Exp $ +/* $Id: isamc.c,v 1.33 2006-11-14 08:12:09 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -119,18 +119,10 @@ ISAMC isamc_open (BFiles bfs, const char *name, int writeflag, ISAMC_M *method) is->merge_buf = NULL; for (i = 0; ino_files; i++) { - char fname[512]; - - sprintf (fname, "%s%c", name, i+'A'); - is->files[i].bf = bf_open (bfs, fname, is->method->filecat[i].bsize, - writeflag); + is->files[i].bf = 0; is->files[i].head_is_dirty = 0; - if (!bf_read (is->files[i].bf, 0, 0, sizeof(ISAMC_head), - &is->files[i].head)) - { - is->files[i].head.lastblock = 1; - is->files[i].head.freelist = 0; - } + is->files[i].head.lastblock = 1; + is->files[i].head.freelist = 0; is->files[i].alloc_entries_num = 0; is->files[i].alloc_entries_max = is->method->filecat[i].bsize / sizeof(zint) - 1; @@ -151,6 +143,28 @@ ISAMC isamc_open (BFiles bfs, const char *name, int writeflag, ISAMC_M *method) init_fc (is, i); } + + for (i = 0; ino_files; i++) + { + char fname[FILENAME_MAX]; + int r; + + sprintf (fname, "%s%c", name, i+'A'); + is->files[i].bf = bf_open (bfs, fname, is->method->filecat[i].bsize, + writeflag); + if (!is->files[i].bf) + { + isamc_close(is); + return 0; + } + r = bf_read(is->files[i].bf, 0, 0, sizeof(ISAMC_head), + &is->files[i].head); + if (r == -1) + { + isamc_close(is); + return 0; + } + } return is; } @@ -194,21 +208,24 @@ int isamc_close (ISAMC is) for (i = 0; ino_files; i++) { release_fc (is, i); - assert (is->files[i].bf); - if (is->files[i].head_is_dirty) - bf_write (is->files[i].bf, 0, 0, sizeof(ISAMC_head), - &is->files[i].head); if (is->method->debug) yaz_log (YLOG_LOG, "isc:%8d%8d%8d%8d%8d%8d", - is->files[i].no_writes, - is->files[i].no_reads, - is->files[i].no_skip_writes, - is->files[i].no_allocated, - is->files[i].no_released, - is->files[i].no_remap); - xfree (is->files[i].fc_list); - flush_block (is, i); - bf_close (is->files[i].bf); + is->files[i].no_writes, + is->files[i].no_reads, + is->files[i].no_skip_writes, + is->files[i].no_allocated, + is->files[i].no_released, + is->files[i].no_remap); + if (is->files[i].bf) + { + if (is->files[i].head_is_dirty) + bf_write (is->files[i].bf, 0, 0, sizeof(ISAMC_head), + &is->files[i].head); + flush_block (is, i); + bf_close (is->files[i].bf); + } + xfree(is->files[i].fc_list); + xfree(is->files[i].alloc_buf); } xfree (is->files); xfree (is->merge_buf); @@ -255,7 +272,6 @@ static void flush_block (ISAMC is, int cat) bf_write (is->files[cat].bf, block, 0, 0, abuf); is->files[cat].alloc_entries_num = 0; } - xfree (abuf); } static zint alloc_block (ISAMC is, int cat) @@ -343,8 +359,6 @@ static void release_block (ISAMC is, int cat, zint pos) #else static void flush_block (ISAMC is, int cat) { - char *abuf = is->files[cat].alloc_buf; - xfree (abuf); } static zint alloc_block (ISAMC is, int cat) diff --git a/rset/rstemp.c b/rset/rstemp.c index 122c0b4..709dd99 100644 --- a/rset/rstemp.c +++ b/rset/rstemp.c @@ -1,4 +1,4 @@ -/* $Id: rstemp.c,v 1.68 2006-08-14 10:40:21 adam Exp $ +/* $Id: rstemp.c,v 1.69 2006-11-14 08:12:09 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -137,7 +137,7 @@ static RSFD r_open(RSET ct, int flag) if (info->fd == -1) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "rstemp: open failed %s", info->fname); - exit(1); + zebra_exit("r_open"); } } rfd = rfd_create_base(ct); @@ -178,7 +178,7 @@ static void r_flush(RSFD rfd, int mk) if (info->fd == -1) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "rstemp: mkstemp %s", template); - exit(1); + zebra_exit("r_flush"); } info->fname = nmem_strdup(rfd->rset->nmem, template); #else @@ -190,7 +190,7 @@ static void r_flush(RSFD rfd, int mk) if (info->fd == -1) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "rstemp: open %s", info->fname); - exit(1); + zebra_exit("r_flush"); } #endif } @@ -202,7 +202,7 @@ static void r_flush(RSFD rfd, int mk) if (lseek(info->fd, info->pos_buf, SEEK_SET) == -1) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "rstemp: lseek (1) %s", info->fname); - exit(1); + zebra_exit("r_flusxh"); } count = info->buf_size; if (count > info->pos_end - info->pos_buf) @@ -214,7 +214,7 @@ static void r_flush(RSFD rfd, int mk) else yaz_log(YLOG_FATAL, "rstemp: write of %ld but got %ld", (long) count, (long) r); - exit(1); + zebra_exit("r_flush"); } info->dirty = 0; } @@ -259,7 +259,7 @@ static void r_reread(RSFD rfd) if (lseek(info->fd, info->pos_buf, SEEK_SET) == -1) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "rstemp: lseek (2) %s fd=%d", info->fname, info->fd); - exit(1); + zebra_exit("r_reread"); } if ((r = read(info->fd, info->buf_mem, count)) < (int) count) { @@ -268,7 +268,7 @@ static void r_reread(RSFD rfd) else yaz_log(YLOG_FATAL, "read of %ld but got %ld", (long) count, (long) r); - exit(1); + zebra_exit("r_reread"); } } } diff --git a/util/Makefile.am b/util/Makefile.am index 0af7186..11c3b96 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.27 2006-10-11 20:19:31 adam Exp $ +## $Id: Makefile.am,v 1.28 2006-11-14 08:12:10 adam Exp $ noinst_LTLIBRARIES = libidzebra-util.la @@ -16,7 +16,8 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(YAZINC) -DDEFAULT_PROFILE_PATH=\"$(pkgdat LDADD = libidzebra-util.la $(YAZLALIB) libidzebra_util_la_SOURCES = zint.c res.c charmap.c zebramap.c passwddb.c \ - zebra-lock.c dirent.c xpath.c atoi_zn.c snippet.c flock.c attrfind.c + zebra-lock.c dirent.c xpath.c atoi_zn.c snippet.c flock.c attrfind.c \ + exit.c tstpass_SOURCES = tstpass.c diff --git a/util/exit.c b/util/exit.c new file mode 100644 index 0000000..6ec5384 --- /dev/null +++ b/util/exit.c @@ -0,0 +1,39 @@ +/* $Id: exit.c,v 1.1 2006-11-14 08:12:10 adam Exp $ + Copyright (C) 1995-2006 + Index Data ApS + +This file is part of the Zebra server. + +Zebra is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Zebra is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include +#include + +void zebra_exit(const char *msg) +{ + yaz_log(YLOG_LOG, "%s: exit", msg); + exit(1); +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/win/makefile b/win/makefile index 7618577..7f98134 100644 --- a/win/makefile +++ b/win/makefile @@ -1,5 +1,5 @@ # Zebra makefile for MS NMAKE -# $Id: makefile,v 1.58 2006-10-05 13:19:10 adam Exp $ +# $Id: makefile,v 1.59 2006-11-14 08:12:11 adam Exp $ ########################################################### ############### Parameters @@ -353,6 +353,7 @@ ZEBRALIB_OBJS= \ $(OBJDIR)\dirs.obj \ $(OBJDIR)\dopen.obj \ $(OBJDIR)\drdwr.obj \ + $(OBJDIR)\exit.obj \ $(OBJDIR)\extract.obj \ $(OBJDIR)\flock.obj \ $(OBJDIR)\imalloc.obj \ -- 1.7.10.4