david@varian.UUCP (David Brown) (11/01/84)
We have recently converted from using SCCS to RCS on a large (6 programmers) project, and have come across a problem involving RCS and make: When a user checks out a file for edit, the lock information is placed in the ,v file itself (as opposed to SCCS, which created a separate lock file with a p. prefix). This changes the modification time of the ,v file, and if someone else does a make on the system before the editing user does a check-in (ci) , that file will be recompiled unnecessarily. As the cross assembler we are using (Microtec Z80 cross assembler, written in Fortran) is very slow, we would prefer to avoid unnecessary compilations. I have thought of a modification to co that would avoid unnecessary recompilations, but I want to get opinions from the net in case there are holes, security problems, etc.. I would also be interested in hearing from anyone who has made a similar change or found a better way around this problem. It seems to me that someone else should have run into this by now. Proposal: There is a system call (utime(2)) that allows you to set the times on a file to whatever you want, rather than the actual time. A quick grep through /usr/src/cmd/*.c found this call used only by the mv(1) command. Modify co to: call stat(2) to find out original modification time of the ,v file do normal processing (write lock info into file & close) call utime(2) to set the modification time of the ,v file back to the original time There will be a short window after the file is closed but before the modification time is set back, but it shouldn't be large enough to worry about a make coming through. Possible problems: 1) How does this affect dumps (my guess is that an incremental dump will not pick up the ,v file, so if we had to do a total restor, the ,v file will no longer be locked. I think I could live with that). 2) utime must be called by superuser or by the owner of the file (at least according to the manual); this implies to me that utime can't be called by someone who only has group write permission on the ,v file. We do use group write permission sometimes, but I think we can avoid that. 3) You will not be able to find out the latest files that have been checked out by doing ls -lt in the RCS directory; you will need to use rlog. We could live with this too. -- David Brown (415) 945-2199 Varian Instruments 2700 Mitchell Dr. Walnut Creek, Ca. 94598 {zehntel,amd,fortune,resonex}!varian!david
steveg@hammer.UUCP (Steve Glaser) (11/02/84)
Summary: Expires: References: <varian.257> Sender: Reply-To: steveg@hammer.UUCP (Steve Glaser) Followup-To: Distribution: net Organization: Tektronix, Inc., Wilsonville, OR Keywords: In article <varian.257> david@varian.UUCP (David Brown) writes: > When a user checks out a file for edit, the lock information is placed > in the ,v file itself (as opposed to SCCS, which created a separate > lock file with a p. prefix). This changes the modification time of the > ,v file, and if someone else does a make on the system before the > editing user does a check-in (ci) , that file will be recompiled > unnecessarily. > > I have thought of a modification to co that would avoid unnecessary > recompilations, but I want to get opinions from the net in case there > are holes, security problems, etc.. I would also be interested in > hearing from anyone who has made a similar change or found a better > way around this problem. It seems to me that someone else should have > run into this by now. > > Proposal: > There is a system call (utime(2)) that allows you to set the times > on a file to whatever you want, rather than the actual time. A quick > grep through /usr/src/cmd/*.c found this call used only by the mv(1) > command. > > Modify co to: > call stat(2) to find out original modification time of the ,v file > do normal processing (write lock info into file & close) > call utime(2) to set the modification time of the ,v file > back to the original time > > There will be a short window after the file is closed but before the > modification time is set back, but it shouldn't be large enough to > worry about a make coming through. > > Possible problems: > 1) How does this affect dumps (my guess is that an incremental dump will not > pick up the ,v file, so if we had to do a total restor, the ,v file will > no longer be locked. I think I could live with that). No problem. There is another time (not settable bu utime(2)) that records the modification time of the inode. Incremental dumps use the later of inode mod time or the normal mod time to decide what to dump. > 2) utime must be called by superuser or by the owner of the file > (at least according to the manual); this implies to me that utime can't > be called by someone who only has group write permission on the ,v file. No problem. All RCS files get copied when you play with them. The last setp of the operation is to do a quick rename of the ,RCSxxxx temp file to the real ,v file. If you do the utime(2) against the ,RCSxxxx file before the rename, there's not even a timing window where it's wrong (rename does not change file mod time except that of the parent directory). > 3) You will not be able to find out the latest files that have been checked > out by doing ls -lt in the RCS directory; you will need to use rlog. > We could live with this too. Right. We made this change to our version of RCS (but under the control of the new -P option). It's useful on more than just co. Supposed you check out something with a lock and later decide you didn't need it after all, a quick "rcs -P -u file" undoes the damage and doesn't change the ,v file time. One further major gotcha with RCS. The number of revisions is strictly limited and the standard number is about 239 revisions. We made it 719 and added a warning if you're within 20 of that. If you overflow the table, the ,v file becomes useless to RCS. Steve Glaser tektronix!steveg
david@varian.UUCP (David Brown) (11/09/84)
A few weeks I asked if anyone saw any problems in having the co and rcs commands of RCS use utime(2) to reset the modification time of the RCS file when it is locked or unlocked; this is to prevent make from recompiling that module when the only change is that someone is checked it out with a lock. I went away and made the changes; they were very simple - I have included them below. tektronix!glaser (Steve Glaser) posted a followup saying that something similar was implemented at Tektronix with a -P flag. He also suggested doing the utime() call before the RCS file is renamed from ,RCSxxxx to close the small window I noticed where a make could come through between the rename and the change of the modification time; I failed to do this in the changes described below, but I plan to change this next time I'm working on RCS modifications. Steve also pointed out the following: One further major gotcha with RCS. The number of revisions is strictly limited and the standard number is about 239 revisions. We made it 719 and added a warning if you're within 20 of that. If you overflow the table, the ,v file becomes useless to RCS. Thanks to Steve and everyone else who replied. In addition, I made a small change to rcsutil.c. On our pdp11 (running sort of 2.8bsd), but not on our VAX (running 4.1bsd), we found a problem where programs running in the background will be stopped by a <ctrl> C typed in the foreground. This is because catchints() is setting SIGINT to catchsig(); I changed catchints() and ignoreints() so that they didn't touch SIGINT at all and things seem to be working fine now. I don't know if there is something strange about our pdp11 kernel or whether the problem is present in all 2.8bsd and v7 systems. Here are my changes to co.c and rcs.c: *** OLD/co.c Thu Apr 7 09:36:23 1983 --- co.c Tue Oct 30 12:44:47 1984 *************** *** 276,281 newRCSfilename[0]='\0'; /* avoid re-deletion by cleanup()*/ if (chmod(RCSfilename,RCSstat.st_mode & ~0222)<0) warn("Can't preserve mode of %s",RCSfilename); catchints(); } --- 279,287 ----- newRCSfilename[0]='\0'; /* avoid re-deletion by cleanup()*/ if (chmod(RCSfilename,RCSstat.st_mode & ~0222)<0) warn("Can't preserve mode of %s",RCSfilename); + #ifdef VARIAN + utime(RCSfilename,&RCSstat.st_atime); + #endif VARIAN catchints(); } *** OLD/rcs.c Tue Oct 9 15:25:39 1984 --- rcs.c Tue Oct 30 12:44:30 1984 *************** *** 514,519 } newRCSfilename[0]='\0'; /* avoid re-unlinking by cleanup()*/ if (!initflag) /* preserve mode bits */ if (chmod(RCSfilename,filestatus.st_mode & ~0222)<0) warn("Can't set mode of %s",RCSfilename); --- 518,525 ----- } newRCSfilename[0]='\0'; /* avoid re-unlinking by cleanup()*/ if (!initflag) /* preserve mode bits */ + #ifdef VARIAN + { + if (chmod(RCSfilename,filestatus.st_mode & ~0222)<0) + warn("Can't set mode of %s",RCSfilename); + utime(RCSfilename,&filestatus.st_atime); + } + #else + if (chmod(RCSfilename,filestatus.st_mode & ~0222)<0) + warn("Can't set mode of %s",RCSfilename); + #endif VARIAN -- David Brown (415) 945-2199 Varian Instruments 2700 Mitchell Dr. Walnut Creek, Ca. 94598 {zehntel,amd,fortune,resonex}!varian!david