xref: /dflybsd-src/usr.sbin/installer/libinstaller/survey.c (revision f59b7dfa1b99e73a6b5338bdf61246d9edf12f4b)
121c1c48aSSascha Wildner /*
221c1c48aSSascha Wildner  * Copyright (c)2004 The DragonFly Project.  All rights reserved.
321c1c48aSSascha Wildner  *
421c1c48aSSascha Wildner  * Redistribution and use in source and binary forms, with or without
521c1c48aSSascha Wildner  * modification, are permitted provided that the following conditions
621c1c48aSSascha Wildner  * are met:
721c1c48aSSascha Wildner  *
821c1c48aSSascha Wildner  *   Redistributions of source code must retain the above copyright
921c1c48aSSascha Wildner  *   notice, this list of conditions and the following disclaimer.
1021c1c48aSSascha Wildner  *
1121c1c48aSSascha Wildner  *   Redistributions in binary form must reproduce the above copyright
1221c1c48aSSascha Wildner  *   notice, this list of conditions and the following disclaimer in
1321c1c48aSSascha Wildner  *   the documentation and/or other materials provided with the
1421c1c48aSSascha Wildner  *   distribution.
1521c1c48aSSascha Wildner  *
1621c1c48aSSascha Wildner  *   Neither the name of the DragonFly Project nor the names of its
1721c1c48aSSascha Wildner  *   contributors may be used to endorse or promote products derived
1821c1c48aSSascha Wildner  *   from this software without specific prior written permission.
1921c1c48aSSascha Wildner  *
2021c1c48aSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2121c1c48aSSascha Wildner  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2221c1c48aSSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2321c1c48aSSascha Wildner  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2421c1c48aSSascha Wildner  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2521c1c48aSSascha Wildner  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2621c1c48aSSascha Wildner  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2721c1c48aSSascha Wildner  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2821c1c48aSSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2921c1c48aSSascha Wildner  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3021c1c48aSSascha Wildner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3121c1c48aSSascha Wildner  * OF THE POSSIBILITY OF SUCH DAMAGE.
3221c1c48aSSascha Wildner  */
3321c1c48aSSascha Wildner 
3421c1c48aSSascha Wildner /*
3521c1c48aSSascha Wildner  * survey.c
3621c1c48aSSascha Wildner  * Survey the storage capacity of the system.
3721c1c48aSSascha Wildner  * $Id: survey.c,v 1.17 2005/02/06 21:05:18 cpressey Exp $
3821c1c48aSSascha Wildner  */
3921c1c48aSSascha Wildner 
4021c1c48aSSascha Wildner #include <sys/types.h>
4121c1c48aSSascha Wildner #include <sys/sysctl.h>
4221c1c48aSSascha Wildner 
4321c1c48aSSascha Wildner #include <stdio.h>
4421c1c48aSSascha Wildner #include <string.h>
4521c1c48aSSascha Wildner 
4621c1c48aSSascha Wildner #include "libaura/dict.h"
4721c1c48aSSascha Wildner 
4821c1c48aSSascha Wildner #include "commands.h"
4921c1c48aSSascha Wildner #include "diskutil.h"
5021c1c48aSSascha Wildner #include "functions.h"
5121c1c48aSSascha Wildner 
5221c1c48aSSascha Wildner static int	fgets_chomp(char *, int, FILE *);
5321c1c48aSSascha Wildner static int	parse_geometry_info(char *, int *, int *, int *);
5421c1c48aSSascha Wildner static int	parse_slice_info(char *, int *,
5521c1c48aSSascha Wildner 		    unsigned long *, unsigned long *, int *, int *);
5621c1c48aSSascha Wildner 
5721c1c48aSSascha Wildner /*
5821c1c48aSSascha Wildner  * Get a line from a file.  Remove any trailing EOL's.
5921c1c48aSSascha Wildner  * Return 1 if we did not hit EOF, 0 if we did.
6021c1c48aSSascha Wildner  */
6121c1c48aSSascha Wildner static int
6221c1c48aSSascha Wildner fgets_chomp(char *line, int size, FILE *f)
6321c1c48aSSascha Wildner {
6421c1c48aSSascha Wildner 	if (fgets(line, size, f) == NULL)
6521c1c48aSSascha Wildner 		return(0);
6621c1c48aSSascha Wildner 	while (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
6721c1c48aSSascha Wildner 		line[strlen(line) - 1] = '\0';
6821c1c48aSSascha Wildner 	return(1);
6921c1c48aSSascha Wildner }
7021c1c48aSSascha Wildner 
7121c1c48aSSascha Wildner /*
7221c1c48aSSascha Wildner  * Given a geometry line from fdisk's summary output, return the
7321c1c48aSSascha Wildner  * number of cylinders, heads, and sectors.
7421c1c48aSSascha Wildner  */
7521c1c48aSSascha Wildner static int
7621c1c48aSSascha Wildner parse_geometry_info(char *line, int *cyl, int *head, int *sec)
7721c1c48aSSascha Wildner {
7821c1c48aSSascha Wildner 	char *word;
7921c1c48aSSascha Wildner 
8021c1c48aSSascha Wildner 	/*
8121c1c48aSSascha Wildner 	 * /dev/ad3: 2112 cyl 16 hd 63 sec
8221c1c48aSSascha Wildner 	 */
8321c1c48aSSascha Wildner 	if ((word = strtok(line, " \t")) == NULL)	/* /dev/ad3: */
8421c1c48aSSascha Wildner 		return(0);
8521c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 2112 */
8621c1c48aSSascha Wildner 		return(0);
8721c1c48aSSascha Wildner 	*cyl = atoi(word);
8821c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* cyl */
8921c1c48aSSascha Wildner 		return(0);
9021c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 16 */
9121c1c48aSSascha Wildner 		return(0);
9221c1c48aSSascha Wildner 	*head = atoi(word);
9321c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* hd */
9421c1c48aSSascha Wildner 		return(0);
9521c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 63 */
9621c1c48aSSascha Wildner 		return(0);
9721c1c48aSSascha Wildner 	*sec = atoi(word);
9821c1c48aSSascha Wildner 
9921c1c48aSSascha Wildner 	return(1);
10021c1c48aSSascha Wildner }
10121c1c48aSSascha Wildner 
10221c1c48aSSascha Wildner /*
10321c1c48aSSascha Wildner  * Given a slice description line from fdisk's summary output, return
10421c1c48aSSascha Wildner  * the number of the slice, and its start, size, type, and flags.
10521c1c48aSSascha Wildner  */
10621c1c48aSSascha Wildner static int
10721c1c48aSSascha Wildner parse_slice_info(char *line, int *slice,
10821c1c48aSSascha Wildner 		 unsigned long *start, unsigned long *size,
10921c1c48aSSascha Wildner 		 int *type, int *flags)
11021c1c48aSSascha Wildner {
11121c1c48aSSascha Wildner 	char *word;
11221c1c48aSSascha Wildner 
11321c1c48aSSascha Wildner 	/*
11421c1c48aSSascha Wildner 	 * Part        Start        Size Type Flags
11521c1c48aSSascha Wildner 	 *    1:          63     2128833 0xa5 0x80
11621c1c48aSSascha Wildner 	 */
11721c1c48aSSascha Wildner 	if ((word = strtok(line, " \t")) == NULL)	/* 1: */
11821c1c48aSSascha Wildner 		return(0);
11921c1c48aSSascha Wildner 	*slice = atoi(word);
12021c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 63 */
12121c1c48aSSascha Wildner 		return(0);
12221c1c48aSSascha Wildner 	*start = strtoul(word, NULL, 10);
12321c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 2128833 */
12421c1c48aSSascha Wildner 		return(0);
12521c1c48aSSascha Wildner 	*size = strtoul(word, NULL, 10);
12621c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 0xa5 */
12721c1c48aSSascha Wildner 		return(0);
12821c1c48aSSascha Wildner 	if (!hex_to_int(word, type))
12921c1c48aSSascha Wildner 		return(0);
13021c1c48aSSascha Wildner 	if ((word = strtok(NULL, " \t")) == NULL)	/* 0x80 */
13121c1c48aSSascha Wildner 		return(0);
13221c1c48aSSascha Wildner 	if (!hex_to_int(word, flags))
13321c1c48aSSascha Wildner 		return(0);
13421c1c48aSSascha Wildner 
13521c1c48aSSascha Wildner 	return(1);
13621c1c48aSSascha Wildner }
13721c1c48aSSascha Wildner 
13821c1c48aSSascha Wildner /*
13921c1c48aSSascha Wildner  * Survey storage capacity of this system.
14021c1c48aSSascha Wildner  */
14121c1c48aSSascha Wildner int
14221c1c48aSSascha Wildner survey_storage(struct i_fn_args *a)
14321c1c48aSSascha Wildner {
14421c1c48aSSascha Wildner 	unsigned long mem = 0;
14521c1c48aSSascha Wildner 	char disks[256], line[256];
14621c1c48aSSascha Wildner 	char *disk, *disk_ptr;
14721c1c48aSSascha Wildner 	struct commands *cmds;
14821c1c48aSSascha Wildner 	struct command *cmd;
14921c1c48aSSascha Wildner 	FILE *f;
15021c1c48aSSascha Wildner 	char *filename;
15121c1c48aSSascha Wildner 	struct disk *d = NULL;
152*f59b7dfaSSascha Wildner 	int number = 0;
15321c1c48aSSascha Wildner 	int failure = 0;
15421c1c48aSSascha Wildner 	size_t len;
15521c1c48aSSascha Wildner 	struct aura_dict *di;
15621c1c48aSSascha Wildner 	void *rk;
15721c1c48aSSascha Wildner 	size_t rk_len;
15821c1c48aSSascha Wildner 
15921c1c48aSSascha Wildner 	disks_free(a->s);
16021c1c48aSSascha Wildner 
16121c1c48aSSascha Wildner 	len = sizeof(mem);
16221c1c48aSSascha Wildner 	if (sysctlbyname("hw.physmem", &mem, &len, NULL, 0) < 0) {
16321c1c48aSSascha Wildner 		failure |= 1;
16421c1c48aSSascha Wildner 	} else {
16521c1c48aSSascha Wildner 		storage_set_memsize(a->s, next_power_of_two(mem >> 20));
16621c1c48aSSascha Wildner 	}
16721c1c48aSSascha Wildner 	len = 256;
16821c1c48aSSascha Wildner 	if (sysctlbyname("kern.disks", disks, &len, NULL, 0) < 0) {
16921c1c48aSSascha Wildner 		failure |= 1;
17021c1c48aSSascha Wildner 	}
17121c1c48aSSascha Wildner 	disk_ptr = disks;
17221c1c48aSSascha Wildner 
17321c1c48aSSascha Wildner 	di = aura_dict_new(1, AURA_DICT_SORTED_LIST);
17421c1c48aSSascha Wildner 	while (!failure && (disk = strsep(&disk_ptr, " ")) != NULL) {
17521c1c48aSSascha Wildner 		if (disk[0] == '\0')
17621c1c48aSSascha Wildner 			continue;
17721c1c48aSSascha Wildner 
17821c1c48aSSascha Wildner 		/*
17921c1c48aSSascha Wildner 		 * If the disk is a memory disk, floppy or CD-ROM, skip it.
18021c1c48aSSascha Wildner 		 */
18121c1c48aSSascha Wildner 		if (strncmp(disk, "md", 2) == 0 ||
18221c1c48aSSascha Wildner 		    strncmp(disk, "cd", 2) == 0 ||
18321c1c48aSSascha Wildner 		    strncmp(disk, "acd", 3) == 0 ||
18421c1c48aSSascha Wildner 		    strncmp(disk, "fd", 2) == 0)
18521c1c48aSSascha Wildner 			continue;
18621c1c48aSSascha Wildner 
18721c1c48aSSascha Wildner 		aura_dict_store(di, disk, strlen(disk) + 1, "", 1);
18821c1c48aSSascha Wildner 	}
18921c1c48aSSascha Wildner 
19021c1c48aSSascha Wildner 	cmds = commands_new();
19121c1c48aSSascha Wildner 	cmd = command_add(cmds, "%s%s -n '' >%ssurvey.txt",
19221c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"), a->tmp);
19321c1c48aSSascha Wildner 	command_set_log_mode(cmd, COMMAND_LOG_SILENT);
19421c1c48aSSascha Wildner 
19521c1c48aSSascha Wildner 	aura_dict_rewind(di);
19621c1c48aSSascha Wildner 	while (!aura_dict_eof(di)) {
19721c1c48aSSascha Wildner 		aura_dict_get_current_key(di, &rk, &rk_len),
19821c1c48aSSascha Wildner 
19921c1c48aSSascha Wildner 		disk = (char *)rk;
20021c1c48aSSascha Wildner 
20121c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '@DISK' >>%ssurvey.txt",
20221c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
20321c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
20421c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '%s' >>%ssurvey.txt",
20521c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), disk, a->tmp);
20621c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
20721c1c48aSSascha Wildner 
20821c1c48aSSascha Wildner 		/*
20921c1c48aSSascha Wildner 		 * Look for descriptions of this disk.
21021c1c48aSSascha Wildner 		 */
21121c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '@DESC' >>%ssurvey.txt",
21221c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
21321c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
21421c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s -w '^%s: [0-9]*MB' %s%s >>%ssurvey.txt || %s%s '%s' >>%ssurvey.txt",
21521c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "GREP"),
21621c1c48aSSascha Wildner 		    disk,
21721c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "DMESG_BOOT"),
21821c1c48aSSascha Wildner 		    a->tmp,
21921c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
22021c1c48aSSascha Wildner 		    disk,
22121c1c48aSSascha Wildner 		    a->tmp);
22221c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
22321c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
22421c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
22521c1c48aSSascha Wildner 
22621c1c48aSSascha Wildner 		/*
227*f59b7dfaSSascha Wildner 		 * Look for the disk's serial number.
228*f59b7dfaSSascha Wildner 		 */
229*f59b7dfaSSascha Wildner 		cmd = command_add(cmds, "%s%s '@SERNO' >>%ssurvey.txt",
230*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
231*f59b7dfaSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
232*f59b7dfaSSascha Wildner 		cmd = command_add(cmds, "if %s%s -d /dev/serno; then %s%s -l /dev/serno | %s%s \"`%s%s -l /dev/%s | %s%s '{print $5, $6;}'`\" | %s%s '{print $10;}' >>%ssurvey.txt; fi",
233*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "TEST"),
234*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "LS"),
235*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "GREP"),
236*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "LS"),
237*f59b7dfaSSascha Wildner 		    disk,
238*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "AWK"),
239*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "AWK"),
240*f59b7dfaSSascha Wildner 		    a->tmp);
241*f59b7dfaSSascha Wildner 		cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
242*f59b7dfaSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
243*f59b7dfaSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
244*f59b7dfaSSascha Wildner 
245*f59b7dfaSSascha Wildner 		/*
24621c1c48aSSascha Wildner 		 * Probe the disk with fdisk.
24721c1c48aSSascha Wildner 		 */
24821c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '@SLICES' >>%ssurvey.txt",
24921c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
25021c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
25121c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s -s %s 2>/dev/null >>%ssurvey.txt || %s%s '' >>%ssurvey.txt",
25221c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "FDISK"),
25321c1c48aSSascha Wildner 		    disk,
25421c1c48aSSascha Wildner 		    a->tmp,
25521c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
25621c1c48aSSascha Wildner 		    a->tmp);
25721c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
25821c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"), a->tmp);
25921c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_SILENT);
26021c1c48aSSascha Wildner 
26121c1c48aSSascha Wildner 		aura_dict_next(di);
26221c1c48aSSascha Wildner 	}
26321c1c48aSSascha Wildner 
26421c1c48aSSascha Wildner 	cmd = command_add(cmds, "%s%s '.' >>%ssurvey.txt",
26521c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"), a->tmp);
26621c1c48aSSascha Wildner 	command_set_log_mode(cmd, COMMAND_LOG_SILENT);
26721c1c48aSSascha Wildner 
26821c1c48aSSascha Wildner 	if (!commands_execute(a, cmds))
26921c1c48aSSascha Wildner 		failure |= 1;
27021c1c48aSSascha Wildner 	commands_free(cmds);
27121c1c48aSSascha Wildner 	temp_file_add(a, "survey.txt");
27221c1c48aSSascha Wildner 
27321c1c48aSSascha Wildner 	aura_dict_free(di);
27421c1c48aSSascha Wildner 
27521c1c48aSSascha Wildner 	/*
27621c1c48aSSascha Wildner 	 * Now read in and parse the file that those commands just created.
27721c1c48aSSascha Wildner 	 */
27821c1c48aSSascha Wildner 	asprintf(&filename, "%ssurvey.txt", a->tmp);
27921c1c48aSSascha Wildner 	if ((f = fopen(filename, "r")) == NULL)
28021c1c48aSSascha Wildner 		failure |= 1;
28121c1c48aSSascha Wildner 	free(filename);
28221c1c48aSSascha Wildner 
28321c1c48aSSascha Wildner 	while (!failure && fgets_chomp(line, 255, f)) {
28421c1c48aSSascha Wildner 		if (strcmp(line, "@DISK") == 0) {
28521c1c48aSSascha Wildner 			if (fgets_chomp(line, 255, f)) {
28621c1c48aSSascha Wildner 				d = disk_new(a->s, line);
287*f59b7dfaSSascha Wildner 				disk_set_number(d, number++);
28821c1c48aSSascha Wildner 			}
28921c1c48aSSascha Wildner 		} else if (strcmp(line, "@DESC") == 0) {
29021c1c48aSSascha Wildner 			while (d != NULL && strcmp(line, "@END") != 0 && fgets_chomp(line, 255, f)) {
29121c1c48aSSascha Wildner 				disk_set_desc(d, line);
29221c1c48aSSascha Wildner 			}
293*f59b7dfaSSascha Wildner 		} else if (strcmp(line, "@SERNO") == 0) {
294*f59b7dfaSSascha Wildner 			fgets_chomp(line, 255, f);
295*f59b7dfaSSascha Wildner 			if (strcmp(line, "@END") != 0)
296*f59b7dfaSSascha Wildner 				disk_set_serno(d, line);
29721c1c48aSSascha Wildner 		} else if (strcmp(line, "@SLICES") == 0) {
29821c1c48aSSascha Wildner 			int cyl, hd, sec;
29921c1c48aSSascha Wildner 			int number, type, flags;
30021c1c48aSSascha Wildner 			unsigned long start, size;
30121c1c48aSSascha Wildner 
30221c1c48aSSascha Wildner 			/*
30321c1c48aSSascha Wildner 			 * /dev/ad3: 2112 cyl 16 hd 63 sec
30421c1c48aSSascha Wildner 			 * Part        Start        Size Type Flags
30521c1c48aSSascha Wildner 			 *    1:          63     2128833 0xa5 0x80
30621c1c48aSSascha Wildner 			 */
30721c1c48aSSascha Wildner 			while (d != NULL && strcmp(line, "@END") != 0 && fgets_chomp(line, 255, f)) {
30821c1c48aSSascha Wildner 				if (strncmp(line, "/dev/", 5) == 0) {
30921c1c48aSSascha Wildner 					parse_geometry_info(line, &cyl, &hd, &sec);
31021c1c48aSSascha Wildner 					disk_set_geometry(d, cyl, hd, sec);
31121c1c48aSSascha Wildner 				} else if (strncmp(line, "Part", 4) == 0) {
31221c1c48aSSascha Wildner 					/* ignore it */
31321c1c48aSSascha Wildner 				} else {
31421c1c48aSSascha Wildner 					if (parse_slice_info(line, &number, &start, &size,
31521c1c48aSSascha Wildner 					    &type, &flags)) {
31621c1c48aSSascha Wildner 						/*
31721c1c48aSSascha Wildner 						fprintfo(log, "| Found slice #%d, sysid %d, "
31821c1c48aSSascha Wildner 						    "start %ld, size %ld\n", number, type, start, size);
31921c1c48aSSascha Wildner 						*/
32021c1c48aSSascha Wildner 						slice_new(d, number, type, flags, start, size);
32121c1c48aSSascha Wildner 					}
32221c1c48aSSascha Wildner 				}
32321c1c48aSSascha Wildner 			}
32421c1c48aSSascha Wildner 		}
32521c1c48aSSascha Wildner 	}
32621c1c48aSSascha Wildner 
32721c1c48aSSascha Wildner 	if (f != NULL)
32821c1c48aSSascha Wildner 		fclose(f);
32921c1c48aSSascha Wildner 
33021c1c48aSSascha Wildner 	/*
33121c1c48aSSascha Wildner 	 * Fix up any disk descriptions that didn't make it.
33221c1c48aSSascha Wildner 	 */
33321c1c48aSSascha Wildner 	for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
33421c1c48aSSascha Wildner 		if (disk_get_desc(d) == NULL)
33521c1c48aSSascha Wildner 			disk_set_desc(d, disk_get_device_name(d));
33621c1c48aSSascha Wildner 	}
33721c1c48aSSascha Wildner 
33821c1c48aSSascha Wildner 	return(!failure);
33921c1c48aSSascha Wildner }
340