ccfd - a ClearCase-aware shell program for Unix
% ccfd cp foo bar
% ccfd -- cp foo bar
% ccfd -c "cp foo bar"
% ccfd
ccfd% cp foo bar
% ccfd -m -i -x -- cp foo bar
% ccfd -mi -- make install
CCFD stands for ClearCase for Dummies. No slight is intended to any human; the reference is to programs which are ``dumb'' in the sense that they don't understand ClearCase. It consists of a program called ccfd and some supporting libraries; in the following, the uppercase acronym CCFD is used to refer to the entire application while ccfd refers to the program.
What CCFD does is inject ``ClearCase awareness'' into any program run under its control (including its children, grandchildren, etc.). The simplest manifestation of this is just-in-time checkouts. For instance, here's an element in a dynamic view:
% ct ls -s foo
foo@@/main/1
ClearCase represents elements as read-only files within a read-only file system:
% ls -l foo
-r--r--r-- 1 dsb ccusers 1880 Mar 22 08:02 foo
So any attempt to modify it without a checkout will of course fail:
% date > foo
Error: foo: cannot create
but with CCFD enabled:
% ccfd <-- starts a new shell process
ccfd% date > foo
Checked out "/vobs_ccfd/t/foo" from version "/main/1".
ccfd% ct ls -s foo
foo@@/main/CHECKEDOUT
ccfd% cat foo
Tue Mar 26 09:41:21 2002
the checkout is done on the fly and the command succeeds.
CCFD can also be told to automatically checkin its checkouts, to create new files as elements, to start views on demand, etc. as described in OPTIONS. The default behavior is checkout-on-demand-and-leave-checked-out only, as demonstrated above.
Another way to think of CCFD is that it implements the hijack
feature of snapshot views for dynamic views, though of course elements
hijacked by CCFD don't need to be converted to checkouts later
because they're already checkouts.
CCFD has no effect on flat files, devices, snapshot views, or view-private files within dynamic views.
-c flag. Semantics are the same as sh -c 'cmd'.
Note that when -c is used the cmd is passed to system() and
thus is parsed by the shell, whereas a trailing command (e.g. ``ccfd --
mv aaa bbb'') is passed directly to execvp() with no shell
intervention.
cleartool diff to
see if any change was made and replaces the <checkin> with an unco
if not. This keeps unnecessary versions from being created but the diff
causes it to run somewhat slower. Use of -I modifies the behavior of
-i such that it skips the diff and checks in the element regardless.
Files which are automatically checked out but replaced with an identical version will be automatically unco-ed. To suppress this feature, which costs some time, use -I without -i.
Note that CCFD always checks in new file elements as they're
created, even if -i is not used. In other words it always uses the
-ci flag to mkelem. This is analogous to the way ``Add to Source
Control'' works in modern ClearCase/Windows releases.
You probably don't want to run interactively in -m mode, as the odds of making elements unintentionally are high. It's mostly useful for scripts or one-shot commands such as this
% ccfd -m -i -- tar -xf foo.tar
to extract and import a tar file in one command.
-o /dev/null. Turns off the usual ClearCase
output to stdout, e.g. messages such as:
Checked out "file" from version "/main/4"
/view/view-tag/... fails, use cleartool startview to ensure the
view is running and try again.
close(2) system call is
made. This has the risk of version churn but is sometimes
preferable. For instance, if a program opens the element ``foo'', writes
to it, closes it, then opens, writes and closes again, two new versions
will be created in synchronous mode whereas normal mode would make just
one.
ccfd -v /vob/one:/vob/two
Elements of this list need not be VOB tags; they may be what the ClearCase documentation refers to as a ``pname-in-vob'', meaning any element within a mounted VOB. Therefore the following:
% ccfd -v. <command>
will always limit CCFD's scope to the current VOB.
This is an octal bitmask to be applied to what ls -l would show for
an MVFS file when CCFD is in effect (technically, it's applied to
the results of all stat(2) system calls which is the same as what
users see with ls -l). The default value is 0200, which causes
the file to appear writeable by the user only. These bits are the same
you would pass to the chmod command except that the read and execute
bits may not be manipulated.
This setting may also be manipulated via the CCFD_PLUSMODE environment variable.
The default should always work but you may choose to turn on different
bits as a visual indicator that the file is really a checked-in
ClearCase element. For instance, without CCFD we see foo as
unwriteable:
% ls -l foo
-r--r--r-- 1 dsb ccusers 25 Mar 26 09:42 foo
With CCFD in default mode it's writeable:
% ccfd ls -l foo
-rw-r--r-- 1 dsb ccusers 25 Mar 26 09:42 foo
And here we tell it to show elements with the ``sticky bit'' (the 'T')
turned on as well. The sticky bit is meaningless in this context; it
serves only as a visual cue for determining from the output of ls -l
which files are elements and which view-private:
% ccfd -p 01200 ls -l foo
-rw-r--r-T 1 dsb ccusers 25 Mar 26 09:42 foo
Warning: overloading supposedly-unused mode bits may collide with other applications which play similar games. In an environment where group-write privileges are the norm this setting may be preferred:
% export CCFD_PLUSMODE=0020
% ccfd ls -l foo
-r--rw-r-- 1 dsb ccusers 25 Mar 26 09:42 foo
Which gives a clear visual cue without stealing any bits for unintended uses.
It's important to understand that PLUSMODE merely controls the
extent of the lie we tell to ourselves. A checked-in element is in fact
read-only; we can pretend otherwise because we have a sneaky plan to do
a just-in-time checkout, but at the time the stat() occurs it is
read-only and saying otherwise is a lie. Of course, you can always
tell the strict truth by setting CCFD_PLUSMODE=0 but that might be more
confusing than the lie. Winston was right.
feature at the cost of using an extra file
descriptor. If your program cannot spare that descriptor, this flag
will suppress the workaround.
The comment provided for automatic operations may be set via the CCFD_COMMENT environment variable. No flag is provided for this.
if [[ "$LD_PRELOAD" = *libccfd* ]]; then
PS1="CCFD $PS1"
fi
The idea is quite simple: CCFD ``wraps'' file-access system calls such
as open(). For instance, checkout-on-demand is handled like this:
the wrapper around open(2) invokes the real system call first. If
that succeeds, and in the majority of failure cases as well, the result
is allowed to stand and the return code passed back to the caller. In
one very specific situation (the open failed, it was attempting to
write, the file it failed to write existed previously, the path is
within a VOB, and a few other tests), the wrapper checks out the file
and retries the open. This 2nd result is always passed back to the
caller.
Other system calls such as mkdir(), stat(), chmod() etc. are
translated to their ClearCase equivalents in a similar manner.
Though a few known bugs are listed below, and the usual set of unknown
ones presumably exist, comfort may be found in this fact about
ClearCase: There are only a few irreversible operations on VOB
objects: rmelem, rmtype, and rmver. As CCFD contains no
code to do any of those things, it is absolutely impossible for it to
destroy ClearCase data. The worst that could happen, if something
went badly wrong, would be a mess that would take some laborious admin
work to clean up (such as linking elements back into directories). And
even this could happen only with the auto-checkin flag (-i) set;
without that the prior state can always be restored by unco-ing
everything and perhaps cleaning up lost+found.
Note that the above applies to ClearCase data; it's not impossible for CCFD to remove view-private data irretrievably. I don't think it does but no promises are made, no warrantee express or implied exists, etc. Critical view-private files, as always, should be backed up or made into versioned elements.
% cp libccfd.so /usr/lib/secure
% export LD_LIBRARY_PATH=/usr/lib/secure
Or placing a link to libccfd.so in a trusted directory, e.g. /usr/lib,
or adding a new trusted lib with crle(1). See ``man ld.so.1'' and
``man crle'' for details. The Linux situation is similar: see ``man ld.so''
and the files /etc/ld.so.preload and /etc/ld.so.config. These
restrictions are imposed by the operating system for security reasons,
not by CCFD. Without this special setup, setuid programs will print
a warning to the effect that they refuse to load libccfd.so. They'll
work correctly but will not be CCFD-enabled.
if [ -w foo ]; then
# foo must be checked out if it's writeable
cleartool checkin foo
fi
This can be worked around either by using cleartool lsco instead of the above trick, or by invoking ccfd so as to suppress the writeability feature. It's generally not hard to deal with these issues either by adding CCFD smarts or subtracting ClearCase smarts.
foo
by moving the original copy to foo~, writing the buffer to a new
file called foo, then unlinking foo~. All of which is faithfully
tracked by CCFD, leaving you with a removed file eclipsed by a new
view-private copy.
Similarly, the standard Unix tar program overwrites existing files
by unlinking them first, whereas GNU tar overwrites them in place. Thus
the standard tar could in theory churn the VOB quite a bit by
rmname-ing elements and then mkelem-ing evil twins on top whereas GNU
tar would be cleaner.
Note that the two problems above are solved; they're mentioned here
only to illustrate the kinds of things that can happen. The workaround
for vim is to set the two options nobackup and nowritebackup
in your .vimrc file. The tar behavior is worked around within CCFD.
Another example is emacs. Emacs does some complex things with hard links, backup files, etc. while writing out the edit buffer. Since Emacs users have clearcase.el http://www.ultranet.com/~esler/ccase-mode/ mode available, CCFD simply turns itself off within emacs on the theory that clearcase.el mode will be in use if ClearCase-awareness is desired.
% cp /etc/motd foo
Checked out "/vobs_st/ccfd/foo" from version "/main/20".
Checked in "/vobs_st/ccfd/foo" version "/main/21".
% cat /etc/motd > foo
Checked out "/vobs_st/ccfd/foo" from version "/main/21".
In the first case the cp command did all the opening, writing, and closing so it interacted with ClearCase beautifully, whereas cat asked the shell for help in opening the output file and CCFD got confused. I have an idea of how to fix this but haven't looked into it.
The same applies to new files created via > in -m mode.
To keep programs which attempt to touch files from failing, CCFD
pretends to update timestamps when asked to but it really doesn't, as
this transcript illustrates:
% ls -l foo
-rw-r--r-- 1 dsb ccusers 25 Mar 26 09:42 foo
% date
Tue Apr 2 11:26:32 EST 2002
% touch foo
% ls -l foo
-rw-r--r-- 1 dsb ccusers 25 Mar 26 09:42 foo
Note that use of timestamp-based logic in an MVFS environment is deprecated for other reasons anyway; this is just an additional one.
However, in the event that timestamps must be changed the -U option is supported. This results in a checkout-touch-checkin sequence.
ld.so.1(1) on Solaris or ld.so(1) on Linux
crle(1) on Solaris
All ClearCase Documentation
David Boyce dsb@boyski.com
Copyright (c) 2002-2005 David Boyce, Clear Guidance Consulting. All rights reserved.
CCFD was inspired by the suggestion of Christian Goetze, who wondered aloud on CCIUG why ClearCase didn't have auto-checkout capabilities like Continuus.