xref: /onnv-gate/usr/src/cmd/hal/probing/storage/probe-storage.c (revision 11329:b7b0c7106406)
12912Sartem /***************************************************************************
22912Sartem  *
32912Sartem  * probe-storage.c : Probe for storage devices
42912Sartem  *
5*11329Sgdamore@opensolaris.org  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
62912Sartem  * Use is subject to license terms.
72912Sartem  *
82912Sartem  * Licensed under the Academic Free License version 2.1
92912Sartem  *
102912Sartem  **************************************************************************/
112912Sartem 
122912Sartem #ifdef HAVE_CONFIG_H
132912Sartem #  include <config.h>
142912Sartem #endif
152912Sartem 
162912Sartem #include <errno.h>
172912Sartem #include <string.h>
182912Sartem #include <strings.h>
192912Sartem #include <ctype.h>
202912Sartem #include <stdlib.h>
212912Sartem #include <stdio.h>
222912Sartem #include <sys/ioctl.h>
232912Sartem #include <sys/types.h>
242912Sartem #include <sys/stat.h>
252912Sartem #include <fcntl.h>
262912Sartem #include <unistd.h>
272912Sartem #include <sys/mnttab.h>
282912Sartem #include <sys/fdio.h>
292912Sartem #include <sys/scsi/scsi.h>
302912Sartem #include <sys/vtoc.h>
312912Sartem #include <sys/efi_partition.h>
322912Sartem #include <priv.h>
332912Sartem 
342912Sartem #include <libhal.h>
352912Sartem #include <cdutils.h>
362912Sartem #include <fsutils.h>
372912Sartem #include <logger.h>
382912Sartem 
392912Sartem /** Check if a filesystem on a special device file is mounted
402912Sartem  *
412912Sartem  *  @param  device_file         Special device file, e.g. /dev/cdrom
422912Sartem  *  @return                     TRUE iff there is a filesystem system mounted
432912Sartem  *                              on the special device file
442912Sartem  */
452912Sartem static dbus_bool_t
is_mounted(const char * device_file)462912Sartem is_mounted (const char *device_file)
472912Sartem {
482912Sartem 	FILE *f;
492912Sartem 	dbus_bool_t rc = FALSE;
502912Sartem 	struct mnttab mp;
512912Sartem 	struct mnttab mpref;
522912Sartem 
532912Sartem 	if ((f = fopen ("/etc/mnttab", "r")) == NULL)
542912Sartem 		return rc;
552912Sartem 
562912Sartem 	bzero(&mp, sizeof (mp));
572912Sartem 	bzero(&mpref, sizeof (mpref));
582912Sartem 	mpref.mnt_special = (char *)device_file;
592912Sartem 	if (getmntany(f, &mp, &mpref) == 0) {
602912Sartem 		rc = TRUE;
612912Sartem 	}
622912Sartem 
632912Sartem 	fclose (f);
642912Sartem 	return rc;
652912Sartem }
662912Sartem 
672912Sartem static int
get_cdrom_properties_walker(void * arg,int profile,boolean_t is_current)682912Sartem get_cdrom_properties_walker (void *arg, int profile, boolean_t is_current)
692912Sartem {
702912Sartem 	LibHalChangeSet	*cs = (LibHalChangeSet *)arg;
712912Sartem 
722912Sartem 	switch (profile) {
732912Sartem 	case 0x09:
742912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE);
752912Sartem 		break;
762912Sartem 	case 0x0a:
772912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE);
782912Sartem 		break;
792912Sartem 	case 0x10:
802912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE);
812912Sartem 		break;
822912Sartem 	case 0x11:
832912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE);
842912Sartem 		break;
852912Sartem 	case 0x12:
862912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE);
872912Sartem 		break;
882912Sartem 	case 0x13:
892912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
902912Sartem 		break;
912912Sartem 	case 0x14:
922912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
932912Sartem 		break;
942912Sartem 	case 0x1a:
952912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE);
962912Sartem 		break;
972912Sartem 	case 0x1b:
982912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", TRUE);
992912Sartem 		break;
1002912Sartem 	case 0x2b:
1012912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE);
1022912Sartem 		break;
1032912Sartem 	case 0x40:
1042912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", TRUE);
1052912Sartem 		break;
1062912Sartem 	case 0x41:
1072912Sartem 	case 0x42:
1082912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", TRUE);
1092912Sartem 		break;
1102912Sartem 	case 0x43:
1112912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", TRUE);
1122912Sartem 		break;
1132912Sartem 	case 0x50:
1142912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", TRUE);
1152912Sartem 		break;
1162912Sartem 	case 0x51:
1172912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", TRUE);
1182912Sartem 		break;
1192912Sartem 	case 0x52:
1202912Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", TRUE);
1212912Sartem 		break;
1222912Sartem 	}
1232912Sartem 
1242912Sartem 	return CDUTIL_WALK_CONTINUE;
1252912Sartem }
1262912Sartem 
1272912Sartem #define	WSPLEN	64
1282912Sartem 
1292912Sartem static void
get_cdrom_properties(int fd,LibHalChangeSet * cs)1302912Sartem get_cdrom_properties (int fd, LibHalChangeSet *cs)
1312912Sartem {
1322912Sartem 	DBusError error;
1332912Sartem 	int capabilities;
1342912Sartem 	int read_speed, write_speed;
1352912Sartem 	intlist_t *write_speeds, *write_speeds_mem, *sp;
1362912Sartem 	int n_wspeeds;
1372912Sartem 	char **wspeeds;
1382912Sartem 	char *wspeeds_mem;
1392912Sartem 	int i;
1402912Sartem 
1412912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE);
1422912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE);
1432912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE);
1442912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE);
1452912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE);
1462912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE);
1472912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE);
1482912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE);
1492912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE);
1502912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE);
1512912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE);
1522912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE);
1532912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE);
1542912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE);
1552912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE);
1562912Sartem 
1572912Sartem 	walk_profiles(fd, get_cdrom_properties_walker, cs);
1582912Sartem 
1592912Sartem 	/* XXX */
1602912Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE);
1612912Sartem 
1622912Sartem 	get_read_write_speeds(fd, &read_speed, &write_speed, &write_speeds, &n_wspeeds, &write_speeds_mem);
1632912Sartem 
1642912Sartem 	libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed);
1652912Sartem 	libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", write_speed);
1662912Sartem 
1672912Sartem 	if (n_wspeeds <= 0) {
1682912Sartem 		wspeeds_mem = NULL;
1692912Sartem  		libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)&wspeeds_mem);
1702912Sartem 		return;
1712912Sartem 	}
1722912Sartem 	if ((wspeeds = (char **)calloc(n_wspeeds + 1, sizeof (char *))) == NULL) {
1732912Sartem 		free (write_speeds_mem);
1742912Sartem 		return;
1752912Sartem 	}
1762912Sartem 	if ((wspeeds_mem = (char *)calloc(n_wspeeds, WSPLEN)) == NULL) {
1772912Sartem 		free (wspeeds);
1782912Sartem 		free (write_speeds_mem);
1792912Sartem 		return;
1802912Sartem 	}
1812912Sartem 	for (i = 0; i < n_wspeeds; i++) {
1822912Sartem 		wspeeds[i] = &wspeeds_mem[i * WSPLEN];
1832912Sartem 	}
1842912Sartem 
1852912Sartem 	for (sp = write_speeds, i = 0; sp != NULL; sp = sp->next, i++) {
1862912Sartem 		snprintf (wspeeds[i], WSPLEN, "%d", sp->val);
1872912Sartem 	}
1882912Sartem 	libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)wspeeds);
1892912Sartem 
1902912Sartem 	free (wspeeds);
1912912Sartem 	free (wspeeds_mem);
1922912Sartem 	free (write_speeds_mem);
1932912Sartem }
1942912Sartem 
1952912Sartem /*
1962912Sartem  * Return a copy of a string without trailing spaces. If 'len' is non-zero,
1972912Sartem  * it specifies max length, otherwise the string must be null-terminated.
1982912Sartem  */
1992912Sartem char *
rtrim_copy(char * src,int len)2002912Sartem rtrim_copy(char *src, int len)
2012912Sartem {
2022912Sartem 	char	*dst, *p;
2032912Sartem 
2042912Sartem 	if (len == 0) {
2052912Sartem 		len = strlen(src);
2062912Sartem 	}
2072912Sartem 	if ((dst = calloc(1, len + 1)) != NULL) {
2082912Sartem 		strncpy(dst, src, len);
2092912Sartem 		p = dst + len - 1;
2102912Sartem 		while ((p >= dst) && (isspace(*p))) {
2112912Sartem 			*p-- = '\0';
2122912Sartem 		}
2132912Sartem 	}
2142912Sartem 	return (dst);
2152912Sartem }
2162912Sartem 
2172912Sartem static void
get_disk_properties(int fd,LibHalChangeSet * cs)2182912Sartem get_disk_properties (int fd, LibHalChangeSet *cs)
2192912Sartem {
2202912Sartem 	struct scsi_inquiry inq;
2212912Sartem 	struct uscsi_cmd ucmd;
2222912Sartem 	union scsi_cdb  cdb;
2232912Sartem 	int		status;
2242912Sartem 	char		*s;
2252912Sartem 
2262912Sartem 	/* INQUIRY */
2272912Sartem 	(void) memset((void *) &inq, 0, sizeof (inq));
2282912Sartem 	(void) memset((void *) &ucmd, 0, sizeof (ucmd));
2292912Sartem 	(void) memset((void *) &cdb, 0, sizeof (union scsi_cdb));
2302912Sartem 	cdb.scc_cmd = SCMD_INQUIRY;
2312912Sartem 	FORMG0COUNT(&cdb, sizeof (inq));
2322912Sartem 	ucmd.uscsi_cdb = (caddr_t) & cdb;
2332912Sartem 	ucmd.uscsi_cdblen = CDB_GROUP0;
2342912Sartem 	ucmd.uscsi_bufaddr = (caddr_t) & inq;
2352912Sartem 	ucmd.uscsi_buflen = sizeof (inq);
2362912Sartem 	ucmd.uscsi_timeout = 30;
2372912Sartem 	ucmd.uscsi_flags = USCSI_READ;
2382912Sartem 	status = ioctl(fd, USCSICMD, &ucmd);
2392912Sartem 	if (status || ucmd.uscsi_status) {
2402912Sartem 		return;
2412912Sartem 	}
2422912Sartem 
2432912Sartem 	if ((s = rtrim_copy(inq.inq_vid, sizeof (inq.inq_vid))) != NULL) {
2442912Sartem 		libhal_changeset_set_property_string (cs, "storage.vendor", s);
2452912Sartem 		free(s);
2462912Sartem 	}
2472912Sartem 	if ((s = rtrim_copy(inq.inq_pid, sizeof (inq.inq_pid))) != NULL) {
2482912Sartem 		libhal_changeset_set_property_string (cs, "storage.model", s);
2492912Sartem 		free(s);
2502912Sartem 	}
2512912Sartem 	if ((s = rtrim_copy(inq.inq_revision, sizeof (inq.inq_revision))) != NULL) {
2522912Sartem 		libhal_changeset_set_property_string (cs, "storage.firmware_revision", s);
2532912Sartem 		free(s);
2542912Sartem 	}
2552912Sartem 	if ((s = rtrim_copy(inq.inq_serial, sizeof (inq.inq_serial))) != NULL) {
2562912Sartem 		libhal_changeset_set_property_string (cs, "storage.serial", s);
2572912Sartem 		free(s);
2582912Sartem 	}
2592912Sartem }
2602912Sartem 
2612912Sartem /*
2622912Sartem  * returns TRUE if diskette is inserted.
2632912Sartem  * also returns write protection status.
2642912Sartem  */
2652912Sartem static dbus_bool_t
check_floppy(int fd,dbus_bool_t * wprot)2662912Sartem check_floppy(int fd, dbus_bool_t *wprot)
2672912Sartem {
2682912Sartem 	int	chg;
2692912Sartem 
2702912Sartem 	if ((ioctl(fd, FDGETCHANGE, &chg) == 0) && !(chg & FDGC_CURRENT)) {
2712912Sartem 		*wprot = ((chg & FDGC_CURWPROT) != NULL);
2722912Sartem 		return (TRUE);
2732912Sartem 	} else {
2742912Sartem 		return (FALSE);
2752912Sartem 	}
2762912Sartem }
2772912Sartem 
2782912Sartem void
drop_privileges()2792912Sartem drop_privileges ()
2802912Sartem {
2812912Sartem 	priv_set_t *pPrivSet = NULL;
2822912Sartem 	priv_set_t *lPrivSet = NULL;
2832912Sartem 
2842912Sartem 	/*
2852912Sartem 	 * Start with the 'basic' privilege set and then remove any
2862912Sartem 	 * of the 'basic' privileges that will not be needed.
2872912Sartem 	 */
2882912Sartem 	if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
2892912Sartem 		return;
2902912Sartem 	}
2912912Sartem 
2922912Sartem 	/* Clear privileges we will not need from the 'basic' set */
2932912Sartem 	(void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
2942912Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_INFO);
2952912Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
2962912Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
2972912Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_FORK);
2982912Sartem 
2992912Sartem 	/* for uscsi */
3002912Sartem 	(void) priv_addset(pPrivSet, PRIV_SYS_DEVICES);
3012912Sartem 
3022912Sartem 	/* to open logindevperm'd devices */
3032912Sartem 	(void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
3042912Sartem 
3052912Sartem 	/* Set the permitted privilege set. */
3062912Sartem 	if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
3072912Sartem 		return;
3082912Sartem 	}
3092912Sartem 
3102912Sartem 	/* Clear the limit set. */
3112912Sartem 	if ((lPrivSet = priv_allocset()) == NULL) {
3122912Sartem 		return;
3132912Sartem 	}
3142912Sartem 
3152912Sartem 	priv_emptyset(lPrivSet);
3162912Sartem 
3172912Sartem 	if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
3182912Sartem 		return;
3192912Sartem 	}
3202912Sartem 
3212912Sartem 	priv_freeset(lPrivSet);
3222912Sartem }
3232912Sartem 
3242912Sartem int
main(int argc,char * argv[])3252912Sartem main (int argc, char *argv[])
3262912Sartem {
3272912Sartem 	int ret = 1;
3282912Sartem 	int fd = -1;
3292912Sartem 	int rfd = -1;
3302912Sartem 	char *udi;
3312912Sartem 	char *device_file;
3322912Sartem 	char *raw_device_file;
3332912Sartem 	LibHalContext *ctx = NULL;
3342912Sartem 	DBusError error;
3352912Sartem 	char *drive_type;
3362912Sartem 	dbus_bool_t is_cdrom;
3372912Sartem 	dbus_bool_t is_floppy;
3382912Sartem 	struct dk_minfo minfo;
339*11329Sgdamore@opensolaris.org 	int rdonly;
3406395Sartem 	unsigned int block_size = 512;
3412912Sartem 	dbus_bool_t only_check_for_media;
3422912Sartem 	int got_media = FALSE;
3432912Sartem 	dbus_bool_t is_write_protected = FALSE;
3442912Sartem 	dbus_bool_t is_mbr = FALSE;
3452912Sartem 	dbus_bool_t is_smi = FALSE;
3462912Sartem 	dbus_bool_t is_gpt = FALSE;
3472912Sartem 	dbus_bool_t is_partitioned = FALSE;
3482912Sartem 	dbus_bool_t vtoc_slices = FALSE;
3492912Sartem 	int dos_cnt = 0;
3502912Sartem 	const char *scheme = "";
3517563SPrasad.Singamsetty@Sun.COM 	struct extvtoc vtoc;
3522912Sartem 	dk_gpt_t *gpt;
3532912Sartem 	LibHalChangeSet *cs = NULL;
3542912Sartem 
3552912Sartem 	if ((udi = getenv ("UDI")) == NULL)
3562912Sartem 		goto out;
3572912Sartem 	if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
3582912Sartem 		goto out;
3592912Sartem 	if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
3602912Sartem 		goto out;
3612912Sartem 	if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
3622912Sartem 		goto out;
3632912Sartem 
3642912Sartem 	drop_privileges ();
3652912Sartem 
3662912Sartem 	setup_logger ();
3672912Sartem 
3682912Sartem 	if (argc == 2 && strcmp (argv[1], "--only-check-for-media") == 0)
3692912Sartem 		only_check_for_media = TRUE;
3702912Sartem 	else
3712912Sartem 		only_check_for_media = FALSE;
3722912Sartem 
3732912Sartem 	is_cdrom = (strcmp (drive_type, "cdrom") == 0);
3742912Sartem 	is_floppy = (strcmp (drive_type, "floppy") == 0);
3752912Sartem 
3762912Sartem 	dbus_error_init (&error);
3772912Sartem 	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
3782912Sartem 		goto out;
3792912Sartem 
3802912Sartem 	if ((cs = libhal_device_new_changeset (udi)) == NULL) {
3812912Sartem 		HAL_DEBUG (("Cannot allocate changeset"));
3822912Sartem 		goto out;
3832912Sartem 	}
3842912Sartem 
3853121Sartem 	HAL_DEBUG (("Doing probe-storage for %s (drive_type %s) (udi=%s) (--only-check-for-media==%d)",
3863121Sartem 	     device_file, drive_type, udi, only_check_for_media));
3872912Sartem 
3882912Sartem 	if ((rfd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0) {
3892912Sartem 		HAL_DEBUG (("Cannot open %s: %s", raw_device_file, strerror (errno)));
3902912Sartem 		goto out;
3912912Sartem 	}
3922912Sartem 
3932912Sartem 	if (!only_check_for_media) {
3942912Sartem 		if (strcmp (drive_type, "cdrom") == 0) {
3952912Sartem 			get_cdrom_properties (rfd, cs);
3962912Sartem 		} else if (strcmp (drive_type, "disk") == 0) {
3972912Sartem 			get_disk_properties (rfd, cs);
3982912Sartem 		}
3992912Sartem 	}
4002912Sartem 
4012912Sartem 	ret = 0;
4022912Sartem 
4032912Sartem 	if (is_cdrom) {
4042912Sartem 		HAL_DEBUG (("Checking for optical disc on %s", raw_device_file));
4052912Sartem 		got_media = get_media_info(rfd, &minfo);
4062912Sartem 		if (!got_media) {
4072912Sartem 			goto out_cs;
4082912Sartem 		}
4096395Sartem 		block_size = minfo.dki_lbsize;
4102912Sartem 		/* XXX */
4112912Sartem 		is_write_protected = TRUE;
4122912Sartem 	} else if (is_floppy) {
4132912Sartem 		HAL_DEBUG (("Checking for floppy on %s", raw_device_file));
4142912Sartem 		if (check_floppy(rfd, &is_write_protected)) {
4152912Sartem 			got_media = TRUE;
4162912Sartem 		}
4172912Sartem 		/* don't look for partitions on floppy */
4182912Sartem 		goto out_cs;
4192912Sartem 	} else {
420*11329Sgdamore@opensolaris.org 		got_media = get_media_info(rfd, &minfo);
421*11329Sgdamore@opensolaris.org 		if (!got_media) {
422*11329Sgdamore@opensolaris.org 			goto out_cs;
423*11329Sgdamore@opensolaris.org 		}
424*11329Sgdamore@opensolaris.org 		block_size = minfo.dki_lbsize;
425*11329Sgdamore@opensolaris.org 		if ((ioctl(rfd, DKIOCREADONLY, &rdonly) == 0) && rdonly) {
426*11329Sgdamore@opensolaris.org 			is_write_protected = TRUE;
4276395Sartem 		}
4282912Sartem 	}
4292912Sartem 
4302912Sartem 	HAL_DEBUG (("Checking for partitions on %s", device_file));
4312912Sartem 
4322912Sartem 	if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
4332912Sartem 		HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
4342912Sartem 		goto out_cs;
4352912Sartem 	}
4362912Sartem 
4376395Sartem 	dos_cnt = get_num_dos_drives(fd, block_size);
4382912Sartem 	is_mbr = (dos_cnt > 0);
4392912Sartem 	if (is_mbr) {
4402912Sartem 		scheme = "mbr";
4412912Sartem 	}
4427563SPrasad.Singamsetty@Sun.COM 	if (read_extvtoc(rfd, &vtoc) >= 0) {
4432912Sartem 		if (!vtoc_one_slice_entire_disk(&vtoc)) {
4442912Sartem 			is_smi = TRUE;
4452912Sartem 			if (!is_mbr) {
4462912Sartem 				/* smi within mbr partition is okay */
4472912Sartem 				scheme = "smi";
4482912Sartem 			}
4492912Sartem 			vtoc_slices = TRUE;
4502912Sartem 		}
4512912Sartem 	} else if (!is_cdrom && (efi_alloc_and_read(rfd, &gpt) >= 0)) {
4522912Sartem 		/*
4532912Sartem 		 * Note: for some reason efi_read takes very long on cdroms.
4542912Sartem 		 * Needs more investigation, skip gpt on cdrom for now.
4552912Sartem 		 */
4562912Sartem 		is_gpt = TRUE;
4572912Sartem 		scheme = "gpt";
4582912Sartem 		efi_free(gpt);
4592912Sartem 	}
4602912Sartem 
4612912Sartem out_cs:
4622912Sartem 	is_partitioned = is_mbr || is_smi || is_gpt;
4632912Sartem 	libhal_changeset_set_property_bool (cs, "storage.no_partitions_hint", !is_partitioned);
4642912Sartem 	libhal_changeset_set_property_bool (cs, "block.no_partitions", !is_partitioned);
4652912Sartem 	libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", scheme);
4662912Sartem 	libhal_changeset_set_property_bool (cs, "storage.solaris.vtoc_slices", vtoc_slices);
4672912Sartem 	libhal_changeset_set_property_int (cs, "storage.solaris.num_dos_partitions", dos_cnt);
4682912Sartem 	/* XXX should only set for removable drives */
4692912Sartem 	libhal_changeset_set_property_bool (cs, "storage.removable.media_available", got_media);
4702912Sartem 	libhal_changeset_set_property_bool (cs, "storage.removable.solaris.read_only", is_write_protected);
4712912Sartem 
4722912Sartem 	libhal_device_commit_changeset (ctx, cs, &error);
4732912Sartem 
4742912Sartem out:
4752912Sartem 	if (cs != NULL) {
4762912Sartem 		libhal_device_free_changeset (cs);
4772912Sartem 	}
4782912Sartem 	if (fd >= 0) {
4792912Sartem 		close (fd);
4802912Sartem 	}
4812912Sartem 	if (rfd >= 0) {
4822912Sartem 		close (rfd);
4832912Sartem 	}
4842912Sartem 	if (ctx != NULL) {
4852912Sartem 		if (dbus_error_is_set(&error)) {
4862912Sartem 			dbus_error_free (&error);
4872912Sartem 		}
4882912Sartem 		libhal_ctx_shutdown (ctx, &error);
4892912Sartem 		libhal_ctx_free (ctx);
4902912Sartem 	}
4912912Sartem 
4922912Sartem 	return ret;
4932912Sartem }
494