[net.unix] RCS + modification time?

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