diff options
author | Phillip Lougher <phillip@squashfs.org.uk> | 2014-04-10 02:15:45 +0100 |
---|---|---|
committer | Phillip Lougher <phillip@squashfs.org.uk> | 2014-04-10 02:15:45 +0100 |
commit | 867f8e9f8567a8671cf35b02d10d979ea11e5ed6 (patch) | |
tree | 321f18e3e8b9bcfc1237bc7f8ad8e4fe38bc5fa2 | |
parent | 4220b0b4bb135603e972a3d19c3827c253566c0a (diff) | |
download | squashfs-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.c | 35 |
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 |