diff --git a/VERSION b/VERSION index 8fe00aa..8294c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.0-github(0) (2012-03-02) \ No newline at end of file +0.1.2 \ No newline at end of file diff --git a/man8/thin_check.8 b/man8/thin_check.8 index 303ffb5..1ba99f0 100644 --- a/man8/thin_check.8 +++ b/man8/thin_check.8 @@ -1,36 +1,46 @@ .TH THIN_REPAIR 8 "Thin Provisioning Tools" "Red Hat, Inc." \" -*- nroff -*- .SH NAME -thin_repair \- repair thin provisioning metadata on device or file +thin_check \- repair thin provisioning metadata on device or file .SH SYNOPSIS -.B thin_repair {device|file} +.B thin_check +.RB [ options ] +.I {device|file} .SH DESCRIPTION -thin_repair checks thin provisioning metadata created by -the device-mapper thin provisioning target on a device or file (see +.B thin_check +checks thin provisioning metadata created by +the device-mapper thin provisioning target on a +.I device +or +.I file. +See .B thin_dump(8) -) on how to dump metadata to a file. -A future release will be able to fix faulty metadata. +how to dump metadata to a file. -.B thin_repair (device|file} +.SH OPTIONS +.IP "\fB\-h, \-\-help\fP" +Print help and exit. -.B thin_repair - {-h|--help} - -.B thin_dump - {-V|--version} +.IP "\fB\-V, \-\-version\fP" +Output version information and exit. .SH EXAMPLE -"thin_repair /dev/vg/metadata" -analyses and repairs thin provisioning metadata on logical volume -/dev/vg/metadata. The device may not be actively used by the target +Analyses and repairs thin provisioning metadata on logical volume +/dev/vg/metadata: +.sp +.B thin_repair /dev/vg/metadata + +The device may not be actively used by the target when repairing! .SH DIAGNOSTICS -thin_repair returns an exit code of 0 for success or 1 for error. +.B thin_check +returns an exit code of 0 for success or 1 for error. .SH SEE ALSO -.B thin_dump(8), thin_restore(8) +.B thin_dump(8) +.B thin_restore(8) .SH AUTHOR Joe Thornber diff --git a/man8/thin_dump.8 b/man8/thin_dump.8 index 82f2e26..697df83 100644 --- a/man8/thin_dump.8 +++ b/man8/thin_dump.8 @@ -3,44 +3,49 @@ thin_dump \- dump thin provisioning metadata from device or file to standard output .SH SYNOPSIS -.B thin_dump [options] {metadata device|file} +.B thin_dump +.RB [options] +.I {metadata device|file} .SH DESCRIPTION -thin_dump dumps thin provisioning metadata created by the device-mapper +.B thin_dump +dumps thin provisioning metadata created by the device-mapper thin provisioning target on a device or file to standard output for analysis or postprocessing in either XML or human readable format. XML formated metadata can be fed into thin_restore (see -.B thin_restore(8) -) in order to put it back onto a metadata device (to process by +.BR thin_restore(8) ) +in order to put it back onto a metadata device (to process by the device-mapper target) or file. -.B thin_dump - {-i|--input} {device|file} - [{-f|--format} {xml|human_readable}] +.IP "\fB\-f, \-\-format\fP \fI{xml|human_readable}\fP". +Print output in XML or human readable format. -.B thin_dump - {-r|--repair} +.IP "\fB\-r, \-\-repair\fP". -.B thin_dump - {-h|--help} +.IP "\fB\-h, \-\-help\fP". +Print help and exit. -.B thin_dump - {-V|--version} +.IP "\fB\-V, \-\-version\fP". +Output version information and exit. .SH EXAMPLES -"thin_dump -f human_redable -i /dev/vg/metadata" -dumps the thin provisioning metadata on logical volume /dev/vg/metadata -to standard output in human readable format. +Dumps the thin provisioning metadata on logical volume /dev/vg/metadata +to standard output in human readable format: +.sp +.B thin_dump -f human_redable /dev/vg/metadata -"thin_dump /dev/vg/metadata" -dumps the thin provisioning metadata on logical volume /dev/vg/metadata -to standard output in XML format. +Dumps the thin provisioning metadata on logical volume /dev/vg/metadata +to standard output in XML format: +.sp +.B thin_dump /dev/vg/metadata .SH DIAGNOSTICS -thin_dump returns an exit code of 0 for success or 1 for error. +.B thin_dump +returns an exit code of 0 for success or 1 for error. .SH SEE ALSO -.B thin_repair(8), thin_restore(8) +.B thin_check(8) +.B thin_restore(8) .SH AUTHOR Joe Thornber diff --git a/man8/thin_restore.8 b/man8/thin_restore.8 index c5407ca..b4a07aa 100644 --- a/man8/thin_restore.8 +++ b/man8/thin_restore.8 @@ -3,37 +3,49 @@ thin_restore \- restore thin provisioning metadata file to device or file .SH SYNOPSIS -.B thin_restore [options] file {metadata device|file} +.B thin_restore +.RB [ options ] +.RB -i +.I {device|file} +.RB -o +.I {device|file} .SH DESCRIPTION -thin_restore restores thin provisioning metadata created by the -respective device-mapper target dumped into an XML formated (see -.B thin_dump(8) -) file, which optionally can be preproccessed to another device or file. +.B thin_restore +restores thin provisioning metadata created by the +respective device-mapper target dumped into an XML formatted (see +.BR thin_dump(8) ) +file, which optionally can be preprocessed to another device or file. If restored to a metadata device, the metadata can be processed by the device-mapper target. -.B thin_restore - {-i|--input} {device|file} - {-o|--output} {device|file} +.IP "\fB\-i, \-\-input\fP \fI{device|file}\fP" +Input file or device with metadata. -.B thin_restore - -h|--help +.IP "\fB\-o, \-\-output\fP \fI{device|file}\fP" +Output file or device. -.B thin_dump - {-V|--version} +.IP "\fB\-h, \-\-help\fP" +Print help and exit. + +.IP "\fB\-V, \-\-version\fP" +Output version information and exit. .SH EXAMPLE -"thin_restore -i metadata -o /dev/vg/metadata" -restores the XML formatted thin provisioning metadata on file "metadata" +Restores the XML formatted thin provisioning metadata on file +.B metadata to logical volume /dev/vg/metadata for further processing by the -respective device-mapper target. +respective device-mapper target: +.sp +.B thin_restore -i metadata -o /dev/vg/metadata .SH DIAGNOSTICS -thin_dump returns an exit code of 0 for success or 1 for error. +.B thin_dump +returns an exit code of 0 for success or 1 for error. .SH SEE ALSO -.B thin_dump(8), thin_repair(8) +.B thin_dump(8) +.B thin_check(8) .SH AUTHOR Joe Thornber diff --git a/metadata.cc b/metadata.cc index 8de2974..a7da4b9 100644 --- a/metadata.cc +++ b/metadata.cc @@ -65,8 +65,8 @@ namespace { if (r) throw runtime_error("Couldn't stat dev path"); - if (S_ISREG(info.st_mode)) - nr_blocks = div_down(info.st_size, MD_BLOCK_SIZE); + if (S_ISREG(info.st_mode) && info.st_size) + nr_blocks = div_up(info.st_size, MD_BLOCK_SIZE); else if (S_ISBLK(info.st_mode)) { // To get the size of a block device we need to diff --git a/restore_emitter.cc b/restore_emitter.cc index 88f365c..d8dbaae 100644 --- a/restore_emitter.cc +++ b/restore_emitter.cc @@ -71,7 +71,7 @@ namespace { // Add entry to the details tree uint64_t key[1] = {dev}; - device_details details = {mapped_blocks, trans_id, creation_time, snap_time}; + device_details details = {mapped_blocks, trans_id, (uint32_t)creation_time, (uint32_t)snap_time}; md_->details_->insert(key, details); // Insert an empty mapping tree diff --git a/thin_check.cc b/thin_check.cc index 9db11bb..abf87df 100644 --- a/thin_check.cc +++ b/thin_check.cc @@ -41,19 +41,19 @@ namespace { } } catch (std::exception &e) { if (!quiet) - cerr << e.what(); + cerr << e.what() << endl; return 1; } return 0; } - void usage(string const &cmd) { - cerr << "Usage: " << cmd << " {device|file}" << endl - << "Options:" << endl - << " {-q|--quiet}" << endl - << " {-h|--help}" << endl - << " {-V|--version}" << endl; + void usage(ostream &out, string const &cmd) { + out << "Usage: " << cmd << " [options] {device|file}" << endl + << "Options:" << endl + << " {-q|--quiet}" << endl + << " {-h|--help}" << endl + << " {-V|--version}" << endl; } } @@ -72,7 +72,7 @@ int main(int argc, char **argv) while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { case 'h': - usage(basename(argv[0])); + usage(cout, basename(argv[0])); return 0; case 'q': @@ -80,13 +80,18 @@ int main(int argc, char **argv) break; case 'V': - cerr << THIN_PROVISIONING_TOOLS_VERSION << endl; + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; return 0; + + default: + usage(cerr, basename(argv[0])); + return 1; } } - if (argc == 1) { - usage(basename(argv[0])); + if (argc == optind) { + cerr << "No input file provided." << endl; + usage(cerr, basename(argv[0])); exit(1); } diff --git a/thin_dump.cc b/thin_dump.cc index 0d11915..5980e2c 100644 --- a/thin_dump.cc +++ b/thin_dump.cc @@ -30,8 +30,6 @@ using namespace persistent_data; using namespace std; using namespace thin_provisioning; -//---------------------------------------------------------------- - namespace { int dump(string const &path, string const &format, bool repair) { try { @@ -49,21 +47,20 @@ namespace { metadata_dump(md, e, repair); } catch (std::exception &e) { - cerr << e.what(); + cerr << e.what() << endl; return 1; } return 0; } - void usage(string const &cmd) { - cerr << "Usage: " << cmd << " [options] {device|file}" << endl << endl - << "Options:" << endl - << " {-h|--help}" << endl - << " {-f|--format} {xml|human_readable}" << endl - << " {-i|--input} {xml|human_readable} input_file" << endl - << " {-r|--repair}" << endl - << " {-V|--version}" << endl; + void usage(ostream &out, string const &cmd) { + out << "Usage: " << cmd << " [options] {device|file}" << endl + << "Options:" << endl + << " {-h|--help}" << endl + << " {-f|--format} {xml|human_readable}" << endl + << " {-r|--repair}" << endl + << " {-V|--version}" << endl; } } @@ -71,12 +68,11 @@ int main(int argc, char **argv) { int c; bool repair = false; - const char shortopts[] = "hf:i:rV"; - string filename, format = "xml"; + const char shortopts[] = "hf:rV"; + string format = "xml"; const struct option longopts[] = { { "help", no_argument, NULL, 'h'}, { "format", required_argument, NULL, 'f' }, - { "input", required_argument, NULL, 'i'}, { "repair", no_argument, NULL, 'r'}, { "version", no_argument, NULL, 'V'}, { NULL, no_argument, NULL, 0 } @@ -85,38 +81,32 @@ int main(int argc, char **argv) while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { case 'h': - usage(basename(argv[0])); + usage(cout, basename(argv[0])); return 0; case 'f': format = optarg; break; - case 'i': - filename = optarg; - break; - case 'r': repair = true; break; case 'V': - cerr << THIN_PROVISIONING_TOOLS_VERSION << endl; + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; return 0; + + default: + usage(cerr, basename(argv[0])); + return 1; } } - if (argc == 1) { - usage(basename(argv[0])); + if (argc == optind) { + cerr << "No input file provided." << endl; + usage(cerr, basename(argv[0])); return 1; } - if (filename.empty()) { - cerr << "No output file provided." << endl; - return 1; - } - - return dump(filename, format, repair); + return dump(argv[optind], format, repair); } - -//---------------------------------------------------------------- diff --git a/thin_repair.cc b/thin_repair.cc deleted file mode 100644 index 43c62e4..0000000 --- a/thin_repair.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2011 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#include -#include -#include - -#include "metadata.h" -#include "metadata_checker.h" -#include "version.h" - -using namespace persistent_data; -using namespace std; -using namespace thin_provisioning; - -namespace { - int check(string const &path) { - metadata::ptr md(new metadata(path, metadata::OPEN)); - - optional maybe_errors = metadata_check(md); - if (maybe_errors) { - cerr << error_selector(*maybe_errors, 3); - return 1; - } - - return 0; - } - - void usage(string const &cmd) { - cerr << "Usage: " << cmd << " {device|file}" << endl; - cerr << "Options:" << endl; - cerr << " {-h|--help}" << endl; - cerr << " {-V|--version}" << endl; - } -} - -int main(int argc, char **argv) -{ - int c; - const char shortopts[] = "hV"; - const struct option longopts[] = { - { "help", no_argument, NULL, 'h'}, - { "version", no_argument, NULL, 'V'}, - { NULL, no_argument, NULL, 0 } - }; - - while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { - switch(c) { - case 'h': - usage(basename(argv[0])); - return 0; - case 'V': - cerr << THIN_PROVISIONING_TOOLS_VERSION << endl; - return 0; - } - } - - if (argc != 2) { - usage(basename(argv[0])); - exit(1); - } - - return check(argv[optind]); -} diff --git a/thin_restore.cc b/thin_restore.cc index 4ec2409..a3ff53f 100644 --- a/thin_restore.cc +++ b/thin_restore.cc @@ -37,31 +37,30 @@ using namespace persistent_data; using namespace std; using namespace thin_provisioning; -//---------------------------------------------------------------- - namespace { int restore(string const &backup_file, string const &dev) { try { + // The block size gets updated by the restorer. metadata::ptr md(new metadata(dev, metadata::CREATE, 128, 0)); emitter::ptr restorer = create_restore_emitter(md); ifstream in(backup_file.c_str(), ifstream::in); parse_xml(in, restorer); } catch (std::exception &e) { - cerr << e.what(); + cerr << e.what() << endl; return 1; } return 0; } - void usage(string const &cmd) { - cerr << "Usage: " << cmd << " [options]" << endl << endl; - cerr << "Options:" << endl; - cerr << " {-h|--help}" << endl; - cerr << " {-i|--input} input_file" << endl; - cerr << " {-o [ --output} {device|file}" << endl; - cerr << " {-V|--version}" << endl; + void usage(ostream &out, string const &cmd) { + out << "Usage: " << cmd << " [options]" << endl + << "Options:" << endl + << " {-h|--help}" << endl + << " {-i|--input} input_file" << endl + << " {-o|--output} {device|file}" << endl + << " {-V|--version}" << endl; } } @@ -81,37 +80,43 @@ int main(int argc, char **argv) while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { case 'h': - usage(basename(argv[0])); + usage(cout, basename(argv[0])); return 0; + case 'i': input = optarg; break; + case 'o': output = optarg; break; + case 'V': - cerr << THIN_PROVISIONING_TOOLS_VERSION << endl; + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; return 0; + + default: + usage(cerr, basename(argv[0])); + return 1; } } - if (argc == 1) { - usage(basename(argv[0])); + if (argc != optind) { + usage(cerr, basename(argv[0])); return 1; } if (input.empty()) { cerr << "No input file provided." << endl; + usage(cerr, basename(argv[0])); return 1; } if (output.empty()) { cerr << "No output file provided." << endl; + usage(cerr, basename(argv[0])); return 1; } return restore(input, output); - } - -//----------------------------------------------------------------