{"id":527,"date":"2011-07-28T16:06:55","date_gmt":"2011-07-28T23:06:55","guid":{"rendered":"http:\/\/www.smallersystems.com\/blog\/?p=527"},"modified":"2011-07-28T16:06:55","modified_gmt":"2011-07-28T23:06:55","slug":"filesystem-recovery-examples-with-ltfsck","status":"publish","type":"post","link":"https:\/\/michaelrichmond.net\/blog\/2011\/07\/28\/filesystem-recovery-examples-with-ltfsck\/","title":{"rendered":"Filesystem recovery examples with <code style=\"font-family: monospace; font-size: larger; font-weight: lighter;\">ltfsck<\/code>"},"content":{"rendered":"<p>In addition to the filesystem implementation, the <a href=\"http:\/\/en.wikipedia.org\/wiki\/LTFS\" title=\"Linear Tape File System\">Linear Tape File System (LTFS) software<\/a> ships with two core utilities, \u201c<code style=\"font-family: monospace;\">mkltfs<\/code>\u201d and \u201c<code style=\"font-family: monospace;\">ltfsck<\/code>\u201d. <code style=\"font-family: monospace;\">mkltfs<\/code> (pronounced &#8220;make LTFS&#8221;) is used to format <a href=\"http:\/\/www.trustlto.com\/\" title=\"Linear Tape Open\">LTO<\/a> cartridges with the LTFS Format. <code style=\"font-family: monospace;\">ltfsck<\/code> is used to check and if necessary recover a partially corrupted LTFS Volume back to a consistent and usable state.<\/p>\n<p>In this post I describe some inconsistent states a volume may wind up in, the scenarios that may lead to these states (often power-loss), and how <code style=\"font-family: monospace;\">ltfsck<\/code> recovers to a consistent state. <!--more--><\/p>\n<p>I&#8217;ve described the layout of a consistent LTFS Volume <a href=\"http:\/\/www.smallersystems.com\/blog\/2011\/06\/how-does-ltfs-work\/\" title=\"How does LTFS work?\">here<\/a> and <a href=\"http:\/\/www.smallersystems.com\/blog\/2011\/07\/ltfs-consistency-and-index-snapshots\/\" title=\"LTFS consistency and Index Snapshots\">here<\/a>. A consistent LTFS Volume is illustrated below. An LTFS Volume must be consistent at mount time otherwise the LTFS software will reject the volume and instruct the user to run the <code style=\"font-family: monospace;\">ltfsck<\/code> utility to recover the volume to a consistent state.<\/p>\n<div id=\"attachment_489\" style=\"width: 650px\" class=\"wp-caption alignright\"><a href=\"https:\/\/michaelrichmond.net\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-489\" src=\"http:\/\/www.smallersystems.com\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-1024x510.png\" alt=\"\" title=\"LTFS Index Generations\" width=\"640\" height=\"318\" class=\"size-large wp-image-489\" \/><\/a><p id=\"caption-attachment-489\" class=\"wp-caption-text\">Logical layout of an LTFS volume showing historical Indexes with back-pointers and multiple files written and edited in-place.<\/p><\/div>\n<p>Notice that this consistent LTFS Volume matches the definition of a <em>consistent state<\/em>. Specifically, that the current Index is written at the end of both partitions on the media.<\/p>\n<p><strong>Power-loss after writing DP Index<\/strong><\/p>\n<p>In the event of a power loss while unmounting the LTFS Volume the volume may end up in the state illustrated below.<\/p>\n<div id=\"attachment_538\" style=\"width: 650px\" class=\"wp-caption alignright\"><a href=\"https:\/\/michaelrichmond.net\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-IPIndexPowerLoss.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-538\" src=\"http:\/\/www.smallersystems.com\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-IPIndexPowerLoss-1024x506.png\" alt=\"\" title=\"LTFS Index Generations - After power-loss writing IP Index\" width=\"640\" height=\"316\" class=\"size-large wp-image-538\" \/><\/a><p id=\"caption-attachment-538\" class=\"wp-caption-text\">Logical layout of an LTFS volume showing historical Indexes with back-pointers and multiple files written and edited in-place after power-loss during IP Index write.<\/p><\/div>\n<p>In the example above, the LTFS cartridge was unmounted after writing File A and B to the volume. This unmount resulted in Index<sup>2<\/sup>. The cartridge was then mounted again and File A was opened for writing and had some new data written. This new data is stored in the purple extent labeled \u201cFile A<sup>3<\/sup>\u201d. The cartridge was then unmounted. This unmount processing wrote the current Index as Index<sup>3<\/sup> and switched to the Index Partition and started to write the current Index. This unmount processing follows the order listed <a href=\"http:\/\/www.smallersystems.com\/blog\/2011\/07\/ltfs-consistency-and-index-snapshots\/\" title=\"LTFS consistency and Index Snapshots\">here<\/a>. Before the Index write completed the system crashed or lost power. This loss of power prevented completion of the Index write to the IP.<\/p>\n<p>If this cartridge is mounted again the LTFS software will identify that the volume is inconsistent and recommend that <code style=\"font-family: monospace;\">ltfsck<\/code> be used with the volume. <code style=\"font-family: monospace;\">ltfsck<\/code> will identify the partial write of the Index to the IP and attempt to read the Index<sup>3<\/sup> stored on the DP. If the Index at the end of the DP can be read successfully then <code style=\"font-family: monospace;\">ltfsck<\/code> will over-write the partial Index on the IP with a duplicate of Index<sup>3<\/sup> from the DP. After this write the cartridge will be consistent and in the state shown in the first diagram on this page.<\/p>\n<p>A similar situation occurs if the power loss occurs after the current Index is written to the DP but before the current Index is written to the IP. The resultant volume structure is shown below.<\/p>\n<div id=\"attachment_544\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/michaelrichmond.net\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-IPIndexNoWrite-e1311889287170.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-544\" src=\"http:\/\/www.smallersystems.com\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-IPIndexNoWrite-1024x506.png\" alt=\"\" title=\"LTFS Index Generations \u2013 After power-loss while changing partitions\" width=\"640\" height=\"316\" class=\"size-large wp-image-544\" \/><\/a><p id=\"caption-attachment-544\" class=\"wp-caption-text\">Logical layout of an LTFS volume showing historical Indexes with back-pointers and multiple files written and edited in-place after power-loss during partition change.<\/p><\/div>\n<p>In the example above, encountering a power-loss while the tape drive is changing partitions has resulted in a correct DP with the current Index as Index<sup>3<\/sup>, but the IP still has the old Index<sup>2<\/sup>. In this scenario, the LTFS software will identify that the Index<sup>2<\/sup> on the IP is out of date based on the values stored in the cartridge MAM parameters and reject the LTFS Volume. <code style=\"font-family: monospace;\">ltfsck<\/code> will identify based on the MAM parameters that Index<sup>3<\/sup> at the end of the DP is the most current Index and will over-write Index<sup>1<\/sup> on the DP with a copy of Index<sup>3<\/sup>.<\/p>\n<p>This recovery is equivalent to the previous recovery of the partially written Index. In both cases, there is no loss of user data.<\/p>\n<p><strong>Power-loss before writing DP Index<\/strong><\/p>\n<p>In the event of a power loss while writing file data to the LTFS Volume the volume may end up in the state illustrated below.<\/p>\n<div id=\"attachment_554\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/michaelrichmond.net\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-DPIndexNoWrite.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-554\" src=\"http:\/\/www.smallersystems.com\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-DPIndexNoWrite-1024x506.png\" alt=\"\" title=\"LTFS Index Generations \u2013 After power-loss while writing file data \" width=\"640\" height=\"316\" class=\"size-large wp-image-554\" \/><\/a><p id=\"caption-attachment-554\" class=\"wp-caption-text\">Logical layout of an LTFS volume showing historical Indexes with back-pointers and multiple files written and edited in-place after power-loss during write of new data file.<\/p><\/div>\n<p>In the example above, the file data write for \u201cFile ?\u201d was in progress when the system crashed or lost power. Immediately before the loss of power the filename for this file existed in memory in the Index but the LTFS software was waiting for the write operation to complete before laying down the current Index as \u201cIndex<sup>4<\/sup>\u201d. Due to the power loss, the updated Index was written to the media and there is no way of knowing whether the data stored in the black extent labeled \u201cFile ?\u201d is complete or just a partial write.<\/p>\n<p>In this example, the LTFS software will refuse to mount the volume and suggest that <code style=\"font-family: monospace;\">ltfsck<\/code> be run against the volume. When <code style=\"font-family: monospace;\">ltfsck<\/code> is run the user has a few different courses of action. By default the <code style=\"font-family: monospace;\">ltfsck<\/code> utility will identify the \u201cunexpected\u201d data at the end of the DP and perform recovery actions to:<\/p>\n<ol>\n<li>read Index<sup>3<\/sup> from the IP,<\/li>\n<li>create a directory at the root of the LTFS filesystem named \u201c<code style=\"font-family: monospace;\">_ltfs_lostandfound<\/code>\u201d if the directory doesn&#8217;t already exist,\n<li>update Index<sup>3<\/sup> to include the \u201cFile ?\u201d data as the contents of one or more files with generated filenames. Each separate file contains the data written to a single block on the media. The files are stored in \u201c<code style=\"font-family: monospace;\">_ltfs_lostandfound<\/code>\u201d,\n<li>write the updated Index out as Index<sup>4<\/sup> to the DP, and\n<li>perform normal unmount processing to write Index<sup>4<\/sup> to the IP.\n<\/ol>\n<p>The layout of the LTFS Volume after these recovery steps have been performed by <code style=\"font-family: monospace;\">ltfsck<\/code> is illustrated below.<\/p>\n<div id=\"attachment_561\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/michaelrichmond.net\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-DPIndexNoWriteRecovery.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-561\" src=\"http:\/\/www.smallersystems.com\/blog\/wp-content\/uploads\/2011\/07\/IndexGenerations-DPIndexNoWriteRecovery-1024x506.png\" alt=\"\" title=\"LTFS Index Generations \u2013 After power-loss while writing file data, followed by full recovery\" width=\"640\" height=\"316\" class=\"size-large wp-image-561\" \/><\/a><p id=\"caption-attachment-561\" class=\"wp-caption-text\">Logical layout of an LTFS volume showing historical Indexes with back-pointers and multiple files written and edited in-place after power-loss during write of new data file, followed by full data recovery by <code style=\"font-family:monospace\">ltfsck<\/code>.<\/p><\/div>\n<p>In the illustration above, the LTFS Volume is consistent but the data blocks shown in black have generated filenames rather than the user-specified filename. Additionally, these recovered data blocks are most likely to contain only partially written data. Recovering the blocks to the volume as recovered files provides the ability for the user to copy these blocks off the volume and re-construct the original data if no other copy exists. In most scenarios the user will still have a copy of the original data elsewhere because the file write to LTFS had not completed before the power loss.<\/p>\n<p>After the user has finished working with the recovered files on the LTFS Volume there is probably no need to leave the blocks on the LTFS Volume. Rather than deleting the recovered files the user can use <code style=\"font-family: monospace;\">ltfsck<\/code> to rollback the LTFS Volume to the Index<sup>3<\/sup> snapshot. Using <code style=\"font-family: monospace;\">ltfsck<\/code> to roll the volume back, rather than deleting the recovered files, means that the space occupied by the partial write (shown in black) will be reclaimed and the LTFS Volume will be returned the the state shown in the first illustration at the top of this page.<\/p>\n<p>If the user has encountered a power loss during file write as described above and the user is not interested in recovering the partially written data, <code style=\"font-family: monospace;\">ltfsck<\/code> provides a command-line option to automate the recovery of the LTFS Volume. With this automated recovery, rather than generating Index<sup>4<\/sup> (described above), <code style=\"font-family: monospace;\">ltfsck<\/code> simply erases the \u201cFile ?\u201d data thereby returning the volume to the consistent state shown in the first illustration at the top of this page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In addition to the filesystem implementation, the Linear Tape File System (LTFS) software ships with two core utilities, \u201cmkltfs\u201d and \u201cltfsck\u201d. mkltfs (pronounced &#8220;make LTFS&#8221;) is used to format LTO cartridges with the LTFS Format. ltfsck is used to check &hellip; <a href=\"https:\/\/michaelrichmond.net\/blog\/2011\/07\/28\/filesystem-recovery-examples-with-ltfsck\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,13,24],"tags":[],"class_list":["post-527","post","type-post","status-publish","format-standard","hentry","category-data-safety","category-data-storage","category-ltfs"],"_links":{"self":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts\/527","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/comments?post=527"}],"version-history":[{"count":0,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts\/527\/revisions"}],"wp:attachment":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/media?parent=527"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/categories?post=527"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/tags?post=527"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}