Line data Source code
1 : /* 2 : * Copyright (C) 2013 Andrea Mazzoleni 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 : */ 17 : 18 : #include "portable.h" 19 : 20 : #include "util.h" 21 : #include "elem.h" 22 : #include "import.h" 23 : #include "state.h" 24 : #include "parity.h" 25 : #include "handle.h" 26 : #include "raid/raid.h" 27 : 28 : /****************************************************************************/ 29 : /* rehash */ 30 : 31 1 : void state_rehash(struct snapraid_state* state) 32 : { 33 : block_off_t blockmax; 34 : block_off_t i; 35 : 36 1 : blockmax = parity_allocated_size(state); 37 : 38 : /* check if a rehash is already in progress */ 39 1 : if (state->prevhash != HASH_UNDEFINED) { 40 : /* LCOV_EXCL_START */ 41 : log_tag("summary:exit:already_in_progress\n"); 42 : log_fatal(EUSER, "You already have a rehash in progress.\n"); 43 : exit(EXIT_FAILURE); 44 : /* LCOV_EXCL_STOP */ 45 : } 46 : 47 1 : if (state->hash == state->besthash) { 48 : /* LCOV_EXCL_START */ 49 : log_tag("summary:exit:not_required\n"); 50 : log_fatal(EUSER, "You are already using the best hash for your platform.\n"); 51 : exit(EXIT_FAILURE); 52 : /* LCOV_EXCL_STOP */ 53 : } 54 : 55 : /* copy the present hash as previous one */ 56 1 : state->prevhash = state->hash; 57 1 : memcpy(state->prevhashseed, state->hashseed, HASH_MAX); 58 : 59 : /* set the new hash and seed */ 60 1 : state->hash = state->besthash; 61 1 : if (randomize(state->hashseed, HASH_MAX) != 0) { 62 : /* LCOV_EXCL_START */ 63 : log_fatal(errno, "Failed to get random values.\n"); 64 : exit(EXIT_FAILURE); 65 : /* LCOV_EXCL_STOP */ 66 : } 67 : 68 : /* mark all the block for rehashing */ 69 9276 : for (i = 0; i < blockmax; ++i) { 70 : snapraid_info info; 71 : 72 : /* if it's unused */ 73 9275 : info = info_get(&state->infoarr, i); 74 9275 : if (info == 0) { 75 : /* skip it */ 76 0 : continue; 77 : } 78 : 79 9275 : if (info_get_rehash(info)) { 80 : /* LCOV_EXCL_START */ 81 : log_fatal(EINTERNAL, "Internal inconsistency for a rehash already in progress\n"); 82 : os_abort(); 83 : /* LCOV_EXCL_STOP */ 84 : } 85 : 86 : /* enable the rehash */ 87 9275 : info = info_set_rehash(info); 88 : 89 : /* save it */ 90 9275 : info_set(&state->infoarr, i, info); 91 : } 92 : 93 : /* save the new content file */ 94 1 : state->need_write = 1; 95 : 96 1 : msg_status("A rehash is now scheduled. It will take place progressively in the next\n"); 97 1 : msg_status("'sync' and 'scrub' commands. You can check the rehash progress using the\n"); 98 1 : msg_status("'status' command.\n"); 99 1 : log_tag("summary:exit:scheduled\n"); 100 1 : } 101 :