Remove support for the append mode. --- squashfs-tools/Makefile +++ squashfs-tools/Makefile @@ -111,7 +111,7 @@ INSTALL_DIR = /usr/local/bin MKSQUASHFS_OBJS = mksquashfs.o read_fs.o action.o swap.o pseudo.o compressor.o \ - sort.o progressbar.o read_file.o info.o restore.o process_fragments.o \ + sort.o progressbar.o read_file.o info.o process_fragments.o \ caches-queues-lists.o UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \ @@ -239,7 +239,7 @@ mksquashfs.o: Makefile mksquashfs.c squashfs_fs.h squashfs_swap.h mksquashfs.h \ sort.h pseudo.h compressor.h xattr.h action.h error.h progressbar.h \ - info.h caches-queues-lists.h read_fs.h restore.h process_fragments.h + info.h caches-queues-lists.h read_fs.h process_fragments.h read_fs.o: read_fs.c squashfs_fs.h squashfs_swap.h compressor.h xattr.h \ error.h mksquashfs.h --- squashfs-tools/mksquashfs.c +++ squashfs-tools/mksquashfs.c @@ -72,10 +72,8 @@ #include "info.h" #include "caches-queues-lists.h" #include "read_fs.h" -#include "restore.h" #include "process_fragments.h" -int delete = FALSE; int fd; struct squashfs_super_block sBlk; @@ -218,23 +216,10 @@ }; 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; - -unsigned int sinode_bytes, scache_bytes, sdirectory_bytes, - sdirectory_cache_bytes, sdirectory_compressed_bytes, - stotal_inode_bytes, stotal_directory_bytes, - sinode_count = 0, sfile_count, ssym_count, sdev_count, - sdir_count, sfifo_count, ssock_count, sdup_files; -int sfragments; int threads; /* flag whether destination file is a block device */ -int block_device = FALSE; +int block_device = FALSE; /* UNUSED after removing APPEND-MODE => introduces dead-code-branches */ /* flag indicating whether files are sorted using sort list(s) */ int sorted = FALSE; @@ -242,10 +227,6 @@ /* save destination file name for deleting on error */ char *destination_file = NULL; -/* recovery file for abnormal exit on appending */ -char *recovery_file = NULL; -int recover = TRUE; - struct id *id_hash_table[ID_ENTRIES]; struct id *id_table[SQUASHFS_IDS], *sid_table[SQUASHFS_IDS]; unsigned int uid_count = 0, guid_count = 0; @@ -258,7 +239,6 @@ struct seq_queue *to_main; pthread_t reader_thread, writer_thread, main_thread; pthread_t *deflator_thread, *frag_deflator_thread, *frag_thread; -pthread_t *restore_thread = NULL; pthread_mutex_t fragment_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t pos_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t dup_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -275,8 +255,6 @@ /* xattr stats */ unsigned int xattr_bytes = 0, total_xattr_bytes = 0; -/* fragment to file mapping used when appending */ -int append_fragments = 0; struct append_file **file_mapping; static char *read_from_disk(long long start, unsigned int avail_bytes); @@ -298,7 +276,6 @@ unsigned short checksum, unsigned short fragment_checksum, int checksum_flag, int checksum_frag_flag); long long generic_write_table(int, void *, int, void *, int); -void restorefs(); struct dir_info *scan1_opendir(char *pathname, char *subpath, int depth); void write_filesystem_tables(struct squashfs_super_block *sBlk, int nopad); unsigned short get_checksum_mem(char *buff, int bytes); @@ -307,26 +284,8 @@ void prep_exit() { - if(restore_thread) { - if(pthread_self() == *restore_thread) { - /* - * Recursive failure when trying to restore filesystem! - * Nothing to do except to exit, otherwise we'll just - * appear to hang. The user should be able to restore - * from the recovery file (which is why it was added, in - * case of catastrophic failure in Mksquashfs) - */ - exit(1); - } else { - /* signal the restore thread to restore */ - pthread_kill(*restore_thread, SIGUSR1); - pthread_exit(NULL); - } - } else if(delete) { - if(destination_file && !block_device) - unlink(destination_file); - } else if(recovery_file) - unlink(recovery_file); + if(destination_file && !block_device) + unlink(destination_file); } @@ -358,39 +317,6 @@ + (((char *)A) - data_cache))) -void restorefs() -{ - ERROR("Exiting - restoring original filesystem!\n\n"); - - bytes = sbytes; - memcpy(data_cache, sdata_cache, cache_bytes = scache_bytes); - memcpy(directory_data_cache, sdirectory_data_cache, - sdirectory_cache_bytes); - directory_cache_bytes = sdirectory_cache_bytes; - inode_bytes = sinode_bytes; - directory_bytes = sdirectory_bytes; - memcpy(directory_table + directory_bytes, sdirectory_compressed, - sdirectory_compressed_bytes); - directory_bytes += sdirectory_compressed_bytes; - total_bytes = stotal_bytes; - total_inode_bytes = stotal_inode_bytes; - total_directory_bytes = stotal_directory_bytes; - inode_count = sinode_count; - file_count = sfile_count; - sym_count = ssym_count; - dev_count = sdev_count; - dir_count = sdir_count; - fifo_count = sfifo_count; - sock_count = ssock_count; - dup_files = sdup_files; - fragments = sfragments; - id_count = sid_count; - restore_xattrs(); - write_filesystem_tables(&sBlk, nopad); - exit(1); -} - - void sighandler() { EXIT_MKSQUASHFS(); @@ -3159,19 +3085,6 @@ 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) @@ -4181,7 +4094,7 @@ int i, inode_number, lookup_bytes = SQUASHFS_LOOKUP_BYTES(inode_count); void *it; - if(inode_count == sinode_count) + if(inode_count == 0) goto skip_inode_hash_table; it = realloc(inode_lookup_table, lookup_bytes); @@ -4506,143 +4419,6 @@ } -#define RECOVER_ID "Squashfs recovery file v1.0\n" -#define RECOVER_ID_SIZE 28 - -void write_recovery_data(struct squashfs_super_block *sBlk) -{ - int res, recoverfd, bytes = sBlk->bytes_used - sBlk->inode_table_start; - pid_t pid = getpid(); - char *metadata; - char header[] = RECOVER_ID; - - if(recover == FALSE) { - printf("No recovery data option specified.\n"); - printf("Skipping saving recovery file.\n\n"); - return; - } - - metadata = malloc(bytes); - if(metadata == NULL) - MEM_ERROR(); - - res = read_fs_bytes(fd, sBlk->inode_table_start, bytes, metadata); - if(res == 0) { - ERROR("Failed to read append filesystem metadata\n"); - BAD_ERROR("Filesystem corrupted?\n"); - } - - res = asprintf(&recovery_file, "squashfs_recovery_%s_%d", - getbase(destination_file), pid); - if(res == -1) - MEM_ERROR(); - - recoverfd = open(recovery_file, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); - if(recoverfd == -1) - BAD_ERROR("Failed to create recovery file, because %s. " - "Aborting\n", strerror(errno)); - - if(write_bytes(recoverfd, header, RECOVER_ID_SIZE) == -1) - BAD_ERROR("Failed to write recovery file, because %s\n", - strerror(errno)); - - if(write_bytes(recoverfd, sBlk, sizeof(struct squashfs_super_block)) == -1) - BAD_ERROR("Failed to write recovery file, because %s\n", - strerror(errno)); - - if(write_bytes(recoverfd, metadata, bytes) == -1) - BAD_ERROR("Failed to write recovery file, because %s\n", - strerror(errno)); - - close(recoverfd); - free(metadata); - - printf("Recovery file \"%s\" written\n", recovery_file); - printf("If Mksquashfs aborts abnormally (i.e. power failure), run\n"); - printf("mksquashfs dummy %s -recover %s\n", destination_file, - recovery_file); - printf("to restore filesystem\n\n"); -} - - -void read_recovery_data(char *recovery_file, char *destination_file) -{ - int fd, recoverfd, bytes; - struct squashfs_super_block orig_sBlk, sBlk; - char *metadata; - int res; - struct stat buf; - char header[] = RECOVER_ID; - char header2[RECOVER_ID_SIZE]; - - recoverfd = open(recovery_file, O_RDONLY); - if(recoverfd == -1) - BAD_ERROR("Failed to open recovery file because %s\n", - strerror(errno)); - - if(stat(destination_file, &buf) == -1) - BAD_ERROR("Failed to stat destination file, because %s\n", - strerror(errno)); - - fd = open(destination_file, O_RDWR); - if(fd == -1) - BAD_ERROR("Failed to open destination file because %s\n", - strerror(errno)); - - res = read_bytes(recoverfd, header2, RECOVER_ID_SIZE); - if(res == -1) - BAD_ERROR("Failed to read recovery file, because %s\n", - strerror(errno)); - if(res < RECOVER_ID_SIZE) - BAD_ERROR("Recovery file appears to be truncated\n"); - if(strncmp(header, header2, RECOVER_ID_SIZE) !=0 ) - BAD_ERROR("Not a recovery file\n"); - - res = read_bytes(recoverfd, &sBlk, sizeof(struct squashfs_super_block)); - if(res == -1) - BAD_ERROR("Failed to read recovery file, because %s\n", - strerror(errno)); - if(res < sizeof(struct squashfs_super_block)) - BAD_ERROR("Recovery file appears to be truncated\n"); - - res = read_fs_bytes(fd, 0, sizeof(struct squashfs_super_block), &orig_sBlk); - if(res == 0) { - ERROR("Failed to read superblock from output filesystem\n"); - BAD_ERROR("Output filesystem is empty!\n"); - } - - if(memcmp(((char *) &sBlk) + 4, ((char *) &orig_sBlk) + 4, - sizeof(struct squashfs_super_block) - 4) != 0) - BAD_ERROR("Recovery file and destination file do not seem to " - "match\n"); - - bytes = sBlk.bytes_used - sBlk.inode_table_start; - - metadata = malloc(bytes); - if(metadata == NULL) - MEM_ERROR(); - - res = read_bytes(recoverfd, metadata, bytes); - if(res == -1) - BAD_ERROR("Failed to read recovery file, because %s\n", - strerror(errno)); - if(res < bytes) - BAD_ERROR("Recovery file appears to be truncated\n"); - - write_destination(fd, 0, sizeof(struct squashfs_super_block), &sBlk); - - write_destination(fd, sBlk.inode_table_start, bytes, metadata); - - close(recoverfd); - close(fd); - - printf("Successfully wrote recovery file \"%s\". Exiting\n", - recovery_file); - - exit(0); -} - - void write_filesystem_tables(struct squashfs_super_block *sBlk, int nopad) { int i; @@ -4679,9 +4455,6 @@ close(fd); - if(recovery_file) - unlink(recovery_file); - total_bytes += total_inode_bytes + total_directory_bytes + sizeof(struct squashfs_super_block) + total_xattr_bytes; @@ -4931,7 +4704,7 @@ { struct stat buf, source_buf; int res, i; - char *b, *root_name = NULL; + char *b; int keep_as_directory = FALSE; squashfs_inode inode; int readq; @@ -4990,7 +4763,7 @@ } else if(strcmp(argv[i], "-e") == 0) break; - else if(strcmp(argv[i], "-root-becomes") == 0 || + else if( strcmp(argv[i], "-ef") == 0 || strcmp(argv[i], "-pf") == 0 || strcmp(argv[i], "-af") == 0 || @@ -5073,15 +4846,7 @@ } if(read_pseudo_def(argv[i]) == FALSE) exit(1); - } else if(strcmp(argv[i], "-recover") == 0) { - if(++i == argc) { - ERROR("%s: -recover missing recovery file\n", - argv[0]); - exit(1); - } - read_recovery_data(argv[i], argv[source + 1]); - } else if(strcmp(argv[i], "-no-recovery") == 0) - recover = FALSE; + } else if(strcmp(argv[i], "-wildcards") == 0) { old_exclude = FALSE; use_regex = FALSE; @@ -5266,23 +5031,13 @@ else if(strcmp(argv[i], "-e") == 0) break; - else if(strcmp(argv[i], "-noappend") == 0) - delete = TRUE; - else if(strcmp(argv[i], "-keep-as-directory") == 0) keep_as_directory = TRUE; else if(strcmp(argv[i], "-exit-on-error") == 0) exit_on_error = TRUE; - else if(strcmp(argv[i], "-root-becomes") == 0) { - if(++i == argc) { - ERROR("%s: -root-becomes: missing name\n", - argv[0]); - exit(1); - } - root_name = argv[i]; - } else if(strcmp(argv[i], "-version") == 0) { + else if(strcmp(argv[i], "-version") == 0) { VERSION(); } else { ERROR("%s: invalid option\n\n", argv[0]); @@ -5336,25 +5091,11 @@ "dirs/files\n"); ERROR("-regex\t\t\tAllow POSIX regular expressions to " "be used in exclude\n\t\t\tdirs/files\n"); - ERROR("\nFilesystem append options:\n"); - ERROR("-noappend\t\tdo not append to existing " - "filesystem\n"); - ERROR("-root-becomes \twhen appending source " - "files/directories, make the\n"); - ERROR("\t\t\toriginal root become a subdirectory in " - "the new root\n"); - ERROR("\t\t\tcalled , rather than adding the new " - "source items\n"); - ERROR("\t\t\tto the original root\n"); ERROR("\nMksquashfs runtime options:\n"); ERROR("-version\t\tprint version, licence and " "copyright message\n"); ERROR("-exit-on-error\t\ttreat normally ignored errors " "as fatal\n"); - ERROR("-recover \t\trecover filesystem data " - "using recovery file \n"); - ERROR("-no-recovery\t\tdon't generate a recovery " - "file\n"); ERROR("-info\t\t\tprint files written to filesystem\n"); ERROR("-no-progress\t\tdon't display the progress " "bar\n"); @@ -5428,35 +5169,14 @@ perror("Could not create destination file"); exit(1); } - delete = TRUE; } else { perror("Could not stat destination file"); exit(1); } } else { - if(S_ISBLK(buf.st_mode)) { - if((fd = open(argv[source + 1], O_RDWR)) == -1) { - perror("Could not open block device as " - "destination"); - exit(1); - } - block_device = 1; - - } else if(S_ISREG(buf.st_mode)) { - fd = open(argv[source + 1], (delete ? O_TRUNC : 0) | - O_RDWR); - if(fd == -1) { - perror("Could not open regular file for " - "writing as destination"); - exit(1); - } - } - else { - ERROR("Destination not block device or regular file\n"); - exit(1); - } - + ERROR("Destination file already exists. Appending is not supported by this version of mksquashfs.\n"); + exit(1); } /* @@ -5472,7 +5192,7 @@ process_exclude_file(argv[++i]); else if(strcmp(argv[i], "-e") == 0) break; - else if(strcmp(argv[i], "-root-becomes") == 0 || + else if( strcmp(argv[i], "-sort") == 0 || strcmp(argv[i], "-pf") == 0 || strcmp(argv[i], "-af") == 0 || @@ -5501,44 +5221,21 @@ sorted ++; } else if(strcmp(argv[i], "-e") == 0) break; - else if(strcmp(argv[i], "-root-becomes") == 0 || + else if( strcmp(argv[i], "-ef") == 0 || strcmp(argv[i], "-pf") == 0 || strcmp(argv[i], "-af") == 0 || strcmp(argv[i], "-comp") == 0) i++; - if(!delete) { - comp = read_super(fd, &sBlk, argv[source + 1]); - if(comp == NULL) { - ERROR("Failed to read existing filesystem - will not " - "overwrite - ABORTING!\n"); - ERROR("To force Mksquashfs to write to this block " - "device or file use -noappend\n"); - EXIT_MKSQUASHFS(); - } - - block_log = slog(block_size = sBlk.block_size); - noI = SQUASHFS_UNCOMPRESSED_INODES(sBlk.flags); - noD = SQUASHFS_UNCOMPRESSED_DATA(sBlk.flags); - noF = SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk.flags); - noX = SQUASHFS_UNCOMPRESSED_XATTRS(sBlk.flags); - no_fragments = SQUASHFS_NO_FRAGMENTS(sBlk.flags); - always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); - duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); - exportable = SQUASHFS_EXPORTABLE(sBlk.flags); - no_xattrs = SQUASHFS_NO_XATTRS(sBlk.flags); - comp_opts = SQUASHFS_COMP_OPTS(sBlk.flags); - } - - initialise_threads(readq, fragq, bwriteq, fwriteq, delete, + initialise_threads(readq, fragq, bwriteq, fwriteq, TRUE /*delete*/, destination_file); res = compressor_init(comp, &stream, SQUASHFS_METADATA_SIZE, 0); if(res) BAD_ERROR("compressor_init failed\n"); - if(delete) { + { int size; void *comp_data = compressor_dump_options(comp, block_size, &size); @@ -5564,135 +5261,6 @@ comp_opts = TRUE; } else bytes = sizeof(struct squashfs_super_block); - } else { - unsigned int last_directory_block, inode_dir_offset, - inode_dir_file_size, root_inode_size, - inode_dir_start_block, uncompressed_data, - compressed_data, inode_dir_inode_number, - inode_dir_parent_inode; - unsigned int root_inode_start = - SQUASHFS_INODE_BLK(sBlk.root_inode), - root_inode_offset = - SQUASHFS_INODE_OFFSET(sBlk.root_inode); - - if((bytes = read_filesystem(root_name, fd, &sBlk, &inode_table, - &data_cache, &directory_table, - &directory_data_cache, &last_directory_block, - &inode_dir_offset, &inode_dir_file_size, - &root_inode_size, &inode_dir_start_block, - &file_count, &sym_count, &dev_count, &dir_count, - &fifo_count, &sock_count, &total_bytes, - &total_inode_bytes, &total_directory_bytes, - &inode_dir_inode_number, - &inode_dir_parent_inode, add_old_root_entry, - &fragment_table, &inode_lookup_table)) == 0) { - ERROR("Failed to read existing filesystem - will not " - "overwrite - ABORTING!\n"); - ERROR("To force Mksquashfs to write to this block " - "device or file use -noappend\n"); - EXIT_MKSQUASHFS(); - } - if((append_fragments = fragments = sBlk.fragments)) { - fragment_table = realloc((char *) fragment_table, - ((fragments + FRAG_SIZE - 1) & ~(FRAG_SIZE - 1)) - * sizeof(struct squashfs_fragment_entry)); - if(fragment_table == NULL) - BAD_ERROR("Out of memory in save filesystem state\n"); - } - - printf("Appending to existing %d.%d filesystem on %s, block " - "size %d\n", SQUASHFS_MAJOR, SQUASHFS_MINOR, argv[source + 1], - block_size); - printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, " - "-always-use-fragments,\n-exportable and -comp options " - "ignored\n"); - printf("\nIf appending is not wanted, please re-run with " - "-noappend specified!\n\n"); - - compressed_data = (inode_dir_offset + inode_dir_file_size) & - ~(SQUASHFS_METADATA_SIZE - 1); - uncompressed_data = (inode_dir_offset + inode_dir_file_size) & - (SQUASHFS_METADATA_SIZE - 1); - - /* save original filesystem state for restoring ... */ - sfragments = fragments; - sbytes = bytes; - sinode_count = sBlk.inodes; - scache_bytes = root_inode_offset + root_inode_size; - sdirectory_cache_bytes = uncompressed_data; - sdata_cache = malloc(scache_bytes); - if(sdata_cache == NULL) - BAD_ERROR("Out of memory in save filesystem state\n"); - sdirectory_data_cache = malloc(sdirectory_cache_bytes); - if(sdirectory_data_cache == NULL) - BAD_ERROR("Out of memory in save filesystem state\n"); - memcpy(sdata_cache, data_cache, scache_bytes); - memcpy(sdirectory_data_cache, directory_data_cache + - compressed_data, sdirectory_cache_bytes); - sinode_bytes = root_inode_start; - stotal_bytes = total_bytes; - stotal_inode_bytes = total_inode_bytes; - stotal_directory_bytes = total_directory_bytes + - compressed_data; - sfile_count = file_count; - ssym_count = sym_count; - sdev_count = dev_count; - sdir_count = dir_count + 1; - sfifo_count = fifo_count; - ssock_count = sock_count; - sdup_files = dup_files; - sid_count = id_count; - write_recovery_data(&sBlk); - save_xattrs(); - appending = TRUE; - - /* - * set the filesystem state up to be able to append to the - * original filesystem. The filesystem state differs depending - * on whether we're appending to the original root directory, or - * if the original root directory becomes a sub-directory - * (root-becomes specified on command line, here root_name != - * NULL) - */ - inode_bytes = inode_size = root_inode_start; - directory_size = last_directory_block; - cache_size = root_inode_offset + root_inode_size; - directory_cache_size = inode_dir_offset + inode_dir_file_size; - if(root_name) { - sdirectory_bytes = last_directory_block; - sdirectory_compressed_bytes = 0; - root_inode_number = inode_dir_parent_inode; - inode_no = sBlk.inodes + 2; - directory_bytes = last_directory_block; - directory_cache_bytes = uncompressed_data; - memmove(directory_data_cache, directory_data_cache + - compressed_data, uncompressed_data); - cache_bytes = root_inode_offset + root_inode_size; - add_old_root_entry(root_name, sBlk.root_inode, - inode_dir_inode_number, SQUASHFS_DIR_TYPE); - total_directory_bytes += compressed_data; - dir_count ++; - } else { - sdirectory_compressed_bytes = last_directory_block - - inode_dir_start_block; - sdirectory_compressed = - malloc(sdirectory_compressed_bytes); - if(sdirectory_compressed == NULL) - BAD_ERROR("Out of memory in save filesystem " - "state\n"); - memcpy(sdirectory_compressed, directory_table + - inode_dir_start_block, - sdirectory_compressed_bytes); - sdirectory_bytes = inode_dir_start_block; - root_inode_number = inode_dir_inode_number; - inode_no = sBlk.inodes + 1; - directory_bytes = inode_dir_start_block; - directory_cache_bytes = inode_dir_offset; - cache_bytes = root_inode_offset; - } - - inode_count = file_count + dir_count + sym_count + dev_count + - fifo_count + sock_count; } if(path) @@ -5701,12 +5269,9 @@ dump_actions(); dump_pseudos(); - if(delete && !keep_as_directory && source == 1 && + if(!keep_as_directory && source == 1 && S_ISDIR(source_buf.st_mode)) dir_scan(&inode, source_path[0], scan1_readdir, progress); - else if(!keep_as_directory && source == 1 && - S_ISDIR(source_buf.st_mode)) - dir_scan(&inode, source_path[0], scan1_single_readdir, progress); else dir_scan(&inode, "", scan1_encomp_readdir, progress); sBlk.root_inode = inode;