PR 55384: detangle pm->ptstart from the "install" flag (selecting a

target partition). Instead introduce a new PTI_INSTALL_TARGET per partition
flag and deal with it in the partitioning backends.

Honour pm->ptstart when allocating new partitions - it is supposed to be
the first sector usable by NetBSD.
This commit is contained in:
martin 2020-10-03 18:54:18 +00:00
parent 10f7eba97a
commit d9c7022040
7 changed files with 111 additions and 52 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: bsddisklabel.c,v 1.45 2020/09/29 15:29:17 martin Exp $ */
/* $NetBSD: bsddisklabel.c,v 1.46 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -1431,7 +1431,7 @@ apply_settings_to_partitions(struct pm_devs *p, struct disk_partitions *parts,
}
}
from = -1;
from = p->ptstart > 0 ? pm->ptstart : -1;
/*
* First add all outer partitions - we need to align those exactly
* with the inner counterpart later.

View File

@ -1,4 +1,4 @@
/* $NetBSD: disklabel.c,v 1.39 2020/09/29 15:29:17 martin Exp $ */
/* $NetBSD: disklabel.c,v 1.40 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 2018 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@ const struct disk_partitioning_scheme disklabel_parts;
struct disklabel_disk_partitions {
struct disk_partitions dp;
struct disklabel l;
daddr_t ptn_alignment;
daddr_t ptn_alignment, install_target;
char last_mounted[MAXPARTITIONS][MOUNTLEN];
uint fs_sub_type[MAXPARTITIONS];
};
@ -150,6 +150,7 @@ disklabel_parts_new(const char *dev, daddr_t start, daddr_t len,
if (parts == NULL)
return NULL;
parts->install_target = -1;
total_size = geo.dg_secperunit;
if (len*(geo.dg_secsize/512) > disklabel_parts.size_limit)
len = disklabel_parts.size_limit/(geo.dg_secsize/512);
@ -213,6 +214,7 @@ disklabel_parts_read(const char *disk, daddr_t start, daddr_t len, size_t bps,
struct disklabel_disk_partitions *parts = calloc(1, sizeof(*parts));
if (parts == NULL)
return NULL;
parts->install_target = -1;
fd = opendisk(disk, O_RDONLY, diskpath, sizeof(diskpath), 0);
if (fd == -1) {
@ -272,8 +274,12 @@ disklabel_parts_read(const char *disk, daddr_t start, daddr_t len, size_t bps,
flags = 0;
if (parts->l.d_partitions[part].p_fstype == FS_MSDOS)
flags = GLM_MAYBE_FAT32;
else if (parts->l.d_partitions[part].p_fstype == FS_BSDFFS)
else if (parts->l.d_partitions[part].p_fstype == FS_BSDFFS) {
flags = GLM_LIKELY_FFS;
if (parts->install_target < 0)
parts->install_target =
parts->l.d_partitions[part].p_offset;
}
if (flags != 0) {
uint fs_type, fs_sub_type;
const char *lm = get_last_mounted(fd,
@ -511,6 +517,9 @@ disklabel_delete(struct disk_partitions *arg, part_id id,
MSG_part_not_deletable);
return false;
}
if (parts->install_target ==
parts->l.d_partitions[part].p_offset)
parts->install_target = -1;
parts->l.d_partitions[part].p_size = 0;
parts->l.d_partitions[part].p_offset = 0;
parts->l.d_partitions[part].p_fstype = FS_UNUSED;
@ -552,6 +561,8 @@ disklabel_delete_range(struct disk_partitions *arg, daddr_t r_start,
if ((start >= r_start && start <= r_start+r_size) ||
(end >= r_start && end <= r_start+r_size)) {
if (start == parts->install_target)
parts->install_target = -1;
if (parts->dp.num_part > 1)
parts->dp.num_part--;
parts->dp.free_space +=
@ -765,6 +776,8 @@ disklabel_get_part_info(const struct disk_partitions *arg, part_id id,
parts->l.d_partitions[part].p_fstype == FS_UNUSED)
info->flags |=
PTI_PSCHEME_INTERNAL|PTI_RAW_PART;
if (info->start == parts->install_target)
info->flags |= PTI_INSTALL_TARGET;
#if RAW_PART == 3
if (part == (RAW_PART-1) && parts->dp.parent != NULL &&
parts->l.d_partitions[part].p_fstype == FS_UNUSED)
@ -789,6 +802,7 @@ disklabel_set_part_info(struct disk_partitions *arg, part_id id,
struct disklabel_disk_partitions *parts =
(struct disklabel_disk_partitions*)arg;
part_id ndx;
bool was_inst_target;
if (dl_types[0].description == NULL)
dl_init_types();
@ -800,6 +814,8 @@ disklabel_set_part_info(struct disk_partitions *arg, part_id id,
continue;
if (ndx == id) {
was_inst_target = parts->l.d_partitions[part].p_offset
== parts->install_target;
parts->l.d_partitions[part].p_offset = info->start;
parts->l.d_partitions[part].p_size = info->size;
parts->l.d_partitions[part].p_fstype =
@ -809,6 +825,10 @@ disklabel_set_part_info(struct disk_partitions *arg, part_id id,
strlcpy(parts->last_mounted[part],
info->last_mounted,
sizeof(parts->last_mounted[part]));
if (info->flags & PTI_INSTALL_TARGET)
parts->install_target = info->start;
else if (was_inst_target)
parts->install_target = -1;
assert(info->fs_type == 0 || info->fs_type ==
parts->l.d_partitions[part].p_fstype);
if (info->fs_sub_type != 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: gpt.c,v 1.18 2020/03/30 12:19:28 martin Exp $ */
/* $NetBSD: gpt.c,v 1.19 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 2018 The NetBSD Foundation, Inc.
@ -137,6 +137,7 @@ struct gpt_part_entry {
#define GPEF_MODIFIED 2 /* this entry has been changed */
#define GPEF_WEDGE 4 /* wedge for this exists */
#define GPEF_RESIZED 8 /* size has changed */
#define GPEF_TARGET 16 /* marked install target */
struct gpt_part_entry *gp_next;
};
@ -281,6 +282,9 @@ gpt_read_from_disk(const char *dev, daddr_t start, daddr_t len, size_t bps,
static const char regpart_prefix[] = "GPT part - ";
struct gpt_disk_partitions *parts;
struct gpt_part_entry *last = NULL, *add_to = NULL;
const struct gpt_ptype_desc *native_root
= gpt_find_native_type(gpt_native_root);
bool have_target = false;
if (collect(T_OUTPUT, &textbuf, "gpt -r show -a %s 2>/dev/null", dev)
< 1)
@ -352,6 +356,11 @@ gpt_read_from_disk(const char *dev, daddr_t start, daddr_t len, size_t bps,
np->gp_start = p_start;
np->gp_size = p_size;
np->gp_flags |= GPEF_ON_DISK;
if (!have_target && native_root != NULL &&
strcmp(np->gp_id, native_root->tid) == 0) {
have_target = true;
np->gp_flags |= GPEF_TARGET;
}
if (last == NULL)
parts->partitions = np;
@ -509,6 +518,8 @@ gpt_get_part_info(const struct disk_partitions *arg, part_id id,
info->last_mounted = p->last_mounted;
info->fs_type = p->fs_type;
info->fs_sub_type = p->fs_sub_type;
if (p->gp_flags & GPEF_TARGET)
info->flags |= PTI_INSTALL_TARGET;
return true;
}
@ -604,6 +615,7 @@ gpt_set_part_info(struct disk_partitions *arg, part_id id,
struct gpt_part_entry *p = parts->partitions, *n;
part_id no;
daddr_t lendiff;
bool was_target;
for (no = 0; p != NULL && no < id; no++)
p = p->gp_next;
@ -611,6 +623,17 @@ gpt_set_part_info(struct disk_partitions *arg, part_id id,
if (no != id || p == NULL)
return false;
/* update target mark - we can only have one */
was_target = (p->gp_flags & GPEF_TARGET) != 0;
if (info->flags & PTI_INSTALL_TARGET)
p->gp_flags |= GPEF_TARGET;
else
p->gp_flags &= ~GPEF_TARGET;
if (was_target)
for (n = parts->partitions; n != NULL; n = n->gp_next)
if (n != p)
n->gp_flags &= ~GPEF_TARGET;
if ((p->gp_flags & GPEF_ON_DISK)) {
if (info->start != p->gp_start) {
/* partition moved, we need to delete and re-add */
@ -1444,7 +1467,7 @@ gpt_write_to_disk(struct disk_partitions *arg)
p->gp_flags &= ~GPEF_WEDGE;
if (root_id == NO_PART && p->gp_type != NULL) {
if (p->gp_type->gent.generic_ptype == PT_root &&
p->gp_start == pm->ptstart) {
(p->gp_flags & GPEF_TARGET)) {
root_id = pno;
root_is_new = !(p->gp_flags & GPEF_ON_DISK);
} else if (efi_id == NO_PART &&

View File

@ -1,4 +1,4 @@
/* $NetBSD: label.c,v 1.25 2020/09/29 14:29:56 martin Exp $ */
/* $NetBSD: label.c,v 1.26 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 1997 Jonathan Stone
@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: label.c,v 1.25 2020/09/29 14:29:56 martin Exp $");
__RCSID("$NetBSD: label.c,v 1.26 2020/10/03 18:54:18 martin Exp $");
#endif
#include <sys/types.h>
@ -190,8 +190,8 @@ verify_parts(struct partition_usage_set *pset, bool install)
daddr_t first_bsdstart, first_bsdsize, inst_start, inst_size;
int rv;
first_bsdstart = first_bsdsize = 0;
inst_start = inst_size = 0;
first_bsdstart = inst_start = -1;
first_bsdsize = inst_size = 0;
num_root = 0;
parts = pset->parts;
for (i = 0; i < pset->num; i++) {
@ -207,18 +207,19 @@ verify_parts(struct partition_usage_set *pset, bool install)
continue;
num_root++;
if (first_bsdstart == 0) {
if (first_bsdstart <= 0) {
first_bsdstart = wanted->cur_start;
first_bsdsize = wanted->size;
}
if (inst_start == 0 && wanted->cur_start == pm->ptstart) {
if (inst_start < 0 &&
(wanted->cur_flags & PTI_INSTALL_TARGET)) {
inst_start = wanted->cur_start;
inst_size = wanted->size;
}
}
if ((num_root == 0 && install) ||
(num_root > 1 && inst_start == 0)) {
(num_root > 1 && inst_start < 0)) {
if (num_root == 0 && install)
msg_display_subst(MSG_must_be_one_root, 2,
msg_string(parts->pscheme->name),
@ -322,10 +323,7 @@ edit_install(menudesc *m, void *arg)
{
struct single_part_fs_edit *edit = arg;
if (edit->info.start == pm->ptstart)
pm->ptstart = 0;
else
pm->ptstart = edit->info.start;
edit->info.flags ^= PTI_INSTALL_TARGET;
return 0;
}
@ -1064,7 +1062,7 @@ draw_edit_ptn_line(menudesc *m, int opt, void *arg)
}
if (m->opts[opt].opt_action == edit_install) {
wprintw(m->mw, "%*s : %s", col_width, ptn_install,
msg_string(edit->info.start == pm->ptstart
msg_string((edit->info.flags & PTI_INSTALL_TARGET)
? MSG_Yes : MSG_No));
return;
}
@ -1318,7 +1316,7 @@ fmt_fspart_row(menudesc *m, int ptn, void *arg)
fp = flag_str;
inst_flags = pset->infos[ptn].instflags;
if (with_inst_flag && info.start == pm->ptstart &&
if (with_inst_flag && (info.flags & PTI_INSTALL_TARGET) &&
info.nat_type->generic_ptype == PT_root) {
static char inst_flag;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mbr.c,v 1.33 2020/09/29 15:29:17 martin Exp $ */
/* $NetBSD: mbr.c,v 1.34 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -133,7 +133,7 @@ struct mbr_disk_partitions {
struct disk_partitions dp, *dlabel;
mbr_info_t mbr;
uint ptn_alignment, ptn_0_offset, ext_ptn_alignment,
geo_sec, geo_head, geo_cyl;
geo_sec, geo_head, geo_cyl, target;
};
const struct disk_partitioning_scheme mbr_parts;
@ -529,7 +529,8 @@ valid_mbr(struct mbr_sector *mbrs)
}
static int
read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri)
read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri,
struct mbr_disk_partitions *parts)
{
struct mbr_partition *mbrp;
struct mbr_sector *mbrs = &mbri->mbr;
@ -552,7 +553,8 @@ read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri)
for (;;) {
if (blockread(fd, secsize, mbrs, sizeof *mbrs,
(ext_base + next_ext) * (off_t)MBR_SECSIZE) - sizeof *mbrs != 0)
(ext_base + next_ext) * (off_t)MBR_SECSIZE)
- sizeof *mbrs != 0)
break;
if (!valid_mbr(mbrs))
@ -605,9 +607,13 @@ read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri)
next_ext = mbrp->mbrp_start;
} else {
uint flags = 0;
if (mbrp->mbrp_type == MBR_PTYPE_NETBSD)
if (mbrp->mbrp_type == MBR_PTYPE_NETBSD) {
flags |= GLM_LIKELY_FFS;
else if (mbrp->mbrp_type == MBR_PTYPE_FAT12 ||
if (parts->target == ~0U)
parts->target =
mbri->sector +
mbrp->mbrp_start;
} else if (mbrp->mbrp_type == MBR_PTYPE_FAT12 ||
mbrp->mbrp_type == MBR_PTYPE_FAT16S ||
mbrp->mbrp_type == MBR_PTYPE_FAT16B ||
mbrp->mbrp_type == MBR_PTYPE_FAT32 ||
@ -923,6 +929,7 @@ mbr_create_new(const char *disk, daddr_t start, daddr_t len,
parts->geo_sec = MAXSECTOR;
parts->geo_head = MAXHEAD;
parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1;
parts->target = ~0U;
if (get_disk_geom(disk, &geo)) {
parts->geo_sec = geo.dg_nsectors;
@ -995,8 +1002,10 @@ mbr_read_from_disk(const char *disk, daddr_t start, daddr_t len, size_t bps,
parts->geo_head = MAXHEAD;
parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1;
parts->dp.bytes_per_sector = bps;
parts->target = ~0U;
mbr_init_default_alignments(parts, 0);
if (read_mbr(disk, parts->dp.bytes_per_sector, &parts->mbr) == -1) {
if (read_mbr(disk, parts->dp.bytes_per_sector, &parts->mbr, parts)
== -1) {
free(parts);
return NULL;
}
@ -1360,8 +1369,12 @@ mbr_do_get_part_info(const struct disk_partitions *arg, part_id id,
const struct mbr_partition *mp, void *cookie)
{
struct disk_part_info *info = cookie;
const struct mbr_disk_partitions *parts =
(const struct mbr_disk_partitions*)arg;
mbr_partition_to_info(mp, mb->sector, info);
if (mp->mbrp_start + mb->sector == parts->target)
info->flags |= PTI_INSTALL_TARGET;
if (mb->last_mounted[i] != NULL && mb->last_mounted[i][0] != 0)
info->last_mounted = mb->last_mounted[i];
if (mb->fs_type[i] != FS_UNUSED) {
@ -1760,6 +1773,10 @@ found:
if (!mbr_info_to_partitition(&data,
&m->mbr.mbr_parts[i], m->sector, err_msg))
return false;
if (data.flags & PTI_INSTALL_TARGET)
parts->target = start;
else if (old_start == parts->target)
parts->target = -1;
if (data.last_mounted && m->last_mounted[i] &&
data.last_mounted != m->last_mounted[i]) {
free(__UNCONST(m->last_mounted[i]));
@ -2077,6 +2094,9 @@ mbr_delete_part(struct disk_partitions *arg, part_id pno, const char **err_msg)
return false;
}
if (parts->target == data.start)
parts->target = ~0U;
if (parts->dlabel) {
/*
* If we change the mbr partitioning, the we must

View File

@ -1,4 +1,4 @@
/* $NetBSD: part_edit.c,v 1.17 2020/09/29 14:29:56 martin Exp $ */
/* $NetBSD: part_edit.c,v 1.18 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@ -243,13 +243,7 @@ edit_part_install(menudesc *m, void *arg)
{
struct part_edit_info *marg = arg;
if (pm->ptstart == marg->cur.start) {
pm->ptstart = 0;
pm->ptsize = 0;
} else {
pm->ptstart = marg->cur.start;
pm->ptsize = marg->cur.size;
}
marg->cur.flags ^= PTI_INSTALL_TARGET;
return 0;
}
@ -571,7 +565,7 @@ add_part_entry(menudesc *m, void *arg)
struct part_edit_info data = { .parts = pdata->av.arg,
.first_custom_opt = PTN_OPTS_COMMON };
int ptn_menu;
daddr_t ptn_alignment;
daddr_t ptn_alignment, start;
menu_ent *opts;
size_t num_opts;
struct disk_part_free_space space;
@ -583,12 +577,13 @@ add_part_entry(menudesc *m, void *arg)
return 1;
ptn_alignment = data.parts->pscheme->get_part_alignment(data.parts);
start = pm->ptstart > 0 ? pm->ptstart : -1;
data.cur_id = NO_PART;
memset(&data.cur, 0, sizeof(data.cur));
data.cur.nat_type = data.parts->pscheme->
get_generic_part_type(PT_root);
if (data.parts->pscheme->get_free_spaces(data.parts, &space, 1,
max(sizemult, ptn_alignment), ptn_alignment, -1, -1) > 0) {
max(sizemult, ptn_alignment), ptn_alignment, start, -1) > 0) {
data.cur.start = space.start;
data.cur.size = space.size;
} else {
@ -691,7 +686,7 @@ draw_outer_ptn_line(menudesc *m, int line, void *arg)
case PTN_OPT_INSTALL:
wprintw(m->mw, "%*s : %s", col_width, ptn_install,
(marg->cur.nat_type->generic_ptype == PT_root &&
marg->cur.start == pm->ptstart) ? yes : no);
(marg->cur.flags & PTI_INSTALL_TARGET)) ? yes : no);
break;
}
@ -768,7 +763,7 @@ draw_outer_part_line(menudesc *m, int opt, void *arg)
return;
}
if (info.start == pm->ptstart &&
if ((info.flags & PTI_INSTALL_TARGET) &&
info.nat_type->generic_ptype == PT_root) {
if (install_flag == 0)
install_flag = msg_string(MSG_install_flag)[0];
@ -965,17 +960,18 @@ parts_use_wholedisk(struct disk_partitions *parts,
part_id nbsd;
struct disk_part_info info;
struct disk_part_free_space space;
daddr_t align;
daddr_t align, start;
size_t i;
parts->pscheme->delete_all_partitions(parts);
align = parts->pscheme->get_part_alignment(parts);
start = pm->ptstart > 0 ? pm->ptstart : -1;
if (ext_parts != NULL) {
for (i = 0; i < add_ext_parts; i++) {
info = ext_parts[i];
if (parts->pscheme->get_free_spaces(parts, &space,
1, info.size, align, -1, -1) != 1)
1, info.size, align, start, -1) != 1)
return false;
info.start = space.start;
if (info.nat_type == NULL)
@ -989,7 +985,7 @@ parts_use_wholedisk(struct disk_partitions *parts,
}
if (parts->pscheme->get_free_spaces(parts, &space, 1, 3*align,
align, -1, -1) != 1)
align, start, -1) != 1)
return false;
memset(&info, 0, sizeof(info));
@ -1009,8 +1005,6 @@ parts_use_wholedisk(struct disk_partitions *parts,
parts->pscheme->secondary_partitions(parts, info.start, true);
}
pm->ptstart = info.start;
pm->ptsize = info.size;
return true;
}
@ -1098,8 +1092,8 @@ verify_outer_parts(struct disk_partitions *parts, bool quiet)
int num_bsdparts;
daddr_t first_bsdstart, first_bsdsize, inst_start, inst_size;
first_bsdstart = first_bsdsize = 0;
inst_start = inst_size = 0;
first_bsdstart = inst_start = -1;
first_bsdsize = inst_size = 0;
num_bsdparts = 0;
for (i = 0; i < parts->num_part; i++) {
struct disk_part_info info;
@ -1111,18 +1105,18 @@ verify_outer_parts(struct disk_partitions *parts, bool quiet)
continue;
num_bsdparts++;
if (first_bsdstart == 0) {
if (first_bsdstart < 0) {
first_bsdstart = info.start;
first_bsdsize = info.size;
}
if (inst_start == 0 && info.start == pm->ptstart) {
if (inst_start< 0 && (info.flags & PTI_INSTALL_TARGET)) {
inst_start = info.start;
inst_size = info.size;
}
}
if (num_bsdparts == 0 ||
(num_bsdparts > 1 && inst_start == 0)) {
(num_bsdparts > 1 && inst_start < 0)) {
if (quiet && num_bsdparts == 0)
return 0;
if (quiet && parts->pscheme->guess_install_target &&
@ -1197,8 +1191,6 @@ ask_outer_partsizes(struct disk_partitions *parts)
set_default_sizemult(parts->disk, MEG, parts->bytes_per_sector);
if (pm->current_cylsize == 0)
pm->current_cylsize = 16065; /* noone cares nowadays */
pm->ptstart = 0;
pm->ptsize = 0;
memset(&data, 0, sizeof data);
data.av.arg = parts;

View File

@ -1,4 +1,4 @@
/* $NetBSD: partitions.h,v 1.16 2020/09/29 15:29:17 martin Exp $ */
/* $NetBSD: partitions.h,v 1.17 2020/10/03 18:54:18 martin Exp $ */
/*
* Copyright 2018 The NetBSD Foundation, Inc.
@ -117,6 +117,12 @@ struct part_type_desc {
#define PTI_PSCHEME_INTERNAL 8 /* no user partition, e.g.
MBRs extend partition */
#define PTI_RAW_PART 16 /* total disk */
#define PTI_INSTALL_TARGET 32 /* marks the target partition
* assumed to become / after
* reboot; may not be
* persistent; may only be
* set for a single partition!
*/
/* A single partition */
struct disk_part_info {