1 /* 2 * Create a squashfs filesystem. This is a highly compressed read only 3 * filesystem. 4 * 5 * Copyright (c) 2013, 2014 6 * Phillip Lougher <phillip (at) squashfs.org.uk> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2, 11 * or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 * info.c 23 */ 24 25 #include <pthread.h> 26 #include <sys/ioctl.h> 27 #include <unistd.h> 28 #include <signal.h> 29 #include <sys/time.h> 30 #include <stdio.h> 31 #include <math.h> 32 #include <stdarg.h> 33 #include <errno.h> 34 #include <stdlib.h> 35 #include <dirent.h> 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <string.h> 39 40 #include "squashfs_fs.h" 41 #include "mksquashfs.h" 42 #include "error.h" 43 #include "progressbar.h" 44 #include "caches-queues-lists.h" 45 46 static int silent = 0; 47 static struct dir_ent *ent = NULL; 48 49 pthread_t info_thread; 50 51 52 void disable_info() 53 { 54 ent = NULL; 55 } 56 57 58 void update_info(struct dir_ent *dir_ent) 59 { 60 ent = dir_ent; 61 } 62 63 64 void print_filename() 65 { 66 struct dir_ent *dir_ent = ent; 67 68 if(dir_ent == NULL) 69 return; 70 71 if(dir_ent->our_dir->subpath[0] != '\0') 72 INFO("%s/%s\n", dir_ent->our_dir->subpath, dir_ent->name); 73 else 74 INFO("/%s\n", dir_ent->name); 75 } 76 77 78 void dump_state() 79 { 80 disable_progress_bar(); 81 82 printf("Queue and Cache status dump\n"); 83 printf("===========================\n"); 84 85 printf("file buffer queue (reader thread -> deflate thread(s))\n"); 86 dump_queue(to_deflate); 87 88 printf("uncompressed fragment queue (reader thread -> fragment" 89 " thread(s))\n"); 90 dump_queue(to_process_frag); 91 92 printf("processed fragment queue (fragment thread(s) -> main" 93 " thread)\n"); 94 dump_seq_queue(to_main, 1); 95 96 printf("compressed block queue (deflate thread(s) -> main thread)\n"); 97 dump_seq_queue(to_main, 0); 98 99 printf("uncompressed packed fragment queue (main thread -> fragment" 100 " deflate thread(s))\n"); 101 dump_queue(to_frag); 102 103 104 printf("locked frag queue (compressed frags waiting while multi-block" 105 " file is written)\n"); 106 dump_queue(locked_fragment); 107 108 printf("compressed block queue (main & fragment deflate threads(s) ->" 109 " writer thread)\n"); 110 dump_queue(to_writer); 111 112 printf("read cache (uncompressed blocks read by reader thread)\n"); 113 dump_cache(reader_buffer); 114 115 printf("block write cache (compressed blocks waiting for the writer" 116 " thread)\n"); 117 dump_cache(bwriter_buffer); 118 printf("fragment write cache (compressed fragments waiting for the" 119 " writer thread)\n"); 120 dump_cache(fwriter_buffer); 121 122 printf("fragment cache (frags waiting to be compressed by fragment" 123 " deflate thread(s))\n"); 124 dump_cache(fragment_buffer); 125 126 printf("fragment reserve cache (avoids pipeline stall if frag cache" 127 " full in dup check)\n"); 128 dump_cache(reserve_cache); 129 130 enable_progress_bar(); 131 } 132 133 134 void *info_thrd(void *arg) 135 { 136 sigset_t sigmask; 137 int sig, err, waiting = 0; 138 139 sigemptyset(&sigmask); 140 sigaddset(&sigmask, SIGQUIT); 141 sigaddset(&sigmask, SIGHUP); 142 sigaddset(&sigmask, SIGALRM); 143 144 while(1) { 145 err = sigwait(&sigmask, &sig); 146 147 if(err == -1) { 148 switch(errno) { 149 case EINTR: 150 continue; 151 default: 152 BAD_ERROR("sigwait failed " 153 "because %s\n", strerror(errno)); 154 } 155 } 156 157 if(sig == SIGQUIT && !waiting) { 158 print_filename(); 159 160 /* set one second interval period, if ^\ received 161 within then, dump queue and cache status */ 162 waiting = 1; 163 alarm(1); 164 } else if (sig == SIGQUIT) { 165 dump_state(); 166 } else if (sig == SIGALRM) { 167 waiting = 0; 168 } 169 } 170 } 171 172 173 void init_info() 174 { 175 pthread_create(&info_thread, NULL, info_thrd, NULL); 176 } 177