LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   writing a partition table to a loop device using a script (fdisk) (http://www.linuxquestions.org/questions/programming-9/writing-a-partition-table-to-a-loop-device-using-a-script-fdisk-902301/)

krisweston 09-10-2011 10:18 AM

writing a partition table to a loop device using a script (fdisk)
 
im trying to make a linux customisation script, part of it involves writing the customisation to a disk image for later use. unfortunately a lot of the how to's and information out there seems to be incorrect for my debian based system, or perhaps i just dont understand it. this has for literally three days solid eluded me, i would really really appreciate some help here. so far ive been following this howto

http://wiki.osdev.org/Loopback_Devic..._the_partition

this suggests you want the heads to be 16 to sectors to be 63 etc...
im stuck on making this loop file be the geometry i want it to be, ive also had some weird errors complaining that 16 heads are impossible, dont know why.
so, anyway, im trying to follow this and make a loop file with the correct geometry first before i partition it for whatever scheme i use in the script, (the script needs to set multiple partition types etc, for various installs)

i also looked at a buch more links than this (literally every link to do with fdisk sfdisk parted EOF etc is purple on my browser, it seems there is nothing left on the net to describe what i want to do :/ )

after discovering parted wont let me set the geometry i moved to fdisk, it seems fdisk also wont let me set the geometry.. so what people seem to be saying works is this:

Code:

/sbin/fdisk $parameters $device << EOF
p
q
EOF
   
exit

fdisk *always* hangs whatever i do. im on ubuntu 11.04 atm...
it seems to me that fdisk might not be seeing a newline or return, but im not sure.
i tried to put a (slash n) after the commands, which also didnt work.

ive also tried this:

Code:

device=/dev/loop0
bytesize=1024
onecylinder=516096
keysize=4076863488
cylindernum="$(($keysize / $onecylinder ))"
sectors=63
heads=16
parameters="-u -C$cylindernum -S$sectors -H$heads"
print_partition_table='p
q'
echo -e "$print_partition_table" | fdisk $parameters $device

this also results in a hang... including if, again, i try and put (slash n) after the commands

ive also found a 'solution' but this also doesnt make sense to me:

Code:

myFunction() {
    cat << EOF
        p
        w
EOF
}

but i dont see how to implement it using his script
http://stackoverflow.com/questions/4...ected-behavior

ta0kira 09-10-2011 04:23 PM

How do you plan to use the image (e.g. VM, copied to hd, looped)? I just created an image file and partitioned it in cfdisk without setting any geometry, but I'm in Slackware. Where is the image located and on what type of filesystem? Try echo p | strace fdisk /dev/loop0 to see where the hang happens. That doesn't hang for me, so if it hangs for you it might be a device problem. You might also try various blockdev queries, which also work for me.
Kevin Barry

krisweston 09-10-2011 07:26 PM

hey ta0kira,
i plan to dd it direct to /dev/sdx when finished.
the image is located in my root/test folder and its standard linux filesystem.
i zero'd the loop file as above with settings it described in the howto. no joy.
i should mention again perhaps im trying to script it.

ta0kira 09-10-2011 07:48 PM

Did you try the strace command I suggested? What about your "print" fdisk line, but without $parameters?
Kevin Barry

syg00 09-10-2011 08:54 PM

For scripting, use sfdisk rather than fdisk. Or parted - separate commands with "-s" should work.

krisweston 09-11-2011 04:39 PM

Code:

write(1, "Device contains neither a valid "..., 247Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
) = 247
write(1, "\n", 1
)                      = 1
write(1, "Using /dev/loop1\n", 17Using /dev/loop1
)      = 17

ta0kira, thanks, i didnt know you could do that...
yeah, youre right, it just hangs there, so there is something up with that...
im revising the answer using sfdisk again, but im unable to create a partition table with it atm...
ill post back shortly...

the main thing im not understanding is how to build a complete image with partition table at the front
so i can mount partitions from the image with offsets...
and write the entire image *without* using offsets...

ta0kira 09-11-2011 04:46 PM

Quote:

Originally Posted by krisweston (Post 4469150)
Code:

write(1, "Device contains neither a valid "..., 247Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
) = 247
write(1, "\n", 1
)                      = 1
write(1, "Using /dev/loop1\n", 17Using /dev/loop1
)      = 17

ta0kira, thanks, i didnt know you could do that...
yeah, youre right, it just hangs there, so there is something up with that...
im revising the answer using sfdisk again, but im unable to create a partition table with it atm...
ill post back shortly...

the main thing im not understanding is how to build a complete image with partition table at the front
so i can mount partitions from the image with offsets...
and write the entire image *without* using offsets...

That's strange. I would have expected an incomplete line at the end of the output, which would indicate a hung system call, or a signal such as SIGTTIN. What is the status of the process when it hangs?
Kevin Barry

krisweston 09-11-2011 05:21 PM

Quote:

Originally Posted by syg00 (Post 4468521)
For scripting, use sfdisk rather than fdisk. Or parted - separate commands with "-s" should work.

Code:

#!/bin/bash

set -x
keysize=4076863488
device0=/dev/loop0
device1=/dev/loop1
devicefile=loop
bytesize="512"
sectors=63
heads=16
onecylinder=$(( $heads * $sectors * $bytesize ))
cylindernum=$(( $keysize / $onecylinder ))
count=$(( $keysize / $bytesize ))
parameters="-C $cylindernum -S $sectors -H $heads"

setup() {
touch loop

dd if=/dev/zero of=loop bs=$bytesize count=$count

losetup $device0 loop
echo "loop device on"
}

setup
sfdisk --force "$parameters" $device0 << EOF
0,407
,407
;
;
EOF

#losetup -o 32256 $device1 $device0

exit

well taking a leaf out of the sfdisk manual, im confused again, i just dont see what the relation of the geometry is to mounting a partition, the whole reason im trying to do it this way is because of the howto above. perhaps its wrong... :/
i get this returned when i run the above:
as you can see its ignored my telling it to have 16 heads, which makes the settings sent to it with EOF string useless, because cylinder length is way larger.
Code:

Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

  Device Boot Start    End  #cyls    #blocks  Id  System
/dev/loop0p1          0+    406    407-  3269227  83  Linux
/dev/loop0p2        407    813    407    3269227+  83  Linux
/dev/loop0p3          0      -      0          0    0  Empty
/dev/loop0p4          0      -      0          0    0  Empty
Warning: partition 1 extends past end of disk
Successfully wrote the new partition table

Re-reading the partition table ...
BLKRRPART: Invalid argument

why does it ignore my geometry ? i really cant understand how im supposed to write the partition table bit at the front....i want to dd this file direct into eg /dev/sdb and have it all bootable etc, just as though you would copy the entire disk into a file. i also cant understand what these /dev/loop0p1 partitions are doing there. it doesnt seem to follow the usual naming convention ie /dev/loop0 etc and i dont see where the begining of the disk is supposed to be displayed, so is this first partition really the first part of the disk ? or do i have to use something else to write that ? and should i be trying to mount these special partitions with kpartx or something ? or should i stay with using offsets with the mount command or losetup ? scuse my ignorance.

krisweston 09-11-2011 05:27 PM

Quote:

Originally Posted by ta0kira (Post 4469153)
That's strange. I would have expected an incomplete line at the end of the output, which would indicate a hung system call, or a signal such as SIGTTIN. What is the status of the process when it hangs?
Kevin Barry

how do i find that out ? is it $? or something ?
it had no specific message at the end, it stopped on that line and i had to ctrl c to get out...
edit: doh by 'hanging' i mean - it stops responding and i have to ctrl c to get out
not an actual crash.

ta0kira 09-11-2011 06:07 PM

Quote:

Originally Posted by krisweston (Post 4469179)
how do i find that out ? is it $? or something ?
it had no specific message at the end, it stopped on that line and i had to ctrl c to get out...
edit: doh by 'hanging' i mean - it stops responding and i have to ctrl c to get out
not an actual crash.

So when you Ctrl-C is the cursor at the beginning of a line in the terminal? Is the output you posted what it shows prior to Ctrl-C? The place your output stops (the line with "= 17") would be a very strange place for it to hang. As an example, type strace sleep 10. It will hang for 10s on the line "nanosleep({10, 0}, ", until nanosleep completes.

To get the status of fdisk, type ps $( pgrep fdisk ) in a separate terminal when fdisk is stuck. The "STAT" column should be something like "S+".
Kevin Barry

krisweston 09-11-2011 06:45 PM

hey there, thanks a lot for these debugging tips, never knew how to do this, im learning more today!
(just learnt arrays and almost learnt spawning processes with FIFO files but that didnt quite work out :)

yes youre right cursor is on next line at left after the end of that line...

Code:

test# ps $( pgrep fdisk )
  PID TTY      STAT  TIME COMMAND
 7416 pts/4    R+    0:04 fdisk /dev/loop1

hmmm, why do they have some many grep commands! pgrep, egrep, grep, then all the different kinds of regex in sed, awk, etc etc... mighty confusing... never seen pgrep before...

ta0kira 09-11-2011 07:27 PM

Quote:

Originally Posted by krisweston (Post 4469234)
hey there, thanks a lot for these debugging tips, never knew how to do this, im learning more today!
(just learnt arrays and almost learnt spawning processes with FIFO files but that didnt quite work out :)

yes youre right cursor is on next line at left after the end of that line...

Code:

test# ps $( pgrep fdisk )
  PID TTY      STAT  TIME COMMAND
 7416 pts/4    R+    0:04 fdisk /dev/loop1

hmmm, why do they have some many grep commands! pgrep, egrep, grep, then all the different kinds of regex in sed, awk, etc etc... mighty confusing... never seen pgrep before...

pgrep comes with ps and it's not directly related to grep. egrep is short for grep -E.

"R" means "running". That probably means fdisk is stuck in an infinite loop containing no system calls, which would explain your strace output. That sounds like an fdisk bug to me, unless fdisk has access to the loop without subsequent system calls (e.g. via a previous mmap), but I'm not sure if that's possible.
Kevin Barry

krisweston 09-11-2011 09:32 PM

yeah, its probably best to use something else, i turned to fdisk out of desperation with the other things not working.. well its parted and sfdisk left now :)

many thanks for the grep tips!

gnashley 09-12-2011 02:15 AM

Yeah, use sfdisk if you are scripting. But, I keep getting the idea that you aren't properly setting up your loop device for the image file. Are you offsetting with losetup before or after trying to write the partition table?

krisweston 09-12-2011 07:51 AM

me too :)

Code:

#!/bin/bash

set -x
keysize=4076863488
device0=/dev/loop0
device1=/dev/loop1
devicefile=loop
bytesize="512"
sectors=63
heads=16
onecylinder=$(( $heads * $sectors * $bytesize ))
cylindernum=$(( $keysize / $onecylinder ))
count=$(( $keysize / $bytesize ))
parameters="-C $cylindernum -S $sectors -H $heads"

setup() {
touch loop

dd if=/dev/zero of=loop bs=$bytesize count=$count

losetup $device0 loop
echo "loop device on"
}

setup
sfdisk --force "$parameters" $device0 << EOF
0,407
,407
;
;
EOF

#losetup -o 32256 $device1 $device0

exit

so what is wrong here ? i just dont see what the relation of the geometry is to mounting a partition, the whole reason im trying to do it this way is because of the howto above. perhaps its wrong... :/ i get this returned when i run the above: as you can see its ignored my telling it to have 16 heads, which makes the settings sent to it with EOF string useless, because cylinder length is way larger.
Code:

Disk /dev/loop0: 7899 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start    End  #cyls    #blocks  Id  System
/dev/loop0p1          0+    406    407-  3269227  83  Linux
/dev/loop0p2        407    813    407    3269227+  83  Linux
/dev/loop0p3          0      -      0          0    0  Empty
/dev/loop0p4          0      -      0          0    0  Empty
Warning: partition 1 extends past end of disk
Successfully wrote the new partition table

Re-reading the partition table ...
BLKRRPART: Invalid argument`code`



All times are GMT -5. The time now is 01:43 PM.