If you specify the --max-delete option to rsync and there are more files to be deleted than the specified number, all the deletes upto that number are normally performed and other files that would otherwise be deleted are now silently ignored. Also, if more files are scheduled for removal, no error code is returned. The --max-delete option is especially usefull if by some misconfiguration a great number of files would be deleted. If it is a job that runs daily, all the files would be silently deleted after a few days rather than all at once more or less defeating the purpose. What I would like to see would be a test that would exit rsync with an error code if too many deletes would take without actually deleting any files. Returning an error code is the least that should be done IMHO. From the 2.6.4 changelog it would seem that the delete code has changed.I have a (barely tested) patch for 2.6.3 here: --- rsync-2.6.3.orig/receiver.c 2004-09-21 11:24:06.000000000 +0200 +++ rsync-2.6.3/receiver.c 2005-03-02 15:41:26.000000000 +0100 @@ -93,6 +93,7 @@ int i, j; char *argv[1], fbuf[MAXPATHLEN]; static int deletion_count; + int deletion_test_count; if (cvs_exclude) add_cvs_excludes(); @@ -102,6 +103,38 @@ return; } + /* if --max-delete is specified, check that not too many files will be deleted */ + if (max_delete) { + + /* count number of files that would be deleted */ + deletion_test_count=0; + + for (j = 0; j < flist->count; j++) { + if (!(flist->files[j]->flags & FLAG_TOP_DIR) + || !S_ISDIR(flist->files[j]->mode)) + continue; + + argv[0] = f_name_to(flist->files[j], fbuf); + + if (!(local_file_list = send_file_list(-1, 1, argv))) + continue; + + for (i = local_file_list->count-1; i >= 0; i--) { + if (!local_file_list->files[i]->basename) + continue; + if (flist_find(flist,local_file_list->files[i]) < 0) + deletion_test_count++; + } + flist_free(local_file_list); + } + + /* check deletion count */ + if ((deletion_count+deletion_test_count) >= max_delete) { + rprintf(FERROR,"too many files would be deleted - skipping file deletion\n"); + return; + } + } + for (j = 0; j < flist->count; j++) { if (!(flist->files[j]->flags & FLAG_TOP_DIR) || !S_ISDIR(flist->files[j]->mode))
Created attachment 1003 [details] patch to limit the number of deletes before the deletes take place Ok, uploaded the patch as a file instead of the comment of the orriginal report.
I agree that rsync should output some kind of warning and return code when it hits the --max-delete limit. Adding an extra delete-counting pass would be pretty slow for large file sets, so if that gets added it would need to be an option.
I don't know if there is an easy check to figure out how many files would be deleted (my patch is a very naive implementation). I understand that the --delete-during option would make this more difficult though. Any chance that the warning and return code will be in the next release?
I have updated the source in CVS so that it complains at the end of the run and returns a new status code (25) when the max-delete value is exceeded. It also mentions how many deletions were skipped. This will let you run rsync with --dry-run --max-delete=1 to see a count of the number of deleted files minus one. I don't have any plans to make rsync check the delete count automatically before starting the deletions.
Thanks. If it is important enough for us, I may consider writing a patch. Maybe it is a good idea to document this in the manual page. Maybe something like: --max-delete=NUM This tells rsync not to delete more than NUM files or directories. This is useful when mirroring very large trees to prevent disasters. Attempting to delete more files or directories will result in an error message and a non-zero exit code.