X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=index%2Flockidx.c;h=423ca72d110cc2c17b31daebf2e7dcb786ea46e3;hb=6c9fcd3b5d3108702fa1ffc92dab4ab6060f9a19;hp=dad7181121fa3471d99ba14702458dff21a0b56d;hpb=4ec5e11d0e4db05000b47db4c681d570431c1818;p=idzebra-moved-to-github.git diff --git a/index/lockidx.c b/index/lockidx.c index dad7181..423ca72 100644 --- a/index/lockidx.c +++ b/index/lockidx.c @@ -1,211 +1,235 @@ -/* - * Copyright (C) 1994-1995, Index Data I/S - * All rights reserved. - * Sebastian Hammer, Adam Dickmeiss - * - * $Log: lockidx.c,v $ - * Revision 1.5 1995-12-13 08:46:09 adam - * Locking uses F_WRLCK and F_RDLCK again! - * - * Revision 1.4 1995/12/12 16:00:57 adam - * System call sync(2) used after update/commit. - * Locking (based on fcntl) uses F_EXLCK and F_SHLCK instead of F_WRLCK - * and F_RDLCK. - * - * Revision 1.3 1995/12/11 11:43:29 adam - * Locking based on fcntl instead of flock. - * Setting commitEnable removed. Command line option -n can be used to - * prevent commit if commit setting is defined in the configuration file. - * - * Revision 1.2 1995/12/08 16:22:54 adam - * Work on update while servers are running. Three lock files introduced. - * The servers reload their registers when necessary, but they don't - * reestablish result sets yet. - * - * Revision 1.1 1995/12/07 17:38:47 adam - * Work locking mechanisms for concurrent updates/commit. - * - */ +/* $Id: lockidx.c,v 1.24 2005-01-15 19:38:26 adam Exp $ + Copyright (C) 1995-2005 + 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 Zebra; see the file LICENSE.zebra. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +*/ + + #include #include +#ifdef WIN32 +#include +#else #include +#endif #include #include #include -#include #include "index.h" +#include "zserver.h" -static int lock_fd = -1; -static int server_lock_cmt = -1; -static int server_lock_org = -1; +static ZebraLockHandle server_lock_main = NULL; +static ZebraLockHandle server_lock_cmt = NULL; +static ZebraLockHandle server_lock_org = NULL; -int zebraIndexWait (int commitPhase) +int zebraIndexWait (ZebraHandle zh, int commitPhase) { - char pathPrefix[1024]; - char path[1024]; - int fd; - - zebraLockPrefix (pathPrefix); + ZebraLockHandle h; - if (server_lock_cmt == -1) + if (server_lock_cmt) + zebra_unlock (server_lock_cmt); + else { - sprintf (path, "%s%s", FNAME_COMMIT_LOCK, pathPrefix); - if ((server_lock_cmt = open (path, O_CREAT|O_RDWR|O_SYNC, 0666)) - == -1) - { - logf (LOG_FATAL|LOG_ERRNO, "create %s", path); - return -1; - } + char path[1024]; + + zebra_lock_prefix (zh->service->res, path); + strcat (path, FNAME_COMMIT_LOCK); + server_lock_cmt = zebra_lock_create (path, 1); + if (!server_lock_cmt) + { + yaz_log (YLOG_WARN|YLOG_ERRNO, "cannot create lock %s", path); + return -1; + } } + if (server_lock_org) + zebra_unlock (server_lock_org); else - zebraUnlock (server_lock_cmt); - if (server_lock_org == -1) { - sprintf (path, "%s%s", FNAME_ORG_LOCK, pathPrefix); - if ((server_lock_org = open (path, O_CREAT|O_RDWR|O_SYNC, 0666)) - == -1) - { - logf (LOG_FATAL|LOG_ERRNO, "create %s", path); - return -1; - } + char path[1024]; + + zebra_lock_prefix (zh->service->res, path); + strcat (path, FNAME_ORG_LOCK); + server_lock_org = zebra_lock_create (path, 1); + if (!server_lock_org) + { + yaz_log (YLOG_WARN|YLOG_ERRNO, "cannot create lock %s", path); + return -1; + } } - else - zebraUnlock (server_lock_org); if (commitPhase) - fd = server_lock_cmt; + h = server_lock_cmt; else - fd = server_lock_org; - if (zebraLockNB (fd, 1) == -1) + h = server_lock_org; + if (zebra_lock_nb (h)) { +#ifndef WIN32 if (errno != EWOULDBLOCK) { - logf (LOG_FATAL|LOG_ERRNO, "flock"); + yaz_log (YLOG_FATAL|YLOG_ERRNO, "flock"); exit (1); } +#endif if (commitPhase) - logf (LOG_LOG, "Waiting for lock cmt"); + yaz_log (YLOG_LOG, "Waiting for lock cmt"); else - logf (LOG_LOG, "Waiting for lock org"); - if (zebraLock (fd, 1) == -1) + yaz_log (YLOG_LOG, "Waiting for lock org"); + if (zebra_lock (h) == -1) { - logf (LOG_FATAL|LOG_ERRNO, "flock"); + yaz_log (YLOG_FATAL, "flock"); exit (1); } } - zebraUnlock (fd); + zebra_unlock (h); return 0; } -void zebraIndexLockMsg (const char *str) +void zebraIndexLockMsg (ZebraHandle zh, const char *str) { char path[1024]; - char pathPrefix[1024]; int l, r, fd; - assert (lock_fd != -1); - lseek (lock_fd, 0L, SEEK_SET); + assert (server_lock_main); + fd = zebra_lock_fd (server_lock_main); + lseek (fd, 0L, SEEK_SET); l = strlen(str); - r = write (lock_fd, str, l); + r = write (fd, str, l); if (r != l) { - logf (LOG_FATAL|LOG_ERRNO, "write lock file"); + yaz_log (YLOG_FATAL|YLOG_ERRNO, "write lock file"); exit (1); } - zebraLockPrefix (pathPrefix); - sprintf (path, "%s%s", pathPrefix, FNAME_TOUCH_TIME); + zebra_lock_prefix (zh->service->res, path); + strcat (path, FNAME_TOUCH_TIME); fd = creat (path, 0666); close (fd); } -void zebraIndexUnlock (void) +void zebraIndexUnlock (ZebraHandle zh) { char path[1024]; - char pathPrefix[1024]; - - zebraLockPrefix (pathPrefix); - sprintf (path, "%s%s", pathPrefix, FNAME_MAIN_LOCK); - unlink (path); + + zebra_lock_prefix (zh->service->res, path); + strcat (path, FNAME_MAIN_LOCK); +#ifdef WIN32 + zebra_lock_destroy (server_lock_main); + if (unlink (path) && errno != ENOENT) + yaz_log (YLOG_WARN|YLOG_ERRNO, "unlink %s failed", path); +#else + if (unlink (path) && errno != ENOENT) + yaz_log (YLOG_WARN|YLOG_ERRNO, "unlink %s failed", path); + zebra_lock_destroy (server_lock_main); +#endif + server_lock_main = 0; } -void zebraIndexLock (int commitNow) +int zebraIndexLock (BFiles bfs, ZebraHandle zh, int commitNow, + const char *rval) { char path[1024]; - char pathPrefix[1024]; char buf[256]; int r; - if (lock_fd != -1) - return ; - zebraLockPrefix (pathPrefix); - sprintf (path, "%s%s", pathPrefix, FNAME_MAIN_LOCK); + if (server_lock_main) + return 0; + + zebra_lock_prefix (zh->service->res, path); + strcat (path, FNAME_MAIN_LOCK); while (1) { - lock_fd = open (path, O_CREAT|O_RDWR|O_EXCL, 0666); - if (lock_fd == -1) + server_lock_main = zebra_lock_create (path, 2); + if (!server_lock_main) { - lock_fd = open (path, O_RDWR); - if (lock_fd == -1) + server_lock_main = zebra_lock_create (path, 1); + if (!server_lock_main) { - if (errno == ENOENT) - continue; - logf (LOG_FATAL|LOG_ERRNO, "open %s", path); - exit (1); + yaz_log (YLOG_FATAL, "couldn't obtain indexer lock"); + exit (1); } - logf (LOG_LOG, "zebraLockNB"); - if (zebraLockNB (lock_fd, 1) == -1) + if (zebra_lock_nb (server_lock_main) == -1) { +#ifdef WIN32 + yaz_log (YLOG_LOG, "waiting for other index process"); + zebra_lock (server_lock_main); + zebra_unlock (server_lock_main); + zebra_lock_destroy (server_lock_main); + continue; +#else if (errno == EWOULDBLOCK) { - logf (LOG_LOG, "Waiting for other index process"); - zebraLock (lock_fd, 1); - zebraUnlock (lock_fd); - close (lock_fd); + yaz_log (YLOG_LOG, "waiting for other index process"); + zebra_lock (server_lock_main); + zebra_unlock (server_lock_main); + zebra_lock_destroy (server_lock_main); continue; } else { - logf (LOG_FATAL|LOG_ERRNO, "flock %s", path); + yaz_log (YLOG_FATAL|YLOG_ERRNO, "flock %s", path); exit (1); } +#endif } else { - logf (LOG_WARN, "Unlocked %s", path); - r = read (lock_fd, buf, 256); + int fd = zebra_lock_fd (server_lock_main); + + yaz_log (YLOG_WARN, "unlocked %s", path); + r = read (fd, buf, 256); if (r == 0) { - logf (LOG_WARN, "Zero length %s", path); - close (lock_fd); - unlink (path); + yaz_log (YLOG_WARN, "zero length %s", path); + zebra_lock_destroy (server_lock_main); + unlink (path); continue; } else if (r == -1) { - logf (LOG_FATAL|LOG_ERRNO, "read %s", path); + yaz_log (YLOG_FATAL|YLOG_ERRNO, "read %s", path); exit (1); } if (*buf == 'r') { - logf (LOG_WARN, "Previous transaction didn't" + yaz_log (YLOG_WARN, "previous transaction didn't" " reach commit"); - close (lock_fd); - bf_commitClean (); + zebra_lock_destroy (server_lock_main); + bf_commitClean (bfs, rval); unlink (path); continue; } else if (*buf == 'd') { - logf (LOG_WARN, "Commit file wan't deleted after commit"); - close (lock_fd); - bf_commitClean (); + yaz_log (YLOG_WARN, "commit file wan't deleted after commit"); + zebra_lock_destroy (server_lock_main); + bf_commitClean (bfs, rval); unlink (path); continue; } else if (*buf == 'w') { - logf (LOG_WARN, "Your index may be inconsistent"); + yaz_log (YLOG_WARN, + "The lock file indicates that your index is"); + yaz_log (YLOG_WARN, "inconsistent. Perhaps the indexer"); + yaz_log (YLOG_WARN, "terminated abnormally in the previous"); + yaz_log (YLOG_WARN, "run. You can try to proceed by"); + yaz_log (YLOG_WARN, "deleting the file %s", path); exit (1); } else if (*buf == 'c') @@ -213,16 +237,16 @@ void zebraIndexLock (int commitNow) if (commitNow) { unlink (path); - close (lock_fd); + zebra_lock_destroy (server_lock_main); continue; } - logf (LOG_FATAL, "Previous transaction didn't" + yaz_log (YLOG_FATAL, "previous transaction didn't" " finish commit. Commit now!"); exit (1); } else { - logf (LOG_FATAL, "Unknown id 0x%02x in %s", *buf, + yaz_log (YLOG_FATAL, "unknown id 0x%02x in %s", *buf, path); exit (1); } @@ -231,6 +255,7 @@ void zebraIndexLock (int commitNow) else break; } - zebraLock (lock_fd, 1); + zebra_lock (server_lock_main); + return 0; }