<GUILT TRIP> I should probably mention the whole fact about ECamp
(www.ecamp.net/www.myecamp.com) paying my time and all that stuff <shrug>
ok </GUILT TRIP>
Take it easy fellahs,
Eric
On Fri, 18 Aug 2000, Eric Peters wrote:
> I havn't tested this much any feedback would be good but after adding
> 100,000 uers and corrupting god knows how many .dir_control files it had
> to be done : )
>
> Eric
>
>
> diff -rcN vpopmail-4.8.9.orig/bigdir.c vpopmail-4.8.9/bigdir.c
> *** vpopmail-4.8.9.orig/bigdir.c Wed Jun 7 21:00:59 2000
> --- vpopmail-4.8.9/bigdir.c Fri Aug 18 07:32:33 2000
> ***************
> *** 25,31 ****
> --- 25,34 ----
> #include <fcntl.h>
> #include <unistd.h>
> #include <string.h>
> + #include <errno.h>
> +
> #include "bigdir.h"
> + #include "file_lock.h"
> #include "config.h"
>
> #define MAX_DIR_LIST 62
> ***************
> *** 66,71 ****
> --- 69,75 ----
> int read_dir_control(vdir_type *vdir)
> {
> FILE *fs;
> + int try=0;
>
> if ( (fs = fopen(".dir-control", "r")) == NULL ) {
> int i;
> ***************
> *** 83,88 ****
> --- 87,112 ----
> vdir->the_dir[0] = 0;
> return(-1);
> }
> +
> + while(read_lock(fileno(fs), 0, SEEK_SET, 0) < 0)
> + {
> + if (errno == EAGAIN || errno == EACCES)
> + {
> + /* there might be other errors cases in which
> + * you might try again.
> + */
> + if (++try < MAX_TRY_RLOCK) {
> + (void) sleep(2);
> + continue;
> + }
> + (void) fprintf(stderr,"File busy try again later!\n");
> + return(-1);
> + }
> +
> + perror("fcntl");
> + exit(2);
> + }
> +
> fscanf(fs, "%lu\n", &vdir->cur_users);
> fscanf(fs, "%d\n", &vdir->level_cur);
> fscanf(fs, "%d\n", &vdir->level_max);
> ***************
> *** 104,109 ****
> --- 128,135 ----
> &vdir->level_index[2]);
> fscanf(fs, "%s\n", vdir->the_dir);
>
> + unlock_lock(fileno(fs), 0, SEEK_SET, 0);
> +
> fclose(fs);
>
> return(0);
> ***************
> *** 112,121 ****
> --- 138,168 ----
> int write_dir_control(vdir_type *vdir)
> {
> FILE *fs;
> + int try=0;
>
> if ( (fs = fopen(".dir-control", "w+")) == NULL ) {
> return(-1);
> }
> +
> + while(read_lock(fileno(fs), 0, SEEK_SET, 0) < 0)
> + {
> + if (errno == EAGAIN || errno == EACCES)
> + {
> + /* there might be other errors cases in which
> + * you might try again.
> + */
> + if (++try < MAX_TRY_RLOCK) {
> + (void) sleep(2);
> + continue;
> + }
> + (void) fprintf(stderr,"File busy try again later!\n");
> + return(-1);
> + }
> +
> + perror("fcntl");
> + exit(2);
> + }
> +
> fprintf(fs, "%lu\n", vdir->cur_users);
> fprintf(fs, "%d\n", vdir->level_cur);
> fprintf(fs, "%d\n", vdir->level_max);
> ***************
> *** 136,141 ****
> --- 183,191 ----
> vdir->level_index[1],
> vdir->level_index[2]);
> fprintf(fs, "%s\n", vdir->the_dir);
> +
> + unlock_lock(fileno(fs), 0, SEEK_SET, 0);
> +
> fclose(fs);
> chown(".dir-control",VPOPMAILUID, VPOPMAILGID);
> return(0);
> diff -rcN vpopmail-4.8.9.orig/bigdir.h vpopmail-4.8.9/bigdir.h
> *** vpopmail-4.8.9.orig/bigdir.h Wed Jun 7 21:00:59 2000
> --- vpopmail-4.8.9/bigdir.h Fri Aug 18 07:32:33 2000
> ***************
> *** 22,27 ****
> --- 22,30 ----
> #define MAX_DIR_LEVELS 3
> #define MAX_USERS_PER_LEVEL 100
>
> + #define MAX_TRY_RLOCK 10
> + #define MAX_TRY_WLOCK 15
> +
> #define MAX_DIR_NAME 300
> typedef struct {
> int level_cur;
> diff -rcN vpopmail-4.8.9.orig/file_lock.c vpopmail-4.8.9/file_lock.c
> *** vpopmail-4.8.9.orig/file_lock.c Wed Dec 31 19:00:00 1969
> --- vpopmail-4.8.9/file_lock.c Fri Aug 18 07:32:33 2000
> ***************
> *** 0 ****
> --- 1,50 ----
> + /*
> + file_lock.c
> +
> + functions straight out of Richard Steven's
> + "Advanced Programming in the UNIX Environment"
> +
> + Translated into bytes by Eric Peters ([EMAIL PROTECTED])
> + August 19, 2000
> +
> + */
> +
> + #include <sys/types.h>
> + #include <stdio.h> /* for perror() */
> + #include <errno.h> /* for perror() */
> + #include <fcntl.h>
> +
> + int
> + lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
> + {
> + struct flock lock;
> +
> + lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
> + lock.l_start = offset; /* byte offset, relative to l_whence */
> + lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
> + lock.l_len = len; /* #bytes (0 means to EOF) */
> +
> + return( fcntl(fd, cmd, &lock) );
> + }
> +
> +
> + pid_t
> + lock_test(int fd, int type, off_t offset, int whence, off_t len)
> + {
> + struct flock lock;
> +
> + lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
> + lock.l_start = offset; /* byte offset, relative to l_whence */
> + lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
> + lock.l_len = len; /* #bytes (0 means to EOF) */
> +
> + if (fcntl(fd, F_GETLK, &lock) < 0)
> + {
> + perror("fcntl error");
> + return(0);
> + }
> +
> + if (lock.l_type == F_UNLCK)
> + return(0); /* false, region is not locked yb another proc */
> + return(lock.l_pid); /* true, return pid of lock owner */
> + }
> diff -rcN vpopmail-4.8.9.orig/file_lock.h vpopmail-4.8.9/file_lock.h
> *** vpopmail-4.8.9.orig/file_lock.h Wed Dec 31 19:00:00 1969
> --- vpopmail-4.8.9/file_lock.h Fri Aug 18 07:32:33 2000
> ***************
> *** 0 ****
> --- 1,38 ----
> + /*
> + file_lock.h
> +
> + functions straight out of Richard Steven's
> + "Advanced Programming in the UNIX Environment"
> +
> + Translated into bytes by Eric Peters ([EMAIL PROTECTED])
> + August 19, 2000
> +
> + */
> +
> + int
> + lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len);
> +
> + #define read_lock(fd, offset, whence, len) \
> + lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
> +
> + #define readw_lock(fd, offset, whence, len) \
> + lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
> +
> + #define write_lock(fd, offset, whence, len) \
> + lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
> +
> + #define writew_lock(fd, offset, whence, len) \
> + lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
> +
> + #define unlock_lock(fd, offset, whence, len) \
> + lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)
> +
> +
> + pid_t
> + lock_test(int fd, int type, off_t offset, int whence, off_t len);
> +
> + #define is_readlock(fd, offset, whence, len) \
> + lock_test(fd, F_RDLCK, offset, whence, len)
> +
> + #define is_writelock(fd, offset, whence, len) \
> + lock_test(fd, F_WRLCK, offset, whence, len)
>
>