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
40795e3215SSascha Wildner #include <sys/param.h>
41795e3215SSascha Wildner #include <sys/diskslice.h>
4221c1c48aSSascha Wildner #include <sys/sysctl.h>
4321c1c48aSSascha Wildner
44795e3215SSascha Wildner #include <fcntl.h>
4521c1c48aSSascha Wildner #include <stdio.h>
4621c1c48aSSascha Wildner #include <string.h>
47795e3215SSascha Wildner #include <unistd.h>
4821c1c48aSSascha Wildner
4921c1c48aSSascha Wildner #include "libaura/dict.h"
5021c1c48aSSascha Wildner
5121c1c48aSSascha Wildner #include "commands.h"
5221c1c48aSSascha Wildner #include "diskutil.h"
5321c1c48aSSascha Wildner #include "functions.h"
5421c1c48aSSascha Wildner
5521c1c48aSSascha Wildner static int fgets_chomp(char *, int, FILE *);
5621c1c48aSSascha Wildner static int parse_geometry_info(char *, int *, int *, int *);
5721c1c48aSSascha Wildner static int parse_slice_info(char *, int *,
5821c1c48aSSascha Wildner unsigned long *, unsigned long *, int *, int *);
5921c1c48aSSascha Wildner
6021c1c48aSSascha Wildner /*
6121c1c48aSSascha Wildner * Get a line from a file. Remove any trailing EOL's.
6221c1c48aSSascha Wildner * Return 1 if we did not hit EOF, 0 if we did.
6321c1c48aSSascha Wildner */
6421c1c48aSSascha Wildner static int
fgets_chomp(char * line,int size,FILE * f)6521c1c48aSSascha Wildner fgets_chomp(char *line, int size, FILE *f)
6621c1c48aSSascha Wildner {
6721c1c48aSSascha Wildner if (fgets(line, size, f) == NULL)
6821c1c48aSSascha Wildner return(0);
6921c1c48aSSascha Wildner while (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
7021c1c48aSSascha Wildner line[strlen(line) - 1] = '\0';
7121c1c48aSSascha Wildner return(1);
7221c1c48aSSascha Wildner }
7321c1c48aSSascha Wildner
7421c1c48aSSascha Wildner /*
7521c1c48aSSascha Wildner * Given a geometry line from fdisk's summary output, return the
7621c1c48aSSascha Wildner * number of cylinders, heads, and sectors.
7721c1c48aSSascha Wildner */
7821c1c48aSSascha Wildner static int
parse_geometry_info(char * line,int * cyl,int * head,int * sec)7921c1c48aSSascha Wildner parse_geometry_info(char *line, int *cyl, int *head, int *sec)
8021c1c48aSSascha Wildner {
8121c1c48aSSascha Wildner char *word;
8221c1c48aSSascha Wildner
8321c1c48aSSascha Wildner /*
8421c1c48aSSascha Wildner * /dev/ad3: 2112 cyl 16 hd 63 sec
8521c1c48aSSascha Wildner */
8621c1c48aSSascha Wildner if ((word = strtok(line, " \t")) == NULL) /* /dev/ad3: */
8721c1c48aSSascha Wildner return(0);
8821c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 2112 */
8921c1c48aSSascha Wildner return(0);
9021c1c48aSSascha Wildner *cyl = atoi(word);
9121c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* cyl */
9221c1c48aSSascha Wildner return(0);
9321c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 16 */
9421c1c48aSSascha Wildner return(0);
9521c1c48aSSascha Wildner *head = atoi(word);
9621c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* hd */
9721c1c48aSSascha Wildner return(0);
9821c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 63 */
9921c1c48aSSascha Wildner return(0);
10021c1c48aSSascha Wildner *sec = atoi(word);
10121c1c48aSSascha Wildner
10221c1c48aSSascha Wildner return(1);
10321c1c48aSSascha Wildner }
10421c1c48aSSascha Wildner
10521c1c48aSSascha Wildner /*
10621c1c48aSSascha Wildner * Given a slice description line from fdisk's summary output, return
10721c1c48aSSascha Wildner * the number of the slice, and its start, size, type, and flags.
10821c1c48aSSascha Wildner */
10921c1c48aSSascha Wildner static int
parse_slice_info(char * line,int * slice,unsigned long * start,unsigned long * size,int * type,int * flags)11021c1c48aSSascha Wildner parse_slice_info(char *line, int *slice,
11121c1c48aSSascha Wildner unsigned long *start, unsigned long *size,
11221c1c48aSSascha Wildner int *type, int *flags)
11321c1c48aSSascha Wildner {
11421c1c48aSSascha Wildner char *word;
11521c1c48aSSascha Wildner
11621c1c48aSSascha Wildner /*
11721c1c48aSSascha Wildner * Part Start Size Type Flags
118*7d89978dSSascha Wildner * 1: 63 2128833 0x6c 0x80
11921c1c48aSSascha Wildner */
12021c1c48aSSascha Wildner if ((word = strtok(line, " \t")) == NULL) /* 1: */
12121c1c48aSSascha Wildner return(0);
12221c1c48aSSascha Wildner *slice = atoi(word);
12321c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 63 */
12421c1c48aSSascha Wildner return(0);
12521c1c48aSSascha Wildner *start = strtoul(word, NULL, 10);
12621c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 2128833 */
12721c1c48aSSascha Wildner return(0);
12821c1c48aSSascha Wildner *size = strtoul(word, NULL, 10);
129*7d89978dSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 0x6c */
13021c1c48aSSascha Wildner return(0);
13121c1c48aSSascha Wildner if (!hex_to_int(word, type))
13221c1c48aSSascha Wildner return(0);
13321c1c48aSSascha Wildner if ((word = strtok(NULL, " \t")) == NULL) /* 0x80 */
13421c1c48aSSascha Wildner return(0);
13521c1c48aSSascha Wildner if (!hex_to_int(word, flags))
13621c1c48aSSascha Wildner return(0);
13721c1c48aSSascha Wildner
13821c1c48aSSascha Wildner return(1);
13921c1c48aSSascha Wildner }
14021c1c48aSSascha Wildner
14121c1c48aSSascha Wildner /*
14221c1c48aSSascha Wildner * Survey storage capacity of this system.
14321c1c48aSSascha Wildner */
14421c1c48aSSascha Wildner int
survey_storage(struct i_fn_args * a)14521c1c48aSSascha Wildner survey_storage(struct i_fn_args *a)
14621c1c48aSSascha Wildner {
14721c1c48aSSascha Wildner unsigned long mem = 0;
14821c1c48aSSascha Wildner char disks[256], line[256];
14921c1c48aSSascha Wildner char *disk, *disk_ptr;
15021c1c48aSSascha Wildner struct commands *cmds;
15121c1c48aSSascha Wildner struct command *cmd;
15221c1c48aSSascha Wildner FILE *f;
15321c1c48aSSascha Wildner char *filename;
15421c1c48aSSascha Wildner struct disk *d = NULL;
155f59b7dfaSSascha Wildner int number = 0;
15621c1c48aSSascha Wildner int failure = 0;
1577dae739fSAntonio Huete Jimenez int ndisks = 0;
158795e3215SSascha Wildner int fd;
15921c1c48aSSascha Wildner size_t len;
16021c1c48aSSascha Wildner struct aura_dict *di;
16121c1c48aSSascha Wildner void *rk;
16221c1c48aSSascha Wildner size_t rk_len;
163795e3215SSascha Wildner struct partinfo diskpart;
164795e3215SSascha Wildner char diskpath[PATH_MAX];
16521c1c48aSSascha Wildner
166a07abcb9SMatthew Dillon sleep(1); /* give devfs time to probe */
16721c1c48aSSascha Wildner disks_free(a->s);
16821c1c48aSSascha Wildner
16921c1c48aSSascha Wildner len = sizeof(mem);
17021c1c48aSSascha Wildner if (sysctlbyname("hw.physmem", &mem, &len, NULL, 0) < 0) {
17121c1c48aSSascha Wildner failure |= 1;
17221c1c48aSSascha Wildner } else {
17321c1c48aSSascha Wildner storage_set_memsize(a->s, next_power_of_two(mem >> 20));
17421c1c48aSSascha Wildner }
17521c1c48aSSascha Wildner len = 256;
17621c1c48aSSascha Wildner if (sysctlbyname("kern.disks", disks, &len, NULL, 0) < 0) {
17721c1c48aSSascha Wildner failure |= 1;
17821c1c48aSSascha Wildner }
17921c1c48aSSascha Wildner disk_ptr = disks;
18021c1c48aSSascha Wildner
18121c1c48aSSascha Wildner di = aura_dict_new(1, AURA_DICT_SORTED_LIST);
18221c1c48aSSascha Wildner while (!failure && (disk = strsep(&disk_ptr, " ")) != NULL) {
18321c1c48aSSascha Wildner if (disk[0] == '\0')
18421c1c48aSSascha Wildner continue;
18521c1c48aSSascha Wildner
18621c1c48aSSascha Wildner /*
18721c1c48aSSascha Wildner * If the disk is a memory disk, floppy or CD-ROM, skip it.
18821c1c48aSSascha Wildner */
18921c1c48aSSascha Wildner if (strncmp(disk, "md", 2) == 0 ||
19021c1c48aSSascha Wildner strncmp(disk, "cd", 2) == 0 ||
19121c1c48aSSascha Wildner strncmp(disk, "acd", 3) == 0 ||
19221c1c48aSSascha Wildner strncmp(disk, "fd", 2) == 0)
19321c1c48aSSascha Wildner continue;
19421c1c48aSSascha Wildner
19521c1c48aSSascha Wildner aura_dict_store(di, disk, strlen(disk) + 1, "", 1);
1967dae739fSAntonio Huete Jimenez ndisks++;
19721c1c48aSSascha Wildner }
19821c1c48aSSascha Wildner
1997dae739fSAntonio Huete Jimenez if (ndisks == 0)
2007dae739fSAntonio Huete Jimenez failure |= 1;
2017dae739fSAntonio Huete Jimenez
20221c1c48aSSascha Wildner cmds = commands_new();
20321c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s -n '' >%ssurvey.txt",
20421c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
20521c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
20621c1c48aSSascha Wildner
2077dae739fSAntonio Huete Jimenez for (aura_dict_rewind(di); !aura_dict_eof(di); aura_dict_next(di) ) {
2087dae739fSAntonio Huete Jimenez aura_dict_get_current_key(di, &rk, &rk_len);
20921c1c48aSSascha Wildner disk = (char *)rk;
21021c1c48aSSascha Wildner
2117dae739fSAntonio Huete Jimenez /*
2127dae739fSAntonio Huete Jimenez * Attempt to get media information from the disk. This information
2137dae739fSAntonio Huete Jimenez * might be used later on for partitioning. Any disk that does not
2147dae739fSAntonio Huete Jimenez * provide the information will be discarded as not suitable for
2157dae739fSAntonio Huete Jimenez * an installation.
2167dae739fSAntonio Huete Jimenez */
2177dae739fSAntonio Huete Jimenez bzero(&diskpart, sizeof(diskpart));
2187dae739fSAntonio Huete Jimenez snprintf(diskpath, PATH_MAX, "/dev/%s", disk);
2197dae739fSAntonio Huete Jimenez if ((fd = open(diskpath, O_RDONLY)) < 0)
2207dae739fSAntonio Huete Jimenez continue;
2217dae739fSAntonio Huete Jimenez if (ioctl(fd, DIOCGPART, &diskpart) < 0)
2227dae739fSAntonio Huete Jimenez continue;
2237dae739fSAntonio Huete Jimenez
22421c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '@DISK' >>%ssurvey.txt",
22521c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
22621c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
22721c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '%s' >>%ssurvey.txt",
22821c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), disk, a->tmp);
22921c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
23021c1c48aSSascha Wildner
23121c1c48aSSascha Wildner /*
23221c1c48aSSascha Wildner * Look for descriptions of this disk.
23321c1c48aSSascha Wildner */
23421c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '@DESC' >>%ssurvey.txt",
23521c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
23621c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
237795e3215SSascha Wildner cmd = command_add(cmds, "%s%s '%s: %luMB' >>%ssurvey.txt",
23821c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"),
23921c1c48aSSascha Wildner disk,
240795e3215SSascha Wildner diskpart.media_size / 1024 / 1024,
24121c1c48aSSascha Wildner a->tmp);
242795e3215SSascha Wildner close(fd);
24321c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
24421c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
24521c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
24621c1c48aSSascha Wildner
24721c1c48aSSascha Wildner /*
248f59b7dfaSSascha Wildner * Look for the disk's serial number.
249f59b7dfaSSascha Wildner */
250f59b7dfaSSascha Wildner cmd = command_add(cmds, "%s%s '@SERNO' >>%ssurvey.txt",
251f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
252f59b7dfaSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
253f59b7dfaSSascha 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",
254f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "TEST"),
255f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "LS"),
256f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "GREP"),
257f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "LS"),
258f59b7dfaSSascha Wildner disk,
259f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "AWK"),
260f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "AWK"),
261f59b7dfaSSascha Wildner a->tmp);
262f59b7dfaSSascha Wildner cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
263f59b7dfaSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
264f59b7dfaSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
265f59b7dfaSSascha Wildner
266f59b7dfaSSascha Wildner /*
26721c1c48aSSascha Wildner * Probe the disk with fdisk.
26821c1c48aSSascha Wildner */
26921c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '@SLICES' >>%ssurvey.txt",
27021c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
27121c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
27221c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s -s %s 2>/dev/null >>%ssurvey.txt || %s%s '' >>%ssurvey.txt",
27321c1c48aSSascha Wildner a->os_root, cmd_name(a, "FDISK"),
27421c1c48aSSascha Wildner disk,
27521c1c48aSSascha Wildner a->tmp,
27621c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"),
27721c1c48aSSascha Wildner a->tmp);
27821c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '@END' >>%ssurvey.txt",
27921c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
28021c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
28121c1c48aSSascha Wildner }
28221c1c48aSSascha Wildner
28321c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s '.' >>%ssurvey.txt",
28421c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), a->tmp);
28521c1c48aSSascha Wildner command_set_log_mode(cmd, COMMAND_LOG_SILENT);
28621c1c48aSSascha Wildner
28721c1c48aSSascha Wildner if (!commands_execute(a, cmds))
28821c1c48aSSascha Wildner failure |= 1;
28921c1c48aSSascha Wildner commands_free(cmds);
29021c1c48aSSascha Wildner temp_file_add(a, "survey.txt");
29121c1c48aSSascha Wildner
29221c1c48aSSascha Wildner aura_dict_free(di);
29321c1c48aSSascha Wildner
29421c1c48aSSascha Wildner /*
29521c1c48aSSascha Wildner * Now read in and parse the file that those commands just created.
29621c1c48aSSascha Wildner */
29721c1c48aSSascha Wildner asprintf(&filename, "%ssurvey.txt", a->tmp);
29821c1c48aSSascha Wildner if ((f = fopen(filename, "r")) == NULL)
29921c1c48aSSascha Wildner failure |= 1;
30021c1c48aSSascha Wildner free(filename);
30121c1c48aSSascha Wildner
30221c1c48aSSascha Wildner while (!failure && fgets_chomp(line, 255, f)) {
30321c1c48aSSascha Wildner if (strcmp(line, "@DISK") == 0) {
30421c1c48aSSascha Wildner if (fgets_chomp(line, 255, f)) {
30521c1c48aSSascha Wildner d = disk_new(a->s, line);
306f59b7dfaSSascha Wildner disk_set_number(d, number++);
30721c1c48aSSascha Wildner }
30821c1c48aSSascha Wildner } else if (strcmp(line, "@DESC") == 0) {
30921c1c48aSSascha Wildner while (d != NULL && strcmp(line, "@END") != 0 && fgets_chomp(line, 255, f)) {
31021c1c48aSSascha Wildner disk_set_desc(d, line);
31121c1c48aSSascha Wildner }
312f59b7dfaSSascha Wildner } else if (strcmp(line, "@SERNO") == 0) {
313f59b7dfaSSascha Wildner fgets_chomp(line, 255, f);
3141557ef28SSascha Wildner if (line[0] != '\0' && strcmp(line, "@END") != 0)
315f59b7dfaSSascha Wildner disk_set_serno(d, line);
31621c1c48aSSascha Wildner } else if (strcmp(line, "@SLICES") == 0) {
31721c1c48aSSascha Wildner int cyl, hd, sec;
318a9879eb2SSascha Wildner int sliceno, type, flags;
31921c1c48aSSascha Wildner unsigned long start, size;
32021c1c48aSSascha Wildner
32121c1c48aSSascha Wildner /*
32221c1c48aSSascha Wildner * /dev/ad3: 2112 cyl 16 hd 63 sec
32321c1c48aSSascha Wildner * Part Start Size Type Flags
324*7d89978dSSascha Wildner * 1: 63 2128833 0x6c 0x80
32521c1c48aSSascha Wildner */
32621c1c48aSSascha Wildner while (d != NULL && strcmp(line, "@END") != 0 && fgets_chomp(line, 255, f)) {
32721c1c48aSSascha Wildner if (strncmp(line, "/dev/", 5) == 0) {
328a9879eb2SSascha Wildner cyl = hd = sec = 0;
32921c1c48aSSascha Wildner parse_geometry_info(line, &cyl, &hd, &sec);
33021c1c48aSSascha Wildner disk_set_geometry(d, cyl, hd, sec);
33121c1c48aSSascha Wildner } else if (strncmp(line, "Part", 4) == 0) {
33221c1c48aSSascha Wildner /* ignore it */
33321c1c48aSSascha Wildner } else {
334a9879eb2SSascha Wildner if (parse_slice_info(line, &sliceno, &start, &size,
33521c1c48aSSascha Wildner &type, &flags)) {
33621c1c48aSSascha Wildner /*
33721c1c48aSSascha Wildner fprintfo(log, "| Found slice #%d, sysid %d, "
338a9879eb2SSascha Wildner "start %ld, size %ld\n", sliceno, type, start, size);
33921c1c48aSSascha Wildner */
340a9879eb2SSascha Wildner slice_new(d, sliceno, type, flags, start, size);
34121c1c48aSSascha Wildner }
34221c1c48aSSascha Wildner }
34321c1c48aSSascha Wildner }
34421c1c48aSSascha Wildner }
34521c1c48aSSascha Wildner }
34621c1c48aSSascha Wildner
34721c1c48aSSascha Wildner if (f != NULL)
34821c1c48aSSascha Wildner fclose(f);
34921c1c48aSSascha Wildner
35021c1c48aSSascha Wildner /*
35121c1c48aSSascha Wildner * Fix up any disk descriptions that didn't make it.
35221c1c48aSSascha Wildner */
35321c1c48aSSascha Wildner for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
35421c1c48aSSascha Wildner if (disk_get_desc(d) == NULL)
35521c1c48aSSascha Wildner disk_set_desc(d, disk_get_device_name(d));
35621c1c48aSSascha Wildner }
35721c1c48aSSascha Wildner
35821c1c48aSSascha Wildner return(!failure);
35921c1c48aSSascha Wildner }
360