From: Brian J. M. <br...@in...> - 2008-04-20 05:26:55
Attachments:
bad_block_find_file
|
Hi Bruce, Let me preface by saying I would have CC'd Frederic BOITEUX but you didn't provide an e-mail address for him in your HowTo. Perhaps you still have it and can forward this little tool for his review as well since he contributed the LVM bits to your howto. I have read your http://smartmontools.sourceforge.net/BadBlockHowTo.txt and while very cool, too many manual steps for me. So I wrote a tool. :-) Please find it attached. I'm wondering if you'd care to peer review it for me. It seems to have worked here on the bad block I was hunting down, but with all of the math and lookups a second, third or even eleventh set of eyes would be useful I think. Let me make a couple of comments about various bits. There is some code conditional on $ut being true. This was/is intended to be a unit test of sorts where it uses the numbers that are actually in your HowTo. I started to get too wrapped up in trying to reproduce your results and gave up on the "$ut = true" conditional code. It still might prove useful one day but for now, I just ran out of time. The commented out dump of the sfdisk output is in that same vane(sp?). The placing of code in deeper and deeper blocks is unfortunately a necessity of shell programming. For example I would love nothing more than to put a "break" on line 29, end the while loop that starts on line 26 on line 31 and start the code that is currently on line 29 outside the line 26 loop as such: sfdisk -lu $disk 2>/dev/null | sed -e '1,/Device Boot/d' | while read device start end size type junk; do [ $start -eq 0 ] && continue if [ $bb_lba -ge $start -a $bb_lba -le $end ]; then break fi done if $ut; then bb_partition_offset=36194858 else bb_partition_offset=$((bb_lba-start)) fi pe_size=$(pvdisplay -c $device | cut -d: -f 8) lba_blocks_per_pe=$((pe_size * 2)) pe_start=$(grep pe_start $(grep -l /dev/sda2 /etc/lvm/backup/*) | sed -e 's/^.* = //') bb_pe=$((bb_partition_offset/lba_blocks_per_pe)) ... but as you probably know, the values of device, start, end, size, and type are no longer available outside of that while loop due to the while loop being in a subshell which is necessary by nature of it having input piped into it. I could use process substitution to get around this with bash, but it's not portable outside of bash. Heh. But I'm just noticing use of the BASH_REMATCH array in the script so it's probably already not portable. :-( Oh well. Anyway, if you'd care to, I would not mind your comments on the script, and more than anything, a sanity check on the calculations. :-) Cheers and many thanks for the Howto. b. |
From: Jim P. <ji...@jt...> - 2008-04-20 22:50:58
|
Hi Brian, > The placing of code in deeper and deeper blocks is unfortunately a > necessity of shell programming. For example I would love nothing more > than to put a "break" on line 29, ... > but as you probably know, the values of device, start, end, size, and > type are no longer available outside of that while loop due to the while > loop being in a subshell which is necessary by nature of it having input > piped into it. I could use process substitution to get around this with > bash, but it's not portable outside of bash. There are two ways around this: rather than nesting deeper, you can create a function that you call with the specific parameters; or, just copy the variables to one in a higher scope so they are available after the loop: foo="" while read bar ; do foo=$bar done echo $bar # empty echo $foo # contains the value read from stdin -jim |
From: Brian J. M. <br...@in...> - 2008-04-20 23:07:18
|
On Sun, 2008-04-20 at 18:50 -0400, Jim Paris wrote: > Hi Brian, Hi, > There are two ways around this: rather than nesting deeper, you can > create a function that you call with the specific parameters; Yeah. I just hate single use functions created merely for the shortcoming of a language. It's a minor annoyance though. > or, just copy the variables to one in a higher scope so they are > available after the loop: > > foo="" > while read bar ; do > foo=$bar > done > echo $bar # empty > echo $foo # contains the value read from stdin Hrm. That does not seem to actually work: $ foo=""; echo "test" | while read bar; do foo=$bar; echo $foo; done; echo $bar; echo $foo test $ b. |
From: Jim P. <ji...@jt...> - 2008-04-20 23:15:23
|
> > foo="" > > while read bar ; do > > foo=$bar > > done > > echo $bar # empty > > echo $foo # contains the value read from stdin > > Hrm. That does not seem to actually work: > > $ foo=""; echo "test" | while read bar; do foo=$bar; echo $foo; done; echo $bar; echo $foo > test > > Hmm.. Right, you said: "due to the while loop being in a subshell which is necessary by nature of it having in put piped into it" and I stupidly made that example without piping input to the while loop, but instead by piping it to the whole script. Nevermind :) -jim |
From: Bruce A. <ba...@gr...> - 2008-04-22 08:00:13
|
Hi Brian, Sorry -- I have been slow to respond. At the moment I am rather distracted with my 'real job' and can't spend time on this. Could I suggest that you send this same email to the smartmontools developers list to get comments and review from others also? It is: Smartmontools Developers List <sma...@li...>, Please sign up for the list and I will approve you as a poster/subscriber. PS: having a tool for this is a great idea -- please don't misinterpret my response to mean otherwise! Cheers, Bruce On Sun, 20 Apr 2008, Brian J. Murrell wrote: > Hi Bruce, > > Let me preface by saying I would have CC'd Frederic BOITEUX but you > didn't provide an e-mail address for him in your HowTo. Perhaps you > still have it and can forward this little tool for his review as well > since he contributed the LVM bits to your howto. > > I have read your http://smartmontools.sourceforge.net/BadBlockHowTo.txt > and while very cool, too many manual steps for me. So I wrote a > tool. :-) > > Please find it attached. I'm wondering if you'd care to peer review it > for me. It seems to have worked here on the bad block I was hunting > down, but with all of the math and lookups a second, third or even > eleventh set of eyes would be useful I think. > > Let me make a couple of comments about various bits. There is some code > conditional on $ut being true. This was/is intended to be a unit test > of sorts where it uses the numbers that are actually in your HowTo. I > started to get too wrapped up in trying to reproduce your results and > gave up on the "$ut = true" conditional code. It still might prove > useful one day but for now, I just ran out of time. The commented out > dump of the sfdisk output is in that same vane(sp?). > > The placing of code in deeper and deeper blocks is unfortunately a > necessity of shell programming. For example I would love nothing more > than to put a "break" on line 29, end the while loop that starts on line > 26 on line 31 and start the code that is currently on line 29 outside > the line 26 loop as such: > > sfdisk -lu $disk 2>/dev/null | > sed -e '1,/Device Boot/d' | > while read device start end size type junk; do > [ $start -eq 0 ] && continue > if [ $bb_lba -ge $start -a $bb_lba -le $end ]; then > break > fi > done > > if $ut; then > bb_partition_offset=36194858 > else > bb_partition_offset=$((bb_lba-start)) > fi > pe_size=$(pvdisplay -c $device | cut -d: -f 8) > lba_blocks_per_pe=$((pe_size * 2)) > pe_start=$(grep pe_start $(grep -l /dev/sda2 /etc/lvm/backup/*) | > sed -e 's/^.* = //') > bb_pe=$((bb_partition_offset/lba_blocks_per_pe)) > ... > > but as you probably know, the values of device, start, end, size, and > type are no longer available outside of that while loop due to the while > loop being in a subshell which is necessary by nature of it having input > piped into it. I could use process substitution to get around this with > bash, but it's not portable outside of bash. > > Heh. But I'm just noticing use of the BASH_REMATCH array in the script > so it's probably already not portable. :-( Oh well. > > Anyway, if you'd care to, I would not mind your comments on the script, > and more than anything, a sanity check on the calculations. :-) > > Cheers and many thanks for the Howto. > > b. > > |