Mon Aug 26 12:14:06 2019 UTC ()
Fix a bug when installing to pre-exising GPT partitions.
Handle GPT labels with spaces.


(martin)
diff -r1.10 -r1.11 src/usr.sbin/sysinst/gpt.c

cvs diff -r1.10 -r1.11 src/usr.sbin/sysinst/gpt.c (expand / switch to unified diff)

--- src/usr.sbin/sysinst/gpt.c 2019/08/14 13:02:23 1.10
+++ src/usr.sbin/sysinst/gpt.c 2019/08/26 12:14:06 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: gpt.c,v 1.10 2019/08/14 13:02:23 martin Exp $ */ 1/* $NetBSD: gpt.c,v 1.11 2019/08/26 12:14:06 martin Exp $ */
2 2
3/* 3/*
4 * Copyright 2018 The NetBSD Foundation, Inc. 4 * Copyright 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -1121,27 +1121,27 @@ gpt_modify_part(const char *disk, struct @@ -1121,27 +1121,27 @@ gpt_modify_part(const char *disk, struct
1121 strcpy(p->gp_id, old.gp_id); 1121 strcpy(p->gp_id, old.gp_id);
1122 1122
1123 /* Check type */ 1123 /* Check type */
1124 if (p->gp_type != old.gp_type) { 1124 if (p->gp_type != old.gp_type) {
1125 if (run_program(RUN_SILENT, 1125 if (run_program(RUN_SILENT,
1126 "gpt label -b %" PRIu64 " -T %s %s", 1126 "gpt label -b %" PRIu64 " -T %s %s",
1127 p->gp_start, p->gp_type->tid, disk) != 0) 1127 p->gp_start, p->gp_type->tid, disk) != 0)
1128 return false; 1128 return false;
1129 } 1129 }
1130 1130
1131 /* Check label */ 1131 /* Check label */
1132 if (strcmp(p->gp_label, old.gp_label) != 0) { 1132 if (strcmp(p->gp_label, old.gp_label) != 0) {
1133 if (run_program(RUN_SILENT, 1133 if (run_program(RUN_SILENT,
1134 "gpt label -b %" PRIu64 " -l %s %s", 1134 "gpt label -b %" PRIu64 " -l \'%s\' %s",
1135 p->gp_start, p->gp_label, disk) != 0) 1135 p->gp_start, p->gp_label, disk) != 0)
1136 return false; 1136 return false;
1137 } 1137 }
1138 1138
1139 /* Check attributes */ 1139 /* Check attributes */
1140 if (p->gp_attr != old.gp_attr) { 1140 if (p->gp_attr != old.gp_attr) {
1141 if (p->gp_attr == 0) { 1141 if (p->gp_attr == 0) {
1142 if (run_program(RUN_SILENT, 1142 if (run_program(RUN_SILENT,
1143 "gpt set -N -b %" PRIu64 " %s", 1143 "gpt set -N -b %" PRIu64 " %s",
1144 p->gp_start, disk) != 0) 1144 p->gp_start, disk) != 0)
1145 return false; 1145 return false;
1146 } else { 1146 } else {
1147 todo_set = (p->gp_attr ^ old.gp_attr) & p->gp_attr; 1147 todo_set = (p->gp_attr ^ old.gp_attr) & p->gp_attr;
@@ -1203,58 +1203,75 @@ gpt_add_wedge(const char *disk, struct g @@ -1203,58 +1203,75 @@ gpt_add_wedge(const char *disk, struct g
1203 if (fd < 0) 1203 if (fd < 0)
1204 return false; 1204 return false;
1205 if (ioctl(fd, DIOCAWEDGE, &dkw) == -1) { 1205 if (ioctl(fd, DIOCAWEDGE, &dkw) == -1) {
1206 close(fd); 1206 close(fd);
1207 return false; 1207 return false;
1208 } 1208 }
1209 close(fd); 1209 close(fd);
1210 1210
1211 strlcpy(p->gp_dev_name, dkw.dkw_devname, sizeof(p->gp_dev_name)); 1211 strlcpy(p->gp_dev_name, dkw.dkw_devname, sizeof(p->gp_dev_name));
1212 p->gp_flags |= GPEF_WEDGE; 1212 p->gp_flags |= GPEF_WEDGE;
1213 return true; 1213 return true;
1214} 1214}
1215 1215
 1216static void
 1217escape_spaces(char *dest, const char *src)
 1218{
 1219 unsigned char c;
 1220
 1221 while (*src) {
 1222 c = *src++;
 1223 if (isspace(c) || c == '\\')
 1224 *dest++ = '\\';
 1225 *dest++ = c;
 1226 }
 1227 *dest = 0;
 1228}
 1229
1216static bool 1230static bool
1217gpt_get_part_device(const struct disk_partitions *arg, 1231gpt_get_part_device(const struct disk_partitions *arg,
1218 part_id id, char *devname, size_t max_devname_len, int *part, 1232 part_id id, char *devname, size_t max_devname_len, int *part,
1219 enum dev_name_usage usage, bool with_path) 1233 enum dev_name_usage usage, bool with_path)
1220{ 1234{
1221 const struct gpt_disk_partitions *parts = 1235 const struct gpt_disk_partitions *parts =
1222 (const struct gpt_disk_partitions*)arg; 1236 (const struct gpt_disk_partitions*)arg;
1223 struct gpt_part_entry *p = parts->partitions; 1237 struct gpt_part_entry *p = parts->partitions;
 1238 char tmpname[GPT_LABEL_LEN*2];
1224 part_id no; 1239 part_id no;
1225 1240
1226 1241
1227 for (no = 0; p != NULL && no < id; no++) 1242 for (no = 0; p != NULL && no < id; no++)
1228 p = p->gp_next; 1243 p = p->gp_next;
1229 1244
1230 if (no != id || p == NULL) 1245 if (no != id || p == NULL)
1231 return false; 1246 return false;
1232 1247
1233 if (part) 1248 if (part)
1234 *part = -1; 1249 *part = -1;
1235 1250
1236 if (!(p->gp_flags & GPEF_WEDGE) && 1251 if (!(p->gp_flags & GPEF_WEDGE) &&
1237 (usage == plain_name || usage == raw_dev_name)) 1252 (usage == plain_name || usage == raw_dev_name))
1238 gpt_add_wedge(arg->disk, p); 1253 gpt_add_wedge(arg->disk, p);
1239 1254
1240 switch (usage) { 1255 switch (usage) {
1241 case logical_name: 1256 case logical_name:
1242 if (p->gp_label[0] != 0) 1257 if (p->gp_label[0] != 0) {
 1258 escape_spaces(tmpname, p->gp_label);
1243 snprintf(devname, max_devname_len, 1259 snprintf(devname, max_devname_len,
1244 "NAME=%s", p->gp_label); 1260 "NAME=%s", tmpname);
1245 else 1261 } else {
1246 snprintf(devname, max_devname_len, 1262 snprintf(devname, max_devname_len,
1247 "NAME=%s", p->gp_id); 1263 "NAME=%s", p->gp_id);
 1264 }
1248 break; 1265 break;
1249 case plain_name: 1266 case plain_name:
1250 assert(p->gp_flags & GPEF_WEDGE); 1267 assert(p->gp_flags & GPEF_WEDGE);
1251 if (with_path) 1268 if (with_path)
1252 snprintf(devname, max_devname_len, _PATH_DEV "%s", 1269 snprintf(devname, max_devname_len, _PATH_DEV "%s",
1253 p->gp_dev_name); 1270 p->gp_dev_name);
1254 else 1271 else
1255 strlcpy(devname, p->gp_dev_name, max_devname_len); 1272 strlcpy(devname, p->gp_dev_name, max_devname_len);
1256 break; 1273 break;
1257 case raw_dev_name: 1274 case raw_dev_name:
1258 assert(p->gp_flags & GPEF_WEDGE); 1275 assert(p->gp_flags & GPEF_WEDGE);
1259 if (with_path) 1276 if (with_path)
1260 snprintf(devname, max_devname_len, _PATH_DEV "r%s", 1277 snprintf(devname, max_devname_len, _PATH_DEV "r%s",
@@ -1265,51 +1282,49 @@ gpt_get_part_device(const struct disk_pa @@ -1265,51 +1282,49 @@ gpt_get_part_device(const struct disk_pa
1265 break; 1282 break;
1266 default: 1283 default:
1267 return false; 1284 return false;
1268 } 1285 }
1269 1286
1270 return true; 1287 return true;
1271} 1288}
1272 1289
1273static bool 1290static bool
1274gpt_write_to_disk(struct disk_partitions *arg) 1291gpt_write_to_disk(struct disk_partitions *arg)
1275{ 1292{
1276 struct gpt_disk_partitions *parts = (struct gpt_disk_partitions*)arg; 1293 struct gpt_disk_partitions *parts = (struct gpt_disk_partitions*)arg;
1277 struct gpt_part_entry *p, *n; 1294 struct gpt_part_entry *p, *n;
1278 char label_arg[sizeof(p->gp_label) + 4]; 1295 char label_arg[sizeof(p->gp_label) + 10];
1279 char diskpath[MAXPATHLEN]; 1296 char diskpath[MAXPATHLEN];
1280 int fd, bits = 0; 1297 int fd, bits = 0;
1281 bool root_is_new = false, efi_is_new = false; 1298 bool root_is_new = false, efi_is_new = false;
1282 part_id root_id = NO_PART, efi_id = NO_PART, pno; 1299 part_id root_id = NO_PART, efi_id = NO_PART, pno;
1283 1300
1284 /* 1301 /*
1285 * Remove all wedges on this disk - they may become invalid and we 1302 * Remove all wedges on this disk - they may become invalid and we
1286 * have no easy way to associate them with the partitioning data. 1303 * have no easy way to associate them with the partitioning data.
1287 * Instead we will explicitly request creation of wedges on demand 1304 * Instead we will explicitly request creation of wedges on demand
1288 * later. 1305 * later.
1289 */ 1306 */
1290 fd = opendisk(arg->disk, O_RDWR, diskpath, sizeof(diskpath), 0); 1307 fd = opendisk(arg->disk, O_RDWR, diskpath, sizeof(diskpath), 0);
1291 if (fd < 0) 1308 if (fd < 0)
1292 return false; 1309 return false;
1293 if (ioctl(fd, DIOCRMWEDGES, &bits) == -1) 1310 if (ioctl(fd, DIOCRMWEDGES, &bits) == -1)
1294 return false; 1311 return false;
1295 close(fd); 1312 close(fd);
1296 1313
1297 /* 1314 /*
1298 * Mark all partitions as "have no wedge yet". While there, 1315 * Collect first root and efi partition (if available)
1299 * collect first root and efi partition (if available) 
1300 */ 1316 */
1301 for (pno = 0, p = parts->partitions; p != NULL; p = p->gp_next, pno++) { 1317 for (pno = 0, p = parts->partitions; p != NULL; p = p->gp_next, pno++) {
1302 p->gp_flags &= ~GPEF_WEDGE; 
1303 if (root_id == NO_PART && p->gp_type != NULL) { 1318 if (root_id == NO_PART && p->gp_type != NULL) {
1304 if (p->gp_type->gent.generic_ptype == PT_root && 1319 if (p->gp_type->gent.generic_ptype == PT_root &&
1305 p->gp_start == pm->ptstart) { 1320 p->gp_start == pm->ptstart) {
1306 root_id = pno; 1321 root_id = pno;
1307 root_is_new = !(p->gp_flags & GPEF_ON_DISK); 1322 root_is_new = !(p->gp_flags & GPEF_ON_DISK);
1308 } else if (efi_id == NO_PART && 1323 } else if (efi_id == NO_PART &&
1309 p->gp_type->gent.generic_ptype == PT_EFI_SYSTEM) { 1324 p->gp_type->gent.generic_ptype == PT_EFI_SYSTEM) {
1310 efi_id = pno; 1325 efi_id = pno;
1311 efi_is_new = !(p->gp_flags & GPEF_ON_DISK); 1326 efi_is_new = !(p->gp_flags & GPEF_ON_DISK);
1312 } 1327 }
1313 } 1328 }
1314 } 1329 }
1315 1330
@@ -1363,27 +1378,27 @@ gpt_write_to_disk(struct disk_partitions @@ -1363,27 +1378,27 @@ gpt_write_to_disk(struct disk_partitions
1363 1378
1364 /* 1379 /*
1365 * Add new partitions 1380 * Add new partitions
1366 */ 1381 */
1367 for (p = parts->partitions; p != NULL; p = p->gp_next) { 1382 for (p = parts->partitions; p != NULL; p = p->gp_next) {
1368 if (p->gp_flags & GPEF_ON_DISK) 1383 if (p->gp_flags & GPEF_ON_DISK)
1369 continue; 1384 continue;
1370 if (!(p->gp_flags & GPEF_MODIFIED)) 1385 if (!(p->gp_flags & GPEF_MODIFIED))
1371 continue; 1386 continue;
1372 1387
1373 if (p->gp_label[0] == 0) 1388 if (p->gp_label[0] == 0)
1374 label_arg[0] = 0; 1389 label_arg[0] = 0;
1375 else 1390 else
1376 sprintf(label_arg, "-l %s", p->gp_label); 1391 sprintf(label_arg, "-l \'%s\'", p->gp_label);
1377 1392
1378 if (p->gp_type != NULL) 1393 if (p->gp_type != NULL)
1379 run_program(RUN_SILENT, 1394 run_program(RUN_SILENT,
1380 "gpt -n add -b %" PRIu64 " -s %" PRIu64 1395 "gpt -n add -b %" PRIu64 " -s %" PRIu64
1381 "s -t %s %s %s", 1396 "s -t %s %s %s",
1382 p->gp_start, p->gp_size, p->gp_type->tid, 1397 p->gp_start, p->gp_size, p->gp_type->tid,
1383 label_arg, arg->disk); 1398 label_arg, arg->disk);
1384 else 1399 else
1385 run_program(RUN_SILENT, 1400 run_program(RUN_SILENT,
1386 "gpt -n add -b %" PRIu64 " -s %" PRIu64 1401 "gpt -n add -b %" PRIu64 " -s %" PRIu64
1387 "s %s %s", 1402 "s %s %s",
1388 p->gp_start, p->gp_size, label_arg, arg->disk); 1403 p->gp_start, p->gp_size, label_arg, arg->disk);
1389 gpt_apply_attr(arg->disk, "set", p->gp_start, p->gp_attr); 1404 gpt_apply_attr(arg->disk, "set", p->gp_start, p->gp_attr);