]> err.no Git - util-linux/commitdiff
libmount: clean up lock.c
authorKarel Zak <kzak@redhat.com>
Thu, 15 Jul 2010 13:22:34 +0000 (15:22 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:40 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/lock.c

index 0f35aa3bd7f45f9b82401317f0aa5437fc4bbfe8..beea23980f544bd9a679642f006f9c516b6a68e0 100644 (file)
@@ -36,7 +36,6 @@
  * lock handler
  */
 struct _mnt_lock {
-       pid_t   id;             /* getpid() or so (see linkfile)... */
        char    *lockfile;      /* path to lock file (e.g. /etc/mtab~) */
        char    *linkfile;      /* path to link file (e.g. /etc/mtab~.<id>) */
        int     lockfile_fd;    /* lock file descriptor */
@@ -46,30 +45,44 @@ struct _mnt_lock {
 
 /**
  * mnt_new_lock:
- * @lockfile: path to lockfile or NULL (default is _PATH_MOUNTED_LOCK)
+ * @dataname: the file that should be covered by the lock
  * @id: unique linkfile identifier or 0 (default is getpid())
  *
  * Returns: newly allocated lock handler or NULL on case of error.
  */
-mnt_lock *mnt_new_lock(const char *lockfile, pid_t id)
+mnt_lock *mnt_new_lock(const char *datafile, pid_t id)
 {
-       mnt_lock *ml = calloc(1, sizeof(struct _mnt_lock));
+       mnt_lock *ml = NULL;
+       char *lo = NULL, *ln = NULL;
 
-       if (!ml)
+       /* lockfile */
+       if (!datafile)
                return NULL;
 
-       ml->lockfile_fd = -1;
-       ml->id = id;
-       if (lockfile) {
-               ml->lockfile = strdup(lockfile);
-               if (!ml->lockfile) {
-                       free(ml);
-                       return NULL;
-               }
+       if (asprintf(&lo, "%s~", datafile) == -1) {
+               lo = NULL;
+               goto err;
+       }
+       if (asprintf(&ln, "%s~.%d", datafile, id ? : getpid()) == -1) {
+               ln = NULL;
+               goto err;
        }
+       ml = calloc(1, sizeof(struct _mnt_lock) );
+       if (!ml)
+               goto err;
+
+       ml->lockfile_fd = -1;
+       ml->linkfile = ln;
+       ml->lockfile = lo;
        return ml;
+err:
+       free(lo);
+       free(ln);
+       free(ml);
+       return NULL;
 }
 
+
 /**
  * mnt_free_lock:
  * @ml: mnt_lock handler
@@ -93,38 +106,21 @@ void mnt_free_lock(mnt_lock *ml)
  */
 const char *mnt_lock_get_lockfile(mnt_lock *ml)
 {
-       if (!ml)
-               return NULL;
-       if (ml->lockfile)
-               return ml->lockfile;
-       return _PATH_MOUNTED_LOCK;
+       return ml ? ml->lockfile : NULL;
 }
 
 /**
  * mnt_lock_get_linkfile:
  * @ml: mnt_lock handler
  *
- * Returns: unique (per process) path to linkfile.
+ * Note that the filename is generated by mnt_new_lock() and depends on
+ * getpid() or 'id' argument of the mnt_new_lock() function.
+ *
+ * Returns: unique (per process/thread) path to linkfile.
  */
 const char *mnt_lock_get_linkfile(mnt_lock *ml)
 {
-       if (!ml)
-               return NULL;
-
-       if (!ml->linkfile) {
-               const char *lf = mnt_lock_get_lockfile(ml);
-               size_t sz;
-
-               if (!lf)
-                       return NULL;
-               sz = strlen(lf) + 32;
-
-               ml->linkfile = malloc(sz);
-               if (ml->linkfile)
-                       snprintf(ml->linkfile, sz, "%s.%d",
-                                       lf, ml->id ? ml->id : getpid());
-       }
-       return ml->linkfile;
+       return ml ? ml->linkfile : NULL;
 }
 
 static void mnt_lockalrm_handler(int sig)
@@ -208,8 +204,10 @@ static int mnt_wait_lock(mnt_lock *ml, struct flock *fl, time_t maxtime)
  *
  * This mtab locking code has been refactored and moved to libmount. The mtab
  * locking is really not perfect (e.g. SIGALRM), but it's stable, reliable and
- * backwardly compatible code. Don't forget that this code has to be compatible
- * with 3rd party mounts (/sbin/mount.<foo>) and has to work with NFS.
+ * backwardly compatible code.
+ *
+ * Don't forget that this code has to be compatible with 3rd party mounts
+ * (/sbin/mount.<foo>) and has to work with NFS.
  * -- kzak@redhat.com [May-2009]
  */
 
@@ -219,13 +217,20 @@ static int mnt_wait_lock(mnt_lock *ml, struct flock *fl, time_t maxtime)
 /* sleep time (in microseconds, max=999999) between attempts */
 #define MOUNTLOCK_WAITTIME             5000
 
-/* Remove lock file.  */
+/**
+ * mnt_unlock_file:
+ * @ml: lock struct
+ *
+ * Unlocks the file. The function could be called independently on the
+ * lock status (for example from exit(3)).
+ */
 void mnt_unlock_file(mnt_lock *ml)
 {
        if (!ml)
                return;
 
-       DBG(DEBUG_LOCKS, fprintf(stderr, "LOCK: (%d) unlocking/cleaning.\n", getpid()));
+       DBG(DEBUG_LOCKS, fprintf(stderr,
+                       "LOCK: (%d) unlocking/cleaning.\n", getpid()));
 
        if (ml->locked == 0 && ml->lockfile && ml->linkfile)
        {
@@ -286,10 +291,14 @@ void mnt_unlock_file(mnt_lock *ml)
  *     int update_mtab()
  *     {
  *             int sig = 0;
+ *             const char *mtab;
  *
- *             atexit(unlock_fallback);
+ *             if (!(mtab = mnt_get_writable_mtab_path()))
+ *                     return 0;                       // system without mtab
+ *             if (!(ml = mnt_new_lock(mtab, 0)))
+ *                     return -1;                      // error
  *
- *             ml = mnt_new_lock(NULL, 0);
+ *             atexit(unlock_fallback);
  *
  *             if (mnt_lock_file(ml) != 0) {
  *                     printf(stderr, "cannot create %s lockfile\n",
@@ -404,7 +413,7 @@ int mnt_lock_file(mnt_lock *ml)
        }
        DBG(DEBUG_LOCKS, fprintf(stderr,
                        "LOCK: %s: (%d) successfully locked\n",
-                       ml->lockfile, getpid()));
+                       lockfile, getpid()));
        unlink(linkfile);
        return 0;
 
@@ -464,15 +473,14 @@ void sig_handler(int sig)
 
 int test_lock(struct mtest *ts, int argc, char *argv[])
 {
-       const char *lockfile, *datafile;
+       const char *datafile;
        int verbose = 0, loops, l;
 
-       if (argc < 4)
+       if (argc < 3)
                return -1;
 
-       lockfile = argv[1];
-       datafile = argv[2];
-       loops = atoi(argv[3]);
+       datafile = argv[1];
+       loops = atoi(argv[2]);
 
        if (argc == 5 && strcmp(argv[4], "--verbose") == 0)
                verbose = 1;
@@ -493,11 +501,13 @@ int test_lock(struct mtest *ts, int argc, char *argv[])
        }
 
        for (l = 0; l < loops; l++) {
-               lock = mnt_new_lock(lockfile, 0);
+               lock = mnt_new_lock(datafile, 0);
+               if (!lock)
+                       return -1;
 
                if (mnt_lock_file(lock) == -1) {
-                       fprintf(stderr, "%d: failed to create lock file: %s\n",
-                                       getpid(), lockfile);
+                       fprintf(stderr, "%d: failed to lock %s file\n",
+                                       getpid(), datafile);
                        return -1;
                }
 
@@ -518,7 +528,7 @@ int test_lock(struct mtest *ts, int argc, char *argv[])
 int main(int argc, char *argv[])
 {
        struct mtest tss[] = {
-       { "--lock", test_lock,  "  <lockfile> <datafile> <loops> [--verbose]   increment number in datafile" },
+       { "--lock", test_lock,  "  <datafile> <loops> [--verbose]   increment number in datafile" },
        { NULL }
        };