 |
 |
 |
 |
| Programming & Packaging A place to discuss programming and packaging. |

5th June 2012, 11:16 AM
|
 |
Registered User
|
|
Join Date: Sep 2010
Location: China
Posts: 75

|
|
how to get a disk partition's start cylinder?
Hi, all:
Is there any way to get a disk partition's [start-end]cylinder in C programming in Linux?
I can't find any direct system call to do this.
so, I guess, it must be computed out via some data.
Do you know any information about this issue.
Thanks for your sharing!!!
__________________
[SIGPIC][/SIGPIC]
|

5th June 2012, 04:10 PM
|
|
Registered User
|
|
Join Date: Jan 2011
Location: Woonsocket, RI
Posts: 377

|
|
|
Re: how to get a disk partition's start cylinder?
First, be aware that "cylinder" values are entirely fictitious when applied to modern hardware, and almost completely irrelevant today. The cylinder/head/sector (CHS) fields in the MBR partitioning system are 24 bits in size (with some weirdness that makes one bit usable only some of the time), rendering a limit to CHS addressing of about 8 GB. A disk that uses GPT rather than MBR doesn't use CHS values at all (except in the hybrid MBR, and those values are likely to be maxed out, and in practice some utilities don't even compute them). Thus, very few programs need to compute this information. Those that do are mostly older tools. If you're writing a new tool and you have a choice of using cylinders vs. using sectors or MiB values in the user interface, I strongly recommend that you not use cylinders.
That said, you can see this Wikipedia article about how these values are computed. Most importantly, there's a formula about halfway down, under "CHS to LBA mapping," that you can use to compute these values. This formula, however, relies on knowledge of the CHS geometry -- that is, how many heads and sectors per track there are on the disk. You can get this information with the HDIO_GETGEO ioctl, thus:
Code:
struct hd_geometry geometry;
if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
numSecs = geometry.sectors;
numHeads = geometry.heads;
}
This code is modified from my own GPT fdisk program, in the diskio-unix.cc file. I'm sure you can find other examples in other programs, such as fdisk or libparted.
One extremely important caveat to all of this is that the CHS geometry may not be fixed on modern hard disks. That is, if you move the disk from one computer to another, or sometimes even if you boot different OSes on one computer, the geometry can change. This is one of many reasons for abandoning this method of disk addressing. (OTOH, on disks over about 8 GB, the CHS geometry is likely to be "maxed out" on any computer.)
|

6th June 2012, 12:21 AM
|
 |
Registered User
|
|
Join Date: Nov 2006
Location: Detroit
Posts: 4,613

|
|
|
Re: how to get a disk partition's start cylinder?
I agree with srs5694 that you should not use cylinders. It's better to use sectors, which is what fdisk uses for the start and end when you display the partition table.
Showing that information using C is easy if you have the parted-devel package installed (it's in the Fedora repos). Here's a simple example (which obviously can be improved a lot  ), which I call getpartinfo.c:
Code:
#include <stdio.h>
#include <parted/parted.h>
int main (int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s disk_name partition_number\n", argv[0]);
exit(1);
}
PedDevice* device = ped_device_get(argv[1]);
int partnum = atoi(argv[2]);
PedDisk* disk = ped_disk_new(device);
PedPartition* part = ped_disk_get_partition(disk, partnum);
printf("Partition: %s%s\n", argv[1], argv[2]);
printf("Partition type: %s\n", part->fs_type->name);
printf("Start sector: %lld\n", part->geom.start);
printf("End sector: %lld\n", part->geom.end);
return 0;
}
Compile it and then run it like this, with 2 command-line parameters (e.g. /dev/sda 1, if you want info on /dev/sda1):
Code:
$ gcc -o getpartinfo getpartinfo.c -lparted
$ ./getpartinfo /dev/sda 1
Partition: /dev/sda1
Partition type: ext3
Start sector: 2048
End sector: 1230847
There's some documentation for the parted API here, though it's pretty minimal.
__________________
OS: Fedora 18 x86_64 | CPU: AMD64 3700+ 2.2GHz | RAM: 2GB PC3200 DDR | Disk: 160GB PATA | Video: ATI Radeon 7500 AGP 64MB | Sound: Turtle Beach Santa Cruz CS4630 | Ethernet: Realtek 8110SC
|

6th June 2012, 03:14 AM
|
 |
Registered User
|
|
Join Date: Sep 2010
Location: China
Posts: 75

|
|
|
Re: how to get a disk partition's start cylinder?
Thanks for your information.
I think I should tell what I'm going to do.
you know, a usb disk can be mounted as sda1,sda2,sda3..., but next time maybe change the order -- sda1 may be the previous time's sda2 or sda3. I need to identify what the partition exact is. I'v considered UUID, but there's no UUID support in the system which my program must be running on. So I want to identify a partition through a partition's cylinder info.
Is there a better way to do this, I am expecting your advice...
Thanks!
__________________
[SIGPIC][/SIGPIC]
|

6th June 2012, 05:46 PM
|
|
Registered User
|
|
Join Date: Jan 2011
Location: Woonsocket, RI
Posts: 377

|
|
|
Re: how to get a disk partition's start cylinder?
Unless a disk is repartitioned, the partition number won't change -- partition 2 will remain partition 2, no matter how many times you unmount it and remount it. The disk's device letter might change without repartitioning -- that is, /dev/sda could become /dev/sdb. Thus, depending on your exact circumstances, you may be trying to solve a problem that doesn't exist. Furthermore, if the disk might be repartitioned between remounts, using the starting cylinder or sector may not be adequate to identify specific filesystems, since the new partition layout could end up looking much like the old one but place new filesystems at old locations. Likewise with two different USB disks; they might be partitioned identically but they'll obviously hold different filesystems. Thus, using the cylinder or sector number might produce "false alarms," where a new or different partition is misidentified as an old one.
These are the problems that UUIDs can solve, so if you really have a need for positively identifying certain filesystems, I recommend you work to get UUID support onto whatever system you're using. If necessary, you can statically link the appropriate libraries into your program to do this. That'll be much more reliable than using cylinder or sector numbers. In some cases you can use filesystem labels for this purpose, too, but many filesystems lack labels, so this isn't really reliable unless you can guarantee that your filesystems will all have unique labels. If for some reason using UUIDs or labels is really impossible, you could use sector numbers. This will be simpler than trying to convert a sector number into a cylinder number, and it'll be more precise. It'll still have the problem that it won't really positively identify specific filesystems, though.
|

7th June 2012, 02:23 AM
|
 |
Registered User
|
|
Join Date: Sep 2010
Location: China
Posts: 75

|
|
|
Re: how to get a disk partition's start cylinder?
Quote:
Originally Posted by srs5694
Unless a disk is repartitioned, the partition number won't change -- partition 2 will remain partition 2, no matter how many times you unmount it and remount it. The disk's device letter might change without repartitioning -- that is, /dev/sda could become /dev/sdb. Thus, depending on your exact circumstances, you may be trying to solve a problem that doesn't exist. Furthermore, if the disk might be repartitioned between remounts, using the starting cylinder or sector may not be adequate to identify specific filesystems, since the new partition layout could end up looking much like the old one but place new filesystems at old locations. Likewise with two different USB disks; they might be partitioned identically but they'll obviously hold different filesystems. Thus, using the cylinder or sector number might produce "false alarms," where a new or different partition is misidentified as an old one.
These are the problems that UUIDs can solve, so if you really have a need for positively identifying certain filesystems, I recommend you work to get UUID support onto whatever system you're using. If necessary, you can statically link the appropriate libraries into your program to do this. That'll be much more reliable than using cylinder or sector numbers. In some cases you can use filesystem labels for this purpose, too, but many filesystems lack labels, so this isn't really reliable unless you can guarantee that your filesystems will all have unique labels. If for some reason using UUIDs or labels is really impossible, you could use sector numbers. This will be simpler than trying to convert a sector number into a cylinder number, and it'll be more precise. It'll still have the problem that it won't really positively identify specific filesystems, though.
|
can you show me the common way to get a partition's start sector number in C source code.
Code:
struct hd_geometry geometry;
if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
numSecs = geometry.sectors;
numHeads = geometry.heads;
}
for the code above. I cant compile it, gcc said HDIO_GETGEO is undeclared and struct hd_geometry is not found.
Thanks a lot!
__________________
[SIGPIC][/SIGPIC]
|

7th June 2012, 03:45 AM
|
|
Registered User
|
|
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,092

|
|
|
Re: how to get a disk partition's start cylinder?
I think you have to include "linux/hdreg.h" for that.
|

8th June 2012, 02:32 AM
|
 |
Registered User
|
|
Join Date: Sep 2010
Location: China
Posts: 75

|
|
|
Re: how to get a disk partition's start cylinder?
Thanks for your replies! I've got the answer.
But I think I should learn more basic knowledge about hard disk.
__________________
[SIGPIC][/SIGPIC]
|

8th June 2012, 03:51 PM
|
|
Registered User
|
|
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,092

|
|
|
Re: how to get a disk partition's start cylinder?
In what sense "more basic knowledge" ? Current disks are doing LBA addressing and the head/sector/platter is useless even before that - the "head" value is faked even then. This was done to allow expanding disks from 512 MB to 2GB. And the "platter" was being faked even earlier (originally fixed disks had 4 physical platters...half height ones had 8 to 12, full height ones 16 (I've still got one, 2.5GB and worked the last time I turned it on).
Unless you are developing disk formatters, the geometry on the disk is arbitrary. The most useful number was the number of sectors, and that only for determining when a head seek would actually cause movement. But now, the disks are fast enough that even that doesn't matter much other than for avoiding pathological cases (IO to #sectors+1 always causes a full rotation delay) but with the formatter providing buffering and readahead, even that isn't true.
Last edited by jpollard; 8th June 2012 at 03:54 PM.
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
Current GMT-time: 05:56 (Sunday, 19-05-2013)
|
|
 |
 |
 |
 |
|
|