aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@squashfs.org.uk>2014-04-10 02:15:45 +0100
committerPhillip Lougher <phillip@squashfs.org.uk>2014-04-10 02:15:45 +0100
commit867f8e9f8567a8671cf35b02d10d979ea11e5ed6 (patch)
tree321f18e3e8b9bcfc1237bc7f8ad8e4fe38bc5fa2
parent4220b0b4bb135603e972a3d19c3827c253566c0a (diff)
downloadsquashfs-tools-867f8e9f8567a8671cf35b02d10d979ea11e5ed6.tar.gz
mksquashfs: fix delay in restoring filesystem if stuck in filesystem scanning
If when appending, control C is hit twice, Mksquashfs should respond by restoring the filesystem and exiting. Previously I discovered Mksquashfs might hang when generating the filesystem for some time when control C was hit. This I discovered was due to the fact the Mksquashfs main thread might not hit a pthread cancellation point for sometime. I fixed this by updating the restore thread to carefully terminate the producer threads and flushing the queues that feed the Mksquashfs main thread, so that it would quickly hit the pthread_cond_wait() cancellation point on empty queues. This works well, and avoids the messy need to insert an explicit pthread_testcancel() within the filesystem generation code. However, I have discovered Mksquashfs can still hang for sometime if control C is hit when Mksquashfs is *scanning* the filesystem prior to starting filesystem generation, if the source filesystem is large. This is again because the filesystem scanning code does not execute any pthread cancellation points, and as it has not yet started filesystem generation, it does not try and read any data from producer queues. The fix here is to exploit the fact that only at filesystem generation time does the destination filesystem get written to, necessitating it to be restored on termination. Prior to this point we can safely exit Mksquashfs without restoring the filesystem (because as yet it hasn't been alterred). So move the creation of the restore thread to just before filesystem generation, with the result that prior to this point Mksquashfs will exit without trying to restore the filesystem, and we avoid trying to pthread cancel code which does not execute any pthread cancellation points. Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
-rw-r--r--squashfs-tools/mksquashfs.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index 84aa485..dd985f4 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -223,6 +223,7 @@ struct old_root_entry_info *old_root_entry;
/* restore orignal filesystem state if appending to existing filesystem is
* cancelled */
+int appending = FALSE;
char *sdata_cache, *sdirectory_data_cache, *sdirectory_compressed;
long long sbytes, stotal_bytes;
@@ -328,9 +329,11 @@ void prep_exit()
pthread_kill(*restore_thread, SIGUSR1);
pthread_exit(NULL);
}
- }
- if(delete && destination_file && !block_device)
- unlink(destination_file);
+ } else if(delete) {
+ if(destination_file && !block_device)
+ unlink(destination_file);
+ } else if(recovery_file)
+ unlink(recovery_file);
}
@@ -3151,9 +3154,25 @@ void dir_scan(squashfs_inode *inode, char *pathname,
if(sorted)
generate_file_priorities(dir_info, 0,
&dir_info->dir_ent->inode->buf);
+
+ if(appending) {
+ sigset_t sigmask;
+
+ restore_thread = init_restore_thread();
+ sigemptyset(&sigmask);
+ sigaddset(&sigmask, SIGINT);
+ sigaddset(&sigmask, SIGTERM);
+ sigaddset(&sigmask, SIGUSR1);
+ if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1)
+ BAD_ERROR("Failed to set signal mask\n");
+ write_destination(fd, SQUASHFS_START, 4, "\0\0\0\0");
+ }
+
queue_put(to_reader, dir_info);
+
if(sorted)
sort_files_and_write(dir_info);
+
set_progressbar_state(progress);
dir_scan6(inode, dir_info);
dir_ent->inode->inode = *inode;
@@ -5468,7 +5487,6 @@ printOptions:
SQUASHFS_INODE_BLK(sBlk.root_inode),
root_inode_offset =
SQUASHFS_INODE_OFFSET(sBlk.root_inode);
- sigset_t sigmask;
if((bytes = read_filesystem(root_name, fd, &sBlk, &inode_table,
&data_cache, &directory_table,
@@ -5539,14 +5557,7 @@ printOptions:
sid_count = id_count;
write_recovery_data(&sBlk);
save_xattrs();
- restore_thread = init_restore_thread();
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGINT);
- sigaddset(&sigmask, SIGTERM);
- sigaddset(&sigmask, SIGUSR1);
- if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1)
- BAD_ERROR("Failed to set signal mask\n");
- write_destination(fd, SQUASHFS_START, 4, "\0\0\0\0");
+ appending = TRUE;
/*
* set the filesystem state up to be able to append to the