use a lock on the cache file to ensure that only one remote-cache node at a time...
authorroot <root@rcn1.VSOFS1.COM>
Sun, 29 Mar 2009 23:15:04 +0000 (10:15 +1100)
committerroot <root@rcn1.VSOFS1.COM>
Sun, 29 Mar 2009 23:15:04 +0000 (10:15 +1100)
migrate/remote-cached.c

index 7dfccc43b60685387cdb59a45b9ba597c7ea7095..e202d765b6267d7e5d1728770d6028874651853b 100644 (file)
@@ -47,6 +47,8 @@ int migrate_files(void)
        int ret = 0;
        struct stat old_st;
        struct stat new_st;
+       struct flock lock;
+       int cache_fd = -1;
 
        /* Open the migrate db database */
        if (migrate_db == NULL) {
@@ -163,6 +165,25 @@ int migrate_files(void)
        }
 
 
+       /* make sure the file exists */
+       cache_fd = open(new_path, O_RDWR|O_CREAT);
+       if (cache_fd == -1) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to create cache file %s, errno:%d\n", new_path, errno));
+               ret = -errno;
+               goto finished;
+       }
+       lock.l_type = F_WRLCK;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = 0;
+       lock.l_len = 1;
+       lock.l_pid = getpid();
+       if (fcntl(cache_fd, F_SETLK, &lock) != 0) {
+               /* someone else is already migrating this file */
+               DEBUG(DEBUG_DEBUG, (__location__ " Failed to get lock on cache file %s.\n", new_path));
+               ret = 0;
+               goto finished;
+       }
+
        migrate_cmd = talloc_asprintf(mem_ctx, "rsync -ptgo \"%s\" \"%s\"", old_path, new_path);
        DEBUG(DEBUG_DEBUG,("Running migration command %s\n", migrate_cmd));
        ret = system(migrate_cmd);
@@ -174,6 +195,9 @@ int migrate_files(void)
 
 
 finished:
+       if (cache_fd != -1) {
+               close(cache_fd);
+       }
        tdb_unlockall(migrate_db);
        talloc_free(mem_ctx);
        return ret;