probe-volume.c revision b96e88d7982efdf721857ee071c9e6739bab83e9
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * probe-volume.c : probe volumes
b96e88d7982efdf721857ee071c9e6739bab83e9artem * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Use is subject to license terms.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
92f381329ebf1c2209df9608670666b32b291e05artem#pragma ident "%Z%%M% %I% %E% SMI"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Return a copy of a string without trailing spaces. If 'len' is non-zero,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * it specifies max length, otherwise the string must be null-terminated.
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic char *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *dst, *p;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (len == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *p-- = '\0';
18c2aff776a775d34a4c9893a4c72e0434d68e36artemset_fstyp_properties (LibHalContext *ctx, const char *udi, const char *fstype, nvlist_t *fsattr)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((cs = libhal_device_new_changeset (udi)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.fsusage", "filesystem");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.fstype", fstype);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* label */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) nvlist_lookup_string(fsattr, "gen_volume_label", &label_orig);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.label", label);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "info.product", label);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.label", "");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "info.product", buf);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (nvlist_lookup_string(fsattr, "gen_uuid", &uuid) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.uuid", uuid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.uuid", "");
7544909da5f7d5b467625910225a72e142c4b6b7artem * hsfs/iso9660 contents detection: Video DVD, Video CD, etc.
7544909da5f7d5b467625910225a72e142c4b6b7artemhsfs_contents(int fd, off_t probe_offset, LibHalContext *ctx, const char *udi)
7544909da5f7d5b467625910225a72e142c4b6b7artem * find 1st Primary Volume Descriptor
7544909da5f7d5b467625910225a72e142c4b6b7artem * PVD contains size and offset of the LSB/MSB path table
7544909da5f7d5b467625910225a72e142c4b6b7artem * Look through path table entries
7544909da5f7d5b467625910225a72e142c4b6b7artem /* load sectors on demand */
7544909da5f7d5b467625910225a72e142c4b6b7artem /* only interested in root directories */
7544909da5f7d5b467625910225a72e142c4b6b7artem if ((name_len < 2) || (name_len > IDE_MAX_NAME_LEN)) {
7544909da5f7d5b467625910225a72e142c4b6b7artem if (strncasecmp (name, "VIDEO_TS", min (8, name_len)) == 0) {
7544909da5f7d5b467625910225a72e142c4b6b7artem } else if (strncasecmp (name, "VCD", min (3, name_len)) == 0) {
7544909da5f7d5b467625910225a72e142c4b6b7artem } else if (strncasecmp (name, "SVCD", min (4, name_len)) == 0) {
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artemprobe_disc (int fd, LibHalContext *ctx, const char *udi, dbus_bool_t *has_data,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) get_disc_capacity_for_profile(fd, profile, &capacity);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * XXX for some reason CDROMREADTOCENTRY fails on video DVDs,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * but extracting the toc directly works okay.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (toc == NULL || !read_toc(fd, 0, 1, toc_size, toc)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* skip leadout */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((cs = libhal_device_new_changeset (udi)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_string (cs, "volume.disc.type", disc_type);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", is_blank);
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", *has_audio);
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem libhal_changeset_set_property_bool (cs, "volume.disc.has_data", *has_data);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", is_appendable);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", is_rewritable);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity);
7544909da5f7d5b467625910225a72e142c4b6b7artem libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", FALSE);
7544909da5f7d5b467625910225a72e142c4b6b7artem libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", FALSE);
7544909da5f7d5b467625910225a72e142c4b6b7artem libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", FALSE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Start with the 'basic' privilege set and then remove any
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * of the 'basic' privileges that will not be needed.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Clear privileges we will not need from the 'basic' set */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* for uscsi */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* to open logindevperm'd devices */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Set the permitted privilege set. */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Clear the limit set. */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unsigned int block_size;
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem dbus_bool_t has_data = TRUE; /* probe for fs by default */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *fstype;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Doing probe-volume for %s\n", device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (fd < 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (rfd < 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* if it's a floppy with no media, bail out */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* block size and total size */
b96e88d7982efdf721857ee071c9e6739bab83e9artem /* driver supports ioctl, but media is not available */
b96e88d7982efdf721857ee071c9e6739bab83e9artem /* driver does not support ioctl, e.g. lofi */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error);
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem if (!probe_disc (rfd, ctx, udi, &has_data, &has_audio)) {
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem /* with audio present, create volume even if fs probing fails */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* don't support partitioned floppy */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * first get partitioning info
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* for a dos drive find partition offset */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem partition_start = vtoc.v_part[partition_number].p_start * block_size;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem partition_start = gpt->efi_parts[partition_number].p_start * block_size;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * ignore duplicate partitions
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((volumes = libhal_manager_find_device_string_match (
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; i < num_volumes; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem continue; /* skip self */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * now determine fs type
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem * XXX We could get better performance from block device,
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem * but for now we use raw device because:
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem * - fstyp_udfs has a bug that it only works on raw
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem * - sd has a bug that causes extremely slow reads
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem * and incorrect probing of hybrid audio/data media
b941d3fc4e70b4411341c7aeb53517bbff5f2df4artem if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) ||