1 |
#if ENABLE_FEATURE_SUN_LABEL |
#if ENABLE_FEATURE_SUN_LABEL |
2 |
|
|
3 |
|
#define SUNOS_SWAP 3 |
4 |
|
#define SUN_WHOLE_DISK 5 |
5 |
|
|
6 |
#define SUN_LABEL_MAGIC 0xDABE |
#define SUN_LABEL_MAGIC 0xDABE |
7 |
#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA |
#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA |
8 |
#define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x)) |
#define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x)) |
42 |
{ |
{ |
43 |
struct stat bootstat; |
struct stat bootstat; |
44 |
|
|
45 |
if (fstat(fd, &bootstat) < 0) { |
if (fstat(dev_fd, &bootstat) < 0) { |
46 |
scsi_disk = 0; |
scsi_disk = 0; |
47 |
floppy = 0; |
floppy = 0; |
48 |
} else if (S_ISBLK(bootstat.st_mode) |
} else if (S_ISBLK(bootstat.st_mode) |
60 |
} |
} |
61 |
} |
} |
62 |
|
|
63 |
static const struct systypes sun_sys_types[] = { |
static const char *const sun_sys_types[] = { |
64 |
{ "\x00" "Empty" }, /* 0 */ |
"\x00" "Empty" , /* 0 */ |
65 |
{ "\x01" "Boot" }, /* 1 */ |
"\x01" "Boot" , /* 1 */ |
66 |
{ "\x02" "SunOS root" }, /* 2 */ |
"\x02" "SunOS root" , /* 2 */ |
67 |
{ "\x03" "SunOS swap" }, /* SUNOS_SWAP */ |
"\x03" "SunOS swap" , /* SUNOS_SWAP */ |
68 |
{ "\x04" "SunOS usr" }, /* 4 */ |
"\x04" "SunOS usr" , /* 4 */ |
69 |
{ "\x05" "Whole disk" }, /* SUN_WHOLE_DISK */ |
"\x05" "Whole disk" , /* SUN_WHOLE_DISK */ |
70 |
{ "\x06" "SunOS stand" }, /* 6 */ |
"\x06" "SunOS stand" , /* 6 */ |
71 |
{ "\x07" "SunOS var" }, /* 7 */ |
"\x07" "SunOS var" , /* 7 */ |
72 |
{ "\x08" "SunOS home" }, /* 8 */ |
"\x08" "SunOS home" , /* 8 */ |
73 |
{ "\x82" "Linux swap" }, /* LINUX_SWAP */ |
"\x82" "Linux swap" , /* LINUX_SWAP */ |
74 |
{ "\x83" "Linux native" }, /* LINUX_NATIVE */ |
"\x83" "Linux native", /* LINUX_NATIVE */ |
75 |
{ "\x8e" "Linux LVM" }, /* 0x8e */ |
"\x8e" "Linux LVM" , /* 0x8e */ |
76 |
/* New (2.2.x) raid partition with autodetect using persistent superblock */ |
/* New (2.2.x) raid partition with autodetect using persistent superblock */ |
77 |
{ "\xfd" "Linux raid autodetect" }, /* 0xfd */ |
"\xfd" "Linux raid autodetect", /* 0xfd */ |
78 |
{ NULL } |
NULL |
79 |
}; |
}; |
80 |
|
|
81 |
|
|
84 |
{ |
{ |
85 |
sunlabel->infos[i].id = sysid; |
sunlabel->infos[i].id = sysid; |
86 |
sunlabel->partitions[i].start_cylinder = |
sunlabel->partitions[i].start_cylinder = |
87 |
SUN_SSWAP32(start / (heads * sectors)); |
SUN_SSWAP32(start / (g_heads * g_sectors)); |
88 |
sunlabel->partitions[i].num_sectors = |
sunlabel->partitions[i].num_sectors = |
89 |
SUN_SSWAP32(stop - start); |
SUN_SSWAP32(stop - start); |
90 |
set_changed(i); |
set_changed(i); |
98 |
|
|
99 |
if (sunlabel->magic != SUN_LABEL_MAGIC |
if (sunlabel->magic != SUN_LABEL_MAGIC |
100 |
&& sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { |
&& sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { |
101 |
current_label_type = label_dos; |
current_label_type = LABEL_DOS; |
102 |
sun_other_endian = 0; |
sun_other_endian = 0; |
103 |
return 0; |
return 0; |
104 |
} |
} |
106 |
ush = ((unsigned short *) (sunlabel + 1)) - 1; |
ush = ((unsigned short *) (sunlabel + 1)) - 1; |
107 |
for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; |
for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; |
108 |
if (csum) { |
if (csum) { |
109 |
fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n" |
printf("Detected sun disklabel with wrong checksum.\n" |
110 |
"Probably you'll have to set all the values,\n" |
"Probably you'll have to set all the values,\n" |
111 |
"e.g. heads, sectors, cylinders and partitions\n" |
"e.g. heads, sectors, cylinders and partitions\n" |
112 |
"or force a fresh label (s command in main menu)\n")); |
"or force a fresh label (s command in main menu)\n"); |
113 |
} else { |
} else { |
114 |
heads = SUN_SSWAP16(sunlabel->ntrks); |
g_heads = SUN_SSWAP16(sunlabel->ntrks); |
115 |
cylinders = SUN_SSWAP16(sunlabel->ncyl); |
g_cylinders = SUN_SSWAP16(sunlabel->ncyl); |
116 |
sectors = SUN_SSWAP16(sunlabel->nsect); |
g_sectors = SUN_SSWAP16(sunlabel->nsect); |
117 |
} |
} |
118 |
update_units(); |
update_units(); |
119 |
current_label_type = label_sun; |
current_label_type = LABEL_SUN; |
120 |
partitions = 8; |
g_partitions = 8; |
121 |
return 1; |
return 1; |
122 |
} |
} |
123 |
|
|
168 |
char *q; |
char *q; |
169 |
int i; |
int i; |
170 |
|
|
171 |
if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) |
if (ioctl(dev_fd, SCSI_IOCTL_GET_IDLUN, &id)) |
172 |
return NULL; |
return NULL; |
173 |
|
|
174 |
sprintf(buffer, |
sprintf(buffer, |
181 |
id[0] & 0xff, |
id[0] & 0xff, |
182 |
(id[0]>>8) & 0xff |
(id[0]>>8) & 0xff |
183 |
); |
); |
184 |
pfd = fopen("/proc/scsi/scsi", "r"); |
pfd = fopen_for_read("/proc/scsi/scsi"); |
185 |
if (!pfd) { |
if (!pfd) { |
186 |
return NULL; |
return NULL; |
187 |
} |
} |
207 |
if (!q) |
if (!q) |
208 |
break; |
break; |
209 |
*q = '\0'; |
*q = '\0'; |
210 |
for (i = 0; i < SIZE(sun_drives); i++) { |
for (i = 0; i < ARRAY_SIZE(sun_drives); i++) { |
211 |
if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor)) |
if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor)) |
212 |
continue; |
continue; |
213 |
if (!strstr(model, sun_drives[i].model)) |
if (!strstr(model, sun_drives[i].model)) |
214 |
continue; |
continue; |
215 |
printf(_("Autoconfigure found a %s%s%s\n"), |
printf("Autoconfigure found a %s%s%s\n", |
216 |
sun_drives[i].vendor, |
sun_drives[i].vendor, |
217 |
(*sun_drives[i].vendor) ? " " : "", |
(*sun_drives[i].vendor) ? " " : "", |
218 |
sun_drives[i].model); |
sun_drives[i].model); |
230 |
create_sunlabel(void) |
create_sunlabel(void) |
231 |
{ |
{ |
232 |
struct hd_geometry geometry; |
struct hd_geometry geometry; |
233 |
unsigned int ndiv; |
unsigned ndiv; |
|
int i; |
|
234 |
unsigned char c; |
unsigned char c; |
235 |
const struct sun_predefined_drives *p = NULL; |
const struct sun_predefined_drives *p = NULL; |
236 |
|
|
237 |
fprintf(stderr, |
printf(msg_building_new_label, "sun disklabel"); |
238 |
_("Building a new sun disklabel. Changes will remain in memory only,\n" |
|
|
"until you decide to write them. After that, of course, the previous\n" |
|
|
"content won't be recoverable.\n\n")); |
|
239 |
sun_other_endian = BB_LITTLE_ENDIAN; |
sun_other_endian = BB_LITTLE_ENDIAN; |
240 |
memset(MBRbuffer, 0, sizeof(MBRbuffer)); |
memset(MBRbuffer, 0, sizeof(MBRbuffer)); |
241 |
sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC); |
sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC); |
242 |
if (!floppy) { |
if (!floppy) { |
243 |
puts(_("Drive type\n" |
unsigned i; |
244 |
|
puts("Drive type\n" |
245 |
" ? auto configure\n" |
" ? auto configure\n" |
246 |
" 0 custom (with hardware detected defaults)")); |
" 0 custom (with hardware detected defaults)"); |
247 |
for (i = 0; i < SIZE(sun_drives); i++) { |
for (i = 0; i < ARRAY_SIZE(sun_drives); i++) { |
248 |
printf(" %c %s%s%s\n", |
printf(" %c %s%s%s\n", |
249 |
i + 'a', sun_drives[i].vendor, |
i + 'a', sun_drives[i].vendor, |
250 |
(*sun_drives[i].vendor) ? " " : "", |
(*sun_drives[i].vendor) ? " " : "", |
251 |
sun_drives[i].model); |
sun_drives[i].model); |
252 |
} |
} |
253 |
while (1) { |
while (1) { |
254 |
c = read_nonempty(_("Select type (? for auto, 0 for custom): ")); |
c = read_nonempty("Select type (? for auto, 0 for custom): "); |
255 |
if (c >= 'a' && c < 'a' + SIZE(sun_drives)) { |
if (c == '0') { |
256 |
|
break; |
257 |
|
} |
258 |
|
if (c >= 'a' && c < 'a' + ARRAY_SIZE(sun_drives)) { |
259 |
p = sun_drives + c - 'a'; |
p = sun_drives + c - 'a'; |
260 |
break; |
break; |
261 |
} else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) { |
} |
262 |
|
if (c >= 'A' && c < 'A' + ARRAY_SIZE(sun_drives)) { |
263 |
p = sun_drives + c - 'A'; |
p = sun_drives + c - 'A'; |
264 |
break; |
break; |
265 |
} else if (c == '0') { |
} |
266 |
break; |
if (c == '?' && scsi_disk) { |
|
} else if (c == '?' && scsi_disk) { |
|
267 |
p = sun_autoconfigure_scsi(); |
p = sun_autoconfigure_scsi(); |
268 |
if (!p) |
if (p) |
269 |
printf(_("Autoconfigure failed.\n")); |
break; |
270 |
else |
printf("Autoconfigure failed\n"); |
|
break; |
|
271 |
} |
} |
272 |
} |
} |
273 |
} |
} |
274 |
if (!p || floppy) { |
if (!p || floppy) { |
275 |
if (!ioctl(fd, HDIO_GETGEO, &geometry)) { |
if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { |
276 |
heads = geometry.heads; |
g_heads = geometry.heads; |
277 |
sectors = geometry.sectors; |
g_sectors = geometry.sectors; |
278 |
cylinders = geometry.cylinders; |
g_cylinders = geometry.cylinders; |
279 |
} else { |
} else { |
280 |
heads = 0; |
g_heads = 0; |
281 |
sectors = 0; |
g_sectors = 0; |
282 |
cylinders = 0; |
g_cylinders = 0; |
283 |
} |
} |
284 |
if (floppy) { |
if (floppy) { |
285 |
sunlabel->nacyl = 0; |
sunlabel->nacyl = 0; |
286 |
sunlabel->pcylcount = SUN_SSWAP16(cylinders); |
sunlabel->pcylcount = SUN_SSWAP16(g_cylinders); |
287 |
sunlabel->rspeed = SUN_SSWAP16(300); |
sunlabel->rspeed = SUN_SSWAP16(300); |
288 |
sunlabel->ilfact = SUN_SSWAP16(1); |
sunlabel->ilfact = SUN_SSWAP16(1); |
289 |
sunlabel->sparecyl = 0; |
sunlabel->sparecyl = 0; |
290 |
} else { |
} else { |
291 |
heads = read_int(1,heads,1024,0,_("Heads")); |
g_heads = read_int(1, g_heads, 1024, 0, "Heads"); |
292 |
sectors = read_int(1,sectors,1024,0,_("Sectors/track")); |
g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track"); |
293 |
if (cylinders) |
if (g_cylinders) |
294 |
cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders")); |
g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders"); |
295 |
else |
else |
296 |
cylinders = read_int(1,0,65535,0,_("Cylinders")); |
g_cylinders = read_int(1, 0, 65535, 0, "Cylinders"); |
297 |
sunlabel->nacyl = SUN_SSWAP16(read_int(0,2,65535,0, _("Alternate cylinders"))); |
sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders")); |
298 |
sunlabel->pcylcount = SUN_SSWAP16(read_int(0,cylinders+SUN_SSWAP16(sunlabel->nacyl), 65535,0, _("Physical cylinders"))); |
sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders")); |
299 |
sunlabel->rspeed = SUN_SSWAP16(read_int(1,5400,100000,0, _("Rotation speed (rpm)"))); |
sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)")); |
300 |
sunlabel->ilfact = SUN_SSWAP16(read_int(1,1,32,0, _("Interleave factor"))); |
sunlabel->ilfact = SUN_SSWAP16(read_int(1, 1, 32, 0, "Interleave factor")); |
301 |
sunlabel->sparecyl = SUN_SSWAP16(read_int(0,0,sectors,0, _("Extra sectors per cylinder"))); |
sunlabel->sparecyl = SUN_SSWAP16(read_int(0, 0, g_sectors, 0, "Extra sectors per cylinder")); |
302 |
} |
} |
303 |
} else { |
} else { |
304 |
sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl); |
sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl); |
309 |
sunlabel->nsect = SUN_SSWAP16(p->nsect); |
sunlabel->nsect = SUN_SSWAP16(p->nsect); |
310 |
sunlabel->rspeed = SUN_SSWAP16(p->rspeed); |
sunlabel->rspeed = SUN_SSWAP16(p->rspeed); |
311 |
sunlabel->ilfact = SUN_SSWAP16(1); |
sunlabel->ilfact = SUN_SSWAP16(1); |
312 |
cylinders = p->ncyl; |
g_cylinders = p->ncyl; |
313 |
heads = p->ntrks; |
g_heads = p->ntrks; |
314 |
sectors = p->nsect; |
g_sectors = p->nsect; |
315 |
puts(_("You may change all the disk params from the x menu")); |
puts("You may change all the disk params from the x menu"); |
316 |
} |
} |
317 |
|
|
318 |
snprintf((char *)(sunlabel->info), sizeof(sunlabel->info), |
snprintf((char *)(sunlabel->info), sizeof(sunlabel->info), |
319 |
"%s%s%s cyl %d alt %d hd %d sec %d", |
"%s%s%s cyl %d alt %d hd %d sec %d", |
320 |
p ? p->vendor : "", (p && *p->vendor) ? " " : "", |
p ? p->vendor : "", (p && *p->vendor) ? " " : "", |
321 |
p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")), |
p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"), |
322 |
cylinders, SUN_SSWAP16(sunlabel->nacyl), heads, sectors); |
g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors); |
323 |
|
|
324 |
sunlabel->ntrks = SUN_SSWAP16(heads); |
sunlabel->ntrks = SUN_SSWAP16(g_heads); |
325 |
sunlabel->nsect = SUN_SSWAP16(sectors); |
sunlabel->nsect = SUN_SSWAP16(g_sectors); |
326 |
sunlabel->ncyl = SUN_SSWAP16(cylinders); |
sunlabel->ncyl = SUN_SSWAP16(g_cylinders); |
327 |
if (floppy) |
if (floppy) |
328 |
set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE); |
set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE); |
329 |
else { |
else { |
330 |
if (cylinders * heads * sectors >= 150 * 2048) { |
if (g_cylinders * g_heads * g_sectors >= 150 * 2048) { |
331 |
ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */ |
ndiv = g_cylinders - (50 * 2048 / (g_heads * g_sectors)); /* 50M swap */ |
332 |
} else |
} else |
333 |
ndiv = cylinders * 2 / 3; |
ndiv = g_cylinders * 2 / 3; |
334 |
set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE); |
set_sun_partition(0, 0, ndiv * g_heads * g_sectors, LINUX_NATIVE); |
335 |
set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP); |
set_sun_partition(1, ndiv * g_heads * g_sectors, g_cylinders * g_heads * g_sectors, LINUX_SWAP); |
336 |
sunlabel->infos[1].flags |= 0x01; /* Not mountable */ |
sunlabel->infos[1].flags |= 0x01; /* Not mountable */ |
337 |
} |
} |
338 |
set_sun_partition(2, 0, cylinders * heads * sectors, SUN_WHOLE_DISK); |
set_sun_partition(2, 0, g_cylinders * g_heads * g_sectors, SUN_WHOLE_DISK); |
339 |
{ |
{ |
340 |
unsigned short *ush = (unsigned short *)sunlabel; |
unsigned short *ush = (unsigned short *)sunlabel; |
341 |
unsigned short csum = 0; |
unsigned short csum = 0; |
346 |
|
|
347 |
set_all_unchanged(); |
set_all_unchanged(); |
348 |
set_changed(0); |
set_changed(0); |
349 |
get_boot(create_empty_sun); |
get_boot(CREATE_EMPTY_SUN); |
350 |
} |
} |
351 |
|
|
352 |
static void |
static void |
365 |
int i, continuous = 1; |
int i, continuous = 1; |
366 |
|
|
367 |
*start = 0; |
*start = 0; |
368 |
*stop = cylinders * heads * sectors; |
*stop = g_cylinders * g_heads * g_sectors; |
369 |
for (i = 0; i < partitions; i++) { |
for (i = 0; i < g_partitions; i++) { |
370 |
if (sunlabel->partitions[i].num_sectors |
if (sunlabel->partitions[i].num_sectors |
371 |
&& sunlabel->infos[i].id |
&& sunlabel->infos[i].id |
372 |
&& sunlabel->infos[i].id != SUN_WHOLE_DISK) { |
&& sunlabel->infos[i].id != SUN_WHOLE_DISK) { |
373 |
starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; |
starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors; |
374 |
lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); |
lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); |
375 |
if (continuous) { |
if (continuous) { |
376 |
if (starts[i] == *start) |
if (starts[i] == *start) |
408 |
int array[8]; |
int array[8]; |
409 |
|
|
410 |
verify_sun_starts = starts; |
verify_sun_starts = starts; |
411 |
fetch_sun(starts,lens,&start,&stop); |
fetch_sun(starts, lens, &start, &stop); |
412 |
for (k = 0; k < 7; k++) { |
for (k = 0; k < 7; k++) { |
413 |
for (i = 0; i < 8; i++) { |
for (i = 0; i < 8; i++) { |
414 |
if (k && (lens[i] % (heads * sectors))) { |
if (k && (lens[i] % (g_heads * g_sectors))) { |
415 |
printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1); |
printf("Partition %d doesn't end on cylinder boundary\n", i+1); |
416 |
} |
} |
417 |
if (lens[i]) { |
if (lens[i]) { |
418 |
for (j = 0; j < i; j++) |
for (j = 0; j < i; j++) |
432 |
endo = starts[i]+lens[i]; |
endo = starts[i]+lens[i]; |
433 |
if (starts[j]+lens[j] < endo) |
if (starts[j]+lens[j] < endo) |
434 |
endo = starts[j]+lens[j]; |
endo = starts[j]+lens[j]; |
435 |
printf(_("Partition %d overlaps with others in " |
printf("Partition %d overlaps with others in " |
436 |
"sectors %d-%d\n"), i+1, starto, endo); |
"sectors %d-%d\n", i+1, starto, endo); |
437 |
} |
} |
438 |
} |
} |
439 |
} |
} |
446 |
else |
else |
447 |
array[i] = -1; |
array[i] = -1; |
448 |
} |
} |
449 |
qsort(array,SIZE(array),sizeof(array[0]), |
qsort(array, ARRAY_SIZE(array), sizeof(array[0]), |
450 |
(int (*)(const void *,const void *)) verify_sun_cmp); |
(int (*)(const void *,const void *)) verify_sun_cmp); |
451 |
if (array[0] == -1) { |
if (array[0] == -1) { |
452 |
printf(_("No partitions defined\n")); |
printf("No partitions defined\n"); |
453 |
return; |
return; |
454 |
} |
} |
455 |
stop = cylinders * heads * sectors; |
stop = g_cylinders * g_heads * g_sectors; |
456 |
if (starts[array[0]]) |
if (starts[array[0]]) |
457 |
printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]); |
printf("Unused gap - sectors 0-%d\n", starts[array[0]]); |
458 |
for (i = 0; i < 7 && array[i+1] != -1; i++) { |
for (i = 0; i < 7 && array[i+1] != -1; i++) { |
459 |
printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]); |
printf("Unused gap - sectors %d-%d\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]); |
460 |
} |
} |
461 |
start = starts[array[i]] + lens[array[i]]; |
start = starts[array[i]] + lens[array[i]]; |
462 |
if (start < stop) |
if (start < stop) |
463 |
printf(_("Unused gap - sectors %d-%d\n"),start,stop); |
printf("Unused gap - sectors %d-%d\n", start, stop); |
464 |
} |
} |
465 |
|
|
466 |
static void |
static void |
474 |
int i, first, last; |
int i, first, last; |
475 |
|
|
476 |
if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) { |
if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) { |
477 |
printf(_("Partition %d is already defined. Delete " |
printf(msg_part_already_defined, n + 1); |
|
"it before re-adding it.\n"), n + 1); |
|
478 |
return; |
return; |
479 |
} |
} |
480 |
|
|
483 |
if (n == 2) |
if (n == 2) |
484 |
whole_disk = 1; |
whole_disk = 1; |
485 |
else { |
else { |
486 |
printf(_("Other partitions already cover the whole disk.\nDelete " |
printf("Other partitions already cover the whole disk.\n" |
487 |
"some/shrink them before retry.\n")); |
"Delete/shrink them before retry.\n"); |
488 |
return; |
return; |
489 |
} |
} |
490 |
} |
} |
491 |
snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); |
snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); |
492 |
while (1) { |
while (1) { |
493 |
if (whole_disk) |
if (whole_disk) |
494 |
first = read_int(0, 0, 0, 0, mesg); |
first = read_int(0, 0, 0, 0, mesg); |
499 |
first *= units_per_sector; |
first *= units_per_sector; |
500 |
else |
else |
501 |
/* Starting sector has to be properly aligned */ |
/* Starting sector has to be properly aligned */ |
502 |
first = (first + heads * sectors - 1) / (heads * sectors); |
first = (first + g_heads * g_sectors - 1) / (g_heads * g_sectors); |
503 |
if (n == 2 && first != 0) |
if (n == 2 && first != 0) |
504 |
printf("\ |
printf("\ |
505 |
It is highly recommended that the third partition covers the whole disk\n\ |
It is highly recommended that the third partition covers the whole disk\n\ |
506 |
and is of type `Whole disk'\n"); |
and is of type 'Whole disk'\n"); |
507 |
/* ewt asks to add: "don't start a partition at cyl 0" |
/* ewt asks to add: "don't start a partition at cyl 0" |
508 |
However, edmundo@rano.demon.co.uk writes: |
However, edmundo@rano.demon.co.uk writes: |
509 |
"In addition to having a Sun partition table, to be able to |
"In addition to having a Sun partition table, to be able to |
520 |
/* On the other hand, one should not use partitions |
/* On the other hand, one should not use partitions |
521 |
starting at block 0 in an md, or the label will |
starting at block 0 in an md, or the label will |
522 |
be trashed. */ |
be trashed. */ |
523 |
for (i = 0; i < partitions; i++) |
for (i = 0; i < g_partitions; i++) |
524 |
if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) |
if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) |
525 |
break; |
break; |
526 |
if (i < partitions && !whole_disk) { |
if (i < g_partitions && !whole_disk) { |
527 |
if (n == 2 && !first) { |
if (n == 2 && !first) { |
528 |
whole_disk = 1; |
whole_disk = 1; |
529 |
break; |
break; |
530 |
} |
} |
531 |
printf(_("Sector %d is already allocated\n"), first); |
printf("Sector %d is already allocated\n", first); |
532 |
} else |
} else |
533 |
break; |
break; |
534 |
} |
} |
535 |
stop = cylinders * heads * sectors; |
stop = g_cylinders * g_heads * g_sectors; |
536 |
stop2 = stop; |
stop2 = stop; |
537 |
for (i = 0; i < partitions; i++) { |
for (i = 0; i < g_partitions; i++) { |
538 |
if (starts[i] > first && starts[i] < stop) |
if (starts[i] > first && starts[i] < stop) |
539 |
stop = starts[i]; |
stop = starts[i]; |
540 |
} |
} |
541 |
snprintf(mesg, sizeof(mesg), |
snprintf(mesg, sizeof(mesg), |
542 |
_("Last %s or +size or +sizeM or +sizeK"), |
"Last %s or +size or +sizeM or +sizeK", |
543 |
str_units(SINGULAR)); |
str_units(SINGULAR)); |
544 |
if (whole_disk) |
if (whole_disk) |
545 |
last = read_int(scround(stop2), scround(stop2), scround(stop2), |
last = read_int(scround(stop2), scround(stop2), scround(stop2), |
557 |
whole_disk = 1; |
whole_disk = 1; |
558 |
last = stop2; |
last = stop2; |
559 |
} else if (last > stop) { |
} else if (last > stop) { |
560 |
printf(_("You haven't covered the whole disk with " |
printf( |
561 |
"the 3rd partition, but your value\n" |
"You haven't covered the whole disk with the 3rd partition,\n" |
562 |
"%d %s covers some other partition. " |
"but your value %d %s covers some other partition.\n" |
563 |
"Your entry has been changed\n" |
"Your entry has been changed to %d %s\n", |
|
"to %d %s\n"), |
|
564 |
scround(last), str_units(SINGULAR), |
scround(last), str_units(SINGULAR), |
565 |
scround(stop), str_units(SINGULAR)); |
scround(stop), str_units(SINGULAR)); |
566 |
last = stop; |
last = stop; |
581 |
if (i == 2 |
if (i == 2 |
582 |
&& sunlabel->infos[i].id == SUN_WHOLE_DISK |
&& sunlabel->infos[i].id == SUN_WHOLE_DISK |
583 |
&& !sunlabel->partitions[i].start_cylinder |
&& !sunlabel->partitions[i].start_cylinder |
584 |
&& (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders) |
&& (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == g_heads * g_sectors * g_cylinders) |
585 |
printf(_("If you want to maintain SunOS/Solaris compatibility, " |
printf("If you want to maintain SunOS/Solaris compatibility, " |
586 |
"consider leaving this\n" |
"consider leaving this\n" |
587 |
"partition as Whole disk (5), starting at 0, with %u " |
"partition as Whole disk (5), starting at 0, with %u " |
588 |
"sectors\n"), nsec); |
"sectors\n", nsec); |
589 |
sunlabel->infos[i].id = 0; |
sunlabel->infos[i].id = 0; |
590 |
sunlabel->partitions[i].num_sectors = 0; |
sunlabel->partitions[i].num_sectors = 0; |
591 |
} |
} |
595 |
{ |
{ |
596 |
if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) { |
if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) { |
597 |
read_maybe_empty( |
read_maybe_empty( |
598 |
_("It is highly recommended that the partition at offset 0\n" |
"It is highly recommended that the partition at offset 0\n" |
599 |
"is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" |
"is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" |
600 |
"there may destroy your partition table and bootblock.\n" |
"there may destroy your partition table and bootblock.\n" |
601 |
"Type YES if you're very sure you would like that partition\n" |
"Type YES if you're very sure you would like that partition\n" |
602 |
"tagged with 82 (Linux swap): ")); |
"tagged with 82 (Linux swap): "); |
603 |
if (strcmp (line_ptr, _("YES\n"))) |
if (strcmp (line_ptr, "YES\n")) |
604 |
return; |
return; |
605 |
} |
} |
606 |
switch (sys) { |
switch (sys) { |
626 |
w = strlen(disk_device); |
w = strlen(disk_device); |
627 |
if (xtra) |
if (xtra) |
628 |
printf( |
printf( |
629 |
_("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n" |
"\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n" |
630 |
"%d cylinders, %d alternate cylinders, %d physical cylinders\n" |
"%d cylinders, %d alternate cylinders, %d physical cylinders\n" |
631 |
"%d extra sects/cyl, interleave %d:1\n" |
"%d extra sects/cyl, interleave %d:1\n" |
632 |
"%s\n" |
"%s\n" |
633 |
"Units = %s of %d * 512 bytes\n\n"), |
"Units = %s of %d * 512 bytes\n\n", |
634 |
disk_device, heads, sectors, SUN_SSWAP16(sunlabel->rspeed), |
disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed), |
635 |
cylinders, SUN_SSWAP16(sunlabel->nacyl), |
g_cylinders, SUN_SSWAP16(sunlabel->nacyl), |
636 |
SUN_SSWAP16(sunlabel->pcylcount), |
SUN_SSWAP16(sunlabel->pcylcount), |
637 |
SUN_SSWAP16(sunlabel->sparecyl), |
SUN_SSWAP16(sunlabel->sparecyl), |
638 |
SUN_SSWAP16(sunlabel->ilfact), |
SUN_SSWAP16(sunlabel->ilfact), |
640 |
str_units(PLURAL), units_per_sector); |
str_units(PLURAL), units_per_sector); |
641 |
else |
else |
642 |
printf( |
printf( |
643 |
_("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n" |
"\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n" |
644 |
"Units = %s of %d * 512 bytes\n\n"), |
"Units = %s of %d * 512 bytes\n\n", |
645 |
disk_device, heads, sectors, cylinders, |
disk_device, g_heads, g_sectors, g_cylinders, |
646 |
str_units(PLURAL), units_per_sector); |
str_units(PLURAL), units_per_sector); |
647 |
|
|
648 |
printf(_("%*s Flag Start End Blocks Id System\n"), |
printf("%*s Flag Start End Blocks Id System\n", |
649 |
w + 1, _("Device")); |
w + 1, "Device"); |
650 |
for (i = 0 ; i < partitions; i++) { |
for (i = 0; i < g_partitions; i++) { |
651 |
if (sunlabel->partitions[i].num_sectors) { |
if (sunlabel->partitions[i].num_sectors) { |
652 |
uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; |
uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors; |
653 |
uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); |
uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); |
654 |
printf("%s %c%c %9ld %9ld %9ld%c %2x %s\n", |
printf("%s %c%c %9ld %9ld %9ld%c %2x %s\n", |
655 |
partname(disk_device, i+1, w), /* device */ |
partname(disk_device, i+1, w), /* device */ |
670 |
sun_set_alt_cyl(void) |
sun_set_alt_cyl(void) |
671 |
{ |
{ |
672 |
sunlabel->nacyl = |
sunlabel->nacyl = |
673 |
SUN_SSWAP16(read_int(0,SUN_SSWAP16(sunlabel->nacyl), 65535, 0, |
SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->nacyl), 65535, 0, |
674 |
_("Number of alternate cylinders"))); |
"Number of alternate cylinders")); |
675 |
} |
} |
676 |
|
|
677 |
static void |
static void |
684 |
sun_set_xcyl(void) |
sun_set_xcyl(void) |
685 |
{ |
{ |
686 |
sunlabel->sparecyl = |
sunlabel->sparecyl = |
687 |
SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), sectors, 0, |
SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), g_sectors, 0, |
688 |
_("Extra sectors per cylinder"))); |
"Extra sectors per cylinder")); |
689 |
} |
} |
690 |
|
|
691 |
static void |
static void |
693 |
{ |
{ |
694 |
sunlabel->ilfact = |
sunlabel->ilfact = |
695 |
SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0, |
SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0, |
696 |
_("Interleave factor"))); |
"Interleave factor")); |
697 |
} |
} |
698 |
|
|
699 |
static void |
static void |
701 |
{ |
{ |
702 |
sunlabel->rspeed = |
sunlabel->rspeed = |
703 |
SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0, |
SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0, |
704 |
_("Rotation speed (rpm)"))); |
"Rotation speed (rpm)")); |
705 |
} |
} |
706 |
|
|
707 |
static void |
static void |
709 |
{ |
{ |
710 |
sunlabel->pcylcount = |
sunlabel->pcylcount = |
711 |
SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0, |
SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0, |
712 |
_("Number of physical cylinders"))); |
"Number of physical cylinders")); |
713 |
} |
} |
714 |
#endif /* FEATURE_FDISK_ADVANCED */ |
#endif /* FEATURE_FDISK_ADVANCED */ |
715 |
|
|
722 |
while (ush < (unsigned short *)(&sunlabel->csum)) |
while (ush < (unsigned short *)(&sunlabel->csum)) |
723 |
csum ^= *ush++; |
csum ^= *ush++; |
724 |
sunlabel->csum = csum; |
sunlabel->csum = csum; |
725 |
if (lseek(fd, 0, SEEK_SET) < 0) |
write_sector(0, sunlabel); |
|
fdisk_fatal(unable_to_seek); |
|
|
if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE) |
|
|
fdisk_fatal(unable_to_write); |
|
726 |
} |
} |
727 |
#endif /* SUN_LABEL */ |
#endif /* SUN_LABEL */ |