db

os_fid.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  * Sleepycat Software. All rights reserved.
00006  */
00007 
00008 #include "config.h"
00009 
00010 #ifndef lint
00011 static const char revid[] = "$Id: os__fid_8c-source.html,v 1.1 2008年06月08日 10:21:13 sebdiaz Exp $";
00012 #endif /* not lint */
00013 
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 
00018 #if TIME_WITH_SYS_TIME
00019 #include <sys/time.h>
00020 #include <time.h>
00021 #else
00022 #if HAVE_SYS_TIME_H
00023 #include <sys/time.h>
00024 #else
00025 #include <time.h>
00026 #endif
00027 #endif
00028 
00029 #include <string.h>
00030 #include <unistd.h>
00031 #endif
00032 
00033 #include "db_int.h"
00034 
00035 #define SERIAL_INIT 0
00036 static u_int32_t fid_serial = SERIAL_INIT;
00037 
00038 /*
00039  * CDB___os_fileid --
00040  * Return a unique identifier for a file.
00041  *
00042  * PUBLIC: int CDB___os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
00043  */
00044 int
00045 CDB___os_fileid(dbenv, fname, unique_okay, fidp)
00046 DB_ENV *dbenv;
00047 const char *fname;
00048 int unique_okay;
00049 u_int8_t *fidp;
00050 {
00051 struct stat sb;
00052 size_t i;
00053 int ret;
00054 u_int32_t tmp;
00055 u_int8_t *p;
00056 
00057 /* Clear the buffer. */
00058 memset(fidp, 0, DB_FILE_ID_LEN);
00059 
00060 /* On POSIX/UNIX, use a dev/inode pair. */
00061 if (stat(fname, &sb)) {
00062 ret = CDB___os_get_errno();
00063 CDB___db_err(dbenv, "%s: %s", fname, strerror(ret));
00064 return (ret);
00065 }
00066 
00067 /* 
00068  * Initialize/increment the serial number we use to help avoid
00069  * fileid collisions. Note that we don't bother with locking;
00070  * it's unpleasant to do from down in here, and if we race on
00071  * this no real harm will be done, since the finished fileid
00072  * has so many other components.
00073  * 
00074  * We increment by 100000 on each call as a simple way of
00075  * randomizing; simply incrementing seems potentially less useful
00076  * if pids are also simply incremented, since this is process-local
00077  * and we may be one of a set of processes starting up. 100000
00078  * pushes us out of pid space on most platforms, and has few 
00079  * interesting properties in base 2.
00080  */
00081 if (fid_serial == SERIAL_INIT)
00082 fid_serial = (u_int32_t)getpid();
00083 else
00084 fid_serial += 100000;
00085 
00086 /*
00087  * !!!
00088  * Nothing is ever big enough -- on Sparc V9, st_ino, st_dev and the
00089  * time_t types are all 8 bytes. As DB_FILE_ID_LEN is only 20 bytes,
00090  * we convert to a (potentially) smaller fixed-size type and use it.
00091  *
00092  * We don't worry about byte sexing or the actual variable sizes.
00093  *
00094  * When this routine is called from the DB access methods, it's only
00095  * called once -- whatever ID is generated when a database is created
00096  * is stored in the database file's metadata, and that is what is
00097  * saved in the mpool region's information to uniquely identify the
00098  * file.
00099  *
00100  * When called from the mpool layer this routine will be called each
00101  * time a new thread of control wants to share the file, which makes
00102  * things tougher. As far as byte sexing goes, since the mpool region
00103  * lives on a single host, there's no issue of that -- the entire
00104  * region is byte sex dependent. As far as variable sizes go, we make
00105  * the simplifying assumption that 32-bit and 64-bit processes will
00106  * get the same 32-bit values if we truncate any returned 64-bit value
00107  * to a 32-bit value. When we're called from the mpool layer, though,
00108  * we need to be careful not to include anything that isn't 
00109  * reproducible for a given file, such as the timestamp or serial 
00110  * number.
00111  */
00112 tmp = (u_int32_t)sb.st_ino;
00113 for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
00114 *fidp++ = *p++;
00115 
00116 tmp = (u_int32_t)sb.st_dev;
00117 for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
00118 *fidp++ = *p++;
00119 
00120 if (unique_okay) {
00121 /*
00122  * We want the number of seconds, not the high-order 0 bits,
00123  * so convert the returned time_t to a (potentially) smaller
00124  * fixed-size type.
00125  */
00126 tmp = (u_int32_t)time(NULL);
00127 for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
00128 *fidp++ = *p++;
00129 
00130 for (p = (u_int8_t *)&fid_serial, i = sizeof(u_int32_t); 
00131 i > 0; --i)
00132 *fidp++ = *p++;
00133 }
00134 
00135 return (0);
00136 }

Generated on Sun Jun 8 10:56:38 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /