#include <signal.h>
#include <pwd.h>
#include <grp.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
#include <glib.h>
#include <glib/gstdio.h>
update_info (DevkitDisksDevice *device)
{
gboolean ret;
+ int fd;
+ int block_size;
DevKitInfo *info;
ret = FALSE;
+ info = NULL;
/* free all info and prep for new info */
free_info (device);
device->priv->info.device_is_drive = FALSE;
}
+ info = devkit_info_new (device->priv->native_path);
+ if (info == NULL) {
+ goto out;
+ }
+
+ device->priv->info.device_file = g_strdup (devkit_info_get_device_file (info));
+ devkit_info_device_file_symlinks_foreach (info, update_info_symlinks_cb, device);
+
+ /* TODO: hmm.. it would be really nice if sysfs could export this. There's a
+ * queue/hw_sector_size in sysfs but that's not available for e.g. RAID
+ */
+ errno = 0;
+ fd = open (devkit_info_get_device_file (info), O_RDONLY);
+ if (fd < 0 && errno != ENOMEDIUM) {
+ g_warning ("Cannot open %s read only", devkit_info_get_device_file (info));
+ goto out;
+ }
+ if (errno == ENOMEDIUM) {
+ block_size = 0;
+ } else {
+ if (ioctl (fd, BLKSSZGET, &block_size) != 0) {
+ g_warning ("Cannot determine block size for %s", devkit_info_get_device_file (info));
+ goto out;
+ }
+ close (fd);
+ }
+ device->priv->info.device_block_size = block_size;
+
device->priv->info.device_is_removable =
(sysfs_get_int (device->priv->native_path, "removable") != 0);
if (!device->priv->info.device_is_removable)
device->priv->info.device_is_media_available = TRUE;
- /* TODO: FIXME; need to get the block size */
- device->priv->info.device_block_size = 512;
device->priv->info.device_size =
sysfs_get_uint64 (device->priv->native_path, "size") * device->priv->info.device_block_size;
/* TODO: handle partitions created by kpartx / dm-linear */
}
-
- info = devkit_info_new (device->priv->native_path);
- if (info == NULL) {
- goto out;
- }
-
- device->priv->info.device_file = g_strdup (devkit_info_get_device_file (info));
- devkit_info_device_file_symlinks_foreach (info, update_info_symlinks_cb, device);
devkit_info_property_foreach (info, update_info_properties_cb, device);
- devkit_info_unref (info);
ret = TRUE;
out:
+ if (info != NULL)
+ devkit_info_unref (info);
return ret;
}
#include <errno.h>
#include <sys/ioctl.h>
#include <ctype.h>
+#include <linux/fs.h>
#include <linux/hdreg.h>
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#include <glib/gstdio.h>
#include "partutil.h"
static void
-DEBUG (const gchar *essage, ...)
+DEBUG (const gchar *format, ...)
{
-#if 0
+#if 1
va_list args;
- va_start (args, message);
- g_vfprintf (stderr, message, args);
+ va_start (args, format);
+ g_vfprintf (stderr, format, args);
va_end (args);
g_fprintf (stderr, "\n");
fflush (stderr);
guint64 offset;
guint64 size;
+ /* block size */
+ guint64 block_size;
+
/* entries in partition table */
GSList *entries;
};
}
static PartitionTable *
-part_table_new_empty (PartitionScheme scheme)
+part_table_new_empty (PartitionScheme scheme, int block_size)
{
PartitionTable *p;
p->scheme = scheme;
p->offset = 0;
p->entries = NULL;
+ p->block_size = block_size;
return p;
}
#if 0
static PartitionTable *
-part_table_parse_bsd (int fd, guint64 offset, guint64 size)
+part_table_parse_bsd (int fd, guint64 offset, guint64 size, int block_size)
{
PartitionTable *p;
#endif
static PartitionTable *
-part_table_parse_msdos_extended (int fd, guint64 offset, guint64 size)
+part_table_parse_msdos_extended (int fd, guint64 offset, guint64 size, int block_size)
{
int n;
PartitionTable *p;
DEBUG ("MSDOS_MAGIC found");
if (p == NULL) {
- p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED);
+ p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED, block_size);
p->offset = offset;
p->size = size;
}
guint64 pstart;
guint64 psize;
- pstart = 0x200 * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
- psize = 0x200 * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
+ pstart = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
+ psize = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
if (psize == 0)
continue;
}
static PartitionTable *
-part_table_parse_msdos (int fd, guint64 offset, guint64 size, gboolean *found_gpt)
+part_table_parse_msdos (int fd, guint64 offset, guint64 size, int block_size, gboolean *found_gpt)
{
int n;
const guint8 mbr[512] __attribute__ ((aligned));
}
}
- p = part_table_new_empty (PART_TYPE_MSDOS);
+ p = part_table_new_empty (PART_TYPE_MSDOS, block_size);
p->offset = offset;
p->size = size;
guint8 ptype;
PartitionTable *e_part_table;
- pstart = 0x200 * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
- psize = 0x200 * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
+ pstart = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
+ psize = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4];
DEBUG ("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype);
case 0x05: /* MS-DOS */
case 0x0f: /* Win95 */
case 0x85: /* Linux */
- e_part_table = part_table_parse_msdos_extended (fd, pstart, psize);
+ e_part_table = part_table_parse_msdos_extended (fd, pstart, psize, block_size);
if (e_part_table != NULL) {
pe = part_entry_new (e_part_table,
&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]),
case 0xa5: /* FreeBSD */
case 0xa6: /* OpenBSD */
case 0xa9: /* NetBSD */
- //e_part_table = part_table_parse_bsd (fd, pstart, psize);
+ //e_part_table = part_table_parse_bsd (fd, pstart, psize, block_size);
//break;
default:
#define GPT_PART_TYPE_GUID_EMPTY "00000000-0000-0000-0000-000000000000"
static PartitionTable *
-part_table_parse_gpt (int fd, guint64 offset, guint64 size)
+part_table_parse_gpt (int fd, guint64 offset, guint64 size, int block_size)
{
int n;
PartitionTable *p;
size_of_entry = get_le32(buf);
- p = part_table_new_empty (PART_TYPE_GPT);
+ p = part_table_new_empty (PART_TYPE_GPT, block_size);
p->offset = offset;
p->size = size;
#define MAC_PART_MAGIC "PM"
static PartitionTable *
-part_table_parse_apple (int fd, guint64 offset, guint64 size)
+part_table_parse_apple (int fd, guint64 offset, guint64 size, int device_block_size)
{
int n;
PartitionTable *p;
DEBUG ("Mac MAGIC found, block_size=%d", block_size);
- p = part_table_new_empty (PART_TYPE_APPLE);
+ p = part_table_new_empty (PART_TYPE_APPLE, block_size);
p->offset = offset;
p->size = size;
PartitionTable *
part_table_load_from_disk (int fd)
{
+ int block_size;
guint64 size;
PartitionTable *p;
gboolean found_gpt;
goto out;
}
- p = part_table_parse_msdos (fd, 0, size, &found_gpt);
+ if (ioctl (fd, BLKSSZGET, &block_size) != 0) {
+ DEBUG ("Cannot determine block size");
+ goto out;
+ }
+
+ p = part_table_parse_msdos (fd, 0, size, block_size, &found_gpt);
if (p != NULL) {
DEBUG ("MSDOS partition table detected");
goto out;
}
if (found_gpt) {
- p = part_table_parse_gpt (fd, 0, size);
+ p = part_table_parse_gpt (fd, 0, size, block_size);
if (p != NULL) {
DEBUG ("EFI GPT partition table detected");
goto out;
}
}
- p = part_table_parse_apple (fd, 0, size);
+ p = part_table_parse_apple (fd, 0, size, block_size);
if (p != NULL) {
DEBUG ("Apple partition table detected");
goto out;
break;
case PART_TYPE_MSDOS:
case PART_TYPE_MSDOS_EXTENDED:
- if (pe->data[4] == 0)
+ if (part_table_entry_get_offset (p, entry) == 0)
ret = FALSE;
else
ret = TRUE;
switch (p->scheme) {
case PART_TYPE_GPT:
- val = 0x200 * ((guint64) get_le64 (pe->data + 32));
+ val = p->block_size * ((guint64) get_le64 (pe->data + 32));
break;
case PART_TYPE_MSDOS:
- val = 0x200 * ((guint64) get_le32 (pe->data + 8));
+ val = p->block_size * ((guint64) get_le32 (pe->data + 8));
break;
case PART_TYPE_MSDOS_EXTENDED:
/* tricky here.. the offset in the EMBR is from the start of the EMBR and they are
* scattered around the ext partition... Hence, just use the entry's offset and subtract
* it's offset from the EMBR..
*/
- val = 0x200 * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET;
+ val = p->block_size * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET;
break;
case PART_TYPE_APPLE:
- val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 1*4));
+ val = p->block_size * ((guint64) get_be32 (pe->data + 2*2 + 1*4));
break;
default:
break;
switch (p->scheme) {
case PART_TYPE_GPT:
- val = 0x200 * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1);
+ val = p->block_size * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1);
break;
case PART_TYPE_MSDOS:
case PART_TYPE_MSDOS_EXTENDED:
- val = 0x200 * ((guint64) get_le32 (pe->data + 12));
+ val = p->block_size * ((guint64) get_le32 (pe->data + 12));
break;
case PART_TYPE_APPLE:
- val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 2*4));
+ val = p->block_size * ((guint64) get_be32 (pe->data + 2*2 + 2*4));
break;
default:
break;