1. 16 10月, 2012 2 次提交
    • D
      Add JSON serialization of virLockSpacePtr objects for process re-exec() · 8057c04e
      Daniel P. Berrange 提交于
      Add two new APIs virLockSpaceNewPostExecRestart and
      virLockSpacePreExecRestart which allow a virLockSpacePtr
      object to be created from a JSON object and saved to a
      JSON object, for the purposes of re-exec'ing a process.
      
      As well as saving the state in JSON format, the second
      method will disable the O_CLOEXEC flag so that the open
      file descriptors are preserved across the process re-exec()
      Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
      8057c04e
    • D
      Introduce an internal API for handling file based lockspaces · eca72d47
      Daniel P. Berrange 提交于
      The previously introduced virFile{Lock,Unlock} APIs provide a
      way to acquire/release fcntl() locks on individual files. For
      unknown reason though, the POSIX spec says that fcntl() locks
      are released when *any* file handle referring to the same path
      is closed. In the following sequence
      
        threadA: fd1 = open("foo")
        threadB: fd2 = open("foo")
        threadA: virFileLock(fd1)
        threadB: virFileLock(fd2)
        threadB: close(fd2)
      
      you'd expect threadA to come out holding a lock on 'foo', and
      indeed it does hold a lock for a very short time. Unfortunately
      when threadB does close(fd2) this releases the lock associated
      with fd1. For the current libvirt use case for virFileLock -
      pidfiles - this doesn't matter since the lock is acquired
      at startup while single threaded an never released until
      exit.
      
      To provide a more generally useful API though, it is necessary
      to introduce a slightly higher level abstraction, which is to
      be referred to as a "lockspace".  This is to be provided by
      a virLockSpacePtr object in src/util/virlockspace.{c,h}. The
      core idea is that the lockspace keeps track of what files are
      already open+locked. This means that when a 2nd thread comes
      along and tries to acquire a lock, it doesn't end up opening
      and closing a new FD. The lockspace just checks the current
      list of held locks and immediately returns VIR_ERR_RESOURCE_BUSY.
      
      NB, the API as it stands is designed on the basis that the
      files being locked are not being otherwise opened and used
      by the application code. One approach to using this API is to
      acquire locks based on a hash of the filepath.
      
      eg to lock /var/lib/libvirt/images/foo.img the application
      might do
      
         virLockSpacePtr lockspace = virLockSpaceNew("/var/lib/libvirt/imagelocks");
         lockname = md5sum("/var/lib/libvirt/images/foo.img");
         virLockSpaceAcquireLock(lockspace, lockname);
      
      NB, in this example, the caller should ensure that the path
      is canonicalized before calculating the checksum.
      
      It is also possible to do locks directly on resources by
      using a NULL lockspace directory and then using the file
      path as the lock name eg
      
         virLockSpacePtr lockspace = virLockSpaceNew(NULL);
         virLockSpaceAcquireLock(lockspace, "/var/lib/libvirt/images/foo.img");
      
      This is only safe to do though if no other part of the process
      will be opening the files. This will be the case when this
      code is used inside the soon-to-be-reposted virlockd daemon
      Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
      eca72d47