delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/08/29/16:42:43

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
Subject: Re: link(2) and atomic file creation on NFS
To: james AT free-lunch DOT demon DOT co DOT uk
Cc: cygwin AT cygwin DOT com
X-Mailer: Lotus Notes Release 5.0.4 June 8, 2000
Message-ID: <OFD88C0F72.0F1E9070-ON85256AB7.0071AEA9@ny.jpmorgan.com>
From: yap_noel AT jpmorgan DOT com
Date: Wed, 29 Aug 2001 16:42:07 -0400
X-MIMETrack: Serialize by Router on NYC_SMTPMTA_03(Release 5.0.7 |March 21, 2001) at 08/29/2001
04:42:09 PM
MIME-Version: 1.0

Would a mkdir do the trick?

Noel

I have some existing code which uses link(2) to achieve atomic locking
on Unix over NFS (since O_EXCL does not work over NFS).  The
application (a GPLed SCCS clone) now compiles under Cygwin, but one
remaining problem is that the lockfile code uses link(2) to create a
hard link to an open file.

This seems not to work under Cygwin B20.1 (over NT4).  The link count
of the file stays at 1 (I think that errno=EPERM, but I could be
wrong).

The link(2) usage is only relevant over NFS, but even if there is an
NFS client for NT [*does* one exist?], I would assume that the Cygwin
link(2) implementation would not correspond with a link(2) operation
via the NT NFS client.   So, the link(2) implementation loses under
NT.  Fine.

Is there a way of safely creating a lock file without race conditions
that will also work under Cygwin?   For the sake of the discussion,
here is the current code :-

(explanation: "mystring" is a C++ class a lot like the standard string
class, and in fact usually *is* the standard string class)


TIA for any helpful hints!


/* WARNING: If you use fstat() on the fd to get the link count, the
 * wrong value is returned for Linux 2.0.34 and glibc-2.0.7, the
 * second time we perform the fstat().  Therefore we use stat(2)
 * rather than fstat(2).
 */
static long get_nlinks(const char *name)
{
  struct stat st;

  if (0 == stat(name, &st))
    {
      return (long)st.st_nlink;
    }
  else
    {
      return -1L;
    }
}

static int atomic_nfs_create(const mystring& path, int flags, int perms)
{
  mystring dirname, basename;
  char buf[32];
  const char *pstr = path.c_str();

  split_filename(path, dirname, basename);

  /* Rely (slightly) on only 11 characters of filename. */
  for (long attempt=0; attempt < 10000; ++attempt)
    {
      /* form the name of a lock file. */
      sprintf(buf, "nfslck%ld", attempt);
      const mystring lockname = dirname + mystring(buf);
      const char *lockstr = lockname.c_str();

      errno = 0;
      int fd = open(lockstr, flags, perms);
      if (fd >= 0)
        {
          if (1 == get_nlinks(lockstr))
            {
              int link_errno = 0;
              errno = 0;
              if (-1 == link(lockstr, pstr))
                link_errno = errno;

              /* ignore other responses */

              if (2 == get_nlinks(lockstr))
                {
                  unlink(lockstr);
                  return fd;    /* success! */
                }
              else              /* link(2) failed. */
                {
                  if (EPERM == link_errno)
                    {
                      /* containing filesystem does not support hard links.
*/
                      close(fd);
                      unlink(lockstr);

                      /* assume that the filesystem supports O_EXCL if it
does
                       * not supprort link(2).
                       */
                      return open(pstr, flags, perms);
                    }
                }
            }
          close(fd);
          unlink(lockstr);
        }
      else                      /* open() failed. */
        {
          switch (errno)
            {
            case EEXIST:
              /* someone else got that lock first; they may in fact not
               * be trying to lock the same s-file (but instead another
               * s-file in the same directory)
               *
               * Try again.  Sleep first if we're not doing well,
               * but try to avoid pathalogical cases...
               */
              if ( (attempt > 4) && (attempt & 1) == (getpid() & 1) )
                {
                  errormsg("Sleeping for one second while "
                           "waiting for lock\n");
                  sleep(1);
                }
              break;

            default:            /* hard failure. */
              /* fall back on the less-safe method, which will
               * probably still fail
               */
              return open(pstr, flags, perms);
            }
        }
    }
  return -1;
}


--
James Youngman
Manchester, UK.  +44 161 226 7339
PGP (GPG) key ID for <jay AT gnu DOT org> is 64A95EE5 (F1B83152).

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/





This communication is for informational purposes only.  It is not intended as
an offer or solicitation for the purchase or sale of any financial instrument
or as an official confirmation of any transaction. All market prices, data
and other information are not warranted as to completeness or accuracy and
are subject to change without notice. Any comments or statements made herein
do not necessarily reflect those of J.P. Morgan Chase & Co., its
subsidiaries and affiliates.


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019