diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.in | 19 | ||||
-rw-r--r-- | doc/api/tmpl/hal-unused.sgml | 299 | ||||
-rw-r--r-- | doc/api/tmpl/libhal-storage.sgml | 324 | ||||
-rw-r--r-- | doc/spec/hal-spec-properties.xml | 208 | ||||
-rw-r--r-- | doc/spec/hal-spec.html | 1081 | ||||
-rw-r--r-- | hald/linux/addons/addon-storage.c | 9 | ||||
-rw-r--r-- | hald/linux/blockdev.c | 2 | ||||
-rw-r--r-- | hald/linux/probing/Makefile.am | 4 | ||||
-rw-r--r-- | hald/linux/probing/probe-storage.c | 182 | ||||
-rw-r--r-- | hald/linux/probing/probe-volume.c | 439 | ||||
-rw-r--r-- | libhal-storage/libhal-storage.c | 59 | ||||
-rw-r--r-- | libhal-storage/libhal-storage.h | 64 | ||||
-rw-r--r-- | libhal/libhal.h | 7 | ||||
-rw-r--r-- | partutil/Makefile.am | 11 | ||||
-rw-r--r-- | partutil/partutil.c | 1791 | ||||
-rw-r--r-- | partutil/partutil.h | 412 |
17 files changed, 4120 insertions, 793 deletions
diff --git a/Makefile.am b/Makefile.am index d0838701..16968d21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = libhal libhal-storage hald hald-runner tools \ +SUBDIRS = libhal libhal-storage partutil hald hald-runner tools \ fdi doc po privileges pkgconfigdir = $(libdir)/pkgconfig diff --git a/configure.in b/configure.in index 42b0cf94..cedcb226 100644 --- a/configure.in +++ b/configure.in @@ -100,6 +100,21 @@ fi AC_SUBST(ACPI_PROC) AM_CONDITIONAL(ACPI_PROC, test x$acpi_proc = xyes) + +dnl libparted +AC_ARG_ENABLE([parted], AC_HELP_STRING([--enable-parted], [Use libparted]), [use_parted=$enableval], [use_parted=no]) +if test "x$use_parted" = "xyes" ; then + USE_PARTED=yes + AC_DEFINE(USE_PARTED,1,[Whether libparted is to be used]) + PARTED_CHECK_LIBPARTED(1.7.1, , + [AC_MSG_ERROR([*** libparted >= 1.7.1 not installed - please install first ***])]) +else + USE_PARTED=no +fi +AC_SUBST(USE_PARTED) +AM_CONDITIONAL(USE_PARTED, test x$use_parted == xyes) + + #### gcc warning flags if test "x$GCC" = "xyes"; then @@ -184,7 +199,7 @@ AM_CONDITIONAL(GCOV, test x$enable_gcov = xyes) EXPAT_LIB="" -AC_ARG_WITH(expat, [ --with-expat=<dir> ese expat from here], +AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here], [ expat=$withval CPPFLAGS="$CPPFLAGS -I$withval/include" @@ -457,6 +472,7 @@ tools/linux/Makefile tools/device-manager/hal-device-manager tools/device-manager/Makefile tools/device-manager/Const.py +partutil/Makefile privileges/Makefile fdi/Makefile fdi/preprobe/Makefile @@ -510,6 +526,7 @@ echo " use acpid interface: ${acpi_acpid} use libusb: ${USE_LIBUSB} use libpci: ${USE_LIBPCI} + use libparted: ${USE_PARTED} use PolicyKit: ${msg_polkit} diff --git a/doc/api/tmpl/hal-unused.sgml b/doc/api/tmpl/hal-unused.sgml index 0f22ab22..6fb25b02 100644 --- a/doc/api/tmpl/hal-unused.sgml +++ b/doc/api/tmpl/hal-unused.sgml @@ -370,6 +370,61 @@ sysfs </para> +<!-- ##### ENUM LibHalDriveBus ##### --> +<para> + +</para> + +@LIBHAL_DRIVE_BUS_UNKNOWN: +@LIBHAL_DRIVE_BUS_IDE: +@LIBHAL_DRIVE_BUS_SCSI: +@LIBHAL_DRIVE_BUS_USB: +@LIBHAL_DRIVE_BUS_IEEE1394: +@LIBHAL_DRIVE_BUS_CCW: + +<!-- ##### ENUM LibHalDriveCdromCaps ##### --> +<para> + +</para> + +@LIBHAL_DRIVE_CDROM_CAPS_CDROM: +@LIBHAL_DRIVE_CDROM_CAPS_CDR: +@LIBHAL_DRIVE_CDROM_CAPS_CDRW: +@LIBHAL_DRIVE_CDROM_CAPS_DVDRAM: +@LIBHAL_DRIVE_CDROM_CAPS_DVDROM: +@LIBHAL_DRIVE_CDROM_CAPS_DVDR: +@LIBHAL_DRIVE_CDROM_CAPS_DVDRW: +@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR: +@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW: +@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL: +@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL: +@LIBHAL_DRIVE_CDROM_CAPS_BDROM: +@LIBHAL_DRIVE_CDROM_CAPS_BDR: +@LIBHAL_DRIVE_CDROM_CAPS_BDRE: +@LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM: +@LIBHAL_DRIVE_CDROM_CAPS_HDDVDR: +@LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW: + +<!-- ##### ENUM LibHalDriveType ##### --> +<para> + +</para> + +@LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: +@LIBHAL_DRIVE_TYPE_DISK: +@LIBHAL_DRIVE_TYPE_CDROM: +@LIBHAL_DRIVE_TYPE_FLOPPY: +@LIBHAL_DRIVE_TYPE_TAPE: +@LIBHAL_DRIVE_TYPE_COMPACT_FLASH: +@LIBHAL_DRIVE_TYPE_MEMORY_STICK: +@LIBHAL_DRIVE_TYPE_SMART_MEDIA: +@LIBHAL_DRIVE_TYPE_SD_MMC: +@LIBHAL_DRIVE_TYPE_CAMERA: +@LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER: +@LIBHAL_DRIVE_TYPE_ZIP: +@LIBHAL_DRIVE_TYPE_JAZ: +@LIBHAL_DRIVE_TYPE_FLASHKEY: + <!-- ##### TYPEDEF LibHalPolicyContext ##### --> <para> @@ -413,6 +468,40 @@ sysfs @LIBHAL_POLICY_RESULT_PERMISSON_DENIED: @LIBHAL_POLICY_RESULT_NO_SUCH_POLICY: +<!-- ##### ENUM LibHalVolumeDiscType ##### --> +<para> + +</para> + +@LIBHAL_VOLUME_DISC_TYPE_CDROM: +@LIBHAL_VOLUME_DISC_TYPE_CDR: +@LIBHAL_VOLUME_DISC_TYPE_CDRW: +@LIBHAL_VOLUME_DISC_TYPE_DVDROM: +@LIBHAL_VOLUME_DISC_TYPE_DVDRAM: +@LIBHAL_VOLUME_DISC_TYPE_DVDR: +@LIBHAL_VOLUME_DISC_TYPE_DVDRW: +@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: +@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: +@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL: +@LIBHAL_VOLUME_DISC_TYPE_BDROM: +@LIBHAL_VOLUME_DISC_TYPE_BDR: +@LIBHAL_VOLUME_DISC_TYPE_BDRE: +@LIBHAL_VOLUME_DISC_TYPE_HDDVDROM: +@LIBHAL_VOLUME_DISC_TYPE_HDDVDR: +@LIBHAL_VOLUME_DISC_TYPE_HDDVDRW: + +<!-- ##### ENUM LibHalVolumeUsage ##### --> +<para> + +</para> + +@LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM: +@LIBHAL_VOLUME_USAGE_PARTITION_TABLE: +@LIBHAL_VOLUME_USAGE_RAID_MEMBER: +@LIBHAL_VOLUME_USAGE_CRYPTO: +@LIBHAL_VOLUME_USAGE_UNKNOWN: +@LIBHAL_VOLUME_USAGE_OTHER: + <!-- ##### MACRO SB_BUFFER_SIZE ##### --> <para> @@ -975,6 +1064,95 @@ sysfs @x: +<!-- ##### FUNCTION libhal_drive_find_all_volumes ##### --> +<para> + +</para> + +@hal_ctx: +@drive: +@num_volumes: +@Returns: + +<!-- ##### FUNCTION libhal_drive_from_udi ##### --> +<para> + +</para> + +@hal_ctx: +@udi: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_compute_icon_name ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_primary ##### --> +<para> + +</para> + +@hal_ctx: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_secondary ##### --> +<para> + +</para> + +@hal_ctx: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_default_use_managed_keyword ##### --> +<para> + +</para> + +@hal_ctx: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_get_desired_mount_point ##### --> +<para> + +</para> + +@drive: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_get_mount_fs ##### --> +<para> + +</para> + +@drive: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_get_mount_options ##### --> +<para> + +</para> + +@drive: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_drive_policy_is_mountable ##### --> +<para> + +</para> + +@drive: +@policy: +@Returns: + <!-- ##### FUNCTION libhal_policy_context_set_txt_source ##### --> <para> @@ -1238,6 +1416,127 @@ sysfs @default_gid: @Returns: +<!-- ##### FUNCTION libhal_storage_policy_free ##### --> +<para> + +</para> + +@policy: + +<!-- ##### FUNCTION libhal_storage_policy_lookup_icon ##### --> +<para> + +</para> + +@policy: +@icon: +@Returns: + +<!-- ##### FUNCTION libhal_storage_policy_set_icon_mapping ##### --> +<para> + +</para> + +@policy: +@pairs: + +<!-- ##### FUNCTION libhal_storage_policy_set_icon_path ##### --> +<para> + +</para> + +@policy: +@icon: +@path: + +<!-- ##### FUNCTION libhal_volume_from_udi ##### --> +<para> + +</para> + +@hal_ctx: +@udi: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_compute_display_name ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_compute_icon_name ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_compute_size_as_string ##### --> +<para> + +</para> + +@volume: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_get_desired_mount_point ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_get_mount_fs ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_get_mount_options ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_is_mountable ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@Returns: + +<!-- ##### FUNCTION libhal_volume_policy_should_be_visible ##### --> +<para> + +</para> + +@drive: +@volume: +@policy: +@target_mount_point: +@Returns: + <!-- ##### FUNCTION lstat ##### --> <para> diff --git a/doc/api/tmpl/libhal-storage.sgml b/doc/api/tmpl/libhal-storage.sgml index ae280397..c99e3c21 100644 --- a/doc/api/tmpl/libhal-storage.sgml +++ b/doc/api/tmpl/libhal-storage.sgml @@ -151,108 +151,6 @@ libhal-storage @Returns: -<!-- ##### FUNCTION libhal_storage_policy_free ##### --> -<para> - -</para> - -@policy: - - -<!-- ##### FUNCTION libhal_storage_policy_set_icon_path ##### --> -<para> - -</para> - -@policy: -@icon: -@path: - - -<!-- ##### FUNCTION libhal_storage_policy_set_icon_mapping ##### --> -<para> - -</para> - -@policy: -@pairs: - - -<!-- ##### FUNCTION libhal_storage_policy_lookup_icon ##### --> -<para> - -</para> - -@policy: -@icon: -@Returns: - - -<!-- ##### ENUM LibHalDriveBus ##### --> -<para> - -</para> - -@LIBHAL_DRIVE_BUS_UNKNOWN: -@LIBHAL_DRIVE_BUS_IDE: -@LIBHAL_DRIVE_BUS_SCSI: -@LIBHAL_DRIVE_BUS_USB: -@LIBHAL_DRIVE_BUS_IEEE1394: -@LIBHAL_DRIVE_BUS_CCW: - -<!-- ##### ENUM LibHalDriveType ##### --> -<para> - -</para> - -@LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: -@LIBHAL_DRIVE_TYPE_DISK: -@LIBHAL_DRIVE_TYPE_CDROM: -@LIBHAL_DRIVE_TYPE_FLOPPY: -@LIBHAL_DRIVE_TYPE_TAPE: -@LIBHAL_DRIVE_TYPE_COMPACT_FLASH: -@LIBHAL_DRIVE_TYPE_MEMORY_STICK: -@LIBHAL_DRIVE_TYPE_SMART_MEDIA: -@LIBHAL_DRIVE_TYPE_SD_MMC: -@LIBHAL_DRIVE_TYPE_CAMERA: -@LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER: -@LIBHAL_DRIVE_TYPE_ZIP: -@LIBHAL_DRIVE_TYPE_JAZ: -@LIBHAL_DRIVE_TYPE_FLASHKEY: - -<!-- ##### ENUM LibHalDriveCdromCaps ##### --> -<para> - -</para> - -@LIBHAL_DRIVE_CDROM_CAPS_CDROM: -@LIBHAL_DRIVE_CDROM_CAPS_CDR: -@LIBHAL_DRIVE_CDROM_CAPS_CDRW: -@LIBHAL_DRIVE_CDROM_CAPS_DVDRAM: -@LIBHAL_DRIVE_CDROM_CAPS_DVDROM: -@LIBHAL_DRIVE_CDROM_CAPS_DVDR: -@LIBHAL_DRIVE_CDROM_CAPS_DVDRW: -@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR: -@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW: -@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL: -@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL: -@LIBHAL_DRIVE_CDROM_CAPS_BDROM: -@LIBHAL_DRIVE_CDROM_CAPS_BDR: -@LIBHAL_DRIVE_CDROM_CAPS_BDRE: -@LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM: -@LIBHAL_DRIVE_CDROM_CAPS_HDDVDR: -@LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW: - -<!-- ##### FUNCTION libhal_drive_from_udi ##### --> -<para> - -</para> - -@hal_ctx: -@udi: -@Returns: - - <!-- ##### FUNCTION libhal_drive_from_device_file ##### --> <para> @@ -476,69 +374,6 @@ libhal-storage @drive: @volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_compute_icon_name ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_is_mountable ##### --> -<para> - -</para> - -@drive: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_get_desired_mount_point ##### --> -<para> - -</para> - -@drive: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_get_mount_options ##### --> -<para> - -</para> - -@drive: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_get_mount_fs ##### --> -<para> - -</para> - -@drive: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_find_all_volumes ##### --> -<para> - -</para> - -@hal_ctx: -@drive: -@num_volumes: @Returns: @@ -547,78 +382,6 @@ libhal-storage </para> -@hal_ctx: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_default_use_managed_keyword ##### --> -<para> - -</para> - -@hal_ctx: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_primary ##### --> -<para> - -</para> - -@hal_ctx: -@Returns: - - -<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_secondary ##### --> -<para> - -</para> - -@hal_ctx: -@Returns: - - -<!-- ##### ENUM LibHalVolumeUsage ##### --> -<para> - -</para> - -@LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM: -@LIBHAL_VOLUME_USAGE_PARTITION_TABLE: -@LIBHAL_VOLUME_USAGE_RAID_MEMBER: -@LIBHAL_VOLUME_USAGE_CRYPTO: -@LIBHAL_VOLUME_USAGE_UNKNOWN: -@LIBHAL_VOLUME_USAGE_OTHER: - -<!-- ##### ENUM LibHalVolumeDiscType ##### --> -<para> - -</para> - -@LIBHAL_VOLUME_DISC_TYPE_CDROM: -@LIBHAL_VOLUME_DISC_TYPE_CDR: -@LIBHAL_VOLUME_DISC_TYPE_CDRW: -@LIBHAL_VOLUME_DISC_TYPE_DVDROM: -@LIBHAL_VOLUME_DISC_TYPE_DVDRAM: -@LIBHAL_VOLUME_DISC_TYPE_DVDR: -@LIBHAL_VOLUME_DISC_TYPE_DVDRW: -@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: -@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: -@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL: -@LIBHAL_VOLUME_DISC_TYPE_BDROM: -@LIBHAL_VOLUME_DISC_TYPE_BDR: -@LIBHAL_VOLUME_DISC_TYPE_BDRE: -@LIBHAL_VOLUME_DISC_TYPE_HDDVDROM: -@LIBHAL_VOLUME_DISC_TYPE_HDDVDR: -@LIBHAL_VOLUME_DISC_TYPE_HDDVDRW: - -<!-- ##### FUNCTION libhal_volume_from_udi ##### --> -<para> - -</para> - -@hal_ctx: -@udi: @Returns: @@ -929,90 +692,3 @@ libhal-storage @Returns: -<!-- ##### FUNCTION libhal_volume_policy_compute_size_as_string ##### --> -<para> - -</para> - -@volume: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_compute_display_name ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_compute_icon_name ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_should_be_visible ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@target_mount_point: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_is_mountable ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_get_desired_mount_point ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_get_mount_options ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - -<!-- ##### FUNCTION libhal_volume_policy_get_mount_fs ##### --> -<para> - -</para> - -@drive: -@volume: -@policy: -@Returns: - - diff --git a/doc/spec/hal-spec-properties.xml b/doc/spec/hal-spec-properties.xml index c3ff5223..77fac0bd 100644 --- a/doc/spec/hal-spec-properties.xml +++ b/doc/spec/hal-spec-properties.xml @@ -2288,9 +2288,7 @@ <entry>partitiontable</entry> <entry></entry> <entry> - The volume contains a partitiontable. If an MS-DOS extended - partition table is found, then <literal>volume.fstype</literal> - will be <literal>msdos_extended_partitiontable</literal>. + The volume contains a partitiontable. </entry> </row> <row> @@ -2315,7 +2313,7 @@ <entry> <literal>volume.fstype</literal> (string) </entry> - <entry>examples: ext3, vfat, msdos_extended_partitiontable</entry> + <entry>examples: ext3, vfat</entry> <entry>Yes (is blank if the type is unknown)</entry> <entry>The specific type of either the file system or what the volume is used for, cf. volume.fsusage</entry> </row> @@ -2405,6 +2403,7 @@ If the volume stems from the Linux Device Mapper this property is set to <literal>TRUE</literal>. </entry> </row> + <row> <entry> <literal>volume.partition.number</literal> (int) @@ -2418,53 +2417,188 @@ The number of the partition. </entry> </row> + + <row> <entry> - <literal>volume.partition.msdos_part_table_type</literal> (int) + <literal>volume.partition.label</literal> (string) </entry> - <entry>examples: 0x83, 0xfd, 0x8e</entry> + <entry></entry> <entry> - No + If, and only if, <literal>volume.is_partition</literal> + is set to <literal>TRUE</literal>. </entry> <entry> - If available, this is the partition type if the disk for which - this volume stems from is using an MS-DOS-style partition table. + Label of partition. Only available for "apm" and "gpt" + partition tables. Note that this is not the same as the + file system label defined in <literal>volume.label</literal>. </entry> </row> <row> <entry> - <literal>volume.partition.msdos_part_table_start</literal> (uint64) + <literal>volume.partition.uuid</literal> (string) </entry> <entry></entry> <entry> - No + If, and only if, <literal>volume.is_partition</literal> + is set to <literal>TRUE</literal>. </entry> <entry> - If available, this is the partition start offset if the disk for which - this volume stems from is using an MS-DOS-style partition table. + The UUID or GUID of the partition table entry. Only available for + "gpt" partition tables. </entry> </row> + <row> <entry> - <literal>volume.partition.msdos_part_table_size</literal> (uint64) + <literal>volume.partition.scheme</literal> (string) </entry> <entry></entry> <entry> - No + If, and only if, <literal>volume.is_partition</literal> + is set to <literal>TRUE</literal>. </entry> <entry> - If available, this is the partition size if the disk for which - this volume stems from is using an MS-DOS-style partition table. - This information is derived from the partition table so it might - not be reliable and match e.g. <literal>volume.size</literal>. - Specifically, for MS-DOS extended partition tables, this number - will be larger as the actual volume is only e.g. 1 kilobyte - (e.g. <literal>volume.size</literal>) while - <literal>volume.partition.msdos_part_table_size</literal> - will be the size enclosing all the logical partitions. + The scheme of the partition table this entry is part of. + Note that this is not necessarily the same as + <literal>storage.partitioning_scheme</literal> as + some partition tables can embed other partition tables. </entry> </row> <row> + <entry></entry> + <entry>mbr</entry> + <entry></entry> + <entry> + Master Boot Record + </entry> + </row> + <row> + <entry></entry> + <entry>embr</entry> + <entry></entry> + <entry> + Extended Master Boot Record + </entry> + </row> + <row> + <entry></entry> + <entry>gpt</entry> + <entry></entry> + <entry> + GUID Partition Table as defined by EFI + </entry> + </row> + <row> + <entry></entry> + <entry>apm</entry> + <entry></entry> + <entry> + Apple Partition Map + </entry> + </row> + + <row> + <entry> + <literal>volume.partition.type</literal> (string) + </entry> + <entry></entry> + <entry> + If, and only if, <literal>volume.is_partition</literal> + is set to <literal>TRUE</literal>. + </entry> + <entry> + The type of the partition table entry. Depends on + <literal>volume.partition.scheme</literal>. + </entry> + </row> + <row> + <entry></entry> + <entry><literal>mbr</literal> and <literal>embr</literal> entries</entry> + <entry></entry> + <entry> + The hexadecimal encoding of the 8-bit partition type, see + http://www.win.tue.nl/~aeb/partitions/partition_types-1.html + for a list. For example the Linux partition type is represented + as the string "0x83". + </entry> + </row> + <row> + <entry></entry> + <entry><literal>gpt</literal> entries</entry> + <entry></entry> + <entry> + The GUID encoded as a string. See http://en.wikipedia.org/wiki/GUID_Partition_Table + for a list of well-known GUID's. + </entry> + </row> + <row> + <entry></entry> + <entry><literal>apm</literal> entries</entry> + <entry></entry> + <entry> + Defined in http://developer.apple.com/documentation/mac/Devices/Devices-126.html. + Also note that for FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" + and "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf. + http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html + </entry> + </row> + + <row> + <entry> + <literal>volume.partition.flags</literal> (strlist) + </entry> + <entry></entry> + <entry> + If, and only if, <literal>volume.is_partition</literal> + is set to <literal>TRUE</literal>. + </entry> + <entry> + Flags conveying specific information about the partition + entry. Dependent on the partitioning scheme. + </entry> + </row> + <row> + <entry></entry> + <entry><literal>mbr</literal> and <literal>embr</literal> entries</entry> + <entry></entry> + <entry> + Only one flag, "boot", is defined. This is used by some BIOS'es and + boot loaders to populate a boot menu. It means that a partition is + bootable. + </entry> + </row> + <row> + <entry></entry> + <entry><literal>gpt</literal> entries</entry> + <entry></entry> + <entry> + Only the flag "required" is recognized. This corresponds to + bit 0 of the attibutes (at offset 48), meaning + "Required for the platform to function. The system cannot + function normally if this partition is removed. This + partition should be considered as part of the hardware of the + system, and if it is removed the system may not boot. It may + contain diagnostics, recovery tools, or other code or data that is + critical to the functioning of a system independent of any OS." + </entry> + </row> + <row> + <entry></entry> + <entry><literal>apm</literal> entries</entry> + <entry></entry> + <entry> + The following flags are recognized: + "allocated" if the partition is already allocated; and + "in_use" if the partition is in use; may be cleared after a system reset; and + "boot" if partition contains valid boot information; and + "allow_read" if partition allows reading; and + "allow_write"; if partition allows writing; and + "boot_code_is_pic"; if boot code is position independent + </entry> + </row> + + <row> <entry> <literal>volume.partition.media_size</literal> (uint64) </entry> @@ -3026,6 +3160,32 @@ </row> <row> <entry> + <literal>storage.partitioning_scheme</literal> (string) + </entry> + <entry></entry> + <entry>Only when media is inserted and is partitioned</entry> + <entry>The partitioning scheme of the media.</entry> + </row> + <row> + <entry></entry> + <entry>mbr</entry> + <entry></entry> + <entry>Master Boot Record partitioning scheme used in most PC's</entry> + </row> + <row> + <entry></entry> + <entry>gpt</entry> + <entry></entry> + <entry>GUID Partitioning Table as defined by UEFI</entry> + </row> + <row> + <entry></entry> + <entry>apm</entry> + <entry></entry> + <entry>Apple Partition Map, used in non-Intel Apple computers</entry> + </row> + <row> + <entry> <literal>storage.size</literal> (uint64) </entry> <entry></entry> diff --git a/doc/spec/hal-spec.html b/doc/spec/hal-spec.html index e77fde13..561d03e9 100644 --- a/doc/spec/hal-spec.html +++ b/doc/spec/hal-spec.html @@ -609,14 +609,24 @@ HREF="#dbus-api" ><DL ><DT ><A -HREF="#AEN4036" +HREF="#AEN4328" >Interface org.freedesktop.Hal.Manager</A ></DT ><DT ><A -HREF="#AEN4055" +HREF="#AEN4347" >Interface org.freedesktop.Hal.Device</A ></DT +><DT +><A +HREF="#AEN4356" +>Interface org.freedesktop.Hal.Device.Volume</A +></DT +><DT +><A +HREF="#AEN4360" +>Interface org.freedesktop.Hal.Device.Storage</A +></DT ></DL ></DD ><DT @@ -3159,6 +3169,120 @@ CLASS="literal" ><TD >SCSI Logical Unit Number</TD ></TR +><TR +><TD +> <TT +CLASS="literal" +>scsi.type</TT +> (string) + </TD +><TD +>Example: disk</TD +><TD +>Yes</TD +><TD +>SCSI device type</TD +></TR +><TR +><TD +> </TD +><TD +>cdrom</TD +><TD +> </TD +><TD +>This is a SCSI cdrom device.</TD +></TR +><TR +><TD +> </TD +><TD +>comm</TD +><TD +> </TD +><TD +>This is a SCSI communication device.</TD +></TR +><TR +><TD +> </TD +><TD +>disk</TD +><TD +> </TD +><TD +>This is a SCSI disk device.</TD +></TR +><TR +><TD +> </TD +><TD +>medium_changer</TD +><TD +> </TD +><TD +>This is a SCSI media changer (e.g. for CD/Tape).</TD +></TR +><TR +><TD +> </TD +><TD +>printer</TD +><TD +> </TD +><TD +>This is a SCSI printer.</TD +></TR +><TR +><TD +> </TD +><TD +>processor</TD +><TD +> </TD +><TD +>This is a SCSI processor device.</TD +></TR +><TR +><TD +> </TD +><TD +>raid</TD +><TD +> </TD +><TD +>This is a SCSI raid device.</TD +></TR +><TR +><TD +> </TD +><TD +>scanner</TD +><TD +> </TD +><TD +>This is a SCSI scanner.</TD +></TR +><TR +><TD +> </TD +><TD +>tape</TD +><TD +> </TD +><TD +>This is a SCSI tape device.</TD +></TR +><TR +><TD +> </TD +><TD +>unknown</TD +><TD +> </TD +><TD +>The type of this SCSI device is unknwon.</TD +></TR ></TBODY ></TABLE ><P @@ -3193,7 +3317,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN804" +NAME="AEN860" ></A ><TABLE BORDER="1" @@ -3318,7 +3442,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN849" +NAME="AEN905" ></A ><TABLE BORDER="1" @@ -3442,7 +3566,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN894" +NAME="AEN950" ></A ><TABLE BORDER="1" @@ -3511,7 +3635,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN915" +NAME="AEN971" ></A ><TABLE BORDER="1" @@ -3580,7 +3704,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN936" +NAME="AEN992" ></A ><TABLE BORDER="1" @@ -3763,7 +3887,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1005" +NAME="AEN1061" ></A ><TABLE BORDER="1" @@ -3953,7 +4077,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1079" +NAME="AEN1135" ></A ><TABLE BORDER="1" @@ -4045,7 +4169,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1111" +NAME="AEN1167" ></A ><TABLE BORDER="1" @@ -4119,7 +4243,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1136" +NAME="AEN1192" ></A ><TABLE BORDER="1" @@ -4230,7 +4354,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1175" +NAME="AEN1231" ></A ><TABLE BORDER="1" @@ -4330,7 +4454,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1209" +NAME="AEN1265" ></A ><TABLE BORDER="1" @@ -4402,7 +4526,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1234" +NAME="AEN1290" ></A ><TABLE BORDER="1" @@ -4687,7 +4811,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1343" +NAME="AEN1399" ></A ><TABLE BORDER="1" @@ -4773,7 +4897,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1374" +NAME="AEN1430" ></A ><TABLE BORDER="1" @@ -4859,7 +4983,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1405" +NAME="AEN1461" ></A ><TABLE BORDER="1" @@ -5016,7 +5140,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1465" +NAME="AEN1521" ></A ><TABLE BORDER="1" @@ -5074,7 +5198,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1484" +NAME="AEN1540" ></A ><TABLE BORDER="1" @@ -5160,7 +5284,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1512" +NAME="AEN1568" ></A ><TABLE BORDER="1" @@ -5339,7 +5463,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1568" +NAME="AEN1624" ></A ><TABLE BORDER="1" @@ -5460,7 +5584,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1606" +NAME="AEN1662" ></A ><TABLE BORDER="1" @@ -5579,15 +5703,7 @@ CLASS="literal" ><TD > </TD ><TD -> The volume contains a partitiontable. If an MS-DOS extended - partition table is found, then <TT -CLASS="literal" ->volume.fstype</TT -> - will be <TT -CLASS="literal" ->msdos_extended_partitiontable</TT ->. +> The volume contains a partitiontable. </TD ></TR ><TR @@ -5628,7 +5744,7 @@ CLASS="literal" > (string) </TD ><TD ->examples: ext3, vfat, msdos_extended_partitiontable</TD +>examples: ext3, vfat</TD ><TD >Yes (is blank if the type is unknown)</TD ><TD @@ -5805,67 +5921,288 @@ CLASS="literal" ><TD > <TT CLASS="literal" ->volume.partition.msdos_part_table_type</TT -> (int) +>volume.partition.label</TT +> (string) </TD ><TD ->examples: 0x83, 0xfd, 0x8e</TD +> </TD ><TD -> No +> If, and only if, <TT +CLASS="literal" +>volume.is_partition</TT +> + is set to <TT +CLASS="literal" +>TRUE</TT +>. </TD ><TD -> If available, this is the partition type if the disk for which - this volume stems from is using an MS-DOS-style partition table. +> Label of partition. Only available for "apm" and "gpt" + partition tables. Note that this is not the same as the + file system label defined in <TT +CLASS="literal" +>volume.label</TT +>. </TD ></TR ><TR ><TD > <TT CLASS="literal" ->volume.partition.msdos_part_table_start</TT -> (uint64) +>volume.partition.uuid</TT +> (string) </TD ><TD > </TD ><TD -> No +> If, and only if, <TT +CLASS="literal" +>volume.is_partition</TT +> + is set to <TT +CLASS="literal" +>TRUE</TT +>. </TD ><TD -> If available, this is the partition start offset if the disk for which - this volume stems from is using an MS-DOS-style partition table. +> The UUID or GUID of the partition table entry. Only available for + "gpt" partition tables. </TD ></TR ><TR ><TD > <TT CLASS="literal" ->volume.partition.msdos_part_table_size</TT -> (uint64) +>volume.partition.scheme</TT +> (string) </TD ><TD > </TD ><TD -> No +> If, and only if, <TT +CLASS="literal" +>volume.is_partition</TT +> + is set to <TT +CLASS="literal" +>TRUE</TT +>. </TD ><TD -> If available, this is the partition size if the disk for which - this volume stems from is using an MS-DOS-style partition table. - This information is derived from the partition table so it might - not be reliable and match e.g. <TT +> The scheme of the partition table this entry is part of. + Note that this is not necessarily the same as + <TT CLASS="literal" ->volume.size</TT ->. - Specifically, for MS-DOS extended partition tables, this number - will be larger as the actual volume is only e.g. 1 kilobyte - (e.g. <TT +>storage.partitioning_scheme</TT +> as + some partition tables can embed other partition tables. + </TD +></TR +><TR +><TD +> </TD +><TD +>mbr</TD +><TD +> </TD +><TD +> Master Boot Record + </TD +></TR +><TR +><TD +> </TD +><TD +>embr</TD +><TD +> </TD +><TD +> Extended Master Boot Record + </TD +></TR +><TR +><TD +> </TD +><TD +>gpt</TD +><TD +> </TD +><TD +> GUID Partition Table as defined by EFI + </TD +></TR +><TR +><TD +> </TD +><TD +>apm</TD +><TD +> </TD +><TD +> Apple Partition Map + </TD +></TR +><TR +><TD +> <TT CLASS="literal" ->volume.size</TT ->) while +>volume.partition.type</TT +> (string) + </TD +><TD +> </TD +><TD +> If, and only if, <TT +CLASS="literal" +>volume.is_partition</TT +> + is set to <TT +CLASS="literal" +>TRUE</TT +>. + </TD +><TD +> The type of the partition table entry. Depends on <TT CLASS="literal" ->volume.partition.msdos_part_table_size</TT +>volume.partition.scheme</TT +>. + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>mbr</TT +> and <TT +CLASS="literal" +>embr</TT +> entries</TD +><TD +> </TD +><TD +> The hexadecimal encoding of the 8-bit partition type, see + http://www.win.tue.nl/~aeb/partitions/partition_types-1.html + for a list. For example the Linux partition type is represented + as the string "0x83". + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>gpt</TT +> entries</TD +><TD +> </TD +><TD +> The GUID encoded as a string. See http://en.wikipedia.org/wiki/GUID_Partition_Table + for a list of well-known GUID's. + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>apm</TT +> entries</TD +><TD +> </TD +><TD +> Defined in http://developer.apple.com/documentation/mac/Devices/Devices-126.html. + Also note that for FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" + and "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf. + http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>volume.partition.flags</TT +> (strlist) + </TD +><TD +> </TD +><TD +> If, and only if, <TT +CLASS="literal" +>volume.is_partition</TT > - will be the size enclosing all the logical partitions. + is set to <TT +CLASS="literal" +>TRUE</TT +>. + </TD +><TD +> Flags conveying specific information about the partition + entry. Dependent on the partitioning scheme. + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>mbr</TT +> and <TT +CLASS="literal" +>embr</TT +> entries</TD +><TD +> </TD +><TD +> Only one flag, "boot", is defined. This is used by some BIOS'es and + boot loaders to populate a boot menu. It means that a partition is + bootable. + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>gpt</TT +> entries</TD +><TD +> </TD +><TD +> Only the flag "required" is recognized. This corresponds to + bit 0 of the attibutes (at offset 48), meaning + "Required for the platform to function. The system cannot + function normally if this partition is removed. This + partition should be considered as part of the hardware of the + system, and if it is removed the system may not boot. It may + contain diagnostics, recovery tools, or other code or data that is + critical to the functioning of a system independent of any OS." + </TD +></TR +><TR +><TD +> </TD +><TD +><TT +CLASS="literal" +>apm</TT +> entries</TD +><TD +> </TD +><TD +> The following flags are recognized: + "allocated" if the partition is already allocated; and + "in_use" if the partition is in use; may be cleared after a system reset; and + "boot" if partition contains valid boot information; and + "allow_read" if partition allows reading; and + "allow_write"; if partition allows writing; and + "boot_code_is_pic"; if boot code is position independent </TD ></TR ><TR @@ -5928,7 +6265,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1781" +NAME="AEN1915" ></A ><TABLE BORDER="1" @@ -6068,7 +6405,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1824" +NAME="AEN1958" ></A ><TABLE BORDER="1" @@ -6242,7 +6579,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN1882" +NAME="AEN2016" ></A ><TABLE BORDER="1" @@ -6624,7 +6961,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2043" +NAME="AEN2177" ></A ><TABLE BORDER="1" @@ -6874,6 +7211,64 @@ CLASS="literal" ><TD > <TT CLASS="literal" +>storage.removable.media_size</TT +> (uint64) + </TD +><TD +> </TD +><TD +>Yes</TD +><TD +>Size of media in storage device. Available only if media have been detected in storage device.</TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>storage.partitioning_scheme</TT +> (string) + </TD +><TD +> </TD +><TD +>Only when media is inserted and is partitioned</TD +><TD +>The partitioning scheme of the media.</TD +></TR +><TR +><TD +> </TD +><TD +>mbr</TD +><TD +> </TD +><TD +>Master Boot Record partitioning scheme used in most PC's</TD +></TR +><TR +><TD +> </TD +><TD +>gpt</TD +><TD +> </TD +><TD +>GUID Partitioning Table as defined by UEFI</TD +></TR +><TR +><TD +> </TD +><TD +>apm</TD +><TD +> </TD +><TD +>Apple Partition Map, used in non-Intel Apple computers</TD +></TR +><TR +><TD +> <TT +CLASS="literal" >storage.size</TT > (uint64) </TD @@ -7153,7 +7548,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2249" +NAME="AEN2410" ></A ><TABLE BORDER="1" @@ -7487,7 +7882,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2383" +NAME="AEN2544" ></A ><TABLE BORDER="1" @@ -7647,7 +8042,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2441" +NAME="AEN2602" ></A ><TABLE BORDER="1" @@ -7783,7 +8178,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2483" +NAME="AEN2644" ></A ><TABLE BORDER="1" @@ -7855,7 +8250,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2505" +NAME="AEN2666" ></A ><TABLE BORDER="1" @@ -7921,7 +8316,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2525" +NAME="AEN2686" ></A ><TABLE BORDER="1" @@ -7985,7 +8380,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2545" +NAME="AEN2706" ></A ><TABLE BORDER="1" @@ -8129,7 +8524,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2595" +NAME="AEN2756" ></A ><TABLE BORDER="1" @@ -8344,7 +8739,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2667" +NAME="AEN2828" ></A ><TABLE BORDER="1" @@ -8455,6 +8850,89 @@ CLASS="literal" ><TD > <TT CLASS="literal" +>alsa.device_pcm_class</TT +> (string) + </TD +><TD +> </TD +><TD +>Yes</TD +><TD +> The PCM class of the device. + </TD +></TR +><TR +><TD +> </TD +><TD +>generic</TD +><TD +> </TD +><TD +> A standard PCM sound device (SND_PCM_CLASS_GENERIC). + </TD +></TR +><TR +><TD +> </TD +><TD +>multi</TD +><TD +> </TD +><TD +> A multichannel device PCM sound device (SND_PCM_CLASS_MULTI) which + e.g. contains a generic and a modem device. + </TD +></TR +><TR +><TD +> </TD +><TD +>digitizer</TD +><TD +> </TD +><TD +> A PCM digitizer device (SND_PCM_CLASS_DIGITIZER). + </TD +></TR +><TR +><TD +> </TD +><TD +>modem</TD +><TD +> </TD +><TD +> A PCM modem device (SND_PCM_CLASS_MODEM). + </TD +></TR +><TR +><TD +> </TD +><TD +>unknown</TD +><TD +> </TD +><TD +> The value is 'unknown' if the kernel provide no information about the + PCM device class of the device (e.g. the file pcm_class is missing). + </TD +></TR +><TR +><TD +> </TD +><TD +>none</TD +><TD +> </TD +><TD +> The value is 'none' if this there is no PCM class for this device. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" >alsa.physical_device</TT > (string) </TD @@ -8608,7 +9086,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2763" +NAME="AEN2960" ></A ><TABLE BORDER="1" @@ -8860,7 +9338,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2852" +NAME="AEN3049" ></A ><TABLE BORDER="1" @@ -8981,7 +9459,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2894" +NAME="AEN3091" ></A ><TABLE BORDER="1" @@ -9069,7 +9547,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2923" +NAME="AEN3120" ></A ><TABLE BORDER="1" @@ -9166,7 +9644,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN2951" +NAME="AEN3148" ></A ><TABLE BORDER="1" @@ -9316,7 +9794,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3010" +NAME="AEN3207" ></A ><TABLE BORDER="1" @@ -9396,7 +9874,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3036" +NAME="AEN3233" ></A ><TABLE BORDER="1" @@ -9463,7 +9941,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3056" +NAME="AEN3253" ></A ><TABLE BORDER="1" @@ -10325,7 +10803,7 @@ CLASS="literal" ><TD > <TT CLASS="literal" ->battery.technology</TT +>battery.reporting.technology</TT > (string) </TD ><TD @@ -10333,7 +10811,30 @@ CLASS="literal" ><TD >No</TD ><TD -> The technology of the battery. +> The technology of the battery as reported by the hardware. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>battery.technology</TT +> (string) + </TD +><TD +> lead-acid, lithium-ion, lithium-polymer, + nickel-metal-hydride, unknown + </TD +><TD +>No</TD +><TD +> The technology of the battery processed to a few standard types. + This key is needed as the hardware often does not specify the + description text for a battery, and so we have to calculate it + from the output of <TT +CLASS="literal" +>battery.reporting.technology</TT +>. </TD ></TR ><TR @@ -10381,7 +10882,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3374" +NAME="AEN3578" ></A ><TABLE BORDER="1" @@ -10496,7 +10997,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3418" +NAME="AEN3622" ></A ><TABLE BORDER="1" @@ -10564,7 +11065,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3439" +NAME="AEN3643" ></A ><TABLE BORDER="1" @@ -10659,7 +11160,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3471" +NAME="AEN3675" ></A ><TABLE BORDER="1" @@ -10771,7 +11272,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3513" +NAME="AEN3717" ></A ><TABLE BORDER="1" @@ -10910,7 +11411,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3569" +NAME="AEN3773" ></A ><TABLE BORDER="1" @@ -11048,7 +11549,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3613" +NAME="AEN3817" ></A ><TABLE BORDER="1" @@ -11112,6 +11613,277 @@ CLASS="literal" ><P ></P ></DIV +><P +> The following methods exist on the interface + <TT +CLASS="literal" +>org.freedesktop.Hal.Device.CPUFreq</TT +>. + </P +><DIV +CLASS="informaltable" +><P +></P +><A +NAME="AEN3840" +></A +><TABLE +BORDER="1" +BGCOLOR="#E0E0E0" +CELLSPACING="0" +CELLPADDING="4" +CLASS="CALSTABLE" +><THEAD +><TR +><TH +>Method (parameter types)</TH +><TH +>Parameters</TH +><TH +>Mandatory</TH +><TH +>Description</TH +></TR +></THEAD +><TBODY +><TR +><TD +> <TT +CLASS="literal" +>SetCPUFreqGovernor</TT +> (string) + </TD +><TD +> The name of the governor to set. Get a list of available governors + with the GetCPUFreqAvailableGovernors method. + </TD +><TD +>No</TD +><TD +> Sets a CPU frequency scaling governor for all CPUFreq + interfaces the kernel provides. If the userspace governor + is set, this interface also contains a proper scaling + mechanism. The default performance is set to 50. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>SetCPUFreqPerformance</TT +> (integer) + </TD +><TD +> The performance between 1 and 100 to set in dynamic scaling modes. + </TD +><TD +>No</TD +><TD +> Sets the performance of the dynamic scaling mechanism. This method + summarizes and abstracts all the different settings which can be taken + for dynamic frequency adjustments, like at which load to switch up + frequency or how many steps the mechanism should traverse until + reaching the maximum frequency. The higher the value, the more + performance you get. Respectively, the higher the value, the sooner + and the more often the frequency is switched up. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>SetCPUFreqConsiderNice</TT +> (boolean) + </TD +><TD +> Whether or not niced processes should be considered on CPU + load calculation. + </TD +><TD +>No</TD +><TD +> Whether or not niced processes should be considered on CPU + load calculation. If niced processes are considered, they can cause a + frequency increment although their absolute load percentage wouldn't + trigger the scaling mechanism to switch up the frequency. The default + setting is 'false'. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>GetCPUFreqGovernor</TT +> (void) + </TD +><TD +> </TD +><TD +>No</TD +><TD +> Get the current active governor for all CPU frequency interfaces (string). + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>GetCPUFreqPerformance</TT +> (void) + </TD +><TD +> </TD +><TD +>No</TD +><TD +> Get the current active performance setting if a dynamic scaling + mechanism is in use (integer between 1 and 100). + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>GetCPUFreqConsiderNice</TT +> (void) + </TD +><TD +> </TD +><TD +>No</TD +><TD +> Returns whether niced processed are considered during CPU load + calculation or not (returns boolean). + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>GetCPUFreqAvailableGovernors</TT +> (void) + </TD +><TD +> </TD +><TD +>No</TD +><TD +> Returns a list of strings of all available governors which + could be set with the SetCPUFreqGovernor method. + </TD +></TR +></TBODY +></TABLE +><P +></P +></DIV +><P +> The following errors maybe raised on the interface + <TT +CLASS="literal" +>org.freedesktop.Hal.Device.CPUFreq</TT +>. + </P +><DIV +CLASS="informaltable" +><P +></P +><A +NAME="AEN3893" +></A +><TABLE +BORDER="1" +BGCOLOR="#E0E0E0" +CELLSPACING="0" +CELLPADDING="4" +CLASS="CALSTABLE" +><THEAD +><TR +><TH +>Error</TH +><TH +>Description</TH +><TH +>Detail field</TH +></TR +></THEAD +><TBODY +><TR +><TD +> <TT +CLASS="literal" +>GeneralError</TT +> + </TD +><TD +> A general error occured. + </TD +><TD +> The exact error. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>UnknownGovernor</TT +> + </TD +><TD +> The governor which was tried to be set doesn't exist. + </TD +><TD +> The governor which was tried be to set. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>PermissionDenied</TT +> + </TD +><TD +> The caller doesn't have the privilege to execute this + method. + </TD +><TD +> The privilege the caller needs to execute the method. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>NoSuitableGovernor</TT +> + </TD +><TD +> The method executed doesn't exist for the current active governor. + </TD +><TD +> The method which was tried to be executed. + </TD +></TR +><TR +><TD +> <TT +CLASS="literal" +>GovernorInitFailed</TT +> + </TD +><TD +> The initialization of the governor failed. + </TD +><TD +> The reason for the failure. + </TD +></TR +></TBODY +></TABLE +><P +></P +></DIV ></DIV ><DIV CLASS="sect2" @@ -11136,7 +11908,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3639" +NAME="AEN3931" ></A ><TABLE BORDER="1" @@ -11229,7 +12001,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3667" +NAME="AEN3959" ></A ><TABLE BORDER="1" @@ -11397,7 +12169,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3719" +NAME="AEN4011" ></A ><TABLE BORDER="1" @@ -11532,7 +12304,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3760" +NAME="AEN4052" ></A ><TABLE BORDER="1" @@ -11795,7 +12567,7 @@ CLASS="literal" > <TT CLASS="literal" >empty</TT -> - can only be used on string properties +> - can only be used on string or strlist properties with 'true' and 'false'. The semantics for 'true' is to match only when the string is non-empty. </P @@ -12014,7 +12786,7 @@ CLASS="literal" string list. For example to remove item 'bla' from property 'foo.bar': <TT CLASS="literal" -><remove key="foo.bar" type="strlist">bla</merge></TT +><remove key="foo.bar" type="strlist">bla</remove></TT > </P ><P @@ -12178,7 +12950,7 @@ WIDTH="100%" ><TD ><PRE CLASS="programlisting" -> <?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- --> +> <?xml version="1.0" encoding="UTF-8"?> <!-- Example: This device information file matches an USB Mass Storage based MP3 player by the matching on the USB vendor and product identifiers. --> @@ -12226,7 +12998,7 @@ WIDTH="100%" ><TD ><PRE CLASS="programlisting" -> <?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- --> +> <?xml version="1.0" encoding="UTF-8"?> <!-- Example: This device information file matches a Sony digital still camera by matching on the USB vendor and product identifers. --> @@ -12272,7 +13044,7 @@ WIDTH="100%" ><TD ><PRE CLASS="programlisting" -> <?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- --> +> <?xml version="1.0" encoding="UTF-8"?> <!-- Example: This device information file matches a memory card reader with multiple storage ports that can be active at the same time. --> @@ -12393,7 +13165,7 @@ WIDTH="100%" ><TD ><PRE CLASS="programlisting" -> <?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- --> +> <?xml version="1.0" encoding="UTF-8"?> <deviceinfo version="0.2"> @@ -12477,7 +13249,7 @@ CLASS="informaltable" ><P ></P ><A -NAME="AEN3994" +NAME="AEN4286" ></A ><TABLE BORDER="1" @@ -12640,7 +13412,7 @@ CLASS="sect2" ><HR><H3 CLASS="sect2" ><A -NAME="AEN4036" +NAME="AEN4328" >Interface org.freedesktop.Hal.Manager</A ></H3 ><P @@ -12744,7 +13516,7 @@ CLASS="sect3" ><HR><H4 CLASS="sect3" ><A -NAME="AEN4047" +NAME="AEN4339" >Example</A ></H4 ><P @@ -12853,7 +13625,7 @@ CLASS="sect2" ><HR><H3 CLASS="sect2" ><A -NAME="AEN4055" +NAME="AEN4347" >Interface org.freedesktop.Hal.Device</A ></H3 ><P @@ -12999,6 +13771,109 @@ void Condition(string condition, ...) signals for only a subset of the devices available. </P ></DIV +><DIV +CLASS="sect2" +><HR><H3 +CLASS="sect2" +><A +NAME="AEN4356" +>Interface org.freedesktop.Hal.Device.Volume</A +></H3 +><P +> The org.freedesktop.Hal.Device.Volume interface is used on objects + with the "volume" capability. This interface has the following methods. + </P +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><PRE +CLASS="programlisting" +> # Mount volume +# +# @param mountpoint Desired mount point. If NULL, will be generated based on label. +# @param fstype Filesystem type +# @param options Mount options +# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice +# org.freedesktop.Hal.Device.Volume.PermissionDenied +# org.freedesktop.Hal.Device.Volume.AlreadyMounted +# org.freedesktop.Hal.Device.Volume.InvalidMountOption +# org.freedesktop.Hal.Device.Volume.UnknownFilesystemType +# org.freedesktop.Hal.Device.Volume.InvalidMountpoint +# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable +# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy +# +void Mount(string mountpoint, string fstype, array{string} options) +# Unmount volume +# +# @param options Unmount options +# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice +# org.freedesktop.Hal.Device.Volume.PermissionDenied +# org.freedesktop.Hal.Device.Volume.InvalidUnmountOption +# org.freedesktop.Hal.Device.Volume.InvalidMountpoint +# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable +# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy +# +void Unmount(array{string} options) +# Eject volume +# +# @param ejectoptions Eject options +# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice +# org.freedesktop.Hal.Device.Volume.PermissionDenied +# org.freedesktop.Hal.Device.Volume.InvalidEjectOption +# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy +# +void Eject(array{string} options) + </PRE +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="sect2" +><HR><H3 +CLASS="sect2" +><A +NAME="AEN4360" +>Interface org.freedesktop.Hal.Device.Storage</A +></H3 +><P +> The org.freedesktop.Hal.Device.Storage interface is used on objects + with the "storage" capability. This interface has the following methods. + </P +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><PRE +CLASS="programlisting" +> # Eject media +# +# @param ejectoptions Eject options +# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice +# org.freedesktop.Hal.Device.Storage.PermissionDenied +# org.freedesktop.Hal.Device.Storage.InvalidEjectOption +# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy +# +void Eject(array{string} options) +# Close media tray +# +# @param closetrayoptions Close tray options +# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice +# org.freedesktop.Hal.Device.Storage.PermissionDenied +# org.freedesktop.Hal.Device.Storage.InvalidCloseTrayOption +# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy +# +void CloseTray(array{string} options) + </PRE +></TD +></TR +></TABLE +></DIV ></DIV ><DIV CLASS="sect1" diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c index 1660abcd..5d848c54 100644 --- a/hald/linux/addons/addon-storage.c +++ b/hald/linux/addons/addon-storage.c @@ -427,7 +427,9 @@ main (int argc, char *argv[]) DBusError error; HAL_DEBUG (("Media removal detected on %s", device_file)); - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error); + libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL); + libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL); + /* attempt to unmount all childs */ unmount_childs (ctx, udi); @@ -449,7 +451,10 @@ main (int argc, char *argv[]) DBusError error; HAL_DEBUG (("Media insertion detected on %s", device_file)); - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error); /* our probe will trigger the appropriate hotplug events */ + + /* our probe will trigger the appropriate hotplug events */ + libhal_device_set_property_bool ( + ctx, udi, "storage.removable.media_available", TRUE, NULL); /* could have a fs on the main block device; do a rescan to add it */ dbus_error_init (&error); diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c index 8fbe0845..3061424b 100644 --- a/hald/linux/blockdev.c +++ b/hald/linux/blockdev.c @@ -780,7 +780,6 @@ hotplug_event_begin_add_blockdev (const gchar *sysfs_path, const gchar *device_f hal_device_property_set_string (d, "storage.physical_device", parent->udi); hal_device_property_set_bool (d, "storage.removable", TRUE); hal_device_property_set_bool (d, "storage.removable.media_available", FALSE); - hal_device_property_set_uint64 (d, "storage.removable.media_size", 0); hal_device_property_set_bool (d, "storage.hotpluggable", FALSE); hal_device_property_set_bool (d, "storage.requires_eject", FALSE); hal_device_property_set_uint64 (d, "storage.size", 0); @@ -924,7 +923,6 @@ hotplug_event_begin_add_blockdev (const gchar *sysfs_path, const gchar *device_f } hal_device_property_set_bool (d, "storage.removable.media_available", FALSE); - hal_device_property_set_uint64 (d, "storage.removable.media_size", 0); hal_device_property_set_bool (d, "storage.removable", is_removable); /* set storage.size only if we have fixed media */ if (!is_removable) { diff --git a/hald/linux/probing/Makefile.am b/hald/linux/probing/Makefile.am index a66d858b..5b2d3c23 100644 --- a/hald/linux/probing/Makefile.am +++ b/hald/linux/probing/Makefile.am @@ -30,10 +30,10 @@ hald_probe_serial_SOURCES = probe-serial.c ../../logger.c hald_probe_serial_LDADD = $(top_builddir)/libhal/libhal.la hald_probe_storage_SOURCES = probe-storage.c linux_dvd_rw_utils.c linux_dvd_rw_utils.h ../../logger.c -hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ @VOLUME_ID_LIBS@ +hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/partutil/libpartutil.la @GLIB_LIBS@ @VOLUME_ID_LIBS@ hald_probe_pc_floppy_SOURCES = probe-pc-floppy.c ../../logger.c hald_probe_volume_SOURCES = probe-volume.c linux_dvd_rw_utils.c ../../logger.c -hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ @VOLUME_ID_LIBS@ +hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/partutil/libpartutil.la @GLIB_LIBS@ @VOLUME_ID_LIBS@ diff --git a/hald/linux/probing/probe-storage.c b/hald/linux/probing/probe-storage.c index 7b84a642..9a6b860a 100644 --- a/hald/linux/probing/probe-storage.c +++ b/hald/linux/probing/probe-storage.c @@ -46,6 +46,7 @@ #include <libvolume_id.h> #include "libhal/libhal.h" +#include "partutil/partutil.h" #include "linux_dvd_rw_utils.h" #include "../../logger.h" @@ -57,7 +58,7 @@ static void vid_log(int priority, const char *file, int line, const char *format va_start(args, format); vsnprintf(log_str, sizeof(log_str), format, args); - logger_forward_debug("%s:%i %s", file, line, log_str); + logger_forward_debug("%s:%i %s\n", file, line, log_str); va_end(args); } @@ -95,6 +96,62 @@ out: return rc; } +#define BSIZE 0x200 +#define MSDOS_MAGIC "\x55\xaa" +#define MSDOS_SIG_OFF 0x01fe +#define MSDOS_PARTTABLE_OFFSET 0x01be + +#define MAC_MAGIC "\x45\x52" +#define MAC_SIG_OFF 0x0000 + +enum { + PART_TABLE_UNKNOWN, + PART_TABLE_MBR, + PART_TABLE_APM, + PART_TABLE_GPT +}; + +/* Detect partition table scheme */ +static int +probe_for_part_scheme (LibHalChangeSet *changeset, int fd) +{ + int res; + const uint8_t buf[BSIZE]; + + res = PART_TABLE_UNKNOWN; + + if (lseek(fd, 0, SEEK_SET) < 0) { + dbg("lseek failed (%s)", strerror(errno)); + goto out; + } + if (read(fd, &buf, BSIZE) < BSIZE) { + dbg("read failed (%s)", strerror(errno)); + goto out; + } + + if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) == 0) { + /* if the first partition have type 0xee, it's a GUID Partitioning Table */ + if (buf[MSDOS_PARTTABLE_OFFSET + 4] == 0xee) { + dbg("foo1"); + res = PART_TABLE_GPT; + } else { + dbg("foo2"); + res = PART_TABLE_MBR; + } + goto out; + } + + if (memcmp(&buf[MAC_SIG_OFF], MAC_MAGIC, 2) == 0) { + dbg("foo3"); + res = PART_TABLE_APM; + goto out; + } + + +out: + return res; +} + int main (int argc, char *argv[]) { @@ -108,6 +165,8 @@ main (int argc, char *argv[]) char *drive_type; char *sysfs_path; dbus_bool_t only_check_for_fs; + LibHalChangeSet *cs; + fd = -1; @@ -139,6 +198,12 @@ main (int argc, char *argv[]) if ((ctx = libhal_ctx_init_direct (&error)) == NULL) goto out; + cs = libhal_device_new_changeset (udi); + if (cs == NULL) { + HAL_DEBUG(("Cannot initialize changeset")); + goto out; + } + HAL_DEBUG (("Doing probe-storage for %s (bus %s) (drive_type %s) (udi=%s) (--only-check-for-fs==%d)", device_file, bus, drive_type, udi, only_check_for_fs)); @@ -169,83 +234,85 @@ main (int argc, char *argv[]) goto out; } - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdr", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdrw", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvd", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdr", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdrw", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdram", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusr", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrw", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrwdl", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrdl", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bd", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bdr", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bdre", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvd", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvdr", FALSE, &error); - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvdrw", FALSE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrwdl", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE); + libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE); if (capabilities & CDC_CD_R) { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdr", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE); } if (capabilities & CDC_CD_RW) { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdrw", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE); } if (capabilities & CDC_DVD) { int profile; - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvd", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE); profile = get_dvd_r_rw_profile (fd); HAL_DEBUG (("get_dvd_r_rw_profile returned: %d", profile)); if (profile & DRIVE_CDROM_CAPS_DVDRW) - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdrw", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE); if (profile & DRIVE_CDROM_CAPS_DVDPLUSR) - libhal_device_set_property_bool(ctx, udi, "storage.cdrom.dvdplusr", TRUE, &error); + libhal_changeset_set_property_bool(cs, "storage.cdrom.dvdplusr", TRUE); if (profile & DRIVE_CDROM_CAPS_DVDPLUSRW) - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrw", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE); if (profile & DRIVE_CDROM_CAPS_DVDPLUSRWDL) - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrwdl", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrwdl", TRUE); if (profile & DRIVE_CDROM_CAPS_DVDPLUSRDL) - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrdl", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE); } if (capabilities & CDC_DVD_R) { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdr", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE); } if (capabilities & CDC_DVD_RAM) { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdram", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE); } /* while we're at it, check if we support media changed */ if (capabilities & CDC_MEDIA_CHANGED) { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.support_media_changed", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE); } else { - libhal_device_set_property_bool (ctx, udi, "storage.cdrom.support_media_changed", FALSE, &error); + libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", FALSE); } if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) { - libhal_device_set_property_int (ctx, udi, "storage.cdrom.read_speed", read_speed, &error); + libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed); if (write_speed > 0) { - libhal_device_set_property_int (ctx, udi, "storage.cdrom.write_speed", write_speed, &error); + libhal_changeset_set_property_int ( + cs, "storage.cdrom.write_speed", write_speed); + if (write_speeds != NULL) { gchar **wspeeds; - int i; - wspeeds = g_strsplit_set (write_speeds, ",", -1); - for (i = 0 ; wspeeds[i] != NULL; i++) { - if (strlen (wspeeds[i]) > 0) - libhal_device_property_strlist_append (ctx, udi, "storage.cdrom.write_speeds", wspeeds[i], &error); - } + wspeeds = g_strsplit_set (write_speeds, ",", -1); + libhal_changeset_set_property_strlist (cs, + "storage.cdrom.write_speeds", + (const char **) wspeeds); + g_strfreev (wspeeds); free (write_speeds); } - } - else - libhal_device_set_property_int (ctx, udi, "storage.cdrom.write_speed", 0, &error); + } else { + libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", 0); + libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", NULL); + } } - + close (fd); } @@ -331,13 +398,13 @@ main (int argc, char *argv[]) if (got_media) { uint64_t size; ret = 2; - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.removable.media_available", TRUE); if (ioctl (fd, BLKGETSIZE64, &size) == 0) { HAL_DEBUG (("media size = %llu", size)); - libhal_device_set_property_uint64 (ctx, udi, "storage.removable.media_size", size, &error); + libhal_changeset_set_property_uint64 (cs, "storage.removable.media_size", size); } } else { - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error); + libhal_changeset_set_property_bool (cs, "storage.removable.media_available", FALSE); } close (fd); @@ -360,18 +427,18 @@ main (int argc, char *argv[]) if (fd < 0) { HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno))); /* no media */ - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error); + libhal_changeset_set_property_bool (cs, "storage.removable.media_available", FALSE); goto out; } HAL_DEBUG (("Returned from open(2)")); /* if we get to here, we have media */ - libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error); + libhal_changeset_set_property_bool (cs, "storage.removable.media_available", TRUE); if (ioctl (fd, BLKGETSIZE64, &size) != 0) size = 0; - libhal_device_set_property_uint64 (ctx, udi, "storage.removable.media_size", size, &error); + libhal_changeset_set_property_uint64 (cs, "storage.removable.media_size", size); /* if the kernel has created partitions, we don't look for a filesystem */ main_device = strrchr (sysfs_path, '/'); @@ -387,13 +454,30 @@ main (int argc, char *argv[]) while ((partition = g_dir_read_name (dir)) != NULL) { if (strncmp (main_device, partition, main_device_len) == 0 && isdigit (partition[main_device_len])) { + PartitionTable *p; + HAL_DEBUG (("partition %s found, skip probing for filesystem", partition)); g_dir_close (dir); + + /* probe for partition table type */ + p = part_table_load_from_disk (device_file); + if (p != NULL) { + + libhal_changeset_set_property_string ( + cs, + "storage.partitioning_scheme", + part_get_scheme_name (part_table_get_scheme (p))); + + part_table_free (p); + } + goto out; } } g_dir_close (dir); + libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", "none"); + /* probe for file system */ vid = volume_id_open_fd (fd); if (vid != NULL) { @@ -416,6 +500,10 @@ main (int argc, char *argv[]) } out: + if (cs != NULL) { + libhal_device_commit_changeset (ctx, cs, &error); + libhal_device_free_changeset (cs); + } if (ctx != NULL) { dbus_error_init (&error); diff --git a/hald/linux/probing/probe-volume.c b/hald/linux/probing/probe-volume.c index 8a57e525..3b6b00b1 100644 --- a/hald/linux/probing/probe-volume.c +++ b/hald/linux/probing/probe-volume.c @@ -44,6 +44,7 @@ #include <libvolume_id.h> #include "libhal/libhal.h" +#include "partutil/partutil.h" #include "linux_dvd_rw_utils.h" #include "../../logger.h" @@ -54,7 +55,7 @@ static void vid_log(int priority, const char *file, int line, const char *format va_start(args, format); vsnprintf(log_str, sizeof(log_str), format, args); - logger_forward_debug("%s:%i %s", file, line, log_str); + logger_forward_debug("%s:%i %s\n", file, line, log_str); va_end(args); } @@ -85,156 +86,9 @@ strdup_valid_utf8 (const char *str) return newstr; } -/* probe_msdos_part_table: return array of partiton type numbers */ -#define BSIZE 0x200 -#define MSDOS_MAGIC "\x55\xaa" -#define MSDOS_PARTTABLE_OFFSET 0x1be -#define MSDOS_SIG_OFF 0x1fe -#define DOS_EXTENDED_PARTITION 0x05 -#define LINUX_EXTENDED_PARTITION 0x85 -#define WIN98_EXTENDED_PARTITION 0x0f -#define is_extended(type) \ - (type == DOS_EXTENDED_PARTITION || \ - type == WIN98_EXTENDED_PARTITION || \ - type == LINUX_EXTENDED_PARTITION) - -struct msdos_part_entry { - uint8_t part_type; - uint64_t start; - uint64_t size; -}; - -static struct msdos_part_entry * -probe_msdos_part_table(int fd) -{ - static struct msdos_part_entry partition_id_index[256]; - unsigned int partition_count; - const uint8_t buf[BSIZE]; - int i; - uint64_t poff; - uint64_t plen; - uint64_t extended = 0; - uint64_t next; - int limit; - int empty = 1; - struct msdos_partition_entry { - uint8_t boot_ind; - uint8_t head; - uint8_t sector; - uint8_t cyl; - uint8_t sys_ind; - uint8_t end_head; - uint8_t end_sector; - uint8_t end_cyl; - uint32_t start_sect; - uint32_t nr_sects; - } __attribute__((packed)) *part; - - if (lseek(fd, 0, SEEK_SET) < 0) { - HAL_DEBUG (("lseek failed (%s)", strerror(errno))); - return NULL; - } - if (read(fd, &buf, BSIZE) < BSIZE) { - HAL_DEBUG (("read failed (%s)", strerror(errno))); - return NULL; - } - if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) - return NULL; - - part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; - /* check flags on all entries for a valid partition table */ - for (i = 0; i < 4; i++) { - if (part[i].boot_ind != 0 && - part[i].boot_ind != 0x80) - return NULL; - - if (GINT32_FROM_LE(part[i].nr_sects) != 0) - empty = 0; - } - if (empty == 1) - return NULL; - - memset(partition_id_index, 0x00, sizeof(partition_id_index)); - - for (i = 0; i < 4; i++) { - poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE; - plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE; - - if (plen == 0) - continue; - - partition_id_index[i].part_type = part[i].sys_ind; - partition_id_index[i].start = poff; - partition_id_index[i].size = plen; - HAL_DEBUG (("part %d -> type=%d off=%lld size=%lld", i, part[i].sys_ind, poff, plen)); - - if (is_extended(part[i].sys_ind)) { - HAL_DEBUG (("found extended partition at 0x%llx", (unsigned long long) poff)); - if (extended == 0) - extended = poff; - } else { - HAL_DEBUG (("found 0x%x primary data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen)); - } - } - - /* follow extended partition chain and add data partitions */ - partition_count = 4; - limit = 255; - next = extended; - while (next != 0) { - uint64_t oldnext; - - if (limit-- == 0) { - HAL_DEBUG(("extended chain limit reached")); - break; - } - - HAL_DEBUG (("read 0x%llx (%llu)", next, next)); - if (lseek(fd, next, SEEK_SET) < 0) { - HAL_DEBUG(("lseek failed (%s)", strerror(errno))); - return NULL; - } - if (read(fd, &buf, BSIZE) < BSIZE) { - HAL_DEBUG(("read failed (%s)", strerror(errno))); - return NULL; - } - if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) - break; - - oldnext = next; - next = 0; - - part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; - for (i = 0; i < 4; i++) { - poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE; - plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE; - - if (plen == 0) - continue; - - if (is_extended(part[i].sys_ind)) { - HAL_DEBUG(("found extended partition (chain) at 0x%llx", (unsigned long long) poff)); - if (next == 0) - next = extended + poff; - } else { - HAL_DEBUG(("found 0x%x logical data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen)); - - partition_id_index[partition_count].part_type = part[i].sys_ind; - partition_id_index[partition_count].start = oldnext + poff; - partition_id_index[partition_count].size = plen; - - partition_count++; - } - } - } - - return partition_id_index; -} static void -set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *changes, struct volume_id *vid) +set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *cs, struct volume_id *vid) { char buf[256]; const char *usage; @@ -257,47 +111,47 @@ set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan usage = "crypto"; break; case VOLUME_ID_UNUSED: - libhal_changeset_set_property_string (changes, "info.product", "Volume (unused)"); + libhal_changeset_set_property_string (cs, "info.product", "Volume (unused)"); usage = "unused"; return; default: usage = ""; } - libhal_changeset_set_property_string (changes, "volume.fsusage", usage); + libhal_changeset_set_property_string (cs, "volume.fsusage", usage); HAL_DEBUG (("volume.fsusage = '%s'", usage)); - libhal_changeset_set_property_string (changes, "volume.fstype", vid->type); + libhal_changeset_set_property_string (cs, "volume.fstype", vid->type); HAL_DEBUG(("volume.fstype = '%s'", vid->type)); if (vid->type_version[0] != '\0') { - libhal_changeset_set_property_string (changes, "volume.fsversion", vid->type_version); + libhal_changeset_set_property_string (cs, "volume.fsversion", vid->type_version); HAL_DEBUG(("volume.fsversion = '%s'", vid->type_version)); } - libhal_changeset_set_property_string (changes, "volume.uuid", vid->uuid); + libhal_changeset_set_property_string (cs, "volume.uuid", vid->uuid); HAL_DEBUG(("volume.uuid = '%s'", vid->uuid)); /* we need to be sure for a utf8 valid label, because dbus accept only utf8 valid strings */ volume_label = strdup_valid_utf8 (vid->label); if( volume_label != NULL ) { - libhal_changeset_set_property_string (changes, "volume.label", volume_label); + libhal_changeset_set_property_string (cs, "volume.label", volume_label); HAL_DEBUG(("volume.label = '%s'", volume_label)); if (strlen(volume_label) > 0) { - libhal_changeset_set_property_string (changes, "info.product", volume_label); + libhal_changeset_set_property_string (cs, "info.product", volume_label); } else { snprintf (buf, sizeof (buf), "Volume (%s)", vid->type); - libhal_changeset_set_property_string (changes, "info.product", buf); + libhal_changeset_set_property_string (cs, "info.product", buf); } g_free(volume_label); } else { snprintf (buf, sizeof (buf), "Volume (%s)", vid->type); - libhal_changeset_set_property_string (changes, "info.product", buf); + libhal_changeset_set_property_string (cs, "info.product", buf); } } static void -advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *changes, +advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *cs, int fd, const char *device_file) { /* the discs block size */ @@ -323,9 +177,9 @@ advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan dbus_error_init (&error); /* set defaults */ - libhal_changeset_set_property_bool (changes, "volume.disc.is_videodvd", FALSE); - libhal_changeset_set_property_bool (changes, "volume.disc.is_vcd", FALSE); - libhal_changeset_set_property_bool (changes, "volume.disc.is_svcd", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", FALSE); /* read the block size */ lseek (fd, 0x8080, SEEK_CUR); @@ -395,19 +249,19 @@ advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan { if (!strcmp (dirname, "VIDEO_TS")) { - libhal_changeset_set_property_bool (changes, "volume.disc.is_videodvd", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", TRUE); HAL_DEBUG(("Disc in %s is a Video DVD", device_file)); break; } else if (!strcmp (dirname, "VCD")) { - libhal_changeset_set_property_bool (changes, "volume.disc.is_vcd", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", TRUE); HAL_DEBUG(("Disc in %s is a Video CD", device_file)); break; } else if (!strcmp (dirname, "SVCD")) { - libhal_changeset_set_property_bool (changes, "volume.disc.is_svcd", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", TRUE); HAL_DEBUG(("Disc in %s is a Super Video CD", device_file)); break; } @@ -445,19 +299,26 @@ main (int argc, char *argv[]) struct volume_id *vid; char *stordev_dev_file; char *partition_number_str; + char *partition_start_str; char *is_disc_str; dbus_bool_t is_disc; unsigned int partition_number; + guint64 partition_start; unsigned int block_size; dbus_uint64_t vol_size; dbus_bool_t should_probe_for_fs; dbus_uint64_t vol_probe_offset = 0; - LibHalChangeSet *changeset; + LibHalChangeSet *cs; fd = -1; + + cs = NULL; + /* hook in our debug into libvolume_id */ volume_id_log_fn = vid_log; + setup_logger (); + /* assume failure */ ret = 1; @@ -475,20 +336,24 @@ main (int argc, char *argv[]) else partition_number = (unsigned int) -1; + partition_start_str = getenv ("HAL_PROP_VOLUME_PARTITION_START"); + if (partition_start_str != NULL) + partition_start = (guint64) strtoll (partition_start_str, NULL, 0); + else + partition_start = (guint64) 0; + is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC"); if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) is_disc = TRUE; else is_disc = FALSE; - setup_logger (); - dbus_error_init (&error); if ((ctx = libhal_ctx_init_direct (&error)) == NULL) goto out; - changeset = libhal_device_new_changeset (udi); - if (changeset == NULL) { + cs = libhal_device_new_changeset (udi); + if (cs == NULL) { HAL_DEBUG(("Cannot initialize changeset")); goto out; } @@ -502,11 +367,11 @@ main (int argc, char *argv[]) /* block size and total size */ if (ioctl (fd, BLKSSZGET, &block_size) == 0) { HAL_DEBUG(("volume.block_size = %d", block_size)); - libhal_changeset_set_property_int (changeset, "volume.block_size", block_size); + libhal_changeset_set_property_int (cs, "volume.block_size", block_size); } if (ioctl (fd, BLKGETSIZE64, &vol_size) == 0) { HAL_DEBUG(("volume.size = %llu", vol_size)); - libhal_changeset_set_property_uint64 (changeset, "volume.size", vol_size); + libhal_changeset_set_property_uint64 (cs, "volume.size", vol_size); } else vol_size = 0; @@ -518,12 +383,12 @@ main (int argc, char *argv[]) struct cdrom_tochdr; /* toc_hdr; */ /* defaults */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "unknown"); - libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", FALSE); - libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", FALSE); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_blank", FALSE); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_appendable", FALSE); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", FALSE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "unknown"); + libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.has_data", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", FALSE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", FALSE); /* Suggested by Alex Larsson to get rid of log spewage * on Alan's cd changer (RH bug 130649) */ @@ -535,33 +400,33 @@ main (int argc, char *argv[]) type = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT); switch (type) { case CDS_AUDIO: /* audio CD */ - libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", TRUE); HAL_DEBUG(("Disc in %s has audio", device_file)); should_probe_for_fs = FALSE; break; case CDS_MIXED: /* mixed mode CD */ - libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", TRUE); - libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.has_data", TRUE); HAL_DEBUG(("Disc in %s has audio+data", device_file)); break; case CDS_DATA_1: /* data CD */ case CDS_DATA_2: case CDS_XA_2_1: case CDS_XA_2_2: - libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.has_data", TRUE); HAL_DEBUG(("Disc in %s has data", device_file)); - advanced_disc_detect (ctx, udi, changeset, fd, device_file); + advanced_disc_detect (ctx, udi, cs, fd, device_file); break; case CDS_NO_INFO: /* blank or invalid CD */ - libhal_changeset_set_property_bool (changeset, "volume.disc.is_blank", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", TRUE); /* set the volume size to 0 if disc is blank and not as 4 from BLKGETSIZE64 */ - libhal_changeset_set_property_int (changeset, "volume.block_size", 0); + libhal_changeset_set_property_int (cs, "volume.block_size", 0); HAL_DEBUG(("Disc in %s is blank", device_file)); should_probe_for_fs = FALSE; break; default: /* should never see this */ - libhal_changeset_set_property_string (changeset, "volume.disc_type", "unknown"); + libhal_changeset_set_property_string (cs, "volume.disc_type", "unknown"); HAL_DEBUG(("Disc in %s returned unknown CDROM_DISC_STATUS", device_file)); should_probe_for_fs = FALSE; break; @@ -575,65 +440,65 @@ main (int argc, char *argv[]) if (type != -1) { switch (type) { case 0x08: /* CD-ROM */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_rom"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_rom"); break; case 0x09: /* CD-R */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_r"); break; case 0x0a: /* CD-RW */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_rw"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_rw"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x10: /* DVD-ROM */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rom"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rom"); break; case 0x11: /* DVD-R Sequential */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_r"); break; case 0x12: /* DVD-RAM */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_ram"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_ram"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x13: /* DVD-RW Restricted Overwrite */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rw"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rw"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x14: /* DVD-RW Sequential */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rw"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rw"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x1A: /* DVD+RW */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_rw"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_rw"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x1B: /* DVD+R */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_r"); break; case 0x2B: /* DVD+R Double Layer */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_r_dl"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_r_dl"); break; case 0x40: /* BD-ROM */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_rom"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_rom"); break; case 0x41: /* BD-R Sequential */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_r"); break; case 0x42: /* BD-R Random */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_r"); break; case 0x43: /* BD-RE */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_re"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_re"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; case 0x50: /* HD DVD-ROM */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_rom"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_rom"); break; case 0x51: /* HD DVD-R */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_r"); + libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_r"); break; case 0x52: /* HD DVD-Rewritable */ - libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_rw"); - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_rw"); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); break; default: break; @@ -642,16 +507,16 @@ main (int argc, char *argv[]) if (get_disc_capacity_for_type (fd, type, &capacity) == 0) { HAL_DEBUG(("volume.disc.capacity = %llu", capacity)); - libhal_changeset_set_property_uint64 (changeset, "volume.disc.capacity", capacity); + libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity); } /* On some hardware the get_disc_type call fails, so we use this as a backup */ if (disc_is_rewritable (fd)) { - libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE); } if (disc_is_appendable (fd)) { - libhal_changeset_set_property_bool (changeset, "volume.disc.is_appendable", TRUE); + libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", TRUE); } #if 0 @@ -703,14 +568,15 @@ main (int argc, char *argv[]) vid = volume_id_open_fd (fd); if (vid != NULL) { if (volume_id_probe_all (vid, vol_probe_offset , vol_size) == 0) { - set_volume_id_values(ctx, udi, changeset, vid); + set_volume_id_values(ctx, udi, cs, vid); } else { - libhal_changeset_set_property_string (changeset, "info.product", "Volume"); + libhal_changeset_set_property_string (cs, "info.product", "Volume"); } /* VOLUME_ID_UNUSED means vol_id didn't detect anything that it knows about - look if * it's an extended msdos partition table */ +#if 0 if (vid->usage_id == VOLUME_ID_UNUSED) { unsigned char buf[2]; @@ -724,64 +590,113 @@ main (int argc, char *argv[]) if (memcmp (buf, MSDOS_MAGIC, 2) == 0) { HAL_DEBUG (("partition is an extended msdos partition table")); - libhal_changeset_set_property_string (changeset, "volume.fsusage", "partitiontable"); - libhal_changeset_set_property_string (changeset, "volume.fstype", "msdos_extended_partitiontable"); - libhal_changeset_set_property_string (changeset, "volume.fsversion", ""); + libhal_changeset_set_property_string (cs, "volume.fsusage", "partitiontable"); + libhal_changeset_set_property_string (cs, "volume.fstype", "msdos_extended_partitiontable"); + libhal_changeset_set_property_string (cs, "volume.fsversion", ""); } } } +#endif volume_id_close(vid); } /* get partition type number, if we find a msdos partition table */ - if (partition_number_str != NULL && partition_number <= 256 && partition_number > 0) { + if (partition_number_str != NULL && + partition_number <= 256 && partition_number > 0 && + partition_start > 0) { struct msdos_part_entry *idx; int fd; + PartitionTable *p; if ((stordev_dev_file = libhal_device_get_property_string ( ctx, parent_udi, "block.device", &error)) == NULL) { goto out; } - fd = open(stordev_dev_file, O_RDONLY); - if (fd >= 0) { - idx = probe_msdos_part_table(fd); - if (idx != NULL) { - uint64_t start; - uint64_t size; - unsigned char type; - - type = idx[partition_number - 1].part_type; - start = idx[partition_number - 1].start; - size = idx[partition_number - 1].size; - if (type > 0) { - libhal_changeset_set_property_int ( - changeset, "volume.partition.msdos_part_table_type", type); - libhal_changeset_set_property_uint64 ( - changeset, "volume.partition.msdos_part_table_start", start); - libhal_changeset_set_property_uint64 ( - changeset, "volume.partition.msdos_part_table_size", size); - - /* NOTE: We trust the type from the partition table - * if it explicitly got correct entries for RAID and - * LVM partitions. - * - * But in general it's not a good idea to trust the - * partition table type as many geek^Wexpert users use - * FAT filesystems on type 0x83 which is Linux. - * - * Linux RAID autodetect is 0xfd and Linux LVM is 0x8e - */ - if (type == 0xfd || type == 0x8e ) { - libhal_changeset_set_property_string ( - changeset, "volume.fsusage", "raid"); - } + + HAL_INFO (("Loading part table")); + p = part_table_load_from_disk (stordev_dev_file); + if (p != NULL) { + PartitionTable *p2; + int entry; + + HAL_INFO (("Looking at part table")); + part_table_find (p, partition_start, &p2, &entry); + if (entry >= 0) { + const char *scheme; + char *type; + char *label; + char *uuid; + char **flags; + + scheme = part_get_scheme_name (part_table_get_scheme (p2)); + type = part_table_entry_get_type (p2, entry); + label = part_table_entry_get_label (p2, entry); + uuid = part_table_entry_get_uuid (p2, entry); + flags = part_table_entry_get_flags (p2, entry); + + if (type == NULL) + type = g_strdup (""); + if (label == NULL) + label = g_strdup (""); + if (uuid == NULL) + uuid = g_strdup (""); + if (flags == NULL) { + flags = g_new0 (char *, 2); + flags[0] = NULL; + } + + libhal_changeset_set_property_string (cs, "volume.partition.scheme", scheme); + libhal_changeset_set_property_string (cs, "volume.partition.type", type); + libhal_changeset_set_property_string (cs, "volume.partition.label", label); + libhal_changeset_set_property_string (cs, "volume.partition.uuid", uuid); + libhal_changeset_set_property_strlist (cs, "volume.partition.flags", flags); + + /* NOTE: We trust the type from the partition table + * if it explicitly got correct entries for RAID and + * LVM partitions. + * + * But in general it's not a good idea to trust the + * partition table type as many geek^Wexpert users use + * FAT filesystems on type 0x83 which is Linux. + * + * For MBR, Linux RAID autodetect is 0xfd and Linux LVM is 0x8e + * + * For GPT, RAID is A19D880F-05FC-4D3B-A006-743F0F84911E and + * LVM is E6D6D379-F507-44C2-A23C-238F2A3DF928. + */ + if ( + ((strcmp (scheme, "mbr") == 0 || strcmp (scheme, "embr") == 0) && + (0xfd == atoi (type) || 0x8e == atoi (type))) + || + ((strcmp (scheme, "gpt") == 0) && + ((strcmp (type, "A19D880F-05FC-4D3B-A006-743F0F84911E") == 0) || + (strcmp (type, "E6D6D379-F507-44C2-A23C-238F2A3DF928")) == 0)) ) { + + libhal_changeset_set_property_string (cs, "volume.fsusage", "raid"); + } + + /* see if this partition is an embedded partition table */ + if (part_table_entry_get_nested (p2, entry) != NULL) { + + libhal_changeset_set_property_string (cs, "volume.fsusage", "partitiontable"); + libhal_changeset_set_property_string (cs, "volume.fstype", ""); + libhal_changeset_set_property_string (cs, "volume.fsversion", ""); + } + + g_free (type); + g_free (label); + g_free (uuid); + g_strfreev (flags); } - close (fd); + + part_table_free (p); } + HAL_INFO (("Done looking at part table")); + libhal_free_string (stordev_dev_file); } } @@ -789,15 +704,17 @@ main (int argc, char *argv[]) /* good so far */ ret = 0; - /* for testing... - char *values[4] = {"foo", "bar", "baz", NULL}; - libhal_changeset_set_property_strlist (changeset, "foo.bar", values); - */ +out: + if (cs != NULL) { + /* for testing... + char *values[4] = {"foo", "bar", "baz", NULL}; + libhal_changeset_set_property_strlist (cs, "foo.bar", values); + */ + libhal_device_commit_changeset (ctx, cs, &error); + libhal_device_free_changeset (cs); + } - libhal_device_commit_changeset (ctx, changeset, &error); - libhal_device_free_changeset (changeset); -out: if (fd >= 0) close (fd); diff --git a/libhal-storage/libhal-storage.c b/libhal-storage/libhal-storage.c index 206ffd3d..b20a5a8d 100644 --- a/libhal-storage/libhal-storage.c +++ b/libhal-storage/libhal-storage.c @@ -711,6 +711,7 @@ struct LibHalDrive_s { dbus_uint64_t drive_size; dbus_uint64_t drive_media_size; + char *partition_scheme; LibHalContext *hal_ctx; @@ -738,6 +739,11 @@ struct LibHalVolume_s { dbus_bool_t is_partition; unsigned int partition_number; + char *partition_scheme; + char *partition_type; + char *partition_label; + char *partition_uuid; + char **partition_flags; int msdos_part_table_type; dbus_uint64_t msdos_part_table_start; @@ -806,6 +812,7 @@ libhal_drive_free (LibHalDrive *drive) libhal_free_string (drive->desired_mount_point); libhal_free_string (drive->mount_filesystem); libhal_free_string_array (drive->capabilities); + libhal_free_string (drive->partition_scheme); free (drive); } @@ -833,6 +840,12 @@ libhal_volume_free (LibHalVolume *vol) libhal_free_string (vol->crypto_backing_volume); libhal_free_string (vol->storage_device); + libhal_free_string (vol->partition_scheme); + libhal_free_string (vol->partition_type); + libhal_free_string (vol->partition_label); + libhal_free_string (vol->partition_uuid); + libhal_free_string (vol->partition_flags); + free (vol); } @@ -941,6 +954,8 @@ libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi) LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size); LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive->requires_eject); + LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme); + LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive->physical_device); LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive->firmware_version); LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive->serial); @@ -1114,6 +1129,12 @@ libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi) LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol->is_partition); LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol->partition_number); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol->partition_scheme); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol->partition_type); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol->partition_label); + LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol->partition_uuid); + LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol->partition_flags); + LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol->partition_start_offset); LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol->partition_media_size); LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type); @@ -1425,6 +1446,13 @@ libhal_drive_get_media_size (LibHalDrive *drive) return drive->drive_media_size; } +const char * +libhal_drive_get_partition_scheme (LibHalDrive *drive) +{ + return drive->partition_scheme; +} + + LibHalDriveType libhal_drive_get_type (LibHalDrive *drive) { @@ -1569,6 +1597,37 @@ libhal_volume_get_partition_number (LibHalVolume *volume) return volume->partition_number; } +const char * +libhal_volume_get_partition_scheme (LibHalVolume *volume) +{ + return volume->partition_scheme; +} + +const char * +libhal_volume_get_partition_type (LibHalVolume *volume) +{ + return volume->partition_type; +} + +const char * +libhal_volume_get_partition_label (LibHalVolume *volume) +{ + return volume->partition_label; +} + +const char * +libhal_volume_get_partition_uuid (LibHalVolume *volume) +{ + return volume->partition_uuid; +} + +const char ** +libhal_volume_get_partition_flags (LibHalVolume *volume) +{ + return volume->partition_flags; +} + + dbus_uint64_t libhal_volume_get_partition_start_offset (LibHalVolume *volume) { diff --git a/libhal-storage/libhal-storage.h b/libhal-storage/libhal-storage.h index 0ce5f2d3..c88a389f 100644 --- a/libhal-storage/libhal-storage.h +++ b/libhal-storage/libhal-storage.h @@ -32,6 +32,9 @@ #if defined(__cplusplus) extern "C" { +#if 0 +} /* shut up emacs indenting */ +#endif #endif struct LibHalDrive_s; @@ -128,17 +131,17 @@ typedef struct { const char *icon_path; } LibHalStoragePolicyIconPair; -LibHalStoragePolicy *libhal_storage_policy_new (void); -void libhal_storage_policy_free (LibHalStoragePolicy *policy); +LibHalStoragePolicy *libhal_storage_policy_new (void) LIBHAL_DEPRECATED; +void libhal_storage_policy_free (LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; void libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon, - const char *path); + const char *path) LIBHAL_DEPRECATED; void libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, - LibHalStoragePolicyIconPair *pairs); + LibHalStoragePolicyIconPair *pairs) LIBHAL_DEPRECATED; const char *libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, - LibHalStoragePolicyIcon icon); + LibHalStoragePolicyIcon icon) LIBHAL_DEPRECATED; typedef enum { LIBHAL_DRIVE_BUS_UNKNOWN = 0x00, @@ -197,6 +200,7 @@ dbus_bool_t libhal_drive_uses_removable_media (LibHalDrive *dr dbus_bool_t libhal_drive_is_media_detected (LibHalDrive *drive); dbus_uint64_t libhal_drive_get_size (LibHalDrive *drive); dbus_uint64_t libhal_drive_get_media_size (LibHalDrive *drive); +const char *libhal_drive_get_partition_scheme (LibHalDrive *drive); dbus_bool_t libhal_drive_no_partitions_hint (LibHalDrive *drive); dbus_bool_t libhal_drive_requires_eject (LibHalDrive *drive); LibHalDriveType libhal_drive_get_type (LibHalDrive *drive); @@ -218,29 +222,29 @@ const char *libhal_drive_get_dedicated_icon_volume (LibHalDrive char *libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; char *libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; dbus_bool_t libhal_drive_policy_is_mountable (LibHalDrive *drive, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_drive_policy_get_mount_options (LibHalDrive *drive, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_drive_policy_get_mount_fs (LibHalDrive *drive, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; char **libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes); -char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx); -dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx); -char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx); -char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx); +char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; +char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED; typedef enum { @@ -290,9 +294,16 @@ dbus_bool_t libhal_volume_is_mounted (LibHalVolume dbus_bool_t libhal_volume_is_mounted_read_only (LibHalVolume *volume); dbus_bool_t libhal_volume_is_partition (LibHalVolume *volume); dbus_bool_t libhal_volume_is_disc (LibHalVolume *volume); + +const char *libhal_volume_get_partition_scheme (LibHalVolume *volume); +const char *libhal_volume_get_partition_type (LibHalVolume *volume); +const char *libhal_volume_get_partition_label (LibHalVolume *volume); +const char *libhal_volume_get_partition_uuid (LibHalVolume *volume); +const char **libhal_volume_get_partition_flags (LibHalVolume *volume); unsigned int libhal_volume_get_partition_number (LibHalVolume *volume); dbus_uint64_t libhal_volume_get_partition_start_offset (LibHalVolume *volume); dbus_uint64_t libhal_volume_get_partition_media_size (LibHalVolume *volume); + const char *libhal_volume_get_label (LibHalVolume *volume); const char *libhal_volume_get_mount_point (LibHalVolume *volume); const char *libhal_volume_get_uuid (LibHalVolume *volume); @@ -309,38 +320,39 @@ dbus_bool_t libhal_volume_disc_is_rewritable (LibHalVolume dbus_bool_t libhal_volume_disc_is_appendable (LibHalVolume *volume); LibHalVolumeDiscType libhal_volume_get_disc_type (LibHalVolume *volume); -int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume); -dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume); -dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume); +int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) LIBHAL_DEPRECATED; +dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) LIBHAL_DEPRECATED; +dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) LIBHAL_DEPRECATED; + dbus_bool_t libhal_volume_should_ignore (LibHalVolume *volume); -char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume); +char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) LIBHAL_DEPRECATED; char *libhal_volume_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; char *libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; dbus_bool_t libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy, - const char *target_mount_point); + const char *target_mount_point) LIBHAL_DEPRECATED; dbus_bool_t libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, - LibHalStoragePolicy *policy); + LibHalStoragePolicy *policy) LIBHAL_DEPRECATED; #if defined(__cplusplus) diff --git a/libhal/libhal.h b/libhal/libhal.h index 15ee2d4b..ab00e576 100644 --- a/libhal/libhal.h +++ b/libhal/libhal.h @@ -35,6 +35,13 @@ extern "C" { #endif #endif +#if defined(__GNUC__) +#define LIBHAL_DEPRECATED __attribute__ ((deprecated)) +#else +#define LIBHAL_DEPRECATED +#endif + + #define LIBHAL_FREE_DBUS_ERROR(_dbus_error_) \ do { \ if (dbus_error_is_set(_dbus_error_)) \ diff --git a/partutil/Makefile.am b/partutil/Makefile.am new file mode 100644 index 00000000..5d409bbd --- /dev/null +++ b/partutil/Makefile.am @@ -0,0 +1,11 @@ + +INCLUDES = @GLIB_CFLAGS@ + +noinst_LTLIBRARIES = libpartutil.la + +libpartutil_la_SOURCES = partutil.h partutil.c ../hald/logger.c + +libpartutil_la_LIBADD = @GLIB_LIBS@ @PARTED_LIBS@ + +clean-local : + rm -f *~ diff --git a/partutil/partutil.c b/partutil/partutil.c new file mode 100644 index 00000000..beeaedb1 --- /dev/null +++ b/partutil/partutil.c @@ -0,0 +1,1791 @@ +/*************************************************************************** + * + * part.c : library for reading and writing partition tables - uses + * libparted for the heavy lifting + * + * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/time.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <ctype.h> + +#include <linux/hdreg.h> + +#define BLKGETSIZE64 _IOR(0x12,114,size_t) + +#include "../hald/logger.h" +#include "partutil.h" + + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + + +#ifdef USE_PARTED +#include <parted/parted.h> +#endif + +const char * +part_get_scheme_name (PartitionScheme scheme) +{ + const char *s; + + switch (scheme) { + case PART_TYPE_GPT: + s = "gpt"; + break; + case PART_TYPE_MSDOS: + s = "mbr"; + break; + case PART_TYPE_MSDOS_EXTENDED: + s = "embr"; + break; + case PART_TYPE_APPLE: + s = "apm"; + break; + default: + s = NULL; + break; + } + + return s; +} + +struct PartitionEntry_s; +typedef struct PartitionEntry_s PartitionEntry; + +struct PartitionEntry_s +{ + gboolean is_part_table; + + /* NULL iff is_part_table==FALSE */ + PartitionTable *part_table; + + /* these are always set */ + guint8 *data; + int length; + + /* offset _on disk_ where the entry starts */ + guint64 offset; +}; + +struct PartitionTable_s +{ + /* partitioning scheme used */ + PartitionScheme scheme; + + /* offset of table on disk */ + guint64 offset; + guint64 size; + + /* entries in partition table */ + GSList *entries; +}; + +void +part_table_find (PartitionTable *p, guint64 offset, + PartitionTable **out_part_table, int *out_entry) +{ + int n; + int num_entries; + + *out_part_table = p; + *out_entry = -1; + + num_entries = part_table_get_num_entries (p); + for (n = 0; n < num_entries; n++) { + guint64 pe_offset; + guint64 pe_size; + + pe_offset = part_table_entry_get_offset (p, n); + pe_size = part_table_entry_get_size (p, n); + + if ((offset >= pe_offset) && (offset < pe_offset + pe_size)) { + PartitionTable *part_table_nested; + + part_table_nested = part_table_entry_get_nested (p, n); + /* return the extended partition only if the offset points to it - otherwise + * look for a logical partition + */ + if (part_table_nested != NULL && offset > pe_offset) { + part_table_find (part_table_nested, offset, out_part_table, out_entry); + } else { + *out_entry = n; + } + + /* and we're done... */ + break; + } + } +} + + +static guint16 +get_le16 (const void *buf) +{ + return GUINT16_FROM_LE ( * ((guint16 *) buf) ); +} + + +static guint32 +get_le32 (const void *buf) +{ + return GUINT32_FROM_LE ( * ((guint32 *) buf) ); +} + +static guint64 +get_le64 (const void *buf) +{ + return GUINT64_FROM_LE ( * ((guint64 *) buf) ); +} + + +static guint32 +get_be32 (const void *buf) +{ + return GUINT32_FROM_BE ( * ((guint32 *) buf) ); +} + +/* see http://en.wikipedia.org/wiki/Globally_Unique_Identifier - excerpt + * + * Guids are most commonly written in text as a sequence of hexadecimal digits as such: + * + * 3F2504E0-4F89-11D3-9A0C-0305E82C3301 + * + * This text notation follows from the data structure defined above. The sequence is + * + * 1. Data1 (8 characters) + * 2. Hyphen + * 3. Data2 (4 characters) + * 4. Hyphen + * 5. Data3 (4 characters) + * 6. Hyphen + * 7. Initial two items from Data4 (4 characters) + * 8. Hyphen + * 9. Remaining six items from Data4 (12 characters) + * + * Often braces are added to enclose the above format, as such: + * + * {3F2504E0-4F89-11D3-9A0C-0305E82C3301} + * + * When printing fewer characters is desired guids are sometimes encoded + * into a base64 string of 22 to 24 characters (depending on + * padding). For instance: + * + * 7QDBkvCA1+B9K/U0vrQx1A + * 7QDBkvCA1+B9K/U0vrQx1A== + */ + +typedef struct efi_guid_s { + guint32 data1; + guint16 data2; + guint16 data3; + guint8 data4[8]; +} __attribute__ ((packed)) efi_guid; + +static char * +get_le_guid (const guint8 *buf) +{ + efi_guid *guid = (efi_guid *) buf; + + return g_strdup_printf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + get_le32 (&(guid->data1)), + get_le16 (&(guid->data2)), + get_le16 (&(guid->data3)), + guid->data4[0], + guid->data4[1], + guid->data4[2], + guid->data4[3], + guid->data4[4], + guid->data4[5], + guid->data4[6], + guid->data4[7]); +} + +static gboolean +set_le_guid (guint8 *buf, const char *source) +{ + efi_guid *guid = (efi_guid *) buf; + guint32 __attribute__((__unused__)) data1; + guint16 __attribute__((__unused__)) data2; + guint16 __attribute__((__unused__)) data3; + guint8 __attribute__((__unused__)) data4[8]; + gboolean ret; + int n; + + n = sscanf (source, "%x-%hx-%hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + &guid->data1, + &guid->data2, + &guid->data3, + &(guid->data4[0]), + &(guid->data4[1]), + &(guid->data4[2]), + &(guid->data4[3]), + &(guid->data4[4]), + &(guid->data4[5]), + &(guid->data4[6]), + &(guid->data4[7])); + + if (n != 11) { + HAL_INFO (("guid '%s' is not valid")); + goto out; + } + +#if 0 + HAL_INFO (("source = %s", source)); + HAL_INFO (("data1 = %08x", guid->data1)); + HAL_INFO (("data2 = %04x", guid->data2)); + HAL_INFO (("data3 = %04x", guid->data3)); + HAL_INFO (("data4[0] = %02x", guid->data4[0])); + HAL_INFO (("data4[1] = %02x", guid->data4[1])); + HAL_INFO (("data4[2] = %02x", guid->data4[2])); + HAL_INFO (("data4[3] = %02x", guid->data4[3])); + HAL_INFO (("data4[4] = %02x", guid->data4[4])); + HAL_INFO (("data4[5] = %02x", guid->data4[5])); + HAL_INFO (("data4[6] = %02x", guid->data4[6])); + HAL_INFO (("data4[7] = %02x", guid->data4[7])); +#endif + + guid->data1 = GUINT32_TO_LE (guid->data1); + guid->data2 = GUINT16_TO_LE (guid->data2); + guid->data3 = GUINT16_TO_LE (guid->data3); + + ret = TRUE; + +out: + return ret; +} + +static PartitionEntry * +part_entry_new (PartitionTable *e_part_table, const guint8 *data, int length, guint64 offset) +{ + PartitionEntry *pe; + + pe = g_new0 (PartitionEntry, 1); + pe->is_part_table = (e_part_table != NULL); + pe->part_table = e_part_table; + pe->offset = offset; + pe->length = length; + pe->data = g_new0 (guint8, length); + memcpy (pe->data, data, length); + + return pe; +} + +static void +part_entry_free (PartitionEntry *pe) +{ + if (pe->part_table != NULL) { + part_table_free (pe->part_table); + } + g_free (pe->data); + g_free (pe); +} + +static PartitionTable * +part_table_new_empty (PartitionScheme scheme) +{ + PartitionTable *p; + + p = g_new0 (PartitionTable, 1); + p->scheme = scheme; + p->offset = 0; + p->entries = NULL; + + return p; +} + +void +part_table_free (PartitionTable *p) +{ + GSList *i; + + for (i = p->entries; i != NULL; i = i->next) { + PartitionEntry *pe = i->data; + part_entry_free (pe); + } + g_slist_free (p->entries); + g_free (p); +} + +#if 0 +static PartitionTable * +part_table_parse_bsd (int fd, guint64 offset, guint64 size) +{ + PartitionTable *p; + + p = NULL; + + /* TODO */ + + return p; +} +#endif + + +#define MSDOS_MAGIC "\x55\xaa" +#define MSDOS_PARTTABLE_OFFSET 0x1be +#define MSDOS_SIG_OFF 0x1fe + +#if 0 +static void +hexdump (const guint8 *mem, int size) +{ + int i; + int j; + int n; + const guint8 *buf = (const guint8 *) mem; + + n = 0; + printf ("Dumping %d=0x%x bytes\n", size, size); + while (n < size) { + + printf ("0x%04x: ", n); + + j = n; + for (i = 0; i < 16; i++) { + if (j >= size) + break; + printf ("%02x ", buf[j]); + j++; + } + + for ( ; i < 16; i++) { + printf (" "); + } + + printf (" "); + + j = n; + for (i = 0; i < 16; i++) { + if (j >= size) + break; + printf ("%c", isprint(buf[j]) ? buf[j] : '.'); + j++; + } + + printf ("\n"); + + n += 16; + } +} +#endif + +static PartitionTable * +part_table_parse_msdos_extended (int fd, guint64 offset, guint64 size) +{ + int n; + PartitionTable *p; + guint64 next; + + //HAL_INFO (("Entering MS-DOS extended parser")); + + p = NULL; + + next = offset; + + while (next != 0) { + guint64 readfrom; + const guint8 embr[512]; + + readfrom = next; + next = 0; + + //HAL_INFO (("readfrom = %lld", readfrom)); + + if (lseek (fd, readfrom, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &embr, sizeof (embr)) != sizeof (embr)) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + + if (memcmp (&embr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) { + HAL_INFO (("No MSDOS_MAGIC found")); + goto out; + } + + //HAL_INFO (("MSDOS_MAGIC found")); + + if (p == NULL) { + p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED); + p->offset = offset; + p->size = size; + } + + + for (n = 0; n < 2; n++) { + PartitionEntry *pe; + 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]))); + + if (psize == 0) + continue; + + pe = NULL; + + if (n == 0) { + //HAL_INFO (("part %d (offset %lld, size %lld, type 0x%02x)", + // n, readfrom + pstart, psize, ptype)); + + //HAL_INFO (("pstart = %lld", pstart)); + + //hexdump (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16); + + pe = part_entry_new (NULL, + &(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), + 16, + readfrom + MSDOS_PARTTABLE_OFFSET + n * 16); + } else { + if (pstart != 0) { + //HAL_INFO (("found chain at offset %lld", offset + pstart); + next = offset + pstart; + } + } + + //HAL_INFO (("pe = %p", pe)); + + if (pe != NULL) { + p->entries = g_slist_append (p->entries, pe); + } + } + + } + +out: + //HAL_INFO (("Exiting MS-DOS extended parser")); + return p; +} + +static PartitionTable * +part_table_parse_msdos (int fd, guint64 offset, guint64 size, gboolean *found_gpt) +{ + int n; + const guint8 mbr[512]; + PartitionTable *p; + + //HAL_INFO (("Entering MS-DOS parser")); + + *found_gpt = FALSE; + + p = NULL; + + if (lseek (fd, offset, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &mbr, sizeof (mbr)) != sizeof (mbr)) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + + if (memcmp (&mbr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) { + HAL_INFO (("No MSDOS_MAGIC found")); + goto out; + } + + //HAL_INFO (("MSDOS_MAGIC found")); + + /* sanity checks */ + for (n = 0; n < 4; n++) { + if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0 && + mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0x80) { + HAL_INFO (("partitioning flag for part %d is not 0x00 or 0x80", n)); + goto out; + } + /* protective MBR for GPT => GPT, not MS-DOS */ + if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4] == 0xee) { + HAL_INFO (("found partition type 0xee => protective MBR for GPT", n)); + *found_gpt = TRUE; + goto out; + } + } + + p = part_table_new_empty (PART_TYPE_MSDOS); + p->offset = offset; + p->size = size; + + /* we _always_ want to create four partitions */ + for (n = 0; n < 4; n++) { + PartitionEntry *pe; + guint64 pstart; + guint64 psize; + 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]))); + ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4]; + + //HAL_INFO (("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype)); + + pe = NULL; + e_part_table = NULL; + + /* look for embedded partition tables */ + switch (ptype) { + + /* extended partitions */ + case 0x05: /* MS-DOS */ + case 0x0f: /* Win95 */ + case 0x85: /* Linux */ + e_part_table = part_table_parse_msdos_extended (fd, pstart, psize); + if (e_part_table != NULL) { + pe = part_entry_new (e_part_table, + &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), + 16, + offset + MSDOS_PARTTABLE_OFFSET + n * 16); + } + break; + + case 0xa5: /* FreeBSD */ + case 0xa6: /* OpenBSD */ + case 0xa9: /* NetBSD */ + //e_part_table = part_table_parse_bsd (fd, pstart, psize); + //break; + + default: + //HAL_INFO (("new part entry")); + pe = part_entry_new (NULL, + &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), + 16, + offset + MSDOS_PARTTABLE_OFFSET + n * 16); + break; + } + + //HAL_INFO (("pe = %p", pe)); + + p->entries = g_slist_append (p->entries, pe); + } + +out: + //HAL_INFO (("Exiting MS-DOS parser")); + return p; +} + +#define GPT_MAGIC "EFI PART" + +#define GPT_PART_TYPE_GUID_EMPTY "00000000-0000-0000-0000-000000000000" + +static PartitionTable * +part_table_parse_gpt (int fd, guint64 offset, guint64 size) +{ + int n; + PartitionTable *p; + guint8 buf[16]; + guint64 partition_entry_lba; + int num_entries; + int size_of_entry; + + HAL_INFO (("Entering EFI GPT parser")); + + /* by way of getting here, we've already checked for a protective MBR */ + + p = NULL; + + /* Check GPT signature */ + if (lseek (fd, offset + 512 + 0, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, buf, 8) != 8) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + if (memcmp (buf, GPT_MAGIC, 8) != 0) { + HAL_INFO (("No GPT_MAGIC found")); + goto out; + } + + HAL_INFO (("GPT magic found")); + + /* Disk UUID */ + if (lseek (fd, offset + 512 + 56, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, buf, 16) != 16) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + //hexdump ((guint8*) buf, 16); + + if (lseek (fd, offset + 512 + 72, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, buf, 8) != 8) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + partition_entry_lba = get_le64 (buf); + + if (lseek (fd, offset + 512 + 80, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, buf, 4) != 4) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + num_entries = get_le32 (buf); + + if (lseek (fd, offset + 512 + 84, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, buf, 4) != 4) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + size_of_entry = get_le32(buf); + + + p = part_table_new_empty (PART_TYPE_GPT); + p->offset = offset; + p->size = size; + + HAL_INFO (("partition_entry_lba=%d", partition_entry_lba)); + HAL_INFO (("num_entries=%d", num_entries)); + HAL_INFO (("size_of_entry=%d", size_of_entry)); + + for (n = 0; n < num_entries; n++) { + PartitionEntry *pe; + struct { + guint8 partition_type_guid[16]; + guint8 partition_guid[16]; + guint8 starting_lba[8]; + guint8 ending_lba[8]; + guint8 attributes[8]; + guint8 partition_name[72]; + } gpt_part_entry; + char *partition_type_guid; + + if (lseek (fd, offset + partition_entry_lba * 512 + n * size_of_entry, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &gpt_part_entry, 128) != 128) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + + partition_type_guid = get_le_guid (gpt_part_entry.partition_type_guid); + + if (strcmp (partition_type_guid, GPT_PART_TYPE_GUID_EMPTY) == 0) + continue; + + pe = part_entry_new (NULL, + (guint8*) &gpt_part_entry, + 128, + offset + partition_entry_lba * 512 + n * size_of_entry); + p->entries = g_slist_append (p->entries, pe); + + g_free (partition_type_guid); + + //hexdump ((guint8 *) &gpt_part_entry, 128); + + } + + +out: + HAL_INFO (("Leaving EFI GPT parser")); + return p; +} + +#define MAC_MAGIC "ER" +#define MAC_PART_MAGIC "PM" + +static PartitionTable * +part_table_parse_apple (int fd, guint64 offset, guint64 size) +{ + int n; + PartitionTable *p; + struct { + guint16 signature; + guint16 block_size; + guint32 block_count; + /* more stuff */ + } __attribute__ ((packed)) mac_header; + struct { + guint16 signature; + guint16 res1; + guint32 map_count; + guint32 start_block; + guint32 block_count; + char name[32]; + char type[32]; + guint32 data_start; + guint32 data_count; + guint32 status; + guint32 boot_start; + guint32 boot_size; + guint32 boot_load; + guint32 boot_load2; + guint32 boot_entry; + guint32 boot_entry2; + guint32 boot_cksum; + char processor[16]; /* identifies ISA of boot */ + /* more stuff */ + } __attribute__ ((packed)) mac_part; + int block_size; + int block_count; + int map_count; + + HAL_INFO (("Entering Apple parser")); + + p = NULL; + + /* Check Mac start of disk signature */ + if (lseek (fd, offset + 0, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &mac_header, sizeof (mac_header)) != sizeof (mac_header)) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + if (memcmp (&(mac_header.signature), MAC_MAGIC, 2) != 0) { + HAL_INFO (("No MAC_MAGIC found")); + goto out; + } + + block_size = GUINT16_FROM_BE (mac_header.block_size); + block_count = GUINT32_FROM_BE (mac_header.block_count); /* num blocks on whole disk */ + + HAL_INFO (("Mac MAGIC found, block_size=%d", block_size)); + + p = part_table_new_empty (PART_TYPE_APPLE); + p->offset = offset; + p->size = size; + + /* get number of entries from first entry */ + if (lseek (fd, offset + block_size, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + map_count = GUINT32_FROM_BE (mac_part.map_count); /* num blocks in part map */ + + HAL_INFO (("map_count = %d", map_count)); + + for (n = 0; n < map_count; n++) { + PartitionEntry *pe; + + if (memcmp (&(mac_part.signature), MAC_PART_MAGIC, 2) != 0) { + HAL_INFO (("No MAC_PART_MAGIC found")); + break; + } + + if (lseek (fd, offset + (n + 1) * block_size, SEEK_SET) < 0) { + HAL_INFO (("lseek failed (%s)", strerror (errno))); + goto out; + } + if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) { + HAL_INFO (("read failed (%s)", strerror (errno))); + goto out; + } + + pe = part_entry_new (NULL, + (guint8*) &mac_part, + sizeof (mac_part), + offset + (n + 1) * block_size); + p->entries = g_slist_append (p->entries, pe); + + } + +out: + HAL_INFO (("Leaving Apple parser")); + return p; +} + +PartitionTable * +part_table_load_from_disk (char *device) +{ + int fd; + guint64 size; + PartitionTable *p; + gboolean found_gpt; + + p = NULL; + + fd = open (device, O_RDONLY); + if (fd < 0) { + HAL_INFO (("Cannot open device %s", device)); + goto out; + } + + if (ioctl (fd, BLKGETSIZE64, &size) != 0) { + HAL_INFO (("Cannot determine size of device")); + goto out; + } + + p = part_table_parse_msdos (fd, 0, size, &found_gpt); + if (p != NULL) { + HAL_INFO (("MSDOS partition table detected")); + goto out; + } + + if (found_gpt) { + p = part_table_parse_gpt (fd, 0, size); + if (p != NULL) { + HAL_INFO (("EFI GPT partition table detected")); + goto out; + } + } + + p = part_table_parse_apple (fd, 0, size); + if (p != NULL) { + HAL_INFO (("Apple partition table detected")); + goto out; + } + + HAL_INFO (("No known partition table found")); + + +out: + if (fd >= 0) + close (fd); + + return p; +} + + + +PartitionScheme +part_table_get_scheme (PartitionTable *p) +{ + return p->scheme; +} + +int +part_table_get_num_entries (PartitionTable *p) +{ + return g_slist_length (p->entries); +} + +guint64 +part_table_get_offset (PartitionTable *p) +{ + return p->offset; +} + +guint64 +part_table_get_size (PartitionTable *p) +{ + return p->size; +} + +PartitionTable * +part_table_entry_get_nested (PartitionTable *p, int entry) +{ + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + if (pe->is_part_table) + return pe->part_table; + else + return NULL; +} + +/**************************************************************************/ + +char * +part_table_entry_get_type (PartitionTable *p, int entry) +{ + char *s = NULL; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + if (p == NULL) + goto out; + + switch (p->scheme) { + case PART_TYPE_GPT: + s = get_le_guid (&(pe->data[0])); + break; + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + s = g_strdup_printf ("0x%02x", pe->data[4]); + break; + case PART_TYPE_APPLE: + s = g_strdup ((char *) pe->data + 2*2 + 3*4 + 32); + g_strchomp (s); + break; + default: + break; + } +out: + if (s != NULL) { + g_strchomp (s); + } + return s; +} + +char * +part_table_entry_get_uuid (PartitionTable *p, int entry) +{ + char *s = NULL; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + if (p == NULL) + goto out; + + switch (p->scheme) { + case PART_TYPE_GPT: + s = get_le_guid (&(pe->data[16])); + break; + default: + break; + } +out: + if (s != NULL) { + g_strchomp (s); + } + return s; +} + +char * +part_table_entry_get_label (PartitionTable *p, int entry) +{ + char *s = NULL; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + if (p == NULL) + goto out; + + switch (p->scheme) { + case PART_TYPE_GPT: + s = g_utf16_to_utf8 ((const gunichar2 *) &(pe->data[56]), 36, NULL, NULL, NULL); + break; + case PART_TYPE_APPLE: + s = g_strdup ((char *) pe->data + 2*2 + 3*4); + g_strchomp (s); + break; + default: + break; + } +out: + if (s != NULL) { + g_strchomp (s); + } + return s; +} + +char ** +part_table_entry_get_flags (PartitionTable *p, int entry) +{ + int n; + char **ss = NULL; + guint32 apm_status; + guint64 gpt_attributes; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + if (p == NULL) + goto out; + + ss = g_new0 (char*, 6 + 1); /* hard coded to max items we'll return */ + ss[0] = NULL; + n = 0; + + switch (p->scheme) { + case PART_TYPE_GPT: + gpt_attributes = get_le64 (&(pe->data[48])); + + /* From Table 16 of EFI 2.0 spec, bit zero means: + * + * "Required for the platform to function. The system + * cannot function normally if this partition is + * removed. This partition should be considered as + * part of the hardware of the system, and if it is + * removed the system may not boot. It may contain + * diagnostics, recovery tools, or other code or data + * that is critical to the functioning of a system + * independent of any OS." + * + */ + if (gpt_attributes & (1<<0)) { + ss[n++] = g_strdup ("required"); + } + + /* TODO: handle partition type specific attributes + * + * Found on the Internet: "For basic data partitions, the following attribute is + * defined:0x8000000000000000 prevents the partition from having a drive letter automatically + * assigned. By default, each partition is assigned a new drive letter. Setting this + * attribute ensures that when a disk is moved to a new computer, a new drive letter + * will not be automatically generated. Instead, the user can manually assign drive + * letters. Note: Other attributes can be added at any time." + */ + break; + + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + if (pe->data[0] == 0x80) { + ss[n++] = g_strdup ("boot"); + } + break; + + case PART_TYPE_APPLE: + apm_status = get_be32 (&(pe->data[2*2 + 3*4 + 2*32 + 2*4])); + if (apm_status&(1<<1)) + ss[n++] = g_strdup ("allocated"); + if (apm_status&(1<<2)) + ss[n++] = g_strdup ("in_use"); + if (apm_status&(1<<3)) + ss[n++] = g_strdup ("boot"); + if (apm_status&(1<<4)) + ss[n++] = g_strdup ("allow_read"); + if (apm_status&(1<<5)) + ss[n++] = g_strdup ("allow_write"); + if (apm_status&(1<<6)) + ss[n++] = g_strdup ("boot_code_is_pic"); + break; + default: + break; + } + ss[n] = NULL; + +out: + return ss; +} + +guint64 +part_table_entry_get_offset (PartitionTable *p, int entry) +{ + guint64 val; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + val = G_MAXUINT64; + if (p == NULL) + goto out; + + switch (p->scheme) { + case PART_TYPE_GPT: + val = 0x200 * ((guint64) get_le64 (pe->data + 32)); + break; + + case PART_TYPE_MSDOS: + val = 0x200 * ((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; + break; + case PART_TYPE_APPLE: + val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 1*4)); + break; + default: + break; + } +out: + return val; +} + +guint64 +part_table_entry_get_size (PartitionTable *p, int entry) +{ + guint64 val; + PartitionEntry *pe = g_slist_nth_data (p->entries, entry); + + val = G_MAXUINT64; + if (p == NULL) + goto out; + + switch (p->scheme) { + case PART_TYPE_GPT: + val = 0x200 * (((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)); + break; + case PART_TYPE_APPLE: + val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 2*4)); + break; + default: + break; + } +out: + return val; +} + +/**************************************************************************/ + +#ifdef USE_PARTED + +/* internal function to both add OR change a partition - if size==0, + * then we're changing, otherwise we're adding + */ + +static gboolean +part_add_change_partition (char *device_file, + guint64 start, guint64 size, + guint64 new_start, guint64 new_size, + guint64 *out_start, guint64 *out_size, + char *type, char *label, char **flags, + int geometry_hps, int geometry_spt) +{ + int n; + gboolean is_change; + gboolean res; + PedDevice *device; + PedDisk *disk; + PedPartition *part; + PedConstraint* constraint; + PedPartitionType ped_type; + guint64 start_sector; + guint64 end_sector; + guint64 new_start_sector; + guint64 new_end_sector; + PartitionTable *p; + PartitionTable *container_p; + int container_entry; + PartitionScheme scheme; + guint8 mbr_flags = 0; + guint8 mbr_part_type = 0; + char *endp; + guint64 gpt_attributes = 0; + guint32 apm_status = 0; + + res = FALSE; + + is_change = FALSE; + if (size == 0) { + is_change = TRUE; + } + + if (is_change) { + HAL_INFO (("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s", device_file, start, new_start, new_size, type)); + } else { + HAL_INFO (("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type)); + } + + /* first, find the kind of (embedded) partition table the new partition is going to be part of */ + p = part_table_load_from_disk (device_file); + if (p == NULL) { + HAL_INFO (("Cannot load partition table from %s", device_file)); + goto out; + } + + part_table_find (p, start + 512, &container_p, &container_entry); + scheme = part_table_get_scheme (container_p); + + if (is_change) { + /* if changing, make sure there is a partition to change */ + if (container_entry < 0) { + HAL_INFO (("Couldn't find partition to change")); + goto out; + } + } else { + /* if adding, make sure there is no partition in the way... */ + if (container_entry >= 0) { + char *part_type; + + /* this might be Apple_Free if we're on PART_TYPE_APPLE */ + part_type = part_table_entry_get_type (p, container_entry); + if (! (p->scheme == PART_TYPE_APPLE && part_type != NULL && (strcmp (part_type, "Apple_Free") == 0))) { + part_table_free (p); + HAL_INFO (("There is a partition in the way on %s", device_file)); + goto out; + } + } + } + + HAL_INFO (("containing partition table scheme = %d", scheme)); + + part_table_free (p); + p = NULL; + + if (!is_change) { + if (type == NULL) { + HAL_INFO (("No type specified")); + goto out; + } + } + + /* now that we know the partitoning scheme, sanity check type and flags */ + switch (scheme) { + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + mbr_flags = 0; + if (flags != NULL) { + for (n = 0; flags[n] != NULL; n++) { + if (strcmp (flags[n], "boot") == 0) { + mbr_flags |= 0x80; + } else { + HAL_INFO (("unknown flag '%s'", flags[n])); + goto out; + } + } + } + + if (type != NULL) { + mbr_part_type = (guint8) (strtol (type, &endp, 0)); + if (*endp != '\0') { + HAL_INFO (("invalid type '%s' given", type)); + goto out; + } + } + + if (label != NULL) { + HAL_INFO (("labeled partitions not supported on MSDOS or MSDOS_EXTENDED")); + goto out; + } + + break; + + case PART_TYPE_GPT: + gpt_attributes = 0; + if (flags != NULL) { + for (n = 0; flags[n] != NULL; n++) { + if (strcmp (flags[n], "required") == 0) { + gpt_attributes |= 1; + } else { + HAL_INFO (("unknown flag '%s'", flags[n])); + goto out; + } + } + } + break; + + case PART_TYPE_APPLE: + apm_status = 0; + if (flags != NULL) { + for (n = 0; flags[n] != NULL; n++) { + if (strcmp (flags[n], "allocated") == 0) { + apm_status |= (1<<1); + } else if (strcmp (flags[n], "in_use") == 0) { + apm_status |= (1<<2); + } else if (strcmp (flags[n], "boot") == 0) { + apm_status |= (1<<3); + } else if (strcmp (flags[n], "allow_read") == 0) { + apm_status |= (1<<4); + } else if (strcmp (flags[n], "allow_write") == 0) { + apm_status |= (1<<5); + } else if (strcmp (flags[n], "boot_code_is_pic") == 0) { + apm_status |= (1<<6); + } else { + HAL_INFO (("unknown flag '%s'", flags[n])); + goto out; + } + } + } + break; + + default: + HAL_INFO (("partitioning scheme %d not supported", scheme)); + goto out; + } + + switch (scheme) { + case PART_TYPE_MSDOS: + if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) { + ped_type = PED_PARTITION_EXTENDED; + } else { + ped_type = PED_PARTITION_NORMAL; + } + break; + + case PART_TYPE_MSDOS_EXTENDED: + ped_type = PED_PARTITION_LOGICAL; + if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) { + HAL_INFO (("Cannot create an extended partition inside an extended partition")); + goto out; + } + break; + + default: + ped_type = PED_PARTITION_NORMAL; + break; + } + + /* now, create the partition */ + + start_sector = start / 512; + end_sector = (start + size) / 512 - 1; + new_start_sector = new_start / 512; + new_end_sector = (new_start + new_size) / 512 - 1; + + device = ped_device_get (device_file); + if (device == NULL) { + HAL_INFO (("ped_device_get() failed")); + goto out; + } + HAL_INFO (("got it")); + + /* set drive geometry on libparted object if the user requested it */ + if (geometry_hps > 0 && geometry_spt > 0 ) { + /* not sure this is authorized use of libparted, but, eh, it seems to work */ + device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt; + device->hw_geom.heads = device->bios_geom.heads = geometry_hps; + device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt; + } + + disk = ped_disk_new (device); + if (disk == NULL) { + HAL_INFO (("ped_disk_new() failed")); + goto out_ped_device; + } + HAL_INFO (("got disk")); + + if (!is_change) { + part = ped_partition_new (disk, + ped_type, + NULL, + start_sector, + end_sector); + if (part == NULL) { + HAL_INFO (("ped_partition_new() failed")); + goto out_ped_disk; + } + HAL_INFO (("new partition")); + } else { + part = ped_disk_get_partition_by_sector (disk, + start_sector); + if (part == NULL) { + HAL_INFO (("ped_partition_get_by_sector() failed")); + goto out_ped_disk; + } + HAL_INFO (("got partition")); + } + + + /* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of + * libparted - we poke at their internal data structures - but + * there ain't nothing we can do about it until libparted + * provides API for this... + */ + if (scheme == PART_TYPE_GPT) { + struct { + efi_guid type; + efi_guid uuid; + char name[37]; + int lvm; + int raid; + int boot; + int hp_service; + int hidden; + /* more stuff */ + } *gpt_data = (void *) part->disk_specific; + + if (type != NULL) { + if (!set_le_guid ((guint8*) &gpt_data->type, type)) { + HAL_INFO (("type '%s' for GPT appear to be malformed", type)); + goto out_ped_partition; + } + } + + if (flags != NULL) { + if (gpt_attributes & 1) { + gpt_data->hidden = 1; + } else { + gpt_data->hidden = 0; + } + } + + } else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED) { + struct { + unsigned char system; + int boot; + /* more stuff */ + } *dos_data = (void *) part->disk_specific; + + if (type != NULL) { + dos_data->system = mbr_part_type; + } + if (flags != NULL) { + if (mbr_flags & 0x80) { + dos_data->boot = 1; + } else { + dos_data->boot = 0; + } + } + + } else if (scheme == PART_TYPE_APPLE) { + struct { + char volume_name[33]; /* eg: "Games" */ + char system_name[33]; /* eg: "Apple_Unix_SVR2" */ + char processor_name[17]; + int is_boot; + int is_driver; + int has_driver; + int is_root; + int is_swap; + int is_lvm; + int is_raid; + PedSector data_region_length; + PedSector boot_region_length; + guint32 boot_base_address; + guint32 boot_entry_address; + guint32 boot_checksum; + guint32 status; + /* more stuff */ + } *mac_data = (void *) part->disk_specific; + + if (type != NULL) { + memset (mac_data->system_name, 0, 33); + strncpy (mac_data->system_name, type, 32); + } + + if (flags != NULL) { + mac_data->status = apm_status; + } + } + + if (label != NULL) { + ped_partition_set_name (part, label); + } + + if (geometry_hps > 0 && geometry_spt > 0 ) { + /* respect drive geometry */ + constraint = ped_constraint_any (device); + } else if (geometry_hps == -1 && geometry_spt == -1 ) { + + /* undocumented (or is it?) libparted usage again.. it appears that + * the probed geometry is stored in hw_geom + */ + device->bios_geom.cylinders = device->hw_geom.cylinders; + device->bios_geom.heads = device->hw_geom.heads; + device->bios_geom.sectors = device->hw_geom.sectors; + + constraint = ped_constraint_any (device); + } else { + PedGeometry *geo_start; + PedGeometry *geo_end; + + /* ignore drive geometry */ + if (is_change) { + geo_start = ped_geometry_new (device, new_start_sector, 1); + geo_end = ped_geometry_new (device, new_end_sector, 1); + } else { + geo_start = ped_geometry_new (device, start_sector, 1); + geo_end = ped_geometry_new (device, end_sector, 1); + } + + constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any, + geo_start, geo_end, 1, device->length); + } + +try_change_again: + if (is_change) { + if (ped_disk_set_partition_geom (disk, + part, + constraint, + new_start_sector, new_end_sector) == 0) { + HAL_INFO (("ped_disk_set_partition_geom() failed")); + goto out_ped_constraint; + } + } else { + if (ped_disk_add_partition (disk, + part, + constraint) == 0) { + HAL_INFO (("ped_disk_add_partition() failed")); + goto out_ped_constraint; + } + } + + *out_start = part->geom.start * 512; + *out_size = part->geom.length * 512; + + if (is_change) { + /* make sure the resulting size is never smaller than requested + * (this is because one will resize the FS and *then* change the partition table) + */ + if (*out_size < new_size) { + HAL_INFO (("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size)); + new_end_sector++; + goto try_change_again; + } else { + HAL_INFO (("changed partition to start=%lld size=%lld", *out_start, *out_size)); + } + } else { + HAL_INFO (("added partition start=%lld size=%lld", *out_start, *out_size)); + } + + + /* hmm, if we don't do this libparted crashes.. I assume that + * ped_disk_add_partition assumes ownership of the + * PedPartition when adding it... sadly this is not documented + * anywhere.. sigh.. + */ + part = NULL; + + /* use commit_to_dev rather than just commit to avoid + * libparted sending BLKRRPART to the kernel - we want to do + * this ourselves... + */ + if (ped_disk_commit_to_dev (disk) == 0) { + HAL_INFO (("ped_disk_commit_to_dev() failed")); + goto out_ped_constraint; + } + HAL_INFO (("committed to disk")); + + res = TRUE; + + ped_constraint_destroy (constraint); + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; + +out_ped_constraint: + ped_constraint_destroy (constraint); + +out_ped_partition: + if (part != NULL) { + ped_partition_destroy (part); + } + +out_ped_disk: + ped_disk_destroy (disk); + +out_ped_device: + ped_device_destroy (device); + +out: + return res; +} + +gboolean +part_add_partition (char *device_file, + guint64 start, guint64 size, + guint64 *out_start, guint64 *out_size, + char *type, char *label, char **flags, + int geometry_hps, int geometry_spt) +{ + return part_add_change_partition (device_file, + start, size, + 0, 0, + out_start, out_size, + type, label, flags, + geometry_hps, geometry_spt); +} + +gboolean +part_change_partition (char *device_file, + guint64 start, + guint64 new_start, guint64 new_size, + guint64 *out_start, guint64 *out_size, + char *type, char *label, char **flags, + int geometry_hps, int geometry_spt) +{ + return part_add_change_partition (device_file, + start, 0, + new_start, new_size, + out_start, out_size, + type, label, flags, + geometry_hps, geometry_spt); +} + +gboolean +part_del_partition (char *device_file, guint64 offset) +{ + gboolean ret; + PedDevice *device; + PedDisk *disk; + PedPartition *part; + PartitionTable *p; + gboolean is_extended; + int n; + + HAL_INFO (("In part_del_partition: device_file=%s, offset=%lld", device_file, offset)); + + ret = FALSE; + + + /* sigh.. one would think that if you passed the sector of where the + * the beginning of the extended partition starts, then _by_sector + * would return the same as _extended_partition. + * + * Sadly it's not so.. + * + * So, check if the passed offset actually corresponds to a nested + * partition table... + */ + is_extended = FALSE; + p = part_table_load_from_disk (device_file); + if (p == NULL) { + HAL_INFO (("Cannot load partition table from %s", device_file)); + goto out; + } + for (n = 0; n < part_table_get_num_entries (p); n++) { + PartitionTable *nested; + nested = part_table_entry_get_nested (p, n); + if (nested != NULL) { + if (part_table_get_offset (nested) == offset) { + HAL_INFO (("partition to delete is an extended partition")); + is_extended = TRUE; + } + } + } + part_table_free (p); + + device = ped_device_get (device_file); + if (device == NULL) { + HAL_INFO (("ped_device_get() failed")); + goto out; + } + HAL_INFO (("got it")); + + disk = ped_disk_new (device); + if (disk == NULL) { + HAL_INFO (("ped_disk_new() failed")); + goto out_ped_device; + } + HAL_INFO (("got disk")); + + if (is_extended) { + part = ped_disk_extended_partition (disk); + } else { + part = ped_disk_get_partition_by_sector (disk, offset / 512); + } + + if (part == NULL) { + HAL_INFO (("ped_disk_get_partition_by_sector() failed")); + goto out_ped_disk; + } + + HAL_INFO (("got partition - part->type=%d", part->type)); + /* allow only to delete primary, logical and extended partitions */ + if (! ((part->type == PED_PARTITION_NORMAL) || + (part->type == PED_PARTITION_LOGICAL) || + (part->type == PED_PARTITION_EXTENDED))) { + HAL_INFO (("no data partition at given offset %lld for device %s", offset, device_file)); + goto out_ped_disk; + } + + if (ped_disk_delete_partition (disk, part) == 0) { + HAL_INFO (("ped_disk_delete_partition() failed")); + goto out_ped_disk; + } + + /* use commit_to_dev rather than just commit to avoid + * libparted sending BLKRRPART to the kernel - we want to do + * this ourselves... + */ + + if (ped_disk_commit_to_dev (disk) == 0) { + HAL_INFO (("ped_disk_commit_to_dev() failed")); + goto out_ped_disk; + } + HAL_INFO (("committed to disk")); + + ret = TRUE; + + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; + +out_ped_disk: + ped_disk_destroy (disk); + +out_ped_device: + ped_device_destroy (device); + +out: + return ret; +} + +gboolean +part_create_partition_table (char *device_file, PartitionScheme scheme) +{ + PedDevice *device; + PedDisk *disk; + PedDiskType *disk_type; + gboolean ret; + + ret = FALSE; + + HAL_INFO (("In part_create_partition_table: device_file=%s, scheme=%d", device_file, scheme)); + + device = ped_device_get (device_file); + if (device == NULL) { + HAL_INFO (("ped_device_get() failed")); + goto out; + } + HAL_INFO (("got it")); + + switch (scheme) { + case PART_TYPE_MSDOS: + disk_type = ped_disk_type_get ("msdos"); + break; + case PART_TYPE_APPLE: + disk_type = ped_disk_type_get ("mac"); + break; + case PART_TYPE_GPT: + disk_type = ped_disk_type_get ("gpt"); + break; + default: + disk_type = NULL; + break; + } + + if (disk_type == NULL) { + HAL_INFO (("Unknown or unsupported partitioning scheme %d", scheme)); + goto out; + } + + disk = ped_disk_new_fresh (device, disk_type); + if (disk == NULL) { + HAL_INFO (("ped_disk_new_fresh() failed")); + goto out_ped_device; + } + HAL_INFO (("got disk")); + + if (ped_disk_commit_to_dev (disk) == 0) { + HAL_INFO (("ped_disk_commit_to_dev() failed")); + goto out_ped_disk; + } + HAL_INFO (("committed to disk")); + + ret = TRUE; + + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; + +out_ped_disk: + ped_disk_destroy (disk); + +out_ped_device: + ped_device_destroy (device); + +out: + return ret; +} + +#endif /* USE_PARTED */ + +/**************************************************************************/ diff --git a/partutil/partutil.h b/partutil/partutil.h new file mode 100644 index 00000000..61dec2f1 --- /dev/null +++ b/partutil/partutil.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * + * part.h : library for reading and writing partition tables - uses + * libparted for the heavy lifting + * + * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifndef PARTUTIL_H +#define PARTUTIL_H + +#include <stdio.h> +#include <glib.h> + +/* Partition schemes understood by this library */ +typedef enum { + PART_TYPE_MSDOS = 0, + PART_TYPE_MSDOS_EXTENDED = 1, + PART_TYPE_APPLE = 2, + PART_TYPE_GPT = 3 +} PartitionScheme; + +/** + * part_get_scheme_name: + * @scheme: the partitioning scheme + * + * Get a name for the partitioning scheme. The current mapping is used + * + * PART_TYPE_MSDOS -> mbr + * PART_TYPE_MSDOS_EXTENDED -> embr + * PART_TYPE_APPLE -> apm + * PART_TYPE_GPT -> gpt + * + * Returns: Name of scheme or NULL for unknown scheme. Caller shall not free this string. + */ +const char *part_get_scheme_name (PartitionScheme scheme); + +struct PartitionTable_s; +typedef struct PartitionTable_s PartitionTable; + + +/** + * part_table_load_from_disk: + * @device: name of device file for entire disk, e.g. /dev/sda + * + * Scans a disk and collect all partition entries and nested partition tables. + * + * Returns: A partition table object. Use part_table_free() to free this object. + */ +PartitionTable *part_table_load_from_disk (char *device); + +/** + * part_table_free: + * @part_table: the partition table + * + * Frees the partition table returned from part_table_load_from_disk(). + */ +void part_table_free (PartitionTable *part_table); + +/* partition table inspection */ + +/** + * part_table_get_scheme: + * @part_table: the partition table + * + * Get partitioning scheme. + * + * Returns: The partitioning scheme. + */ +PartitionScheme part_table_get_scheme (PartitionTable *part_table); + +/** + * part_table_get_num_entries: + * @part_table: the partition table + * + * Get number of entries in partition table. + * + * Returns: Number of entries. + */ +int part_table_get_num_entries (PartitionTable *part_table); + +/** + * part_table_get_offset: + * @part_table: the partition table + * + * Get offset from start of disk where partition table starts (as + * referenced in the partition table entry if it's an embedded + * partition table, otherwise zero for the full disk) + * + * Returns: offset, from start of disk, in bytes + */ +guint64 part_table_get_offset (PartitionTable *part_table); + +/** + * part_table_get_size: + * @part_table: the partition table + * + * Get size of partition table (as referenced in the partition table + * entry if it's an embedded partition table, otherwise the size of + * the full disk) + * + * Returns: size of partition, in bytes + */ +guint64 part_table_get_size (PartitionTable *part_table); + +/** + * part_table_find: + * @part_table: the partition table + * @offset: the offset to test for + * @out_part_table: where the (embedded) enclosing the entry will be stored + * @out_entry: there the partition table entry number will be stored + * + * This function finds the entry that a certain byte of the disk belongs to. + * As partition tables can be embedded (think MS-DOS extended partitions) + * the returned partition table (out_part_table) might be different from + * the one passed. If the offset belongs to a primary partition then the + * return partition_table will be the same as the passed one. + * + * If there is no partition at the given offset (might be free space), + * out_entry will be set to -1. Note that out_part_table will always + * be set though and free space in the primary disk space and the + * extended partition space differs. + * + * This is a convenience function. + */ +void part_table_find (PartitionTable *part_table, + guint64 offset, + PartitionTable **out_part_table, + int *out_entry); + + +/** + * part_table_entry_get_nested: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * If the partition table entry points to an embedded partition table this + * function will return a PartitionTable object representing it. + * + * Returns: NULL if the entry does not point to a an embedded partition table. + * Do not free with part_table_free() - the object will be freed when + * freeing the root object. + */ +PartitionTable *part_table_entry_get_nested (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_type: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Get the partition table type - the type itself is partitioning scheme + * specific as described below. + * + * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED, the type is an integer + * encoded in a string, e.g. 0x83 is Linux. Use atoi() to convert back to + * an integer. See http://www.win.tue.nl/~aeb/partitions/partition_types-1.html + * for details. + * + * For PART_TYPE_GPT, this is the GUID encoded as a string, see + * http://en.wikipedia.org/wiki/GUID_Partition_Table for details. + * + * For PART_TYPE_APPLE, this is a string as defined in + * http://developer.apple.com/documentation/mac/Devices/Devices-126.html. + * For FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" and + * "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf. + * http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html + * + * Returns: The partition table type. Caller shall free this with g_free(). + */ +char *part_table_entry_get_type (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_label: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Label of the partition. This is only supported for PART_TYPE_APPLE and + * PART_TYPE_GPT. Note that this is not the same as the file system label + * in a file system in the partition. + * + * Returns: The label or NULL if the partitioning scheme does not support + * labels. Caller shall free this with g_free(). + */ +char *part_table_entry_get_label (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_uuid: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Some UUID/GUID of the partition. This is only supported for PART_TYPE_GPT. + * + * Returns: The UUID or NULL if the partitioning scheme does not support + * UUID/GUID. Caller shall free this with g_free(). + */ +char *part_table_entry_get_uuid (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_flags: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Get flags of partition table entry. This is dependent on the partitioning + * scheme. + * + * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED the following flags are + * recognized: + * - "boot"; meaning that the bootable flag is set. This is used by some + * BIOS'es and boot loaders to populate a boot menu. + * + * For PART_TYPE_GPT the following flags are recognized: + * - "required" which corresponds to bit 0 of the attibutes + * (offset 48), meaning "Required for the platform to function. The + * system cannot function normally if this partition is removed. This + * partition should be considered as part of the hardware of the + * system, and if it is removed the system may not boot. It may + * contain diagnostics, recovery tools, or other code or data that is + * critical to the functioning of a system independent of any OS." + * + * + * For PART_TYPE_APPLE the following flags are recognized: + * - "allocated"; if the partition is already allocated + * - "in_use"; if the partition is in use; may be cleared after a system reset + * - "boot"; if partition contains valid boot information + * - "allow_read"; if partition allows reading + * - "allow_write"; if partition allows writing + * - "boot_code_is_pic"; if boot code is position independent + * + * Returns: An array of strings, one per flag, terminated by NULL. Caller + * shall free this with g_strfreev(). + */ +char **part_table_entry_get_flags (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_offset: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Get offset from start of disk where partition starts (as referenced in the + * partition table entry) + * + * Returns: offset, from start of disk, in bytes + */ +guint64 part_table_entry_get_offset (PartitionTable *part_table, int entry); + +/** + * part_table_entry_get_size: + * @part_table: the partition table + * @entry: zero-based index of entry in partition table + * + * Get size of partition (as referenced in the partition table entry) + * + * Returns: size of partition, in bytes + */ +guint64 part_table_entry_get_size (PartitionTable *part_table, int entry); + + +/** + * part_create_partition_table: + * @device: name of device file for entire disk, e.g. /dev/sda + * @scheme: the partitioning scheme + * + * Create a new fresh partition on a disk. + * + * Returns: TRUE if the operation was succesful, otherwise FALSE + */ +gboolean part_create_partition_table (char *device, PartitionScheme scheme); + + +/** + * part_add_partition: + * @device: name of device file for entire disk, e.g. /dev/sda + * @start: start offset of partition, in bytes + * @size: size of partition, in bytes + * @out_start: where partition will start, after satisfying disk geometry constraints + * @out_size: size of partition, after satisfying disk geometry constraints + * @type: the partition type as defined in part_table_entry_get_type() + * @flags: the partition flags as defined in part_table_entry_get_flags() + * @label: the partition label as defined in part_table_entry_get_label() + * @geometry_hps: heads-per-sector used for LBA<->CHS conversions + * @geometry_spt: sectors-per-track used for LBA<->CHS conversions + * + * Adds a new partition to a disk. + * + * If geometry_hps and geomtry_spt are both positive, they will be + * used as the geometry of the disk for CHS<->LBA conversions. Notably + * this is only applicable for MSDOS / MSDOS_EXTENDED partition + * tables. Also, in this case, geometry is enforced to ensure that + * partitions start and end at cylinder boundaries. + * + * If either geometry_hps or geomtry_spt are zero, geometry is + * simply ignored and partitions will only be aligned to blocks, e.g. + * normally 512 byte boundaries. + * + * If both geometry_hps or geomtry_spt are -1, then geometry information + * probed from existing partition table entries / file systems on the + * disk. This is not always reliable. + * + * As such, the caller cannot always expect that the partition created + * will be at the requested offset and size due to e.g. geometry and + * block boundary alignment. Therefore, the start and size where the + * partition ends up is passed in the out_start and out_size + * arguments. + * + * As embedded partition tables are supported, the caller should use + * part_table_find() in advance to make sure that the passed type, + * label and flags match the (embedded) partition table that this + * partition will be part of. + * + * To create an MSDOS extended partition table in a MSDOS partition + * table, simply pass 0x05, 0x0f or 0x85 as the partition type. + * + * In order for changes to take effect, the caller needs to poke the + * OS kernel himself to make it reload the partition table. It is not + * automatically done by this function. + * + * NOTE: After calling this function you need to discard any partition table + * obtained with part_table_load_from_disk() since the in-memory data structure + * is not updated. + * + * Returns: TRUE if the operation was succesful, otherwise FALSE + */ +gboolean part_add_partition (char *device, + guint64 start, guint64 size, + guint64 *out_start, guint64 *out_size, + char *type, char *label, char **flags, + int geometry_hps, int geometry_spt); + +/** + * @device: name of device file for entire disk, e.g. /dev/sda + * @start: start offset of existing partition, in bytes + * @new_start: new start offset of partition, in bytes + * @new_size: new size of partition, in bytes + * @out_start: where partition will start, after satisfying disk geometry constraints + * @out_size: size of partition, after satisfying disk geometry constraints + * @type: the partition type as defined in part_table_entry_get_type() or NULL to not change + * @flags: the partition flags as defined in part_table_entry_get_flags() or NULL to not change + * @label: the partition label as defined in part_table_entry_get_label() or NULL to not change + * @geometry_hps: heads-per-sector used for LBA<->CHS conversions + * @geometry_spt: sectors-per-track used for LBA<->CHS conversions + * + * Changes an existing partition table entry on disk. The contents of + * the partition will not be touched. + * + * XXX TODO FIXME: probably be careful with overlapping partitions as + * e.g. extended MS-DOS partitions have the partition information just + * before the partition data itself. Need to look into this. + * + * If new_start and new_size matches the existing start and size, only + * flags, label and type are changed. Any of flags, label and type can + * be set to NULL to signal there should be no change. Thus, this + * function serves two purposes. It can be used to both change offset and/or + * size and it can be used to change type and/or flags and/or label. + * + * See part_add_partition() for information about geometry_hps and + * geometry_spt and how it affects the resulting partition offset and + * size. This function gives one guarantee though: the resulting size + * will never be smaller than the requested size. This is useful for + * two-step operations by which a file system is first shrinked and + * then the partition table is updated. + * + * In order for changes to take effect, the caller needs to poke the + * OS kernel himself to make it reload the partition table. It is not + * automatically done by this function. + * + * NOTE: After calling this function you need to discard any partition + * table obtained with part_table_load_from_disk() since the in-memory + * data structure is not updated. + * + * Returns: TRUE if the operation was succesful, otherwise FALSE + */ +gboolean part_change_partition (char *device_file, + guint64 start, + guint64 new_start, guint64 new_size, + guint64 *out_start, guint64 *out_size, + char *type, char *label, char **flags, + int geometry_hps, int geometry_spt); + +/** + * part_del_partition: + * @device: name of device file for entire disk, e.g. /dev/sda + * @offset: offset of somewhere within the partition to delete, in bytes + * + * Deletes a partition. Just pass the offset of the partition. If you + * delete an extended partition all logical partitions will be deleted + * too. + * + * NOTE: After calling this function you need to discard any partition table + * obtained with part_table_load_from_disk() since the in-memory data structure + * is not updated. + * + * Returns: TRUE if the operation was succesful, otherwise FALSE + */ +gboolean part_del_partition (char *device, guint64 offset); + + +#endif /* PARTUTIL_H */ |