xref: /illumos-gate/usr/src/cmd/hal/probing/storage/probe-storage.c (revision 32248f11785f2b2ee12fa041aa8a92932c1245ca)
118c2aff7Sartem /***************************************************************************
218c2aff7Sartem  *
318c2aff7Sartem  * probe-storage.c : Probe for storage devices
418c2aff7Sartem  *
534de8762SGarrett D'Amore  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
618c2aff7Sartem  * Use is subject to license terms.
718c2aff7Sartem  *
818c2aff7Sartem  * Licensed under the Academic Free License version 2.1
918c2aff7Sartem  *
1018c2aff7Sartem  **************************************************************************/
1118c2aff7Sartem 
1218c2aff7Sartem #ifdef HAVE_CONFIG_H
1318c2aff7Sartem #  include <config.h>
1418c2aff7Sartem #endif
1518c2aff7Sartem 
1618c2aff7Sartem #include <errno.h>
1718c2aff7Sartem #include <string.h>
1818c2aff7Sartem #include <strings.h>
1918c2aff7Sartem #include <ctype.h>
2018c2aff7Sartem #include <stdlib.h>
2118c2aff7Sartem #include <stdio.h>
2218c2aff7Sartem #include <sys/ioctl.h>
2318c2aff7Sartem #include <sys/types.h>
2418c2aff7Sartem #include <sys/stat.h>
2518c2aff7Sartem #include <fcntl.h>
2618c2aff7Sartem #include <unistd.h>
2718c2aff7Sartem #include <sys/mnttab.h>
2818c2aff7Sartem #include <sys/fdio.h>
2918c2aff7Sartem #include <sys/scsi/scsi.h>
3018c2aff7Sartem #include <sys/vtoc.h>
3118c2aff7Sartem #include <sys/efi_partition.h>
3218c2aff7Sartem #include <priv.h>
3318c2aff7Sartem 
3418c2aff7Sartem #include <libhal.h>
3518c2aff7Sartem #include <cdutils.h>
3618c2aff7Sartem #include <fsutils.h>
3718c2aff7Sartem #include <logger.h>
3818c2aff7Sartem 
3918c2aff7Sartem /** Check if a filesystem on a special device file is mounted
4018c2aff7Sartem  *
4118c2aff7Sartem  *  @param  device_file         Special device file, e.g. /dev/cdrom
4218c2aff7Sartem  *  @return                     TRUE iff there is a filesystem system mounted
4318c2aff7Sartem  *                              on the special device file
4418c2aff7Sartem  */
4518c2aff7Sartem static dbus_bool_t
is_mounted(const char * device_file)4618c2aff7Sartem is_mounted (const char *device_file)
4718c2aff7Sartem {
4818c2aff7Sartem 	FILE *f;
4918c2aff7Sartem 	dbus_bool_t rc = FALSE;
5018c2aff7Sartem 	struct mnttab mp;
5118c2aff7Sartem 	struct mnttab mpref;
5218c2aff7Sartem 
5318c2aff7Sartem 	if ((f = fopen ("/etc/mnttab", "r")) == NULL)
5418c2aff7Sartem 		return rc;
5518c2aff7Sartem 
5618c2aff7Sartem 	bzero(&mp, sizeof (mp));
5718c2aff7Sartem 	bzero(&mpref, sizeof (mpref));
5818c2aff7Sartem 	mpref.mnt_special = (char *)device_file;
5918c2aff7Sartem 	if (getmntany(f, &mp, &mpref) == 0) {
6018c2aff7Sartem 		rc = TRUE;
6118c2aff7Sartem 	}
6218c2aff7Sartem 
6318c2aff7Sartem 	fclose (f);
6418c2aff7Sartem 	return rc;
6518c2aff7Sartem }
6618c2aff7Sartem 
6718c2aff7Sartem static int
get_cdrom_properties_walker(void * arg,int profile,boolean_t is_current)6818c2aff7Sartem get_cdrom_properties_walker (void *arg, int profile, boolean_t is_current)
6918c2aff7Sartem {
7018c2aff7Sartem 	LibHalChangeSet	*cs = (LibHalChangeSet *)arg;
7118c2aff7Sartem 
7218c2aff7Sartem 	switch (profile) {
7318c2aff7Sartem 	case 0x09:
7418c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE);
7518c2aff7Sartem 		break;
7618c2aff7Sartem 	case 0x0a:
7718c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE);
7818c2aff7Sartem 		break;
7918c2aff7Sartem 	case 0x10:
8018c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE);
8118c2aff7Sartem 		break;
8218c2aff7Sartem 	case 0x11:
8318c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE);
8418c2aff7Sartem 		break;
8518c2aff7Sartem 	case 0x12:
8618c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE);
8718c2aff7Sartem 		break;
8818c2aff7Sartem 	case 0x13:
8918c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
9018c2aff7Sartem 		break;
9118c2aff7Sartem 	case 0x14:
9218c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
9318c2aff7Sartem 		break;
9418c2aff7Sartem 	case 0x1a:
9518c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE);
9618c2aff7Sartem 		break;
9718c2aff7Sartem 	case 0x1b:
9818c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", TRUE);
9918c2aff7Sartem 		break;
10018c2aff7Sartem 	case 0x2b:
10118c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE);
10218c2aff7Sartem 		break;
10318c2aff7Sartem 	case 0x40:
10418c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", TRUE);
10518c2aff7Sartem 		break;
10618c2aff7Sartem 	case 0x41:
10718c2aff7Sartem 	case 0x42:
10818c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", TRUE);
10918c2aff7Sartem 		break;
11018c2aff7Sartem 	case 0x43:
11118c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", TRUE);
11218c2aff7Sartem 		break;
11318c2aff7Sartem 	case 0x50:
11418c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", TRUE);
11518c2aff7Sartem 		break;
11618c2aff7Sartem 	case 0x51:
11718c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", TRUE);
11818c2aff7Sartem 		break;
11918c2aff7Sartem 	case 0x52:
12018c2aff7Sartem 		libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", TRUE);
12118c2aff7Sartem 		break;
12218c2aff7Sartem 	}
12318c2aff7Sartem 
12418c2aff7Sartem 	return CDUTIL_WALK_CONTINUE;
12518c2aff7Sartem }
12618c2aff7Sartem 
12718c2aff7Sartem #define	WSPLEN	64
12818c2aff7Sartem 
12918c2aff7Sartem static void
get_cdrom_properties(int fd,LibHalChangeSet * cs)13018c2aff7Sartem get_cdrom_properties (int fd, LibHalChangeSet *cs)
13118c2aff7Sartem {
13218c2aff7Sartem 	DBusError error;
13318c2aff7Sartem 	int capabilities;
13418c2aff7Sartem 	int read_speed, write_speed;
13518c2aff7Sartem 	intlist_t *write_speeds, *write_speeds_mem, *sp;
13618c2aff7Sartem 	int n_wspeeds;
13718c2aff7Sartem 	char **wspeeds;
13818c2aff7Sartem 	char *wspeeds_mem;
13918c2aff7Sartem 	int i;
14018c2aff7Sartem 
14118c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE);
14218c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE);
14318c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE);
14418c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE);
14518c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE);
14618c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE);
14718c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE);
14818c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE);
14918c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE);
15018c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE);
15118c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE);
15218c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE);
15318c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE);
15418c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE);
15518c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE);
15618c2aff7Sartem 
15718c2aff7Sartem 	walk_profiles(fd, get_cdrom_properties_walker, cs);
15818c2aff7Sartem 
15918c2aff7Sartem 	/* XXX */
16018c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE);
16118c2aff7Sartem 
16218c2aff7Sartem 	get_read_write_speeds(fd, &read_speed, &write_speed, &write_speeds, &n_wspeeds, &write_speeds_mem);
16318c2aff7Sartem 
16418c2aff7Sartem 	libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed);
16518c2aff7Sartem 	libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", write_speed);
16618c2aff7Sartem 
16718c2aff7Sartem 	if (n_wspeeds <= 0) {
16818c2aff7Sartem 		wspeeds_mem = NULL;
16918c2aff7Sartem 		libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)&wspeeds_mem);
17018c2aff7Sartem 		return;
17118c2aff7Sartem 	}
17218c2aff7Sartem 	if ((wspeeds = (char **)calloc(n_wspeeds + 1, sizeof (char *))) == NULL) {
17318c2aff7Sartem 		free (write_speeds_mem);
17418c2aff7Sartem 		return;
17518c2aff7Sartem 	}
17618c2aff7Sartem 	if ((wspeeds_mem = (char *)calloc(n_wspeeds, WSPLEN)) == NULL) {
17718c2aff7Sartem 		free (wspeeds);
17818c2aff7Sartem 		free (write_speeds_mem);
17918c2aff7Sartem 		return;
18018c2aff7Sartem 	}
18118c2aff7Sartem 	for (i = 0; i < n_wspeeds; i++) {
18218c2aff7Sartem 		wspeeds[i] = &wspeeds_mem[i * WSPLEN];
18318c2aff7Sartem 	}
18418c2aff7Sartem 
18518c2aff7Sartem 	for (sp = write_speeds, i = 0; sp != NULL; sp = sp->next, i++) {
18618c2aff7Sartem 		snprintf (wspeeds[i], WSPLEN, "%d", sp->val);
18718c2aff7Sartem 	}
18818c2aff7Sartem 	libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)wspeeds);
18918c2aff7Sartem 
19018c2aff7Sartem 	free (wspeeds);
19118c2aff7Sartem 	free (wspeeds_mem);
19218c2aff7Sartem 	free (write_speeds_mem);
19318c2aff7Sartem }
19418c2aff7Sartem 
19518c2aff7Sartem /*
19618c2aff7Sartem  * Return a copy of a string without trailing spaces. If 'len' is non-zero,
19718c2aff7Sartem  * it specifies max length, otherwise the string must be null-terminated.
19818c2aff7Sartem  */
19918c2aff7Sartem char *
rtrim_copy(char * src,int len)20018c2aff7Sartem rtrim_copy(char *src, int len)
20118c2aff7Sartem {
20218c2aff7Sartem 	char	*dst, *p;
20318c2aff7Sartem 
20418c2aff7Sartem 	if (len == 0) {
20518c2aff7Sartem 		len = strlen(src);
20618c2aff7Sartem 	}
20718c2aff7Sartem 	if ((dst = calloc(1, len + 1)) != NULL) {
20818c2aff7Sartem 		strncpy(dst, src, len);
20918c2aff7Sartem 		p = dst + len - 1;
21018c2aff7Sartem 		while ((p >= dst) && (isspace(*p))) {
21118c2aff7Sartem 			*p-- = '\0';
21218c2aff7Sartem 		}
21318c2aff7Sartem 	}
21418c2aff7Sartem 	return (dst);
21518c2aff7Sartem }
21618c2aff7Sartem 
21718c2aff7Sartem static void
get_disk_properties(int fd,LibHalChangeSet * cs)21818c2aff7Sartem get_disk_properties (int fd, LibHalChangeSet *cs)
21918c2aff7Sartem {
22018c2aff7Sartem 	struct scsi_inquiry inq;
22118c2aff7Sartem 	struct uscsi_cmd ucmd;
22218c2aff7Sartem 	union scsi_cdb  cdb;
22318c2aff7Sartem 	int		status;
22418c2aff7Sartem 	char		*s;
22518c2aff7Sartem 
22618c2aff7Sartem 	/* INQUIRY */
22718c2aff7Sartem 	(void) memset((void *) &inq, 0, sizeof (inq));
22818c2aff7Sartem 	(void) memset((void *) &ucmd, 0, sizeof (ucmd));
22918c2aff7Sartem 	(void) memset((void *) &cdb, 0, sizeof (union scsi_cdb));
23018c2aff7Sartem 	cdb.scc_cmd = SCMD_INQUIRY;
23118c2aff7Sartem 	FORMG0COUNT(&cdb, sizeof (inq));
23218c2aff7Sartem 	ucmd.uscsi_cdb = (caddr_t) & cdb;
23318c2aff7Sartem 	ucmd.uscsi_cdblen = CDB_GROUP0;
23418c2aff7Sartem 	ucmd.uscsi_bufaddr = (caddr_t) & inq;
23518c2aff7Sartem 	ucmd.uscsi_buflen = sizeof (inq);
23618c2aff7Sartem 	ucmd.uscsi_timeout = 30;
23718c2aff7Sartem 	ucmd.uscsi_flags = USCSI_READ;
23818c2aff7Sartem 	status = ioctl(fd, USCSICMD, &ucmd);
23918c2aff7Sartem 	if (status || ucmd.uscsi_status) {
24018c2aff7Sartem 		return;
24118c2aff7Sartem 	}
24218c2aff7Sartem 
24318c2aff7Sartem 	if ((s = rtrim_copy(inq.inq_vid, sizeof (inq.inq_vid))) != NULL) {
24418c2aff7Sartem 		libhal_changeset_set_property_string (cs, "storage.vendor", s);
24518c2aff7Sartem 		free(s);
24618c2aff7Sartem 	}
24718c2aff7Sartem 	if ((s = rtrim_copy(inq.inq_pid, sizeof (inq.inq_pid))) != NULL) {
24818c2aff7Sartem 		libhal_changeset_set_property_string (cs, "storage.model", s);
24918c2aff7Sartem 		free(s);
25018c2aff7Sartem 	}
25118c2aff7Sartem 	if ((s = rtrim_copy(inq.inq_revision, sizeof (inq.inq_revision))) != NULL) {
25218c2aff7Sartem 		libhal_changeset_set_property_string (cs, "storage.firmware_revision", s);
25318c2aff7Sartem 		free(s);
25418c2aff7Sartem 	}
25518c2aff7Sartem 	if ((s = rtrim_copy(inq.inq_serial, sizeof (inq.inq_serial))) != NULL) {
25618c2aff7Sartem 		libhal_changeset_set_property_string (cs, "storage.serial", s);
25718c2aff7Sartem 		free(s);
25818c2aff7Sartem 	}
25918c2aff7Sartem }
26018c2aff7Sartem 
26118c2aff7Sartem /*
26218c2aff7Sartem  * returns TRUE if diskette is inserted.
26318c2aff7Sartem  * also returns write protection status.
26418c2aff7Sartem  */
26518c2aff7Sartem static dbus_bool_t
check_floppy(int fd,dbus_bool_t * wprot)26618c2aff7Sartem check_floppy(int fd, dbus_bool_t *wprot)
26718c2aff7Sartem {
26818c2aff7Sartem 	int	chg;
26918c2aff7Sartem 
27018c2aff7Sartem 	if ((ioctl(fd, FDGETCHANGE, &chg) == 0) && !(chg & FDGC_CURRENT)) {
271*32248f11SToomas Soome 		*wprot = ((chg & FDGC_CURWPROT) != 0);
27218c2aff7Sartem 		return (TRUE);
27318c2aff7Sartem 	} else {
27418c2aff7Sartem 		return (FALSE);
27518c2aff7Sartem 	}
27618c2aff7Sartem }
27718c2aff7Sartem 
27818c2aff7Sartem void
drop_privileges()27918c2aff7Sartem drop_privileges ()
28018c2aff7Sartem {
28118c2aff7Sartem 	priv_set_t *pPrivSet = NULL;
28218c2aff7Sartem 	priv_set_t *lPrivSet = NULL;
28318c2aff7Sartem 
28418c2aff7Sartem 	/*
28518c2aff7Sartem 	 * Start with the 'basic' privilege set and then remove any
28618c2aff7Sartem 	 * of the 'basic' privileges that will not be needed.
28718c2aff7Sartem 	 */
28818c2aff7Sartem 	if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
28918c2aff7Sartem 		return;
29018c2aff7Sartem 	}
29118c2aff7Sartem 
29218c2aff7Sartem 	/* Clear privileges we will not need from the 'basic' set */
29318c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
29418c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_INFO);
29518c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
29618c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
29718c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_FORK);
29818c2aff7Sartem 
29918c2aff7Sartem 	/* for uscsi */
30018c2aff7Sartem 	(void) priv_addset(pPrivSet, PRIV_SYS_DEVICES);
30118c2aff7Sartem 
30218c2aff7Sartem 	/* to open logindevperm'd devices */
30318c2aff7Sartem 	(void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
30418c2aff7Sartem 
30518c2aff7Sartem 	/* Set the permitted privilege set. */
30618c2aff7Sartem 	if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
30718c2aff7Sartem 		return;
30818c2aff7Sartem 	}
30918c2aff7Sartem 
31018c2aff7Sartem 	/* Clear the limit set. */
31118c2aff7Sartem 	if ((lPrivSet = priv_allocset()) == NULL) {
31218c2aff7Sartem 		return;
31318c2aff7Sartem 	}
31418c2aff7Sartem 
31518c2aff7Sartem 	priv_emptyset(lPrivSet);
31618c2aff7Sartem 
31718c2aff7Sartem 	if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
31818c2aff7Sartem 		return;
31918c2aff7Sartem 	}
32018c2aff7Sartem 
32118c2aff7Sartem 	priv_freeset(lPrivSet);
32218c2aff7Sartem }
32318c2aff7Sartem 
32418c2aff7Sartem int
main(int argc,char * argv[])32518c2aff7Sartem main (int argc, char *argv[])
32618c2aff7Sartem {
32718c2aff7Sartem 	int ret = 1;
32818c2aff7Sartem 	int fd = -1;
32918c2aff7Sartem 	int rfd = -1;
33018c2aff7Sartem 	char *udi;
33118c2aff7Sartem 	char *device_file;
33218c2aff7Sartem 	char *raw_device_file;
33318c2aff7Sartem 	LibHalContext *ctx = NULL;
33418c2aff7Sartem 	DBusError error;
33518c2aff7Sartem 	char *drive_type;
33618c2aff7Sartem 	dbus_bool_t is_cdrom;
33718c2aff7Sartem 	dbus_bool_t is_floppy;
33818c2aff7Sartem 	struct dk_minfo minfo;
33934de8762SGarrett D'Amore 	int rdonly;
340422ee277Sartem 	unsigned int block_size = 512;
34118c2aff7Sartem 	dbus_bool_t only_check_for_media;
34218c2aff7Sartem 	int got_media = FALSE;
34318c2aff7Sartem 	dbus_bool_t is_write_protected = FALSE;
34418c2aff7Sartem 	dbus_bool_t is_mbr = FALSE;
34518c2aff7Sartem 	dbus_bool_t is_smi = FALSE;
34618c2aff7Sartem 	dbus_bool_t is_gpt = FALSE;
34718c2aff7Sartem 	dbus_bool_t is_partitioned = FALSE;
34818c2aff7Sartem 	dbus_bool_t vtoc_slices = FALSE;
34918c2aff7Sartem 	int dos_cnt = 0;
35018c2aff7Sartem 	const char *scheme = "";
351342440ecSPrasad Singamsetty 	struct extvtoc vtoc;
35218c2aff7Sartem 	dk_gpt_t *gpt;
35318c2aff7Sartem 	LibHalChangeSet *cs = NULL;
35418c2aff7Sartem 
35518c2aff7Sartem 	if ((udi = getenv ("UDI")) == NULL)
35618c2aff7Sartem 		goto out;
35718c2aff7Sartem 	if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
35818c2aff7Sartem 		goto out;
35918c2aff7Sartem 	if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
36018c2aff7Sartem 		goto out;
36118c2aff7Sartem 	if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
36218c2aff7Sartem 		goto out;
36318c2aff7Sartem 
36418c2aff7Sartem 	drop_privileges ();
36518c2aff7Sartem 
36618c2aff7Sartem 	setup_logger ();
36718c2aff7Sartem 
36818c2aff7Sartem 	if (argc == 2 && strcmp (argv[1], "--only-check-for-media") == 0)
36918c2aff7Sartem 		only_check_for_media = TRUE;
37018c2aff7Sartem 	else
37118c2aff7Sartem 		only_check_for_media = FALSE;
37218c2aff7Sartem 
37318c2aff7Sartem 	is_cdrom = (strcmp (drive_type, "cdrom") == 0);
37418c2aff7Sartem 	is_floppy = (strcmp (drive_type, "floppy") == 0);
37518c2aff7Sartem 
37618c2aff7Sartem 	dbus_error_init (&error);
37718c2aff7Sartem 	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
37818c2aff7Sartem 		goto out;
37918c2aff7Sartem 
38018c2aff7Sartem 	if ((cs = libhal_device_new_changeset (udi)) == NULL) {
38118c2aff7Sartem 		HAL_DEBUG (("Cannot allocate changeset"));
38218c2aff7Sartem 		goto out;
38318c2aff7Sartem 	}
38418c2aff7Sartem 
38500687e57Sartem 	HAL_DEBUG (("Doing probe-storage for %s (drive_type %s) (udi=%s) (--only-check-for-media==%d)",
38600687e57Sartem 	     device_file, drive_type, udi, only_check_for_media));
38718c2aff7Sartem 
38818c2aff7Sartem 	if ((rfd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0) {
38918c2aff7Sartem 		HAL_DEBUG (("Cannot open %s: %s", raw_device_file, strerror (errno)));
39018c2aff7Sartem 		goto out;
39118c2aff7Sartem 	}
39218c2aff7Sartem 
39318c2aff7Sartem 	if (!only_check_for_media) {
39418c2aff7Sartem 		if (strcmp (drive_type, "cdrom") == 0) {
39518c2aff7Sartem 			get_cdrom_properties (rfd, cs);
39618c2aff7Sartem 		} else if (strcmp (drive_type, "disk") == 0) {
39718c2aff7Sartem 			get_disk_properties (rfd, cs);
39818c2aff7Sartem 		}
39918c2aff7Sartem 	}
40018c2aff7Sartem 
40118c2aff7Sartem 	ret = 0;
40218c2aff7Sartem 
40318c2aff7Sartem 	if (is_cdrom) {
40418c2aff7Sartem 		HAL_DEBUG (("Checking for optical disc on %s", raw_device_file));
40518c2aff7Sartem 		got_media = get_media_info(rfd, &minfo);
40618c2aff7Sartem 		if (!got_media) {
40718c2aff7Sartem 			goto out_cs;
40818c2aff7Sartem 		}
409422ee277Sartem 		block_size = minfo.dki_lbsize;
41018c2aff7Sartem 		/* XXX */
41118c2aff7Sartem 		is_write_protected = TRUE;
41218c2aff7Sartem 	} else if (is_floppy) {
41318c2aff7Sartem 		HAL_DEBUG (("Checking for floppy on %s", raw_device_file));
41418c2aff7Sartem 		if (check_floppy(rfd, &is_write_protected)) {
41518c2aff7Sartem 			got_media = TRUE;
41618c2aff7Sartem 		}
41718c2aff7Sartem 		/* don't look for partitions on floppy */
41818c2aff7Sartem 		goto out_cs;
41918c2aff7Sartem 	} else {
42034de8762SGarrett D'Amore 		got_media = get_media_info(rfd, &minfo);
42134de8762SGarrett D'Amore 		if (!got_media) {
42234de8762SGarrett D'Amore 			goto out_cs;
42334de8762SGarrett D'Amore 		}
424422ee277Sartem 		block_size = minfo.dki_lbsize;
42534de8762SGarrett D'Amore 		if ((ioctl(rfd, DKIOCREADONLY, &rdonly) == 0) && rdonly) {
42634de8762SGarrett D'Amore 			is_write_protected = TRUE;
427422ee277Sartem 		}
42818c2aff7Sartem 	}
42918c2aff7Sartem 
43018c2aff7Sartem 	HAL_DEBUG (("Checking for partitions on %s", device_file));
43118c2aff7Sartem 
43218c2aff7Sartem 	if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
43318c2aff7Sartem 		HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
43418c2aff7Sartem 		goto out_cs;
43518c2aff7Sartem 	}
43618c2aff7Sartem 
437422ee277Sartem 	dos_cnt = get_num_dos_drives(fd, block_size);
43818c2aff7Sartem 	is_mbr = (dos_cnt > 0);
43918c2aff7Sartem 	if (is_mbr) {
44018c2aff7Sartem 		scheme = "mbr";
44118c2aff7Sartem 	}
442342440ecSPrasad Singamsetty 	if (read_extvtoc(rfd, &vtoc) >= 0) {
44318c2aff7Sartem 		if (!vtoc_one_slice_entire_disk(&vtoc)) {
44418c2aff7Sartem 			is_smi = TRUE;
44518c2aff7Sartem 			if (!is_mbr) {
44618c2aff7Sartem 				/* smi within mbr partition is okay */
44718c2aff7Sartem 				scheme = "smi";
44818c2aff7Sartem 			}
44918c2aff7Sartem 			vtoc_slices = TRUE;
45018c2aff7Sartem 		}
45118c2aff7Sartem 	} else if (!is_cdrom && (efi_alloc_and_read(rfd, &gpt) >= 0)) {
45218c2aff7Sartem 		/*
45318c2aff7Sartem 		 * Note: for some reason efi_read takes very long on cdroms.
45418c2aff7Sartem 		 * Needs more investigation, skip gpt on cdrom for now.
45518c2aff7Sartem 		 */
45618c2aff7Sartem 		is_gpt = TRUE;
45718c2aff7Sartem 		scheme = "gpt";
45818c2aff7Sartem 		efi_free(gpt);
45918c2aff7Sartem 	}
46018c2aff7Sartem 
46118c2aff7Sartem out_cs:
46218c2aff7Sartem 	is_partitioned = is_mbr || is_smi || is_gpt;
46318c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.no_partitions_hint", !is_partitioned);
46418c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "block.no_partitions", !is_partitioned);
46518c2aff7Sartem 	libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", scheme);
46618c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.solaris.vtoc_slices", vtoc_slices);
46718c2aff7Sartem 	libhal_changeset_set_property_int (cs, "storage.solaris.num_dos_partitions", dos_cnt);
46818c2aff7Sartem 	/* XXX should only set for removable drives */
46918c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.removable.media_available", got_media);
47018c2aff7Sartem 	libhal_changeset_set_property_bool (cs, "storage.removable.solaris.read_only", is_write_protected);
47118c2aff7Sartem 
47218c2aff7Sartem 	libhal_device_commit_changeset (ctx, cs, &error);
47318c2aff7Sartem 
47418c2aff7Sartem out:
47518c2aff7Sartem 	if (cs != NULL) {
47618c2aff7Sartem 		libhal_device_free_changeset (cs);
47718c2aff7Sartem 	}
47818c2aff7Sartem 	if (fd >= 0) {
47918c2aff7Sartem 		close (fd);
48018c2aff7Sartem 	}
48118c2aff7Sartem 	if (rfd >= 0) {
48218c2aff7Sartem 		close (rfd);
48318c2aff7Sartem 	}
48418c2aff7Sartem 	if (ctx != NULL) {
48518c2aff7Sartem 		if (dbus_error_is_set(&error)) {
48618c2aff7Sartem 			dbus_error_free (&error);
48718c2aff7Sartem 		}
48818c2aff7Sartem 		libhal_ctx_shutdown (ctx, &error);
48918c2aff7Sartem 		libhal_ctx_free (ctx);
49018c2aff7Sartem 	}
49118c2aff7Sartem 
49218c2aff7Sartem 	return ret;
49318c2aff7Sartem }
494