[vhffs-dev] [1292] Fixed some race conditions on rename() |
[ Thread Index |
Date Index
| More vhffs.org/vhffs-dev Archives
]
Revision: 1292
Author: gradator
Date: 2008-10-26 03:46:53 +0100 (Sun, 26 Oct 2008)
Log Message:
-----------
Fixed some race conditions on rename()
Modified Paths:
--------------
trunk/vhffs-fssync/vhffsfssync_master.c
trunk/vhffs-fssync/vhffsfssync_slave.c
Modified: trunk/vhffs-fssync/vhffsfssync_master.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_master.c 2008-10-25 14:48:25 UTC (rev 1291)
+++ trunk/vhffs-fssync/vhffsfssync_master.c 2008-10-26 02:46:53 UTC (rev 1292)
@@ -39,7 +39,7 @@
// the maximum number of files simultaneously opened
// huge values offer better performance
-// actually it is MAX = VHFFSFSSYNC_MAX_OPENFILES + number of clients
+// actually it is MAX = VHFFSFSSYNC_MAX_OPENFILES + files currently uploaded
#define VHFFSFSSYNC_MAX_OPENFILES 512
// each monitor entry is associated with a path, we need to keep it to compute the path
@@ -64,10 +64,14 @@
int vhffsfssync_openfiles;
+GHashTable *vhffsfssync_missedfiles;
+
// protos
int vhffsfssync_add_watch(int inotifyfd, const char *pathname, uint32_t mask);
+int vhffsfssync_modify_watch(int inotifyfd, const char *from, const char *to);
int vhffsfssync_del_watch(int inotifyfd, const char *pathname, int wd);
int vhffsfssync_add_watch_recursively(int inotifyfd, const char *pathname, uint32_t mask);
+int vhffsfssync_manage_event_remove(int inotifyfd, char *pathname);
int vhffsfssync_manage_event_create(int inotifyfd, char *pathname, gboolean sendfile);
int vhffsfssync_manage_event(int inotifyfd, struct inotify_event *event);
int vhffsfssync_fake_events_recursively(int inotifyfd, char *pathname);
@@ -460,10 +464,11 @@
// do we need to free a file fd ?
if(vhffsfssync_openfiles > VHFFSFSSYNC_MAX_OPENFILES) {
GList *msgs;
+ fprintf(stderr, "Maximum number of opened files reached, consider adding more\n");
// we prefer to fclose() the fd of the msg with the lowest priority
for(msgs = g_list_last(conn->messages) ; msgs ; ) {
vhffsfssync_net_message *msg = msgs->data;
- msgs = g_list_previous(msgs);
+ msgs = g_list_previous(msgs);
if(msg->msg_family == VHFFSFSSYNC_NET_MESSAGE_FILE) {
vhffsfssync_net_message_file *filemsg = (vhffsfssync_net_message_file*)msg;
@@ -1250,6 +1255,7 @@
#if DEBUG_INOTIFY
printf("==> REMOVE %s\n", pathname);
#endif
+ g_hash_table_remove(vhffsfssync_missedfiles, pathname);
if( (_wd = g_hash_table_lookup(vhffsfssync_path_to_wd, pathname)) ) {
vhffsfssync_del_watch(inotifyfd, NULL, *_wd);
@@ -1310,7 +1316,7 @@
if(ret < 0) {
if(errno == ENOENT) {
// file already disappeared (common for temporary files)
- vhffsfssync_manage_event_remove(inotifyfd, pathname);
+ g_hash_table_insert(vhffsfssync_missedfiles, g_strdup(pathname), "");
} else {
fprintf(stderr, "cannot readlink() '%s': %s\n", pathname, strerror(errno));
return -1;
@@ -1323,7 +1329,7 @@
else {
if(errno == ENOENT) {
// file already disappeared (common for temporary files)
- vhffsfssync_manage_event_remove(inotifyfd, pathname);
+ g_hash_table_insert(vhffsfssync_missedfiles, g_strdup(pathname), "");
} else {
fprintf(stderr, "cannot lstat() '%s': %s\n", pathname, strerror(errno));
return -1;
@@ -1448,7 +1454,14 @@
if( vhffsfssync_cookie.isdir )
vhffsfssync_modify_watch(inotifyfd, vhffsfssync_cookie.from, pathname);
- vhffsfssync_net_broadcast_event( g_strdup_printf("move%c%s%c%s%c", '\0', vhffsfssync_cookie.from, '\0', pathname, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
+ if(! g_hash_table_lookup(vhffsfssync_missedfiles, vhffsfssync_cookie.from) ) {
+ vhffsfssync_net_broadcast_event( g_strdup_printf("move%c%s%c%s%c", '\0', vhffsfssync_cookie.from, '\0', pathname, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
+ }
+ else {
+ vhffsfssync_manage_event_create(inotifyfd, pathname, TRUE);
+ g_hash_table_remove(vhffsfssync_missedfiles, vhffsfssync_cookie.from);
+ }
+
vhffsfssync_cookie.id = 0;
free(vhffsfssync_cookie.from);
}
@@ -1535,6 +1548,7 @@
vhffsfssync_cookie.id = 0;
vhffsfssync_cookie.from = NULL;
vhffsfssync_openfiles = 0;
+ vhffsfssync_missedfiles = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
inotifyfd = inotify_init();
Modified: trunk/vhffs-fssync/vhffsfssync_slave.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_slave.c 2008-10-25 14:48:25 UTC (rev 1291)
+++ trunk/vhffs-fssync/vhffsfssync_slave.c 2008-10-26 02:46:53 UTC (rev 1292)
@@ -387,12 +387,19 @@
else if(!strcmp(args[0], "symlink")) {
char *from = args[1];
char *to = args[2];
- symlink(to, from);
+ if( symlink(to, from) ) {
+ fprintf(stderr, "symlink() failed on %s -> %s: %s\n", from, to, strerror(errno));
+ }
}
else if(!strcmp(args[0], "move")) {
char *from = args[1];
char *to = args[2];
- rename(from, to);
+ if( rename(from, to) ) {
+ fprintf(stderr, "rename() failed from %s to %s: %s\n", from, to, strerror(errno));
+ if( errno == ENOENT ) {
+ vhffsfssync_net_send_event(conn, g_strdup_printf("get%c%s%c", '\0', to, '\0') );
+ }
+ }
}
else if(!strcmp(args[0], "write")) {
char *pathname = args[1];