xref: /dflybsd-src/usr.sbin/installer/libinstaller/diskutil.c (revision 2574e737794af29adabc7cc931607783cfe513ab)
121c1c48aSSascha Wildner /*
2f9602a12SMatthew Dillon  * Copyright (c)2004,2015 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  * diskutil.c
3621c1c48aSSascha Wildner  * Disk utility functions for installer.
3721c1c48aSSascha Wildner  * $Id: diskutil.c,v 1.44 2005/02/07 06:41:42 cpressey Exp $
3821c1c48aSSascha Wildner  */
3921c1c48aSSascha Wildner 
40*2574e737SSascha Wildner #include <sys/diskmbr.h>
41*2574e737SSascha Wildner 
4221c1c48aSSascha Wildner #include <stdarg.h>
4321c1c48aSSascha Wildner #include <stdio.h>
4421c1c48aSSascha Wildner #include <stdlib.h>
4521c1c48aSSascha Wildner #include <string.h>
4621c1c48aSSascha Wildner 
4721c1c48aSSascha Wildner #include "libaura/mem.h"
4821c1c48aSSascha Wildner #include "libaura/fspred.h"
4921c1c48aSSascha Wildner #include "libaura/popen.h"
5021c1c48aSSascha Wildner 
5121c1c48aSSascha Wildner #include "libdfui/dfui.h"
5221c1c48aSSascha Wildner #include "libdfui/dump.h"
5321c1c48aSSascha Wildner 
5421c1c48aSSascha Wildner #define NEEDS_DISKUTIL_STRUCTURE_DEFINITIONS
5521c1c48aSSascha Wildner #include "diskutil.h"
5621c1c48aSSascha Wildner #undef NEEDS_DISKUTIL_STRUCTURE_DEFINITIONS
5721c1c48aSSascha Wildner 
5821c1c48aSSascha Wildner #include "commands.h"
5921c1c48aSSascha Wildner #include "functions.h"
6021c1c48aSSascha Wildner #include "uiutil.h"
6121c1c48aSSascha Wildner 
6221c1c48aSSascha Wildner static int	disk_description_is_better(const char *, const char *);
6321c1c48aSSascha Wildner 
6421c1c48aSSascha Wildner /** STORAGE DESCRIPTORS **/
6521c1c48aSSascha Wildner 
6621c1c48aSSascha Wildner struct storage *
storage_new(void)6721c1c48aSSascha Wildner storage_new(void)
6821c1c48aSSascha Wildner {
6921c1c48aSSascha Wildner 	struct storage *s;
7021c1c48aSSascha Wildner 
7121c1c48aSSascha Wildner 	AURA_MALLOC(s, storage);
7221c1c48aSSascha Wildner 
7321c1c48aSSascha Wildner 	s->disk_head = NULL;
7421c1c48aSSascha Wildner 	s->disk_tail = NULL;
7521c1c48aSSascha Wildner 	s->selected_disk = NULL;
7621c1c48aSSascha Wildner 	s->selected_slice = NULL;
7721c1c48aSSascha Wildner 	s->ram = -1;
7821c1c48aSSascha Wildner 
7921c1c48aSSascha Wildner 	return(s);
8021c1c48aSSascha Wildner }
8121c1c48aSSascha Wildner 
8221c1c48aSSascha Wildner int
storage_get_tmpfs_status(const char * mountpoint,struct storage * s)83761cad2fSSascha Wildner storage_get_tmpfs_status(const char *mountpoint, struct storage *s)
8421c1c48aSSascha Wildner {
8521c1c48aSSascha Wildner 	struct subpartition *sp;
8621c1c48aSSascha Wildner 	sp = NULL;
8721c1c48aSSascha Wildner 	for (sp = slice_subpartition_first(s->selected_slice);
8821c1c48aSSascha Wildner 		sp != NULL; sp = subpartition_next(sp)) {
8921c1c48aSSascha Wildner 		if(strcmp(subpartition_get_mountpoint(sp), mountpoint) == 0) {
90761cad2fSSascha Wildner 			if(subpartition_is_tmpfsbacked(sp) == 1) {
9121c1c48aSSascha Wildner 				return 1;
9221c1c48aSSascha Wildner 			} else {
9321c1c48aSSascha Wildner 				return 0;
9421c1c48aSSascha Wildner 			}
9521c1c48aSSascha Wildner 		}
9621c1c48aSSascha Wildner 	}
9721c1c48aSSascha Wildner 	return 0;
9821c1c48aSSascha Wildner }
9921c1c48aSSascha Wildner 
10021c1c48aSSascha Wildner void
storage_free(struct storage * s)10121c1c48aSSascha Wildner storage_free(struct storage *s)
10221c1c48aSSascha Wildner {
10321c1c48aSSascha Wildner 	disks_free(s);
10421c1c48aSSascha Wildner 	AURA_FREE(s, storage);
10521c1c48aSSascha Wildner }
10621c1c48aSSascha Wildner 
10721c1c48aSSascha Wildner void
storage_set_memsize(struct storage * s,unsigned long memsize)10821c1c48aSSascha Wildner storage_set_memsize(struct storage *s, unsigned long memsize)
10921c1c48aSSascha Wildner {
11021c1c48aSSascha Wildner 	s->ram = memsize;
11121c1c48aSSascha Wildner }
11221c1c48aSSascha Wildner 
113a9879eb2SSascha Wildner long
storage_get_memsize(const struct storage * s)11421c1c48aSSascha Wildner storage_get_memsize(const struct storage *s)
11521c1c48aSSascha Wildner {
11621c1c48aSSascha Wildner 	return(s->ram);
11721c1c48aSSascha Wildner }
11821c1c48aSSascha Wildner 
11921c1c48aSSascha Wildner struct disk *
storage_disk_first(const struct storage * s)12021c1c48aSSascha Wildner storage_disk_first(const struct storage *s)
12121c1c48aSSascha Wildner {
12221c1c48aSSascha Wildner 	return(s->disk_head);
12321c1c48aSSascha Wildner }
12421c1c48aSSascha Wildner 
12521c1c48aSSascha Wildner void
storage_set_selected_disk(struct storage * s,struct disk * d)12621c1c48aSSascha Wildner storage_set_selected_disk(struct storage *s, struct disk *d)
12721c1c48aSSascha Wildner {
12821c1c48aSSascha Wildner 	s->selected_disk = d;
12921c1c48aSSascha Wildner }
13021c1c48aSSascha Wildner 
13121c1c48aSSascha Wildner struct disk *
storage_get_selected_disk(const struct storage * s)13221c1c48aSSascha Wildner storage_get_selected_disk(const struct storage *s)
13321c1c48aSSascha Wildner {
13421c1c48aSSascha Wildner 	return(s->selected_disk);
13521c1c48aSSascha Wildner }
13621c1c48aSSascha Wildner 
13721c1c48aSSascha Wildner void
storage_set_selected_slice(struct storage * s,struct slice * sl)13821c1c48aSSascha Wildner storage_set_selected_slice(struct storage *s, struct slice *sl)
13921c1c48aSSascha Wildner {
14021c1c48aSSascha Wildner 	s->selected_slice = sl;
14121c1c48aSSascha Wildner }
14221c1c48aSSascha Wildner 
14321c1c48aSSascha Wildner struct slice *
storage_get_selected_slice(const struct storage * s)14421c1c48aSSascha Wildner storage_get_selected_slice(const struct storage *s)
14521c1c48aSSascha Wildner {
14621c1c48aSSascha Wildner 	return(s->selected_slice);
14721c1c48aSSascha Wildner }
14821c1c48aSSascha Wildner 
14921c1c48aSSascha Wildner /*
15021c1c48aSSascha Wildner  * Create a new disk description structure.
15121c1c48aSSascha Wildner  */
15221c1c48aSSascha Wildner struct disk *
disk_new(struct storage * s,const char * dev_name)15321c1c48aSSascha Wildner disk_new(struct storage *s, const char *dev_name)
15421c1c48aSSascha Wildner {
15521c1c48aSSascha Wildner 	struct disk *d;
15621c1c48aSSascha Wildner 
15721c1c48aSSascha Wildner 	AURA_MALLOC(d, disk);
15821c1c48aSSascha Wildner 
15921c1c48aSSascha Wildner 	d->device = aura_strdup(dev_name);
16021c1c48aSSascha Wildner 	d->desc = NULL;
161f59b7dfaSSascha Wildner 	d->serno = NULL;
16221c1c48aSSascha Wildner 	d->we_formatted = 0;
16321c1c48aSSascha Wildner 	d->capacity = 0;
16421c1c48aSSascha Wildner 
16521c1c48aSSascha Wildner 	d->cylinders = -1;	/* -1 indicates "we don't know" */
16621c1c48aSSascha Wildner 	d->heads = -1;
16721c1c48aSSascha Wildner 	d->sectors = -1;
16821c1c48aSSascha Wildner 
16921c1c48aSSascha Wildner 	d->slice_head = NULL;
17021c1c48aSSascha Wildner 	d->slice_tail = NULL;
17121c1c48aSSascha Wildner 
17221c1c48aSSascha Wildner 	d->next = NULL;
17321c1c48aSSascha Wildner 	if (s->disk_head == NULL)
17421c1c48aSSascha Wildner 		s->disk_head = d;
17521c1c48aSSascha Wildner 	else
17621c1c48aSSascha Wildner 		s->disk_tail->next = d;
17721c1c48aSSascha Wildner 
17821c1c48aSSascha Wildner 	d->prev = s->disk_tail;
17921c1c48aSSascha Wildner 	s->disk_tail = d;
18021c1c48aSSascha Wildner 
18121c1c48aSSascha Wildner 	return(d);
18221c1c48aSSascha Wildner }
18321c1c48aSSascha Wildner 
18421c1c48aSSascha Wildner static int
disk_description_is_better(const char * existing,const char * new_desc __unused)18521c1c48aSSascha Wildner disk_description_is_better(const char *existing, const char *new_desc __unused)
18621c1c48aSSascha Wildner {
18721c1c48aSSascha Wildner 	if (existing == NULL)
18821c1c48aSSascha Wildner 		return(1);
18921c1c48aSSascha Wildner 	return(0);
19021c1c48aSSascha Wildner }
19121c1c48aSSascha Wildner 
19221c1c48aSSascha Wildner const char *
disk_get_desc(const struct disk * d)19321c1c48aSSascha Wildner disk_get_desc(const struct disk *d)
19421c1c48aSSascha Wildner {
19521c1c48aSSascha Wildner 	return(d->desc);
19621c1c48aSSascha Wildner }
19721c1c48aSSascha Wildner 
198a07abcb9SMatthew Dillon unsigned long
disk_get_capacity(const struct disk * d)199a07abcb9SMatthew Dillon disk_get_capacity(const struct disk *d)
200a07abcb9SMatthew Dillon {
201a07abcb9SMatthew Dillon 	return(d->capacity);
202a07abcb9SMatthew Dillon }
203a07abcb9SMatthew Dillon 
204a07abcb9SMatthew Dillon 
20521c1c48aSSascha Wildner void
disk_set_desc(struct disk * d,const char * desc)20621c1c48aSSascha Wildner disk_set_desc(struct disk *d, const char *desc)
20721c1c48aSSascha Wildner {
20821c1c48aSSascha Wildner 	char *c;
20921c1c48aSSascha Wildner 
21021c1c48aSSascha Wildner 	if (!disk_description_is_better(d->desc, desc))
21121c1c48aSSascha Wildner 		return;
21221c1c48aSSascha Wildner 	if (d->desc != NULL)
21321c1c48aSSascha Wildner 		free(d->desc);
21421c1c48aSSascha Wildner 	d->desc = aura_strdup(desc);
21521c1c48aSSascha Wildner 
21621c1c48aSSascha Wildner 	/*
21721c1c48aSSascha Wildner 	 * Get the disk's total capacity.
21821c1c48aSSascha Wildner 	 * XXX we should do this with C/H/S ?
21921c1c48aSSascha Wildner 	 */
22021c1c48aSSascha Wildner 	c = d->desc;
22121c1c48aSSascha Wildner 	while (*c != ':' && *c != '\0')
22221c1c48aSSascha Wildner 		c++;
22321c1c48aSSascha Wildner 	if (*c == '\0')
22421c1c48aSSascha Wildner 		d->capacity = 0;
22521c1c48aSSascha Wildner 	else
226a07abcb9SMatthew Dillon 		d->capacity = strtoul(c + 1, NULL, 0);
22721c1c48aSSascha Wildner }
22821c1c48aSSascha Wildner 
22921c1c48aSSascha Wildner /*
23021c1c48aSSascha Wildner  * Returns the name of the device node used to represent the disk.
23121c1c48aSSascha Wildner  * Note that the storage used for the returned string is static,
23221c1c48aSSascha Wildner  * and the string is overwritten each time this function is called.
23321c1c48aSSascha Wildner  */
23421c1c48aSSascha Wildner const char *
disk_get_device_name(const struct disk * d)23521c1c48aSSascha Wildner disk_get_device_name(const struct disk *d)
23621c1c48aSSascha Wildner {
23721c1c48aSSascha Wildner 	static char tmp_dev_name[256];
23821c1c48aSSascha Wildner 
23921c1c48aSSascha Wildner 	snprintf(tmp_dev_name, 256, "%s", d->device);
24021c1c48aSSascha Wildner 	return(tmp_dev_name);
24121c1c48aSSascha Wildner }
24221c1c48aSSascha Wildner 
24321c1c48aSSascha Wildner const char *
disk_get_serno(const struct disk * d)244f59b7dfaSSascha Wildner disk_get_serno(const struct disk *d)
24521c1c48aSSascha Wildner {
246f59b7dfaSSascha Wildner 	return(d->serno);
247f59b7dfaSSascha Wildner }
24821c1c48aSSascha Wildner 
249f59b7dfaSSascha Wildner void
disk_set_serno(struct disk * d,const char * serno)250f59b7dfaSSascha Wildner disk_set_serno(struct disk *d, const char *serno)
251f59b7dfaSSascha Wildner {
252f59b7dfaSSascha Wildner 	d->serno = aura_strdup(serno);
253f59b7dfaSSascha Wildner }
254f59b7dfaSSascha Wildner 
255f59b7dfaSSascha Wildner int
disk_get_number(const struct disk * d)256f59b7dfaSSascha Wildner disk_get_number(const struct disk *d)
257f59b7dfaSSascha Wildner {
258f59b7dfaSSascha Wildner 	return(d->number);
259f59b7dfaSSascha Wildner }
260f59b7dfaSSascha Wildner 
261f59b7dfaSSascha Wildner void
disk_set_number(struct disk * d,const int number)262f59b7dfaSSascha Wildner disk_set_number(struct disk *d, const int number)
263f59b7dfaSSascha Wildner {
264f59b7dfaSSascha Wildner 	d->number = number;
26521c1c48aSSascha Wildner }
26621c1c48aSSascha Wildner 
26721c1c48aSSascha Wildner /*
26821c1c48aSSascha Wildner  * Find the first disk description structure in the given
26921c1c48aSSascha Wildner  * storage description which matches the given device name
27021c1c48aSSascha Wildner  * prefix.  Note that this means that if a storage
27121c1c48aSSascha Wildner  * description s contains disks named "ad0" and "ad1",
27221c1c48aSSascha Wildner  * disk_find(s, "ad0s1c") will return a pointer to the disk
27321c1c48aSSascha Wildner  * structure for "ad0".
27421c1c48aSSascha Wildner  */
27521c1c48aSSascha Wildner struct disk *
disk_find(const struct storage * s,const char * device)27621c1c48aSSascha Wildner disk_find(const struct storage *s, const char *device)
27721c1c48aSSascha Wildner {
27821c1c48aSSascha Wildner 	struct disk *d = s->disk_head;
27921c1c48aSSascha Wildner 
28021c1c48aSSascha Wildner 	while (d != NULL) {
281a96dd725SSascha Wildner 		if (strncmp(device, d->device, strlen(d->device)) == 0 &&
282a96dd725SSascha Wildner 		    strlen(device) == strlen(d->device))
28321c1c48aSSascha Wildner 			return(d);
28421c1c48aSSascha Wildner 		d = d->next;
28521c1c48aSSascha Wildner 	}
28621c1c48aSSascha Wildner 
28721c1c48aSSascha Wildner 	return(NULL);
28821c1c48aSSascha Wildner }
28921c1c48aSSascha Wildner 
29021c1c48aSSascha Wildner struct disk *
disk_next(const struct disk * d)29121c1c48aSSascha Wildner disk_next(const struct disk *d)
29221c1c48aSSascha Wildner {
29321c1c48aSSascha Wildner 	return(d->next);
29421c1c48aSSascha Wildner }
29521c1c48aSSascha Wildner 
29621c1c48aSSascha Wildner struct slice *
disk_slice_first(const struct disk * d)29721c1c48aSSascha Wildner disk_slice_first(const struct disk *d)
29821c1c48aSSascha Wildner {
29921c1c48aSSascha Wildner 	return(d->slice_head);
30021c1c48aSSascha Wildner }
30121c1c48aSSascha Wildner 
30221c1c48aSSascha Wildner void
disk_set_formatted(struct disk * d,int formatted)30321c1c48aSSascha Wildner disk_set_formatted(struct disk *d, int formatted)
30421c1c48aSSascha Wildner {
30521c1c48aSSascha Wildner 	d->we_formatted = formatted;
30621c1c48aSSascha Wildner }
30721c1c48aSSascha Wildner 
30821c1c48aSSascha Wildner int
disk_get_formatted(const struct disk * d)30921c1c48aSSascha Wildner disk_get_formatted(const struct disk *d)
31021c1c48aSSascha Wildner {
31121c1c48aSSascha Wildner 	return(d->we_formatted);
31221c1c48aSSascha Wildner }
31321c1c48aSSascha Wildner 
31421c1c48aSSascha Wildner void
disk_set_geometry(struct disk * d,int cyl,int hd,int sec)31521c1c48aSSascha Wildner disk_set_geometry(struct disk *d, int cyl, int hd, int sec)
31621c1c48aSSascha Wildner {
31721c1c48aSSascha Wildner 	d->cylinders = cyl;
31821c1c48aSSascha Wildner 	d->heads = hd;
31921c1c48aSSascha Wildner 	d->sectors = sec;
32021c1c48aSSascha Wildner }
32121c1c48aSSascha Wildner 
32221c1c48aSSascha Wildner void
disk_get_geometry(const struct disk * d,int * cyl,int * hd,int * sec)32321c1c48aSSascha Wildner disk_get_geometry(const struct disk *d, int *cyl, int *hd, int *sec)
32421c1c48aSSascha Wildner {
32521c1c48aSSascha Wildner 	*cyl = d->cylinders;
32621c1c48aSSascha Wildner 	*hd = d->heads;
32721c1c48aSSascha Wildner 	*sec = d->sectors;
32821c1c48aSSascha Wildner }
32921c1c48aSSascha Wildner 
33021c1c48aSSascha Wildner /*
33121c1c48aSSascha Wildner  * Free the memory allocated to hold the set of disk descriptions.
33221c1c48aSSascha Wildner  */
33321c1c48aSSascha Wildner void
disks_free(struct storage * s)33421c1c48aSSascha Wildner disks_free(struct storage *s)
33521c1c48aSSascha Wildner {
33621c1c48aSSascha Wildner 	struct disk *d = s->disk_head, *next;
33721c1c48aSSascha Wildner 
33821c1c48aSSascha Wildner 	while (d != NULL) {
33921c1c48aSSascha Wildner 		next = d->next;
34021c1c48aSSascha Wildner 		slices_free(d->slice_head);
34121c1c48aSSascha Wildner 		free(d->desc);
34221c1c48aSSascha Wildner 		free(d->device);
34321c1c48aSSascha Wildner 		AURA_FREE(d, disk);
34421c1c48aSSascha Wildner 		d = next;
34521c1c48aSSascha Wildner 	}
34621c1c48aSSascha Wildner 
34721c1c48aSSascha Wildner 	s->disk_head = NULL;
34821c1c48aSSascha Wildner 	s->disk_tail = NULL;
34921c1c48aSSascha Wildner }
35021c1c48aSSascha Wildner 
35121c1c48aSSascha Wildner /*
35221c1c48aSSascha Wildner  * Create a new slice description and add it to a disk description.
35321c1c48aSSascha Wildner  */
35421c1c48aSSascha Wildner struct slice *
slice_new(struct disk * d,int number,int type,int flags,unsigned long start,unsigned long size)35521c1c48aSSascha Wildner slice_new(struct disk *d, int number, int type, int flags,
35621c1c48aSSascha Wildner 	  unsigned long start, unsigned long size)
35721c1c48aSSascha Wildner {
35821c1c48aSSascha Wildner 	struct slice *s;
35921c1c48aSSascha Wildner 	const char *sysid_desc = NULL;
36021c1c48aSSascha Wildner 	char unknown[256];
36121c1c48aSSascha Wildner 	int i;
36221c1c48aSSascha Wildner 
36321c1c48aSSascha Wildner 	dfui_debug("** adding slice %d (start %ld, size %ld, sysid %d) "
36421c1c48aSSascha Wildner 	    "to disk %s\n", number, start, size, type, d->device);
36521c1c48aSSascha Wildner 
36621c1c48aSSascha Wildner 	AURA_MALLOC(s, slice);
36721c1c48aSSascha Wildner 
36821c1c48aSSascha Wildner 	s->parent = d;
36921c1c48aSSascha Wildner 
37021c1c48aSSascha Wildner 	s->subpartition_head = NULL;
37121c1c48aSSascha Wildner 	s->subpartition_tail = NULL;
37221c1c48aSSascha Wildner 	s->number = number;
37321c1c48aSSascha Wildner 
37421c1c48aSSascha Wildner 	s->type = type;
37521c1c48aSSascha Wildner 	s->flags = flags;
37621c1c48aSSascha Wildner 	s->start = start;
37721c1c48aSSascha Wildner 	s->size = size;
37821c1c48aSSascha Wildner 
37921c1c48aSSascha Wildner 	for (i = 0; ; i++) {
380*2574e737SSascha Wildner 		if (dos_ptypes[i].type == type) {
381*2574e737SSascha Wildner 			sysid_desc = dos_ptypes[i].name;
38221c1c48aSSascha Wildner 			break;
38321c1c48aSSascha Wildner 		}
384*2574e737SSascha Wildner 		if (dos_ptypes[i].type == 255)
38521c1c48aSSascha Wildner 			break;
38621c1c48aSSascha Wildner 	}
38721c1c48aSSascha Wildner 	if (sysid_desc == NULL) {
38821c1c48aSSascha Wildner 		snprintf(unknown, 256, "??? Unknown, sysid = %d", type);
38921c1c48aSSascha Wildner 		sysid_desc = unknown;
39021c1c48aSSascha Wildner 	}
39121c1c48aSSascha Wildner 
39221c1c48aSSascha Wildner 	asprintf(&s->desc, "%ldM - %ldM: %s",
39321c1c48aSSascha Wildner 	    start / 2048, (start + size) / 2048, sysid_desc);
39421c1c48aSSascha Wildner 	s->capacity = size / 2048;
39521c1c48aSSascha Wildner 
39621c1c48aSSascha Wildner 	s->next = NULL;
39721c1c48aSSascha Wildner 	if (d->slice_head == NULL)
39821c1c48aSSascha Wildner 		d->slice_head = s;
39921c1c48aSSascha Wildner 	else
40021c1c48aSSascha Wildner 		d->slice_tail->next = s;
40121c1c48aSSascha Wildner 
40221c1c48aSSascha Wildner 	s->prev = d->slice_tail;
40321c1c48aSSascha Wildner 	d->slice_tail = s;
40421c1c48aSSascha Wildner 
40521c1c48aSSascha Wildner 	return(s);
40621c1c48aSSascha Wildner }
40721c1c48aSSascha Wildner 
40821c1c48aSSascha Wildner /*
40921c1c48aSSascha Wildner  * Find a slice description on a given disk description given the
41021c1c48aSSascha Wildner  * slice number.
41121c1c48aSSascha Wildner  */
41221c1c48aSSascha Wildner struct slice *
slice_find(const struct disk * d,int number)41321c1c48aSSascha Wildner slice_find(const struct disk *d, int number)
41421c1c48aSSascha Wildner {
41521c1c48aSSascha Wildner 	struct slice *s = d->slice_head;
41621c1c48aSSascha Wildner 
41721c1c48aSSascha Wildner 	while (s != NULL) {
41821c1c48aSSascha Wildner 		if (s->number == number)
41921c1c48aSSascha Wildner 			return(s);
42021c1c48aSSascha Wildner 		s = s->next;
42121c1c48aSSascha Wildner 	}
42221c1c48aSSascha Wildner 
42321c1c48aSSascha Wildner 	return(NULL);
42421c1c48aSSascha Wildner }
42521c1c48aSSascha Wildner 
42621c1c48aSSascha Wildner struct slice *
slice_next(const struct slice * s)42721c1c48aSSascha Wildner slice_next(const struct slice *s)
42821c1c48aSSascha Wildner {
42921c1c48aSSascha Wildner 	return(s->next);
43021c1c48aSSascha Wildner }
43121c1c48aSSascha Wildner 
43221c1c48aSSascha Wildner /*
43321c1c48aSSascha Wildner  * Returns the name of the device node used to represent the slice.
43421c1c48aSSascha Wildner  * Note that the storage used for the returned string is static,
43521c1c48aSSascha Wildner  * and the string is overwritten each time this function is called.
43621c1c48aSSascha Wildner  */
43721c1c48aSSascha Wildner const char *
slice_get_device_name(const struct slice * s)43821c1c48aSSascha Wildner slice_get_device_name(const struct slice *s)
43921c1c48aSSascha Wildner {
44021c1c48aSSascha Wildner 	static char tmp_dev_name[256];
44121c1c48aSSascha Wildner 
44221c1c48aSSascha Wildner 	snprintf(tmp_dev_name, 256, "%ss%d", s->parent->device, s->number);
44321c1c48aSSascha Wildner 	return(tmp_dev_name);
44421c1c48aSSascha Wildner }
44521c1c48aSSascha Wildner 
44621c1c48aSSascha Wildner int
slice_get_number(const struct slice * s)44721c1c48aSSascha Wildner slice_get_number(const struct slice *s)
44821c1c48aSSascha Wildner {
44921c1c48aSSascha Wildner 	return(s->number);
45021c1c48aSSascha Wildner }
45121c1c48aSSascha Wildner 
45221c1c48aSSascha Wildner const char *
slice_get_desc(const struct slice * s)45321c1c48aSSascha Wildner slice_get_desc(const struct slice *s)
45421c1c48aSSascha Wildner {
45521c1c48aSSascha Wildner 	return(s->desc);
45621c1c48aSSascha Wildner }
45721c1c48aSSascha Wildner 
45821c1c48aSSascha Wildner unsigned long
slice_get_capacity(const struct slice * s)45921c1c48aSSascha Wildner slice_get_capacity(const struct slice *s)
46021c1c48aSSascha Wildner {
46121c1c48aSSascha Wildner 	return(s->capacity);
46221c1c48aSSascha Wildner }
46321c1c48aSSascha Wildner 
46421c1c48aSSascha Wildner unsigned long
slice_get_start(const struct slice * s)46521c1c48aSSascha Wildner slice_get_start(const struct slice *s)
46621c1c48aSSascha Wildner {
46721c1c48aSSascha Wildner 	return(s->start);
46821c1c48aSSascha Wildner }
46921c1c48aSSascha Wildner 
47021c1c48aSSascha Wildner unsigned long
slice_get_size(const struct slice * s)47121c1c48aSSascha Wildner slice_get_size(const struct slice *s)
47221c1c48aSSascha Wildner {
47321c1c48aSSascha Wildner 	return(s->size);
47421c1c48aSSascha Wildner }
47521c1c48aSSascha Wildner 
47621c1c48aSSascha Wildner int
slice_get_type(const struct slice * s)47721c1c48aSSascha Wildner slice_get_type(const struct slice *s)
47821c1c48aSSascha Wildner {
47921c1c48aSSascha Wildner 	return(s->type);
48021c1c48aSSascha Wildner }
48121c1c48aSSascha Wildner 
48221c1c48aSSascha Wildner int
slice_get_flags(const struct slice * s)48321c1c48aSSascha Wildner slice_get_flags(const struct slice *s)
48421c1c48aSSascha Wildner {
48521c1c48aSSascha Wildner 	return(s->flags);
48621c1c48aSSascha Wildner }
48721c1c48aSSascha Wildner 
48821c1c48aSSascha Wildner struct subpartition *
slice_subpartition_first(const struct slice * s)48921c1c48aSSascha Wildner slice_subpartition_first(const struct slice *s)
49021c1c48aSSascha Wildner {
49121c1c48aSSascha Wildner 	return(s->subpartition_head);
49221c1c48aSSascha Wildner }
49321c1c48aSSascha Wildner 
49421c1c48aSSascha Wildner /*
49521c1c48aSSascha Wildner  * Free all memory for a list of slice descriptions.
49621c1c48aSSascha Wildner  */
49721c1c48aSSascha Wildner void
slices_free(struct slice * head)49821c1c48aSSascha Wildner slices_free(struct slice *head)
49921c1c48aSSascha Wildner {
50021c1c48aSSascha Wildner 	struct slice *next;
50121c1c48aSSascha Wildner 
50221c1c48aSSascha Wildner 	while (head != NULL) {
50321c1c48aSSascha Wildner 		next = head->next;
50421c1c48aSSascha Wildner 		subpartitions_free(head);
50521c1c48aSSascha Wildner 		free(head->desc);
50621c1c48aSSascha Wildner 		AURA_FREE(head, slice);
50721c1c48aSSascha Wildner 		head = next;
50821c1c48aSSascha Wildner 	}
50921c1c48aSSascha Wildner }
51021c1c48aSSascha Wildner 
51121c1c48aSSascha Wildner struct subpartition *
subpartition_new_hammer(struct slice * s,const char * mountpoint,long capacity,int encrypted)512e90c1ebbSMatthew Dillon subpartition_new_hammer(struct slice *s, const char *mountpoint,
513e90c1ebbSMatthew Dillon 			long capacity, int encrypted)
51421c1c48aSSascha Wildner {
51521c1c48aSSascha Wildner 	struct subpartition *sp;
516f9602a12SMatthew Dillon 	struct subpartition *last = s->subpartition_tail;
51721c1c48aSSascha Wildner 
51821c1c48aSSascha Wildner 	AURA_MALLOC(sp, subpartition);
51921c1c48aSSascha Wildner 
52021c1c48aSSascha Wildner 	sp->parent = s;
52121c1c48aSSascha Wildner 
52221c1c48aSSascha Wildner 	if (last == NULL) {
52321c1c48aSSascha Wildner 		sp->letter = 'a';
52421c1c48aSSascha Wildner 	} else if (last->letter == 'b') {
52521c1c48aSSascha Wildner 		sp->letter = 'd';
52621c1c48aSSascha Wildner 	} else {
52721c1c48aSSascha Wildner 		sp->letter = (char)(last->letter + 1);
52821c1c48aSSascha Wildner 	}
529f9602a12SMatthew Dillon 	if (sp->letter == 'b' && strcmp(mountpoint, "swap") != 0)
530f9602a12SMatthew Dillon 		sp->letter = 'd';
53121c1c48aSSascha Wildner 
53221c1c48aSSascha Wildner 	sp->mountpoint = aura_strdup(mountpoint);
53321c1c48aSSascha Wildner 	sp->capacity = capacity;
53488cfb1f7SSascha Wildner 	sp->encrypted = encrypted;
53521c1c48aSSascha Wildner 	sp->type = FS_HAMMER;
53621c1c48aSSascha Wildner 
53721c1c48aSSascha Wildner 	/*
53821c1c48aSSascha Wildner 	 * We need this here, because a UFS /boot needs valid values
53921c1c48aSSascha Wildner 	 */
54021c1c48aSSascha Wildner 	if (sp->capacity < 1024)
54121c1c48aSSascha Wildner 		sp->fsize = 1024;
54221c1c48aSSascha Wildner 	else
54321c1c48aSSascha Wildner 		sp->fsize = 2048;
54421c1c48aSSascha Wildner 
54521c1c48aSSascha Wildner 	if (sp->capacity < 1024)
54621c1c48aSSascha Wildner 		sp->bsize = 8192;
54721c1c48aSSascha Wildner 	else
54821c1c48aSSascha Wildner 		sp->bsize = 16384;
54921c1c48aSSascha Wildner 
55021c1c48aSSascha Wildner 	sp->is_swap = 0;
551f9602a12SMatthew Dillon #if 0
55221c1c48aSSascha Wildner 	sp->pfs = 0;
553f9602a12SMatthew Dillon #endif
55421c1c48aSSascha Wildner 	if (strcasecmp(mountpoint, "swap") == 0)
55521c1c48aSSascha Wildner 		sp->is_swap = 1;
556f9602a12SMatthew Dillon #if 0
55721c1c48aSSascha Wildner 	if (strcmp(mountpoint, "/") != 0 && strcmp(mountpoint, "/boot") != 0 &&
55821c1c48aSSascha Wildner 	    strcmp(mountpoint, "swap") != 0)
55921c1c48aSSascha Wildner 		sp->pfs = 1;
560f9602a12SMatthew Dillon #endif
56121c1c48aSSascha Wildner 
56221c1c48aSSascha Wildner 	sp->next = NULL;
56321c1c48aSSascha Wildner 	if (s->subpartition_head == NULL)
56421c1c48aSSascha Wildner 		s->subpartition_head = sp;
56521c1c48aSSascha Wildner 	else
56621c1c48aSSascha Wildner 		s->subpartition_tail->next = sp;
56721c1c48aSSascha Wildner 
56821c1c48aSSascha Wildner 	sp->prev = s->subpartition_tail;
56921c1c48aSSascha Wildner 	s->subpartition_tail = sp;
57021c1c48aSSascha Wildner 
57121c1c48aSSascha Wildner 	return(sp);
57221c1c48aSSascha Wildner }
57321c1c48aSSascha Wildner 
574e90c1ebbSMatthew Dillon struct subpartition *
subpartition_new_hammer2(struct slice * s,const char * mountpoint,long capacity,int encrypted)575e90c1ebbSMatthew Dillon subpartition_new_hammer2(struct slice *s, const char *mountpoint,
576e90c1ebbSMatthew Dillon 			 long capacity, int encrypted)
577e90c1ebbSMatthew Dillon {
578e90c1ebbSMatthew Dillon 	struct subpartition *sp;
579e90c1ebbSMatthew Dillon 	struct subpartition *last = s->subpartition_tail;
580e90c1ebbSMatthew Dillon 
581e90c1ebbSMatthew Dillon 	AURA_MALLOC(sp, subpartition);
582e90c1ebbSMatthew Dillon 
583e90c1ebbSMatthew Dillon 	sp->parent = s;
584e90c1ebbSMatthew Dillon 
585e90c1ebbSMatthew Dillon 	if (last == NULL) {
586e90c1ebbSMatthew Dillon 		sp->letter = 'a';
587e90c1ebbSMatthew Dillon 	} else if (last->letter == 'b') {
588e90c1ebbSMatthew Dillon 		sp->letter = 'd';
589e90c1ebbSMatthew Dillon 	} else {
590e90c1ebbSMatthew Dillon 		sp->letter = (char)(last->letter + 1);
591e90c1ebbSMatthew Dillon 	}
592e90c1ebbSMatthew Dillon 	if (sp->letter == 'b' && strcmp(mountpoint, "swap") != 0)
593e90c1ebbSMatthew Dillon 		sp->letter = 'd';
594e90c1ebbSMatthew Dillon 
595e90c1ebbSMatthew Dillon 	sp->mountpoint = aura_strdup(mountpoint);
596e90c1ebbSMatthew Dillon 	sp->capacity = capacity;
597e90c1ebbSMatthew Dillon 	sp->encrypted = encrypted;
598e90c1ebbSMatthew Dillon 	sp->type = FS_HAMMER2;
599e90c1ebbSMatthew Dillon 
600e90c1ebbSMatthew Dillon 	/*
601e90c1ebbSMatthew Dillon 	 * We need this here, because a UFS /boot needs valid values
602e90c1ebbSMatthew Dillon 	 */
603e90c1ebbSMatthew Dillon 	if (sp->capacity < 1024)
604e90c1ebbSMatthew Dillon 		sp->fsize = 1024;
605e90c1ebbSMatthew Dillon 	else
606e90c1ebbSMatthew Dillon 		sp->fsize = 2048;
607e90c1ebbSMatthew Dillon 
608e90c1ebbSMatthew Dillon 	if (sp->capacity < 1024)
609e90c1ebbSMatthew Dillon 		sp->bsize = 8192;
610e90c1ebbSMatthew Dillon 	else
611e90c1ebbSMatthew Dillon 		sp->bsize = 16384;
612e90c1ebbSMatthew Dillon 
613e90c1ebbSMatthew Dillon 	sp->is_swap = 0;
614e90c1ebbSMatthew Dillon #if 0
615e90c1ebbSMatthew Dillon 	sp->pfs = 0;
616e90c1ebbSMatthew Dillon #endif
617e90c1ebbSMatthew Dillon 	if (strcasecmp(mountpoint, "swap") == 0)
618e90c1ebbSMatthew Dillon 		sp->is_swap = 1;
619e90c1ebbSMatthew Dillon #if 0
620e90c1ebbSMatthew Dillon 	if (strcmp(mountpoint, "/") != 0 && strcmp(mountpoint, "/boot") != 0 &&
621e90c1ebbSMatthew Dillon 	    strcmp(mountpoint, "swap") != 0)
622e90c1ebbSMatthew Dillon 		sp->pfs = 1;
623e90c1ebbSMatthew Dillon #endif
624e90c1ebbSMatthew Dillon 
625e90c1ebbSMatthew Dillon 	sp->next = NULL;
626e90c1ebbSMatthew Dillon 	if (s->subpartition_head == NULL)
627e90c1ebbSMatthew Dillon 		s->subpartition_head = sp;
628e90c1ebbSMatthew Dillon 	else
629e90c1ebbSMatthew Dillon 		s->subpartition_tail->next = sp;
630e90c1ebbSMatthew Dillon 
631e90c1ebbSMatthew Dillon 	sp->prev = s->subpartition_tail;
632e90c1ebbSMatthew Dillon 	s->subpartition_tail = sp;
633e90c1ebbSMatthew Dillon 
634e90c1ebbSMatthew Dillon 	return(sp);
635e90c1ebbSMatthew Dillon }
636e90c1ebbSMatthew Dillon 
63721c1c48aSSascha Wildner /*
63821c1c48aSSascha Wildner  * NOTE: arguments to this function are not checked for sanity.
63921c1c48aSSascha Wildner  *
64021c1c48aSSascha Wildner  * fsize and/or bsize may both be -1, indicating
64121c1c48aSSascha Wildner  * "choose a reasonable default."
64221c1c48aSSascha Wildner  */
64321c1c48aSSascha Wildner struct subpartition *
subpartition_new_ufs(struct slice * s,const char * mountpoint,long capacity,int encrypted,int softupdates,long fsize,long bsize,int tmpfsbacked)64488cfb1f7SSascha Wildner subpartition_new_ufs(struct slice *s, const char *mountpoint, long capacity,
64588cfb1f7SSascha Wildner     int encrypted, int softupdates, long fsize, long bsize, int tmpfsbacked)
64621c1c48aSSascha Wildner {
647f9602a12SMatthew Dillon 	struct subpartition *sp;
648f9602a12SMatthew Dillon 	struct subpartition *last = s->subpartition_tail;
64921c1c48aSSascha Wildner 
65021c1c48aSSascha Wildner 	AURA_MALLOC(sp, subpartition);
65121c1c48aSSascha Wildner 
652f9602a12SMatthew Dillon 	if (tmpfsbacked) {
653f9602a12SMatthew Dillon 		sp->letter = '@';
654f9602a12SMatthew Dillon 	} else {
655f9602a12SMatthew Dillon 		while (last && last->letter == '@')
656f9602a12SMatthew Dillon 			last = last->prev;
657f9602a12SMatthew Dillon 		if (last == NULL) {
658f9602a12SMatthew Dillon 			sp->letter = 'a';
659f9602a12SMatthew Dillon 		} else if (last->letter == 'b') {
660f9602a12SMatthew Dillon 			sp->letter = 'd';
661f9602a12SMatthew Dillon 		} else {
662f9602a12SMatthew Dillon 			sp->letter = (char)(last->letter + 1);
663f9602a12SMatthew Dillon 		}
664f9602a12SMatthew Dillon 		if (sp->letter == 'b' && strcmp(mountpoint, "swap") != 0)
665f9602a12SMatthew Dillon 			sp->letter = 'd';
666f9602a12SMatthew Dillon 	}
667f9602a12SMatthew Dillon 
66821c1c48aSSascha Wildner 	sp->parent = s;
66921c1c48aSSascha Wildner 
67021c1c48aSSascha Wildner 	sp->mountpoint = aura_strdup(mountpoint);
67121c1c48aSSascha Wildner 	sp->capacity = capacity;
67288cfb1f7SSascha Wildner 	sp->encrypted = encrypted;
67321c1c48aSSascha Wildner 	sp->type = FS_UFS;
67421c1c48aSSascha Wildner 
67521c1c48aSSascha Wildner 	if (fsize == -1) {
67621c1c48aSSascha Wildner 		if (sp->capacity < 1024)
67721c1c48aSSascha Wildner 			sp->fsize = 1024;
67821c1c48aSSascha Wildner 		else
67921c1c48aSSascha Wildner 			sp->fsize = 2048;
68021c1c48aSSascha Wildner 	} else {
68121c1c48aSSascha Wildner 		sp->fsize = fsize;
68221c1c48aSSascha Wildner 	}
68321c1c48aSSascha Wildner 
68421c1c48aSSascha Wildner 	if (bsize == -1) {
68521c1c48aSSascha Wildner 		if (sp->capacity < 1024)
68621c1c48aSSascha Wildner 			sp->bsize = 8192;
68721c1c48aSSascha Wildner 		else
68821c1c48aSSascha Wildner 			sp->bsize = 16384;
68921c1c48aSSascha Wildner 	} else {
69021c1c48aSSascha Wildner 		sp->bsize = bsize;
69121c1c48aSSascha Wildner 	}
69221c1c48aSSascha Wildner 
69321c1c48aSSascha Wildner 	if (softupdates == -1) {
69421c1c48aSSascha Wildner 		if (strcmp(mountpoint, "/") == 0)
69521c1c48aSSascha Wildner 			sp->softupdates = 0;
69621c1c48aSSascha Wildner 		else
69721c1c48aSSascha Wildner 			sp->softupdates = 1;
69821c1c48aSSascha Wildner 	} else {
69921c1c48aSSascha Wildner 		sp->softupdates = softupdates;
70021c1c48aSSascha Wildner 	}
70121c1c48aSSascha Wildner 
702761cad2fSSascha Wildner 	sp->tmpfsbacked = tmpfsbacked;
70321c1c48aSSascha Wildner 
70421c1c48aSSascha Wildner 	sp->is_swap = 0;
70521c1c48aSSascha Wildner 	if (strcasecmp(mountpoint, "swap") == 0)
70621c1c48aSSascha Wildner 		sp->is_swap = 1;
70721c1c48aSSascha Wildner 
708f9602a12SMatthew Dillon 	/*
709f9602a12SMatthew Dillon 	 * install
710f9602a12SMatthew Dillon 	 */
711f9602a12SMatthew Dillon 	sp->next = NULL;
712f9602a12SMatthew Dillon 	if (s->subpartition_head == NULL)
71321c1c48aSSascha Wildner 		s->subpartition_head = sp;
71421c1c48aSSascha Wildner 	else
71521c1c48aSSascha Wildner 		s->subpartition_tail->next = sp;
716f9602a12SMatthew Dillon 
717f9602a12SMatthew Dillon 	sp->prev = s->subpartition_tail;
71821c1c48aSSascha Wildner 	s->subpartition_tail = sp;
719f9602a12SMatthew Dillon 
720f9602a12SMatthew Dillon #if 0
72121c1c48aSSascha Wildner 
72221c1c48aSSascha Wildner 	for (sptmp = s->subpartition_head; sptmp != NULL;
72321c1c48aSSascha Wildner 	     sptmp = sptmp->next) {
724761cad2fSSascha Wildner 		if (sptmp->tmpfsbacked)
72521c1c48aSSascha Wildner 			sptmp->letter = '@';
72621c1c48aSSascha Wildner 		else if (strcmp(sptmp->mountpoint, "/") == 0 ||
72721c1c48aSSascha Wildner 			 strcmp(sptmp->mountpoint, "/dummy") == 0)
72821c1c48aSSascha Wildner 			sptmp->letter = 'a';
72921c1c48aSSascha Wildner 		else if (strcasecmp(sptmp->mountpoint, "swap") == 0)
73021c1c48aSSascha Wildner 			sptmp->letter = 'b';
73121c1c48aSSascha Wildner 		else
73221c1c48aSSascha Wildner 			sptmp->letter = letter++;
73321c1c48aSSascha Wildner 	}
734f9602a12SMatthew Dillon #endif
73521c1c48aSSascha Wildner 
73621c1c48aSSascha Wildner 	return(sp);
73721c1c48aSSascha Wildner }
73821c1c48aSSascha Wildner 
73921c1c48aSSascha Wildner /*
74021c1c48aSSascha Wildner  * Find the subpartition description in the given storage
74121c1c48aSSascha Wildner  * description whose mountpoint matches the given string exactly.
74221c1c48aSSascha Wildner  */
74321c1c48aSSascha Wildner struct subpartition *
subpartition_find(const struct slice * s,const char * fmt,...)74421c1c48aSSascha Wildner subpartition_find(const struct slice *s, const char *fmt, ...)
74521c1c48aSSascha Wildner {
74621c1c48aSSascha Wildner 	struct subpartition *sp = s->subpartition_head;
74721c1c48aSSascha Wildner 	char *mountpoint;
74821c1c48aSSascha Wildner 	va_list args;
74921c1c48aSSascha Wildner 
75021c1c48aSSascha Wildner 	va_start(args, fmt);
75121c1c48aSSascha Wildner 	vasprintf(&mountpoint, fmt, args);
75221c1c48aSSascha Wildner 	va_end(args);
75321c1c48aSSascha Wildner 
75421c1c48aSSascha Wildner 	while (sp != NULL) {
75521c1c48aSSascha Wildner 		if (strcmp(mountpoint, sp->mountpoint) == 0) {
75621c1c48aSSascha Wildner 			free(mountpoint);
75721c1c48aSSascha Wildner 			return(sp);
75821c1c48aSSascha Wildner 		}
75921c1c48aSSascha Wildner 		sp = sp->next;
76021c1c48aSSascha Wildner 	}
76121c1c48aSSascha Wildner 
76221c1c48aSSascha Wildner 	free(mountpoint);
76321c1c48aSSascha Wildner 	return(NULL);
76421c1c48aSSascha Wildner }
76521c1c48aSSascha Wildner 
76621c1c48aSSascha Wildner /*
76721c1c48aSSascha Wildner  * Find the subpartition description in the given storage
76821c1c48aSSascha Wildner  * description where the given filename would presumably
76921c1c48aSSascha Wildner  * reside.  This is the subpartition whose mountpoint is
77021c1c48aSSascha Wildner  * the longest match for the given filename.
77121c1c48aSSascha Wildner  */
77221c1c48aSSascha Wildner struct subpartition *
subpartition_of(const struct slice * s,const char * fmt,...)77321c1c48aSSascha Wildner subpartition_of(const struct slice *s, const char *fmt, ...)
77421c1c48aSSascha Wildner {
77521c1c48aSSascha Wildner 	struct subpartition *sp = s->subpartition_head;
77621c1c48aSSascha Wildner 	struct subpartition *csp = NULL;
77721c1c48aSSascha Wildner 	size_t len = 0;
77821c1c48aSSascha Wildner 	char *filename;
77921c1c48aSSascha Wildner 	va_list args;
78021c1c48aSSascha Wildner 
78121c1c48aSSascha Wildner 	va_start(args, fmt);
78221c1c48aSSascha Wildner 	vasprintf(&filename, fmt, args);
78321c1c48aSSascha Wildner 	va_end(args);
78421c1c48aSSascha Wildner 
78521c1c48aSSascha Wildner 	while (sp != NULL) {
78621c1c48aSSascha Wildner 		if (strlen(sp->mountpoint) > len &&
78721c1c48aSSascha Wildner 		    strlen(sp->mountpoint) <= strlen(filename) &&
78821c1c48aSSascha Wildner 		    strncmp(filename, sp->mountpoint, strlen(sp->mountpoint)) == 0) {
78921c1c48aSSascha Wildner 				csp = sp;
79021c1c48aSSascha Wildner 				len = strlen(csp->mountpoint);
79121c1c48aSSascha Wildner 		}
79221c1c48aSSascha Wildner 		sp = sp->next;
79321c1c48aSSascha Wildner 	}
79421c1c48aSSascha Wildner 
79521c1c48aSSascha Wildner 	free(filename);
79621c1c48aSSascha Wildner 	return(csp);
79721c1c48aSSascha Wildner }
79821c1c48aSSascha Wildner 
79921c1c48aSSascha Wildner struct subpartition *
subpartition_find_capacity(const struct slice * s,long capacity)80021c1c48aSSascha Wildner subpartition_find_capacity(const struct slice *s, long capacity)
80121c1c48aSSascha Wildner {
80221c1c48aSSascha Wildner 	struct subpartition *sp = s->subpartition_head;
80321c1c48aSSascha Wildner 
80421c1c48aSSascha Wildner 	while (sp != NULL) {
80521c1c48aSSascha Wildner 		if (sp->capacity == capacity)
80621c1c48aSSascha Wildner 			return(sp);
80721c1c48aSSascha Wildner 		sp = sp->next;
80821c1c48aSSascha Wildner 	}
80921c1c48aSSascha Wildner 
81021c1c48aSSascha Wildner 	return(NULL);
81121c1c48aSSascha Wildner }
81221c1c48aSSascha Wildner 
81321c1c48aSSascha Wildner struct subpartition *
subpartition_next(const struct subpartition * sp)81421c1c48aSSascha Wildner subpartition_next(const struct subpartition *sp)
81521c1c48aSSascha Wildner {
81621c1c48aSSascha Wildner 	return(sp->next);
81721c1c48aSSascha Wildner }
81821c1c48aSSascha Wildner 
81921c1c48aSSascha Wildner int
subpartition_get_pfs(const struct subpartition * sp)82021c1c48aSSascha Wildner subpartition_get_pfs(const struct subpartition *sp)
82121c1c48aSSascha Wildner {
82221c1c48aSSascha Wildner 	return(sp->pfs);
82321c1c48aSSascha Wildner }
82421c1c48aSSascha Wildner 
82521c1c48aSSascha Wildner /*
82621c1c48aSSascha Wildner  * Returns the name of the device node used to represent
827f59b7dfaSSascha Wildner  * the subpartition, either by serial number or traditional style.
82821c1c48aSSascha Wildner  * Note that the storage used for the returned string is static,
82921c1c48aSSascha Wildner  * and the string is overwritten each time this function is called.
83021c1c48aSSascha Wildner  */
83121c1c48aSSascha Wildner const char *
subpartition_get_device_name(const struct subpartition * sp)83221c1c48aSSascha Wildner subpartition_get_device_name(const struct subpartition *sp)
83321c1c48aSSascha Wildner {
83421c1c48aSSascha Wildner 	static char tmp_dev_name[256];
83521c1c48aSSascha Wildner 
836f59b7dfaSSascha Wildner 	if (sp->parent->parent->serno != NULL)
837f59b7dfaSSascha Wildner 		snprintf(tmp_dev_name, 256, "serno/%s.s%d%c",
838f59b7dfaSSascha Wildner 		    sp->parent->parent->serno, sp->parent->number, sp->letter);
839f59b7dfaSSascha Wildner 	else
840f59b7dfaSSascha Wildner 		snprintf(tmp_dev_name, 256, "%ss%d%c",
841f59b7dfaSSascha Wildner 		    sp->parent->parent->device, sp->parent->number, sp->letter);
84221c1c48aSSascha Wildner 	return(tmp_dev_name);
84321c1c48aSSascha Wildner }
84421c1c48aSSascha Wildner 
8450c941bc8SSascha Wildner /*
8460c941bc8SSascha Wildner  * /dev/mapper/
8470c941bc8SSascha Wildner  *
8480c941bc8SSascha Wildner  * (result is persistant until next call)
8490c941bc8SSascha Wildner  */
8500c941bc8SSascha Wildner const char *
subpartition_get_mapper_name(const struct subpartition * sp,int withdev)8510c941bc8SSascha Wildner subpartition_get_mapper_name(const struct subpartition *sp, int withdev)
8520c941bc8SSascha Wildner {
8530c941bc8SSascha Wildner 	const char *src;
8540c941bc8SSascha Wildner 	static char *save;
8550c941bc8SSascha Wildner 
8560c941bc8SSascha Wildner 	src = strrchr(sp->mountpoint, '/');
8570c941bc8SSascha Wildner 	if (src == NULL || src[1] == 0)
8580c941bc8SSascha Wildner 		src = "root";
8590c941bc8SSascha Wildner 	else
8600c941bc8SSascha Wildner 		++src;
8610c941bc8SSascha Wildner 
8620c941bc8SSascha Wildner 	if (save)
8630c941bc8SSascha Wildner 		free(save);
8640c941bc8SSascha Wildner 	switch(withdev) {
8650c941bc8SSascha Wildner 	case -1:
8660c941bc8SSascha Wildner 		asprintf(&save, "%s", src);
8670c941bc8SSascha Wildner 		break;
8680c941bc8SSascha Wildner 	case 0:
8690c941bc8SSascha Wildner 		asprintf(&save, "mapper/%s", src);
8700c941bc8SSascha Wildner 		break;
8710c941bc8SSascha Wildner 	case 1:
8720c941bc8SSascha Wildner 	default:
8730c941bc8SSascha Wildner 		asprintf(&save, "/dev/mapper/%s", src);
8740c941bc8SSascha Wildner 		break;
8750c941bc8SSascha Wildner 	}
8760c941bc8SSascha Wildner 	return save;
8770c941bc8SSascha Wildner }
8780c941bc8SSascha Wildner 
87921c1c48aSSascha Wildner const char *
subpartition_get_mountpoint(const struct subpartition * sp)88021c1c48aSSascha Wildner subpartition_get_mountpoint(const struct subpartition *sp)
88121c1c48aSSascha Wildner {
88221c1c48aSSascha Wildner 	return(sp->mountpoint);
88321c1c48aSSascha Wildner }
88421c1c48aSSascha Wildner 
88521c1c48aSSascha Wildner char
subpartition_get_letter(const struct subpartition * sp)88621c1c48aSSascha Wildner subpartition_get_letter(const struct subpartition *sp)
88721c1c48aSSascha Wildner {
88821c1c48aSSascha Wildner 	return(sp->letter);
88921c1c48aSSascha Wildner }
89021c1c48aSSascha Wildner 
89121c1c48aSSascha Wildner unsigned long
subpartition_get_fsize(const struct subpartition * sp)89221c1c48aSSascha Wildner subpartition_get_fsize(const struct subpartition *sp)
89321c1c48aSSascha Wildner {
89421c1c48aSSascha Wildner 	return(sp->fsize);
89521c1c48aSSascha Wildner }
89621c1c48aSSascha Wildner 
89721c1c48aSSascha Wildner unsigned long
subpartition_get_bsize(const struct subpartition * sp)89821c1c48aSSascha Wildner subpartition_get_bsize(const struct subpartition *sp)
89921c1c48aSSascha Wildner {
90021c1c48aSSascha Wildner 	return(sp->bsize);
90121c1c48aSSascha Wildner }
90221c1c48aSSascha Wildner 
903a9879eb2SSascha Wildner long
subpartition_get_capacity(const struct subpartition * sp)90421c1c48aSSascha Wildner subpartition_get_capacity(const struct subpartition *sp)
90521c1c48aSSascha Wildner {
90621c1c48aSSascha Wildner 	return(sp->capacity);
90721c1c48aSSascha Wildner }
90821c1c48aSSascha Wildner 
909b8d2998cSSascha Wildner void
subpartition_clr_encrypted(struct subpartition * sp)910b8d2998cSSascha Wildner subpartition_clr_encrypted(struct subpartition *sp)
911b8d2998cSSascha Wildner {
912b8d2998cSSascha Wildner 	sp->encrypted = 0;
913b8d2998cSSascha Wildner }
914b8d2998cSSascha Wildner 
91521c1c48aSSascha Wildner int
subpartition_is_encrypted(const struct subpartition * sp)91688cfb1f7SSascha Wildner subpartition_is_encrypted(const struct subpartition *sp)
91788cfb1f7SSascha Wildner {
91888cfb1f7SSascha Wildner 	return(sp->encrypted);
91988cfb1f7SSascha Wildner }
92088cfb1f7SSascha Wildner 
92188cfb1f7SSascha Wildner int
subpartition_is_swap(const struct subpartition * sp)92221c1c48aSSascha Wildner subpartition_is_swap(const struct subpartition *sp)
92321c1c48aSSascha Wildner {
92421c1c48aSSascha Wildner 	return(sp->is_swap);
92521c1c48aSSascha Wildner }
92621c1c48aSSascha Wildner 
92721c1c48aSSascha Wildner int
subpartition_is_softupdated(const struct subpartition * sp)92821c1c48aSSascha Wildner subpartition_is_softupdated(const struct subpartition *sp)
92921c1c48aSSascha Wildner {
93021c1c48aSSascha Wildner 	return(sp->softupdates);
93121c1c48aSSascha Wildner }
93221c1c48aSSascha Wildner int
subpartition_is_tmpfsbacked(const struct subpartition * sp)933761cad2fSSascha Wildner subpartition_is_tmpfsbacked(const struct subpartition *sp)
93421c1c48aSSascha Wildner {
935761cad2fSSascha Wildner 	return(sp->tmpfsbacked);
93621c1c48aSSascha Wildner }
93721c1c48aSSascha Wildner 
93821c1c48aSSascha Wildner int
subpartition_count(const struct slice * s)93921c1c48aSSascha Wildner subpartition_count(const struct slice *s)
94021c1c48aSSascha Wildner {
94121c1c48aSSascha Wildner 	struct subpartition *sp = s->subpartition_head;
94221c1c48aSSascha Wildner 	int count = 0;
94321c1c48aSSascha Wildner 
94421c1c48aSSascha Wildner 	while (sp != NULL) {
94521c1c48aSSascha Wildner 		count++;
94621c1c48aSSascha Wildner 		sp = sp->next;
94721c1c48aSSascha Wildner 	}
94821c1c48aSSascha Wildner 
94921c1c48aSSascha Wildner 	return(count);
95021c1c48aSSascha Wildner }
95121c1c48aSSascha Wildner 
95221c1c48aSSascha Wildner void
subpartitions_free(struct slice * s)95321c1c48aSSascha Wildner subpartitions_free(struct slice *s)
95421c1c48aSSascha Wildner {
95521c1c48aSSascha Wildner 	struct subpartition *sp = s->subpartition_head, *next;
95621c1c48aSSascha Wildner 
95721c1c48aSSascha Wildner 	while (sp != NULL) {
95821c1c48aSSascha Wildner 		next = sp->next;
95921c1c48aSSascha Wildner 		free(sp->mountpoint);
96021c1c48aSSascha Wildner 		AURA_FREE(sp, subpartition);
96121c1c48aSSascha Wildner 		sp = next;
96221c1c48aSSascha Wildner 	}
96321c1c48aSSascha Wildner 
96421c1c48aSSascha Wildner 	s->subpartition_head = NULL;
96521c1c48aSSascha Wildner 	s->subpartition_tail = NULL;
96621c1c48aSSascha Wildner }
96721c1c48aSSascha Wildner 
96821c1c48aSSascha Wildner long
measure_activated_swap(const struct i_fn_args * a)96921c1c48aSSascha Wildner measure_activated_swap(const struct i_fn_args *a)
97021c1c48aSSascha Wildner {
97121c1c48aSSascha Wildner 	FILE *p;
97221c1c48aSSascha Wildner 	char line[256];
97321c1c48aSSascha Wildner 	char *word;
97421c1c48aSSascha Wildner 	long swap = 0;
97521c1c48aSSascha Wildner 
97621c1c48aSSascha Wildner 	if ((p = aura_popen("%s%s -k", "r", a->os_root, cmd_name(a, "SWAPINFO"))) == NULL)
97721c1c48aSSascha Wildner 		return(0);
97821c1c48aSSascha Wildner 	while (fgets(line, 255, p) != NULL) {
97921c1c48aSSascha Wildner 		if ((word = strtok(line, " \t")) == NULL)
98021c1c48aSSascha Wildner 			continue;
98121c1c48aSSascha Wildner 		if (strcmp(word, "Device") == 0)
98221c1c48aSSascha Wildner 			continue;
98321c1c48aSSascha Wildner 		if ((word = strtok(NULL, " \t")) == NULL)
98421c1c48aSSascha Wildner 			continue;
98521c1c48aSSascha Wildner 		swap += atol(word);
98621c1c48aSSascha Wildner 	}
98721c1c48aSSascha Wildner 	aura_pclose(p);
98821c1c48aSSascha Wildner 
98921c1c48aSSascha Wildner 	return(swap / 1024);
99021c1c48aSSascha Wildner }
99121c1c48aSSascha Wildner 
99221c1c48aSSascha Wildner long
measure_activated_swap_from_slice(const struct i_fn_args * a,const struct disk * d,const struct slice * s)99321c1c48aSSascha Wildner measure_activated_swap_from_slice(const struct i_fn_args *a,
99421c1c48aSSascha Wildner     const struct disk *d, const struct slice *s)
99521c1c48aSSascha Wildner {
99621c1c48aSSascha Wildner 	FILE *p;
99721c1c48aSSascha Wildner 	char *dev, *word;
99821c1c48aSSascha Wildner 	char line[256];
99921c1c48aSSascha Wildner 	long swap = 0;
100021c1c48aSSascha Wildner 
100121c1c48aSSascha Wildner 	if ((p = aura_popen("%s%s -k", "r", a->os_root, cmd_name(a, "SWAPINFO"))) == NULL)
100221c1c48aSSascha Wildner 		return(0);
100321c1c48aSSascha Wildner 
100421c1c48aSSascha Wildner 	asprintf(&dev, "/dev/%ss%d", d->device, s->number);
100521c1c48aSSascha Wildner 
100621c1c48aSSascha Wildner 	while (fgets(line, 255, p) != NULL) {
100721c1c48aSSascha Wildner 		if ((word = strtok(line, " \t")) == NULL)
100821c1c48aSSascha Wildner 			continue;
100921c1c48aSSascha Wildner 		if (strcmp(word, "Device") == 0)
101021c1c48aSSascha Wildner 			continue;
101121c1c48aSSascha Wildner 		if (strstr(word, dev) != word)
101221c1c48aSSascha Wildner 			continue;
101321c1c48aSSascha Wildner 		if ((word = strtok(NULL, " \t")) == NULL)
101421c1c48aSSascha Wildner 			continue;
101521c1c48aSSascha Wildner 		swap += atol(word);
101621c1c48aSSascha Wildner 	}
101721c1c48aSSascha Wildner 	aura_pclose(p);
101821c1c48aSSascha Wildner 	free(dev);
101921c1c48aSSascha Wildner 
102021c1c48aSSascha Wildner 	return(swap / 1024);
102121c1c48aSSascha Wildner }
102221c1c48aSSascha Wildner 
102321c1c48aSSascha Wildner long
measure_activated_swap_from_disk(const struct i_fn_args * a,const struct disk * d)102421c1c48aSSascha Wildner measure_activated_swap_from_disk(const struct i_fn_args *a,
102521c1c48aSSascha Wildner 				 const struct disk *d)
102621c1c48aSSascha Wildner {
102721c1c48aSSascha Wildner 	struct slice *s;
102821c1c48aSSascha Wildner 	long swap = 0;
102921c1c48aSSascha Wildner 
103021c1c48aSSascha Wildner 	for (s = d->slice_head; s != NULL; s = s->next)
103121c1c48aSSascha Wildner 		swap += measure_activated_swap_from_slice(a, d, s);
103221c1c48aSSascha Wildner 
103321c1c48aSSascha Wildner 	return(swap);
103421c1c48aSSascha Wildner }
10359687cd27SSascha Wildner 
10369687cd27SSascha Wildner void *
swapoff_all(const struct i_fn_args * a)10379687cd27SSascha Wildner swapoff_all(const struct i_fn_args *a)
10389687cd27SSascha Wildner {
10399687cd27SSascha Wildner 	FILE *p;
10409687cd27SSascha Wildner 
10419687cd27SSascha Wildner 	if ((p = aura_popen("%s%s off; %s%s | %s%s \"^/dev\" | %s%s '{print $1;}' | %s%s %s%s", "r",
10429687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "DUMPON"),
10439687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "SWAPINFO"),
10449687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "GREP"),
10459687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "AWK"),
10469687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "XARGS"),
10479687cd27SSascha Wildner 		    a->os_root, cmd_name(a, "SWAPOFF"))) != NULL)
10489687cd27SSascha Wildner 		aura_pclose(p);
10499687cd27SSascha Wildner 
10509687cd27SSascha Wildner 	return(p);
10519687cd27SSascha Wildner }
1052fa419eaeSSascha Wildner 
1053fa419eaeSSascha Wildner void *
remove_all_mappings(const struct i_fn_args * a)1054fa419eaeSSascha Wildner remove_all_mappings(const struct i_fn_args *a)
1055fa419eaeSSascha Wildner {
1056fa419eaeSSascha Wildner 	FILE *p;
1057fa419eaeSSascha Wildner 
105851871435SSascha Wildner 	if ((p = aura_popen("%s%s -1 /dev/mapper | %s%s -vw control | %s%s -n 1 %s%s luksClose", "r",
1059fa419eaeSSascha Wildner 		    a->os_root, cmd_name(a, "LS"),
1060fa419eaeSSascha Wildner 		    a->os_root, cmd_name(a, "GREP"),
1061fa419eaeSSascha Wildner 		    a->os_root, cmd_name(a, "XARGS"),
1062fa419eaeSSascha Wildner 		    a->os_root, cmd_name(a, "CRYPTSETUP"))) != NULL)
1063fa419eaeSSascha Wildner 		aura_pclose(p);
1064fa419eaeSSascha Wildner 
1065fa419eaeSSascha Wildner 	return(p);
1066fa419eaeSSascha Wildner }
1067