From 06c0349c445958aebb8a4611bdb7082711585754 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Jul 1998 00:10:26 +0000 Subject: locking.c: Added lock type to is_locked() and do_lock() as the code in reply_lockingX wasn't taking account of the difference between read and write locks ! How did this ever work :-) ! reply.c: server.c: Add lock type to is_locked() and do_lock(). util.c: Also added code from klausr@ITAP.Physik.Uni-Stuttgart.De to fix problem with log files growing too large if an smbd writes less than 100 debug messages. Jeremy. (This used to be commit 80080abf772a470d5f0f4dcd4a75fb2a09a9fb2a) --- source3/include/proto.h | 6 ++-- source3/lib/util.c | 81 +++++++++++++++++++++++++++++++---------------- source3/locking/locking.c | 74 +++++++++++++++++++++++++++---------------- source3/smbd/nttrans.c | 12 +++---- source3/smbd/reply.c | 27 ++++++++-------- source3/smbd/server.c | 16 +++++++++- 6 files changed, 140 insertions(+), 76 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index b390cb60d9..5819d1aadc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1149,8 +1149,9 @@ void lp_set_name_resolve_order(char *new_order); /*The following definitions come from locking.c */ -BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset); -BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); +BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type); +BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, + int *eclass,uint32 *ecode); BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); BOOL locking_init(int read_only); BOOL locking_end(void); @@ -1980,6 +1981,7 @@ int sig_usr2(void); int sig_usr1(void); void setup_logging(char *pname,BOOL interactive); void reopen_logs(void); +void force_check_log_size(void); char *tmpdir(void); BOOL is_a_socket(int fd); BOOL next_token(char **ptr,char *buff,char *sep); diff --git a/source3/lib/util.c b/source3/lib/util.c index ec12affe79..22db8d4ab6 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -184,55 +184,82 @@ void reopen_logs(void) pstring fname; if (DEBUGLEVEL > 0) - { - pstrcpy(fname,debugf); - if (lp_loaded() && (*lp_logfile())) - pstrcpy(fname,lp_logfile()); + { + pstrcpy(fname,debugf); + if (lp_loaded() && (*lp_logfile())) + pstrcpy(fname,lp_logfile()); - if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) - { - int oldumask = umask(022); - pstrcpy(debugf,fname); - if (dbf) fclose(dbf); - if (append_log) - dbf = fopen(debugf,"a"); - else - dbf = fopen(debugf,"w"); - if (dbf) setbuf(dbf,NULL); - umask(oldumask); - } + if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) + { + int oldumask = umask(022); + pstrcpy(debugf,fname); + if (dbf) + fclose(dbf); + if (append_log) + dbf = fopen(debugf,"a"); + else + dbf = fopen(debugf,"w"); + /* + * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De + * to fix problem where smbd's that generate less + * than 100 messages keep growing the log. + */ + force_check_log_size(); + if (dbf) + setbuf(dbf,NULL); + umask(oldumask); } + } else + { + if (dbf) { - if (dbf) - { - fclose(dbf); - dbf = NULL; - } + fclose(dbf); + dbf = NULL; } + } } +/******************************************************************* + Number of debug messages that have been output. + Used to check log size. +********************************************************************/ + +static int debug_count=0; + +/******************************************************************* + Force a check of the log size. +********************************************************************/ + +void force_check_log_size(void) +{ + debug_count = 100; +} /******************************************************************* -check if the log has grown too big + Check if the log has grown too big ********************************************************************/ + static void check_log_size(void) { - static int debug_count=0; int maxlog; struct stat st; - if (debug_count++ < 100 || getuid() != 0) return; + if (debug_count++ < 100 || getuid() != 0) + return; maxlog = lp_max_log_size() * 1024; - if (!dbf || maxlog <= 0) return; + if (!dbf || maxlog <= 0) + return; if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) { - fclose(dbf); dbf = NULL; + fclose(dbf); + dbf = NULL; reopen_logs(); if (dbf && file_size(debugf) > maxlog) { pstring name; - fclose(dbf); dbf = NULL; + fclose(dbf); + dbf = NULL; slprintf(name,sizeof(name)-1,"%s.old",debugf); rename(debugf,name); reopen_logs(); diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 189ac0bcfe..d5d767d2cc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -39,11 +39,13 @@ extern files_struct Files[]; static struct share_ops *share_ops; /**************************************************************************** - utility function called to see if a file region is locked + Utility function called to see if a file region is locked. ****************************************************************************/ -BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) + +BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) { int snum = SNUM(cnum); + files_struct *fsp = &Files[fnum]; if (count == 0) return(False); @@ -51,17 +53,22 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count, - (Files[fnum].can_write?F_WRLCK:F_RDLCK))); + if((lock_type == F_WRLCK) && !fsp->can_write) + lock_type = F_RDLCK; + + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } /**************************************************************************** - utility function called by locking requests + Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) + +BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, + int *eclass,uint32 *ecode) { BOOL ok = False; + files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(cnum))) return(True); @@ -72,9 +79,12 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec return False; } - if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) - ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count, - (Files[fnum].can_write?F_WRLCK:F_RDLCK)); + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) { + if(lock_type == F_WRLCK && !fsp->can_write) + lock_type = F_RDLCK; + + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,lock_type); + } if (!ok) { *eclass = ERRDOS; @@ -86,17 +96,19 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec /**************************************************************************** - utility function called by unlocking requests + Utility function called by unlocking requests. ****************************************************************************/ + BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) { BOOL ok = False; + files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(cnum))) return(True); - if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) - ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; @@ -109,8 +121,9 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * /**************************************************************************** - initialise the locking functions + Initialise the locking functions. ****************************************************************************/ + BOOL locking_init(int read_only) { if (share_ops) return True; @@ -133,8 +146,9 @@ BOOL locking_init(int read_only) } /******************************************************************* - deinitialize the share_mode management - ******************************************************************/ + Deinitialize the share_mode management. +******************************************************************/ + BOOL locking_end(void) { if (share_ops) @@ -144,24 +158,27 @@ BOOL locking_end(void) /******************************************************************* - lock a hash bucket entry - ******************************************************************/ + Lock a hash bucket entry. +******************************************************************/ + BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) { return share_ops->lock_entry(cnum, dev, inode, ptok); } /******************************************************************* - unlock a hash bucket entry - ******************************************************************/ + Unlock a hash bucket entry. +******************************************************************/ + BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token) { return share_ops->unlock_entry(cnum, dev, inode, token); } /******************************************************************* -get all share mode entries for a dev/inode pair. + Get all share mode entries for a dev/inode pair. ********************************************************************/ + int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, share_mode_entry **shares) { @@ -169,42 +186,45 @@ int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, } /******************************************************************* -del the share mode of a file. + Del the share mode of a file. ********************************************************************/ + void del_share_mode(int token, int fnum) { share_ops->del_entry(token, fnum); } /******************************************************************* -set the share mode of a file. Return False on fail, True on success. + Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ + BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type) { return share_ops->set_entry(token, fnum, port, op_type); } /******************************************************************* -Remove an oplock port and mode entry from a share mode. + Remove an oplock port and mode entry from a share mode. ********************************************************************/ BOOL remove_share_oplock(int fnum, int token) { return share_ops->remove_oplock(fnum, token); } - /******************************************************************* -call the specified function on each entry under management by the -share mode system + Call the specified function on each entry under management by the + share mode system. ********************************************************************/ + int share_mode_forall(void (*fn)(share_mode_entry *, char *)) { return share_ops->forall(fn); } /******************************************************************* -dump the state of the system + Dump the state of the system. ********************************************************************/ + void share_status(FILE *f) { share_ops->status(f); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 672e2c0802..9b6cfe1621 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -620,12 +620,12 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize) p += 8; SIVAL(p,0,fmode); /* File Attributes. */ p += 12; - if(sizeof(off_t) == 8) { +#if OFF_T_IS_64_BITS SIVAL(p,0, file_len & 0xFFFFFFFF); SIVAL(p,4, file_len >> 32); - } else { +#else /* OFF_T_IS_64_BITS */ SIVAL(p,0,file_len); - } +#endif /* OFF_T_IS_64_BITS */ p += 12; SCVAL(p,0,fsp->is_directory ? 1 : 0); } @@ -822,12 +822,12 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, p += 8; SIVAL(p,0,fmode); /* File Attributes. */ p += 12; - if(sizeof(off_t) == 8) { +#if OFF_T_IS_64_BITS SIVAL(p,0, file_len & 0xFFFFFFFF); SIVAL(p,4, (file_len >> 32)); - } else { +#else /* OFF_T_IS_64_BITS */ SIVAL(p,0,file_len); - } +#endif /* OFF_T_IS_64_BITS */ } /* Send the required number of replies */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index f6fd2ccd90..35189883e2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1858,7 +1858,7 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) } - if (!is_locked(fnum,cnum,maxcount,startpos)) + if (!is_locked(fnum,cnum,maxcount,startpos, F_RDLCK)) { int size = Files[fnum].size; int sizeneeded = startpos + maxcount; @@ -1943,7 +1943,7 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fnum, cnum, numtoread, startpos, &eclass, &ecode)) + if(!do_lock( fnum, cnum, numtoread, startpos, F_RDLCK, &eclass, &ecode)) return (ERROR(eclass,ecode)); nread = read_file(fnum,data,startpos,numtoread); @@ -1987,7 +1987,7 @@ int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if (is_locked(fnum,cnum,numtoread,startpos)) + if (is_locked(fnum,cnum,numtoread,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); if (numtoread > 0) @@ -2035,7 +2035,7 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) set_message(outbuf,12,0,True); data = smb_buf(outbuf); - if (is_locked(fnum,cnum,smb_maxcnt,smb_offs)) + if (is_locked(fnum,cnum,smb_maxcnt,smb_offs, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); nread = read_file(fnum,data,smb_offs,smb_maxcnt); ok = True; @@ -2097,7 +2097,7 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(inbuf,smb_com) = SMBwritec; CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,cnum,tcount,startpos)) + if (is_locked(fnum,cnum,tcount,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); if (seek_file(fnum,startpos) != startpos) @@ -2188,7 +2188,7 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fnum,cnum,numtowrite,startpos)) + if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); @@ -2243,7 +2243,7 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fnum,cnum,numtowrite,startpos)) + if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); @@ -2299,7 +2299,7 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) data = smb_base(inbuf) + smb_doff; - if (is_locked(fnum,cnum,smb_dsize,smb_offs)) + if (is_locked(fnum,cnum,smb_dsize,smb_offs, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,smb_offs); @@ -2512,7 +2512,7 @@ int reply_writeclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) mtime = make_unix_date3(inbuf+smb_vwv4); data = smb_buf(inbuf) + 1; - if (is_locked(fnum,cnum,numtowrite,startpos)) + if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); @@ -2559,7 +2559,7 @@ int reply_lock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count)); - if(!do_lock( fnum, cnum, count, offset, &eclass, &ecode)) + if(!do_lock( fnum, cnum, count, offset, F_WRLCK, &eclass, &ecode)) return (ERROR(eclass,ecode)); return(outsize); @@ -3729,7 +3729,8 @@ dev = %x, inode = %x\n", for(i = 0; i < (int)num_locks; i++) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - if(!do_lock(fnum,cnum,count,offset, &eclass, &ecode)) + if(!do_lock(fnum,cnum,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + &eclass, &ecode)) break; } @@ -3796,7 +3797,7 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize) tcount = maxcount; total_read = 0; - if (is_locked(fnum,cnum,maxcount,startpos)) + if (is_locked(fnum,cnum,maxcount,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); do @@ -3858,7 +3859,7 @@ int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) not an SMBwritebmpx - set this up now so we don't forget */ CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,cnum,tcount,startpos)) + if (is_locked(fnum,cnum,tcount,startpos,F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 9df2ed37bb..62ee75db0a 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -1948,7 +1948,7 @@ static void truncate_unless_locked(int fnum, int cnum, int token, BOOL *share_locked) { if (Files[fnum].can_write){ - if (is_locked(fnum,cnum,0x3FFFFFFF,0)){ + if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){ /* If share modes are in force for this connection we have the share entry locked. Unlock it before closing. */ if (*share_locked && lp_share_modes(SNUM(cnum))) @@ -2861,6 +2861,20 @@ max can be %d\n", num_interfaces, FD_SETSIZE)); return True; } close(Client); /* The parent doesn't need this socket */ + + /* + * Force parent to check log size after spawning child. + * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De. + * The parent smbd will log to logserver.smb. + * It writes only two messages for each child + * started/finished. But each child writes, say, 50 messages also in + * logserver.smb, begining with the debug_count of the parent, before the + * child opens its own log file logserver.client. In a worst case + * scenario the size of logserver.smb would be checked after about + * 50*50=2500 messages (ca. 100kb). + */ + force_check_log_size(); + #endif /* NO_FORK_DEBUG */ } /* end for num */ } /* end while 1 */ -- cgit