1 /* @(#)labelsubs.c	1.25 09/07/11 Copyright 1988-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)labelsubs.c	1.25 09/07/11 Copyright 1988-2009 J. Schilling";
6 #endif
7 /*
8  *	Subroutines that deal with the primary disk label
9  *
10  *	Copyright (c) 1988-2009 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #include <schily/param.h>	/* XXX nonportable to use u_char */
27 #include <schily/stdio.h>
28 #include <schily/standard.h>
29 #include <schily/signal.h>
30 #include <schily/stdlib.h>
31 #include <schily/errno.h>
32 #include <schily/schily.h>
33 
34 #include "dsklabel.h"
35 
36 #include <scg/scsireg.h>
37 #include <scg/scsidefs.h>
38 #include <scg/scsitransp.h>
39 
40 #include "scsicmds.h"
41 
42 #include "fmt.h"
43 
44 extern	int	debug;
45 extern	int	nowait;
46 
47 extern	int	autoformat;
48 extern	int	reformat_only;
49 extern	int	label;
50 
51 union x_label {
52 	struct	dk_label label;
53 	char		 space[MAX_SECSIZE];
54 } x_label;
55 struct	dk_label *d_label = (struct  dk_label *)&x_label;
56 
57 extern	char		*Lname;
58 
59 EXPORT	void	read_primary_label	__PR((SCSI *scgp, struct disk *dp));
60 EXPORT	void	create_label		__PR((SCSI *scgp, struct disk *dp));
61 LOCAL	void	set_driver_geom		__PR((SCSI *scgp));
62 EXPORT	void	label_disk		__PR((SCSI *scgp, struct disk *dp));
63 LOCAL	BOOL	read_backup_label	__PR((SCSI *scgp, struct disk *dp, struct dk_label *lp));
64 LOCAL	void	labelintr		__PR((int sig));
65 LOCAL	BOOL	scan_backup_label	__PR((SCSI *scgp, struct dk_label *lp, long *start, BOOL lgeom_ok));
66 EXPORT	int	read_disk_label		__PR((SCSI *scgp, struct dk_label *lp, long secno));
67 LOCAL	void	print_label_err		__PR((struct dk_label *lp));
68 LOCAL	BOOL	has_space_for_acyl	__PR((SCSI *scgp, struct disk *dp, long *lblk));
69 LOCAL	BOOL	has_unused_space	__PR((SCSI *scgp, struct disk *dp, long *lblk));
70 EXPORT	long	get_default_lncyl	__PR((SCSI *scgp, struct disk *dp));
71 EXPORT	void	select_label_geom	__PR((SCSI *scgp, struct disk *dp));
72 EXPORT	BOOL	select_backup_label	__PR((SCSI *scgp, struct disk *dp, BOOL lgeom_ok));
73 LOCAL	BOOL	get_defpart		__PR((SCSI *scgp, struct disk *dp, struct dk_label *lp));
74 EXPORT	void	select_partition	__PR((SCSI *scgp, struct disk *dp));
75 EXPORT	void	get_default_partition	__PR((SCSI *scgp, struct disk *dp));
76 
77 EXPORT void
read_primary_label(scgp,dp)78 read_primary_label(scgp, dp)
79 	SCSI		*scgp;
80 	struct disk	*dp;
81 {
82 	if (dp->formatted > 0 && !yes("Ignore old disk Label? ")) {
83 		/*
84 		 * Disk is formatted,
85 		 * Label magic and Label checksum OK, use it!
86 		 */
87 		if (read_disk_label(scgp, d_label, 0L) < 0) {
88 			error("Could not read label from disk\n");
89 
90 			if (select_backup_label(scgp, dp, FALSE) == TRUE)
91 				dp->labelread = 1;
92 
93 		} else if (setval_from_label(dp, d_label)) {
94 			dp->labelread = 1;
95 			printf("<%s>\n", d_label->dkl_asciilabel);
96 
97 		} else {
98 			print_label_err(d_label);
99 		}
100 	} else if (dp->formatted == 0) {
101 		/*
102 		 * Disk is formatted,
103 		 * Corrupt Label.
104 		 */
105 		if (select_backup_label(scgp, dp, FALSE) == TRUE)
106 			dp->labelread = 1;
107 	}
108 }
109 
110 EXPORT void
create_label(scgp,dp)111 create_label(scgp, dp)
112 	SCSI		*scgp;
113 	struct disk	*dp;
114 {
115 extern	int	format_done;
116 	BOOL	geom_changed	= FALSE;
117 	BOOL	write_label	= format_done && !nowait;
118 
119 	if (autoformat) {
120 		label_disk(scgp, dp);
121 		return;
122 	}
123 	scgp->silent++;
124 	read_capacity(scgp);
125 	scgp->silent--;
126 	if ((scgp->cap->c_baddr + 1) != dp->cur_capacity) {
127 		printf("WARNING:\n");
128 		printf("Format changed Disk Geometry.\n");
129 		printf("Capacity before: %ld Capacity after: %ld\n",
130 				dp->cur_capacity,
131 				(long)(scgp->cap->c_baddr + 1));
132 
133 		dp->cur_capacity = scgp->cap->c_baddr + 1;
134 		select_label_geom(scgp, dp);
135 		geom_changed = TRUE;
136 		write_label = TRUE;
137 	}
138 	if (debug)
139 		printf("nowait: %d write_label: %d geom_changed: %d\n",
140 					nowait, write_label, geom_changed);
141 	/*
142 	 * ALT: !nowait
143 	 * NEU:
144 	 * Wenn nowait, Label nicht schreiben es sei denn geometrie ge�ndert.
145 	 * Wenn nicht formatiert, fragen ob Label schreiben
146 	 * Wenn formatiert, fragen ob Label �ndern
147 	 * (impliziert ge�ndertes Label schreiben)
148 	 * Wenn formatiert & geometrie ge�ndert, dann immber Label �ndern.
149 	 */
150 	if ((write_label || !format_done) &&
151 					yes("Print disk label? ")) {
152 		printlabel(d_label);
153 		checklabel(dp, d_label, 0);
154 	}
155 	if ((write_label || !format_done) &&
156 			(geom_changed || yes("Modify disk label? "))) do {
157 		write_label = TRUE;
158 
159 		makelabel(scgp, dp, d_label);
160 		printlabel(d_label);
161 		checklabel(dp, d_label, 1);
162 	} while (!yes("Use this label? "));
163 
164 	if (debug)
165 		printf("nowait: %d write_label: %d geom_changed: %d\n",
166 					nowait, write_label, geom_changed);
167 	/*
168 	 * fill in default vtmap if not done yet
169 	 */
170 	check_vtmap(d_label, label || write_label);
171 	if (label) {
172 		writelabel(Lname, d_label);
173 		/* NOTREACHED */
174 	} else if (write_label) {
175 		if (!format_done && !yes("Write label on disk? "))
176 			exit(1);
177 		label_disk(scgp, dp);
178 	}
179 }
180 
181 LOCAL void
set_driver_geom(scgp)182 set_driver_geom(scgp)
183 	SCSI	*scgp;
184 {
185 	int	diskno = maptodisk(scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
186 	char	*dname;
187 	struct dk_label xl;
188 
189 	if (diskno < 0) {
190 			errmsgno(EX_BAD,
191 			"Cannot set geometry to driver (cannot map disk name).\n");
192 		return;
193 	}
194 	dname = diskdevname(diskno);
195 
196 	if (!readlabel(dname, &xl)) {
197 		if (geterrno() == ENXIO) {
198 			errmsgno(EX_BAD, "Cannot verify mapping.\n");
199 			if (yes("Set geometry to driver? "))
200 				(void) setlabel(dname, d_label);
201 		}
202 		return;
203 	}
204 
205 	if (cmpbytes(d_label, &xl, sizeof (xl)) < sizeof (xl)) {
206 		errmsgno(EX_BAD,
207 			"Will not set geometry to driver (mapping error).\n");
208 		return;
209 	}
210 	(void) setlabel(dname, d_label);
211 }
212 
213 /*---------------------------------------------------------------------------
214 |
215 |	Die Backuplabels stehen auf dem letzten Reservezylinder
216 |	auf dem letzten Kopf.
217 |
218 +---------------------------------------------------------------------------*/
219 EXPORT void
label_disk(scgp,dp)220 label_disk(scgp, dp)
221 	SCSI		*scgp;
222 	struct disk	*dp;
223 {
224 	long	backup_label_blk;
225 	int	i;
226 
227 	backup_label_blk = d_label->dkl_ncyl + d_label->dkl_acyl - 1;
228 	backup_label_blk *= d_label->dkl_nhead * d_label->dkl_nsect;
229 	backup_label_blk += (d_label->dkl_nhead-1) * d_label->dkl_nsect;
230 
231 	if (old_acb(scgp->dev)) {
232 		backup_label_blk = d_label->dkl_pcyl;
233 		backup_label_blk *= d_label->dkl_nhead * d_label->dkl_nsect;
234 		backup_label_blk -= (d_label->dkl_nhead-1) * d_label->dkl_nsect;
235 	}
236 
237 	if (write_scsi(scgp, (caddr_t)d_label, 0L, 1) < 0)
238 		error("Could not write label to disk\n");
239 	if (dp->lacyl > 0) {
240 		for (i = 1; i < 10; i += 2) {
241 			if (write_scsi(scgp, (caddr_t)d_label, backup_label_blk+i, 1) < 0)
242 				error("Could not write backup label to disk\n");
243 		}
244 	}
245 	set_driver_geom(scgp);
246 }
247 
248 /*---------------------------------------------------------------------------
249 |
250 |	Die Backuplabels stehen auf dem letzten Alternativen Zylinder
251 |	auf dem letzten Kopf auf den ersten 5 ungeraden Sektoren.
252 |	Bei Adaptec 4000 geht das nicht, weil i.a. die Kapazitaet nicht
253 |	ausreicht. Daher:
254 |	Alt: Letzter Alternativen Zylinder Kopf 1
255 |	Neu: Letzter Alternativen Zylinder Kopf 2
256 |
257 +---------------------------------------------------------------------------*/
258 LOCAL BOOL
read_backup_label(scgp,dp,lp)259 read_backup_label(scgp, dp, lp)
260 	SCSI		*scgp;
261 	struct disk	*dp;
262 	struct dk_label *lp;
263 {
264 	long	backup_label_blk;
265 	int	i;
266 	int	ret;
267 
268 	backup_label_blk = d_label->dkl_ncyl + d_label->dkl_acyl - 1;
269 	backup_label_blk *= d_label->dkl_nhead * d_label->dkl_nsect;
270 	backup_label_blk += (d_label->dkl_nhead-1) * d_label->dkl_nsect;
271 printf("lab: %ld\n", backup_label_blk+1);
272 	backup_label_blk = dp->lncyl + dp->lacyl - 1;
273 	backup_label_blk *= dp->lhead * dp->lspt;
274 	backup_label_blk += (dp->lhead-1) * dp->lspt;
275 printf("lab: %ld\n", backup_label_blk+1);
276 
277 	if (old_acb(scgp->dev)) {
278 		if (dp->lpcyl > 0)
279 			backup_label_blk = dp->lpcyl;
280 		else
281 			backup_label_blk = dp->pcyl;
282 		backup_label_blk *= dp->lhead * dp->lspt;
283 		backup_label_blk -= (dp->lhead-1) * dp->lspt;
284 	}
285 
286 	if (dp->lacyl > 0) {
287 		for (i = 1; i < 10; i += 2) {
288 			if ((ret = read_disk_label(scgp, lp, backup_label_blk+i)) < 0)
289 				error("Could not read backup label from disk\n");
290 			if (ret == TRUE)
291 				return (TRUE);
292 			error("Backup label: ");
293 			print_label_err(lp);
294 		}
295 		return (FALSE);
296 	}
297 	error("No alt Cylinders!\n");
298 	return (FALSE);
299 }
300 
301 LOCAL	int	scan_intr;
302 
303 LOCAL void
labelintr(sig)304 labelintr(sig)
305 	int	sig;
306 {
307 	scan_intr++;
308 }
309 
310 LOCAL BOOL
scan_backup_label(scgp,lp,start,lgeom_ok)311 scan_backup_label(scgp, lp, start, lgeom_ok)
312 	SCSI	*scgp;
313 	struct dk_label *lp;
314 	long	*start;
315 	BOOL	lgeom_ok;
316 {
317 	int	i;
318 	int	limit;
319 	long	l;
320 	void	(*osig) __PR((int));
321 
322 	scgp->silent++;
323 	if (read_capacity(scgp) < 0) {
324 		scgp->silent--;
325 		return (FALSE);
326 	}
327 	scgp->silent--;
328 	if (start && *start)
329 		l = *start;
330 	else
331 		l = scgp->cap->c_baddr;
332 
333 	osig = signal(SIGINT, labelintr);
334 
335 	printf("Scanning for backup label..."); flush();
336 
337 	limit = scgp->cap->c_baddr/200;
338 	if (!lgeom_ok)
339 		limit *= 10;
340 	scan_intr = 0;
341 	for (i = 0; scan_intr == 0 && i < limit; i++, l--) {
342 		if (read_disk_label(scgp, lp, l) == TRUE) {
343 			printf("\nScan for backup label: found at: %ld n: %d\n",
344 								l, i);
345 			signal(SIGINT, osig);
346 			if (start)
347 				*start = --l;
348 			return (TRUE);
349 		}
350 	}
351 	signal(SIGINT, osig);
352 
353 	printf("\nScan for backup label: NOT found : %ld n: %d\n", l, i);
354 	return (FALSE);
355 }
356 
357 EXPORT int
read_disk_label(scgp,lp,secno)358 read_disk_label(scgp, lp, secno)
359 	SCSI	*scgp;
360 	struct dk_label *lp;
361 	long	secno;
362 {
363 	fillbytes((caddr_t)lp, sizeof (*lp), '\0');
364 	if (read_scsi(scgp, (caddr_t)lp, secno, 1) < 0)
365 		return (-1);
366 	return (lp->dkl_magic == DKL_MAGIC && lp->dkl_cksum == do_cksum(lp));
367 }
368 
369 LOCAL void
print_label_err(lp)370 print_label_err(lp)
371 	struct dk_label *lp;
372 {
373 /*	if (lp->dkl_magic == 0 || do_cksum(lp) == 0)*/
374 /*		error("Could not read label.\n");*/
375 	if (lp->dkl_magic != DKL_MAGIC)
376 		error("No label found.\n");
377 	if (lp->dkl_cksum != do_cksum(lp))
378 		error("Corrupt label.\n");
379 }
380 
381 LOCAL BOOL
has_space_for_acyl(scgp,dp,lblk)382 has_space_for_acyl(scgp, dp, lblk)
383 	SCSI	*scgp;
384 	struct disk	*dp;
385 	long	*lblk;
386 {
387 	*lblk = dp->lncyl + dp->lacyl - 1;
388 	*lblk *= dp->lhead * dp->lspt;
389 	*lblk += (dp->lhead - 1) * dp->lspt;
390 	*lblk += 9;	/* XXX letztes backuplabel */
391 	if (*lblk > scgp->cap->c_baddr) {
392 		*lblk -= scgp->cap->c_baddr;
393 		*lblk += dp->lhead * dp->lspt;
394 		*lblk /= dp->lhead * dp->lspt;
395 		printf("WARNING: Alternate cylinders exceed end of disk. (%ld cyls)\n", *lblk);
396 		return (FALSE);
397 	}
398 	return (TRUE);
399 }
400 
401 LOCAL BOOL
has_unused_space(scgp,dp,lblk)402 has_unused_space(scgp, dp, lblk)
403 	SCSI	*scgp;
404 	struct disk	*dp;
405 	long	*lblk;
406 {
407 	/*
408 	 * Wenn aus Sicht der Labelgeometrie mindestens ein ganzer
409 	 * Zylinder oder mehr verschenkt wird, wird gewarnt.
410 	 */
411 	*lblk = scgp->cap->c_baddr + 1;
412 	*lblk -= (dp->lncyl+dp->lacyl) * dp->lhead*dp->lspt;
413 
414 	if (*lblk >= dp->lhead * dp->lspt) {
415 		*lblk /= dp->lhead * dp->lspt;
416 		printf("WARNING: Unused space on disk. (%ld cyls)\n", *lblk);
417 		printf("\tThis may be correct on a generic label that fits for a group of disks.\n");
418 		printf("\tIn this case the disk space must match the smallest disk of that group.\n");
419 		return (TRUE);
420 	}
421 	return (FALSE);
422 }
423 
424 EXPORT long
get_default_lncyl(scgp,dp)425 get_default_lncyl(scgp, dp)
426 	SCSI		*scgp;
427 	struct disk	*dp;
428 {
429 	long	lncyl;
430 
431 	if (dp->lpcyl < 0 || dp->lpcyl != dp->pcyl) {
432 		printf("NOTICE: setting lpcyl:\n");
433 		printf("get_default_lncyl lpcyl: %ld lhead: %ld lspt: %ld\n", dp->lpcyl, dp->lhead, dp->lspt);
434 		get_lgeom_defaults(scgp, dp);
435 		printf("get_default_lncyl lpcyl: %ld lhead: %ld lspt: %ld\n", dp->lpcyl, dp->lhead, dp->lspt);
436 	}
437 	if (scgp->cap->c_baddr <= 0) {
438 		lncyl = dp->lpcyl-dp->lacyl;
439 	} else if (dp->lhead > 0 && dp->lspt > 0 && dp->lacyl > 0) {
440 		lncyl = scgp->cap->c_baddr+1;
441 		lncyl /= dp->lhead*dp->lspt;
442 		lncyl -= dp->lacyl;
443 	} else {
444 		lncyl = -1;
445 	}
446 	return (lncyl);
447 }
448 
449 EXPORT void
select_label_geom(scgp,dp)450 select_label_geom(scgp, dp)
451 	SCSI		*scgp;
452 	struct disk	*dp;
453 {
454 	long	minlacyl = old_acb(scgp->dev) ? 2L : 1L;
455 	long	maxlncyl;
456 	long	lncyl;
457 	long	lblk;
458 
459 	lncyl = get_default_lncyl(scgp, dp);
460 top:
461 	getlong("Enter number of data      heads     (Label)",
462 						&dp->lhead, 1L, 0xFFFEL);
463 	getlong("Enter number of data sectors/track  (Label)",
464 						&dp->lspt, 1L, 0xFFFEL);
465 	getlong("Enter number of alternate cylinders (Label)",
466 					&dp->lacyl, minlacyl, 10L);
467 
468 	maxlncyl = dp->pcyl;
469 	maxlncyl *= dp->nhead*dp->spt;
470 
471 	if (!reformat_only)
472 	printf("Sch�tze cap: %ld ist cap: %ld\n", maxlncyl, (long)scgp->cap->c_baddr+1);
473 
474 	maxlncyl /= dp->lhead*dp->lspt;
475 	maxlncyl -= dp->lacyl;
476 
477 	lncyl = get_default_lncyl(scgp, dp);
478 
479 	if (!reformat_only) {
480 		printf("Current lncyl: %ld\n", dp->lncyl);
481 		printf("Sch�tze lncyl: %ld\n", lncyl);
482 		printf("old: %ld new: %ld\n",
483 				dp->pcyl-dp->lacyl, maxlncyl);
484 	}
485 	if (lncyl > maxlncyl && lncyl > dp->lpcyl)
486 		maxlncyl = lncyl;
487 	if (dp->lpcyl-dp->lacyl > maxlncyl)
488 		maxlncyl = dp->lpcyl-dp->lacyl;
489 	if (dp->lncyl < 0)
490 		dp->lncyl = lncyl;
491 	getlong("Enter number of data      cylinders (Label)",
492 					&dp->lncyl, 1L, maxlncyl);
493 
494 	dp->int_cyl = dp->pcyl - dp->lncyl
495 			- dp->lacyl - dp->atrk/dp->nhead;
496 /*printf("int_cyl: %d\n", dp->int_cyl);*/
497 
498 	if (!has_space_for_acyl(scgp, dp, &lblk)) {
499 		if (!yes("Use this label geometry? ")) {
500 			if (yes("Adjust number of data cylinders to maximum possible value? "))
501 				dp->lncyl -= lblk;
502 			goto top;
503 		}
504 	}
505 
506 	/*
507 	 * Hilfe fuer die Wartung der Datei 'sformat.dat'
508 	 * Der Service soll nicht sehen, dasz Platz verschenkt ist.
509 	 */
510 	if (!reformat_only && has_unused_space(scgp, dp, &lblk)) {
511 		if (!yes("Use this label geometry? ")) {
512 			if (yes("Adjust number of data cylinders to maximum possible value? "))
513 				dp->lncyl += lblk;
514 			goto top;
515 		}
516 	}
517 }
518 
519 EXPORT BOOL
select_backup_label(scgp,dp,lgeom_ok)520 select_backup_label(scgp, dp, lgeom_ok)
521 	SCSI	*scgp;
522 	struct disk	*dp;
523 	BOOL	lgeom_ok;
524 {
525 	union	x_label d_blabel;
526 	long	start = 0L;
527 
528 	if (!lgeom_ok) {
529 		printf("WARNING:\n\n");
530 		printf("The label geometry is not known at this time.\n\n");
531 		printf("Scanning for backup labels may take a long time!\n");
532 		printf("If you want to confirm the correct geometry,\n");
533 		printf("hit RETURN on the next question.\n");
534 	}
535 	if (!yes("%s for backup labels? ", lgeom_ok ? "Search":"Scan"))
536 		return (FALSE);
537 
538 	if (lgeom_ok && read_backup_label(scgp, dp, &d_blabel.label)) {
539 		printf("<%s>\n", d_blabel.label.dkl_asciilabel);
540 	} else {
541 		do {
542 			if (!scan_backup_label(scgp, &d_blabel.label,
543 							&start, lgeom_ok))
544 				return (FALSE);
545 
546 			printf("<%s>\n", d_blabel.label.dkl_asciilabel);
547 			if (yes("Print partition table? ")) {
548 				printparts(&d_blabel.label);
549 			}
550 		} while (yes("Scan for other backup label? "));
551 	}
552 
553 	if (yes("Use backuplabel? ")) {
554 		movebytes((caddr_t)&d_blabel.label,
555 				(caddr_t)d_label, sizeof (*d_label));
556 
557 		if (!setval_from_label(dp, d_label)) {
558 			print_label_err(d_label);
559 			fillbytes((caddr_t)d_label, sizeof (*d_label), '\0');
560 			return (FALSE);
561 		}
562 		return (TRUE);
563 	}
564 	return (FALSE);
565 }
566 
567 LOCAL BOOL
get_defpart(scgp,dp,lp)568 get_defpart(scgp, dp, lp)
569 	SCSI		*scgp;
570 	struct disk	*dp;
571 	struct dk_label *lp;
572 {
573 	get_lgeom_defaults(scgp, dp);
574 	label_null(lp);
575 	return (get_part_defaults(scgp, dp, lp));
576 }
577 
578 EXPORT void
select_partition(scgp,dp)579 select_partition(scgp, dp)
580 	SCSI		*scgp;
581 	struct disk	*dp;
582 {
583 	struct	dk_label d_xlabel;
584 	char	*pname = dp->default_part;
585 
586 	label_null(&d_xlabel);
587 	if (dp->labelread > 0)
588 		movebytes((char *)d_label, (char *)&d_xlabel, sizeof (*d_label));
589 	if (!yes("Use default partition? "))
590 		pname = NULL;
591 	if (ext_part(scgp, dp->disk_type, pname, dp->default_part,
592 						&d_xlabel, get_defpart, dp)) {
593 		if (dp->labelread < 0 || yes("Use selected label? ")) {
594 			printf("setval: %d\n", setval_from_label(dp, &d_xlabel));
595 /*			merge_label(&d_xlabel, d_label);*/
596 			movebytes((char *)&d_xlabel, (char *)d_label,
597 							sizeof (*d_label));
598 			if (dp->labelread < 0)
599 				dp->labelread = 0;
600 			else
601 				dp->labelread = 1;
602 		}
603 #ifdef	ALT_deflabel
604 	/*
605 	 * Wenn die Autpart hier und nicht in ext_part() vorgenommen wird, dann
606 	 * wird dp->labelread nicht auf 0 gesetzt und damit
607 	 * immer Labelgeometrie abgefragt. Ist das besser?
608 	 */
609 	} else if (pname == NULL) {
610 		if (get_defpart(&d_xlabel)) {
611 			printparts(&d_xlabel);
612 			movebytes((char *)&d_xlabel, (char *)d_label,
613 							sizeof (*d_label));
614 		}
615 #endif
616 	}
617 }
618 
619 EXPORT void
get_default_partition(scgp,dp)620 get_default_partition(scgp, dp)
621 	SCSI		*scgp;
622 	struct disk	*dp;
623 {
624 	struct	dk_label d_xlabel;
625 	char	*pname = dp->default_part;
626 
627 	label_null(&d_xlabel);
628 	/*
629 	 * Wenn nur default Label aus der Datenbank zul�ssig sein sollen, dann
630 	 * mu� statt get_defpart() ein NULL Pointer genommen werden.
631 	 */
632 	if (ext_part(scgp, dp->disk_type, pname, pname,
633 						&d_xlabel, get_defpart, dp)) {
634 			if (!setval_from_label(dp, &d_xlabel)) {
635 				comerrno(EX_BAD, "BAD default partition.\n");
636 				/* NOTREACHED */
637 			}
638 /*			merge_label(&d_xlabel, d_label);*/
639 			movebytes((char *)&d_xlabel, (char *)d_label,
640 							sizeof (*d_label));
641 			dp->labelread = 1;
642 	} else {
643 		comerrno(EX_BAD, "Default partition not found.\n");
644 		/* NOTREACHED */
645 	}
646 }
647