[vhffs-dev] [1639] Fixed a max open file issue on master, but without shield, only by

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1639
Author:   gradator
Date:     2010-11-17 02:05:22 +0100 (Wed, 17 Nov 2010)
Log Message:
-----------
Fixed a max open file issue on master, but without shield, only by 
reordering how files are being sent to slaves. Reaching maximum openable 
files is however still possible on very busy systems and where the 
network cannot support the amount of data.

Master is no more sending mtime,uid and gid that failed to be stat()'ed, 
everything that cannot be stat()'ed is now silently discarded, so all 
useless checks in slave about that are now removed.

However all this stuff highlighted a similar issue of max open file on 
the slave that still need to be fixed ;-)

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	2010-11-16 22:07:35 UTC (rev 1638)
+++ trunk/vhffs-fssync/vhffsfssync_master.c	2010-11-17 01:05:22 UTC (rev 1639)
@@ -177,10 +177,10 @@
 
 /* net - filehandle */
 typedef struct {
-	FILE *file_stream;
 	char *file_pathname;
-	off_t file_size;
+	int file_fd;
 	int ref;
+	struct stat file_stat;
 } vhffsfssync_net_file;
 
 GHashTable *vhffsfssync_net_files;
@@ -220,8 +220,8 @@
 void vhffsfssync_net_broadcast_event(char *data, uint32_t priority);
 int vhffsfssync_net_send_file(vhffsfssync_conn *conn, char *pathname);
 void vhffsfssync_net_destroy_file(vhffsfssync_conn *conn, vhffsfssync_net_message_file *filemsg);
-vhffsfssync_net_file *vhffsfssync_net_file_open(vhffsfssync_conn *conn, const char *pathname, const char *mode);
-int vhffsfssync_net_file_close(vhffsfssync_conn *conn, vhffsfssync_net_file *file);
+vhffsfssync_net_file *vhffsfssync_net_file_open(const char *pathname);
+int vhffsfssync_net_file_close(vhffsfssync_net_file *file);
 int vhffsfssync_net_remove_file(vhffsfssync_conn *conn, char *pathname);
 void vhffsfssync_net_broadcast_file(char *pathname);
 char *vhffsfssync_net_parent_attrib(char *pathname);
@@ -379,6 +379,9 @@
 }
 
 inline int vhffsfssync_net_send_event(vhffsfssync_conn *conn, char *data, uint32_t priority)  {
+
+	if(!data) return -1;
+
 	return vhffsfssync_net_send_data(conn, data, vhffsfssync_net_event_len(data), priority);
 }
 
@@ -400,6 +403,9 @@
 
 	GList *conns;
 	ssize_t len;
+
+	if(!data) return;
+
 	len = vhffsfssync_net_event_len(data);
 	for(conns = g_list_first(vhffsfssync_conns) ; conns ; )  {
 		vhffsfssync_conn *conn = conns->data;
@@ -419,29 +425,21 @@
 	vhffsfssync_net_message_file *msg;
 	uint32_t maxprio = -1;  // 4294967295
 	vhffsfssync_net_file *file;
-	struct stat st;
-	st.st_mode=0;
-	st.st_uid=-1;
-	st.st_gid=-1;
 
 	if(!conn || !pathname)
 		return -1;
 
-	file = vhffsfssync_net_file_open(conn, pathname, "r");
+	file = vhffsfssync_net_file_open(pathname);
 	if(!file)
 		return -1;
 
-	if( fstat(fileno(file->file_stream), &st) < 0 )  {
-		fprintf(stderr, "fstat() failed on %s: %s\n", file->file_pathname, strerror(errno));
-	}
-
 	//printf("%d SENDING FILE %s\n", conn->fd, pathname);
-	vhffsfssync_net_send_event(conn, g_strdup_printf("open%c%s%c%d%c%d%c%d%c", '\0', pathname, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
+	vhffsfssync_net_send_event(conn, g_strdup_printf("open%c%s%c%d%c%d%c%d%c", '\0', pathname, '\0', file->file_stat.st_mode&07777, '\0', file->file_stat.st_uid, '\0', file->file_stat.st_gid, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
 	vhffsfssync_net_send_event(conn, vhffsfssync_net_parent_attrib(pathname) , VHFFSFSSYNC_NET_PRIO_MEDIUM);
 
 	// the size of the file is the priority (small files are sent with more priority)
 	// but don't set the priority too low, low value can be used for anything else
-	msg = (vhffsfssync_net_message_file*)vhffsfssync_net_new_message(conn, VHFFSFSSYNC_NET_MESSAGE_FILE, MAX(MIN(file->file_size, maxprio),1000) );
+	msg = (vhffsfssync_net_message_file*)vhffsfssync_net_new_message(conn, VHFFSFSSYNC_NET_MESSAGE_FILE, MAX(MIN(file->file_stat.st_size, maxprio),1000) );
 	msg->file = file;
 	msg->file_offset = 0;
 	msg->file_chunksize = -1;
@@ -454,8 +452,6 @@
 
 
 void vhffsfssync_net_destroy_file(vhffsfssync_conn *conn, vhffsfssync_net_message_file *filemsg)  {
-	struct stat st;
-	st.st_mtime=-1;
 
 	conn->messages = g_list_remove(conn->messages, (vhffsfssync_net_message*)filemsg);
 	conn->messages_num--;
@@ -470,23 +466,17 @@
 		}
 	}
 
-	// get mtime
-	if( fstat(fileno(filemsg->file->file_stream), &st) < 0 )  {
-		fprintf(stderr, "fstat() failed on %s: %s\n", filemsg->file->file_pathname, strerror(errno));
-	}
-
-	vhffsfssync_net_send_event(conn, g_strdup_printf("close%c%s%c%ld%c", '\0', filemsg->file->file_pathname, '\0', st.st_mtime, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
-	vhffsfssync_net_file_close(conn, filemsg->file);
+	vhffsfssync_net_send_event(conn, g_strdup_printf("close%c%s%c%ld%c", '\0', filemsg->file->file_pathname, '\0', filemsg->file->file_stat.st_mtime, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
+	vhffsfssync_net_file_close(filemsg->file);
 	free(filemsg);
 }
 
 
-vhffsfssync_net_file *vhffsfssync_net_file_open(vhffsfssync_conn *conn, const char *pathname, const char *mode)  {
-	FILE *stream;
+vhffsfssync_net_file *vhffsfssync_net_file_open(const char *pathname)  {
 	vhffsfssync_net_file *file;
 	struct stat st;
 
-	if(!conn || !pathname || !mode)
+	if(!pathname)
 		return NULL;
 
 	file = g_hash_table_lookup(vhffsfssync_net_files, pathname);
@@ -506,23 +496,17 @@
 		return NULL;
 	}
 
-	stream = fopen(pathname, mode);
-	if(!stream) {
-		fprintf(stderr, "fopen() failed on %s: %s\n", pathname, strerror(errno));
-		return NULL;
-	}
-
 	file = malloc(sizeof(vhffsfssync_net_file));
-	file->file_stream = stream;
+	file->file_fd = -1;
 	file->file_pathname = strdup(pathname);
-	file->file_size = st.st_size;
+	memcpy(&file->file_stat, &st, sizeof(struct stat));
 	file->ref = 1;
 	g_hash_table_insert(vhffsfssync_net_files, file->file_pathname, file);
 	return file;
 }
 
 
-int vhffsfssync_net_file_close(vhffsfssync_conn *conn, vhffsfssync_net_file *file)  {
+int vhffsfssync_net_file_close(vhffsfssync_net_file *file)  {
 	int r;
 
 	if(!file)
@@ -534,9 +518,10 @@
 
 	g_hash_table_remove(vhffsfssync_net_files, file->file_pathname);
 
-	r = fclose(file->file_stream);
-	if( r )
-		fprintf(stderr, "fclose() failed: %s\n", strerror(errno));
+	if(file->file_fd >= 0) {
+		r = close(file->file_fd);
+		if(r) fprintf(stderr, "close() failed: %s\n", strerror(errno));
+	}
 
 	free(file->file_pathname);
 	free(file);
@@ -584,16 +569,15 @@
 char *vhffsfssync_net_parent_attrib(char *pathname)  {
 	char *cur;
 	struct stat st;
-	char *ret;
-	st.st_mtime=-1;
-	st.st_mode=0;
-	st.st_uid=-1;
-	st.st_gid=-1;
+	char *ret = NULL;
 
 	for( cur = pathname+strlen(pathname) ; *cur != '/' ; cur-- );
 	*cur = '\0';
 
-	if( lstat(pathname, &st) )  {
+	if( !lstat(pathname, &st) )  {
+		ret = g_strdup_printf("attrib%c%s%c%ld%c%d%c%d%c%d%c", '\0', pathname, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+	}
+	else {
 		if(errno == ENOENT) {
 			// file already disappeared (common for temporary files)
 		} else {
@@ -601,7 +585,6 @@
 		}
 	}
 
-	ret = g_strdup_printf("attrib%c%s%c%ld%c%d%c%d%c%d%c", '\0', pathname, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
 	*cur = '/';
 	return ret;
 }
@@ -674,12 +657,22 @@
 			ssize_t lentowrite;
 
 			filemsg = (vhffsfssync_net_message_file*)msg;
+
+			// we need to open the file
+			if(filemsg->file->file_fd < 0) {
+				filemsg->file->file_fd = open(filemsg->file->file_pathname, O_RDONLY);
+				if(filemsg->file->file_fd < 0) {
+					fprintf(stderr, "open() failed on %s: %s\n", filemsg->file->file_pathname, strerror(errno));
+					vhffsfssync_net_destroy_file(conn, filemsg);
+					continue;
+				}
+			}
 #if DEBUG_NET
-			printf("    file: %s, offset = %lld, size = %lld\n", filemsg->file->file_pathname, (long long int)filemsg->file_offset, (long long int)filemsg->file->file_size);
+			printf("    file: %s, offset = %lld, size = %lld\n", filemsg->file->file_pathname, (long long int)filemsg->file_offset, (long long int)filemsg->file_stat.st_size);
 #endif
 			/* new chunk */
 			if(filemsg->file_chunksize < 0)  {
-				lentowrite = filemsg->file_chunksize = MIN(VHFFSFSSYNC_NET_MESSAGE_FILE_CHUNK, filemsg->file->file_size - filemsg->file_offset);
+				lentowrite = filemsg->file_chunksize = MIN(VHFFSFSSYNC_NET_MESSAGE_FILE_CHUNK, filemsg->file->file_stat.st_size - filemsg->file_offset);
 				filemsg->file_chunkcur = 0;
 				// we need to make sure that the chunk will not be truncated, we set the current message to the highest priority
 				msg->msg_priority = 1;
@@ -693,7 +686,7 @@
 			}
 
 			/* try to send the file */
-			written = sendfile(conn->fd, fileno(filemsg->file->file_stream), &filemsg->file_offset, lentowrite);
+			written = sendfile(conn->fd, filemsg->file->file_fd, &filemsg->file_offset, lentowrite);
 			if(written < 0) {
 				switch(errno)  {
 					case EAGAIN:
@@ -715,7 +708,7 @@
 				filemsg->file_chunkcur += written;
 
 				/* end of file or file completed */
-				if( written == 0 || filemsg->file_offset == filemsg->file->file_size )  {
+				if( written == 0 || filemsg->file_offset == filemsg->file->file_stat.st_size )  {
 					vhffsfssync_net_destroy_file(conn, filemsg);
 				}
 
@@ -726,15 +719,8 @@
 
 				/* the chunk is sent */
 				else if(written == lentowrite) {
-					uint32_t maxprio = -1;  // 4294967295
-
 					filemsg->file_chunksize = -1;
 					filemsg->file_chunkcur = 0;
-
-					// reschedule this file to a nicer priority
-					msg->msg_priority = MAX(MIN(filemsg->file->file_size - filemsg->file_offset, maxprio),1000);
-					conn->messages = g_list_remove(conn->messages, msg);
-					conn->messages = g_list_insert_sorted(conn->messages, msg, vhffsfssync_net_message_insert_compare);
 				}
 			}
 		}
@@ -1057,50 +1043,48 @@
 
 		d = opendir(pathname);
 		if(d) {
-			struct dirent *dir;
-			GString *msg;
 			struct stat st;
-			st.st_mtime=-1;
-			st.st_mode=0;
-			st.st_uid=-1;
-			st.st_gid=-1;
 
-			if(lstat(pathname, &st) )  {
-				fprintf(stderr, "cannot lstat() '%s': %s\n", pathname, strerror(errno));
-			}
+			if(!lstat(pathname, &st) )  {
+				struct dirent *dir;
+				GString *msg;
 
-			msg = g_string_sized_new(1024);
-			g_string_append_printf(msg, "ls%c%s%c%ld%c%d%c%d%c%d%c", '\0', pathname, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+				msg = g_string_sized_new(1024);
+				g_string_append_printf(msg, "ls%c%s%c%ld%c%d%c%d%c%d%c", '\0', pathname, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
 
-			while( (dir = readdir(d)) ) {
-				if( strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..") ) {
-					char *path = g_strdup_printf("%s/%s", pathname, dir->d_name);
-					struct stat st;
+				while( (dir = readdir(d)) ) {
+					if( strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..") ) {
+						char *path = g_strdup_printf("%s/%s", pathname, dir->d_name);
 
-					if(! lstat(path, &st) )  {
-						if( S_ISDIR(st.st_mode) )  {
-							// register a new directory
-							ldirs = g_list_append(ldirs, g_strdup(path));
-							g_string_append_printf(msg, "%s%cdir%c0%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+						if(! lstat(path, &st) )  {
+							if( S_ISDIR(st.st_mode) )  {
+								// register a new directory
+								ldirs = g_list_append(ldirs, g_strdup(path));
+								g_string_append_printf(msg, "%s%cdir%c0%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+							}
+							else if( S_ISREG(st.st_mode) )  {
+								g_string_append_printf(msg, "%s%cfile%c%lld%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', (long long int)st.st_size, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+							}
+							else if( S_ISLNK(st.st_mode) )  {
+								g_string_append_printf(msg, "%s%clink%c%lld%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', (long long int)st.st_size, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+							}
+							/* we don't need other file types (chr, block, fifo, socket, ...) */
 						}
-						else if( S_ISREG(st.st_mode) )  {
-							g_string_append_printf(msg, "%s%cfile%c%lld%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', (long long int)st.st_size, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
+						else {
+							fprintf(stderr, "cannot lstat() '%s': %s\n", path, strerror(errno));
 						}
-						else if( S_ISLNK(st.st_mode) )  {
-							g_string_append_printf(msg, "%s%clink%c%lld%c%ld%c%d%c%d%c%d%c", dir->d_name, '\0', '\0', (long long int)st.st_size, '\0', st.st_mtime, '\0', st.st_mode&07777, '\0', st.st_uid, '\0', st.st_gid, '\0');
-						}
-						/* we don't need other file types (chr, block, fifo, socket, ...) */
+						free(path);
 					}
-					else {
-						fprintf(stderr, "cannot lstat() '%s': %s\n", path, strerror(errno));
-					}
-					free(path);
 				}
+
+				vhffsfssync_net_send_event(conn, g_string_free(msg, FALSE) , VHFFSFSSYNC_NET_PRIO_MEDIUM);
+
+			} else {
+				fprintf(stderr, "cannot lstat() '%s': %s\n", pathname, strerror(errno));
 			}
+
 			closedir(d);
 
-			vhffsfssync_net_send_event(conn, g_string_free(msg, FALSE) , VHFFSFSSYNC_NET_PRIO_MEDIUM);
-
 			// any subdirectories ?
 			if(ldirs) {
 				// register the list to the pseudo-tree

Modified: trunk/vhffs-fssync/vhffsfssync_slave.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_slave.c	2010-11-16 22:07:35 UTC (rev 1638)
+++ trunk/vhffs-fssync/vhffsfssync_slave.c	2010-11-17 01:05:22 UTC (rev 1639)
@@ -298,16 +298,15 @@
 	}
 	if(fd >= 0) {
 		if(i == argc) {
-			if(mtime>=0) {
-				struct timeval tv[2];
-				tv[0].tv_sec = (time_t)mtime;
-				tv[0].tv_usec = 0;
-				tv[1].tv_sec = (time_t)mtime;
-				tv[1].tv_usec = 0;
-				futimes(fd, &tv[0]);
-			}
+			struct timeval tv[2];
 
-			if(vhffsfssync_preserve && uid>=0)  {
+			tv[0].tv_sec = (time_t)mtime;
+			tv[0].tv_usec = 0;
+			tv[1].tv_sec = (time_t)mtime;
+			tv[1].tv_usec = 0;
+			futimes(fd, &tv[0]);
+
+			if(vhffsfssync_preserve)  {
 				if( fchmod(fd, mode) ) {
 					fprintf(stderr, "fchmod() failed on %s: %s\n", pathname, strerror(errno));
 				}
@@ -451,7 +450,7 @@
 		int gid = atol(args[5]);
 		int fd;
 
-		if(!vhffsfssync_preserve || uid<0)
+		if(!vhffsfssync_preserve)
 			mode = 0644;
 
 		fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode);
@@ -467,7 +466,7 @@
 				fprintf(stderr, "futimes() failed on %s: %s\n", pathname, strerror(errno));
 			}
 
-			if(vhffsfssync_preserve && uid>=0)  {
+			if(vhffsfssync_preserve)  {
 				if( fchmod(fd, mode) ) {
 					fprintf(stderr, "fchmod() failed on %s: %s\n", pathname, strerror(errno));
 				}
@@ -489,7 +488,7 @@
 		int gid = atol(args[4]);
 		int fd;
 
- 		if(!vhffsfssync_preserve || uid<0)
+ 		if(!vhffsfssync_preserve)
 			mode = 0644;
 
 		if( !g_hash_table_lookup(conn->openfiles, pathname) ) {
@@ -498,7 +497,7 @@
 			if(fd >= 0) {
 				FILE *f;
 
-				if(vhffsfssync_preserve && uid>=0)  {
+				if(vhffsfssync_preserve)  {
 					if( fchmod(fd, mode) ) {
 						fprintf(stderr, "fchmod() failed on %s: %s\n", pathname, strerror(errno));
 					}
@@ -528,18 +527,18 @@
 
 		f = g_hash_table_lookup(conn->openfiles, pathname);
 		if(f) {
+			struct timeval tv[2];
+
+			// we need to flush the data before changing mtime
 			fflush(f);
 
-			if(mtime>=0) {
-				struct timeval tv[2];
-				tv[0].tv_sec = (time_t)mtime;
-				tv[0].tv_usec = 0;
-				tv[1].tv_sec = (time_t)mtime;
-				tv[1].tv_usec = 0;
+			tv[0].tv_sec = (time_t)mtime;
+			tv[0].tv_usec = 0;
+			tv[1].tv_sec = (time_t)mtime;
+			tv[1].tv_usec = 0;
 
-				if( futimes(fileno(f), tv) ) {
-					fprintf(stderr, "futimes() failed on %s: %s\n", pathname, strerror(errno));
-				}
+			if( futimes(fileno(f), tv) ) {
+				fprintf(stderr, "futimes() failed on %s: %s\n", pathname, strerror(errno));
 			}
 		}
 		g_hash_table_remove(conn->openfiles, pathname);
@@ -568,6 +567,7 @@
 			fprintf(stderr, "symlink() failed on %s -> %s: %s\n", from, to, strerror(errno));
 		} else {
 			struct timeval tv[2];
+
 			tv[0].tv_sec = (time_t)mtime;
 			tv[0].tv_usec = 0;
 			tv[1].tv_sec = (time_t)mtime;
@@ -638,18 +638,16 @@
 		int mode = atol(args[3]);
 		int uid = atol(args[4]);
 		int gid = atol(args[5]);
+		struct timeval tv[2];
 
-		if(mtime>=0) {
-			struct timeval tv[2];
-			tv[0].tv_sec = (time_t)mtime;
-			tv[0].tv_usec = 0;
-			tv[1].tv_sec = (time_t)mtime;
-			tv[1].tv_usec = 0;
+		tv[0].tv_sec = (time_t)mtime;
+		tv[0].tv_usec = 0;
+		tv[1].tv_sec = (time_t)mtime;
+		tv[1].tv_usec = 0;
 
-			lutimes(pathname, &tv[0]);
-		}
+		lutimes(pathname, &tv[0]);
 
-		if(vhffsfssync_preserve && uid>=0)  {
+		if(vhffsfssync_preserve)  {
 			struct stat st;
 
 			if(! lstat(pathname, &st) )  {


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/