1 |
#if ENABLE_FEATURE_SGI_LABEL |
#if ENABLE_FEATURE_SGI_LABEL |
2 |
|
|
3 |
|
#define SGI_DEBUG 0 |
4 |
|
|
5 |
/* |
/* |
6 |
* Copyright (C) Andreas Neuper, Sep 1998. |
* Copyright (C) Andreas Neuper, Sep 1998. |
7 |
* This file may be modified and redistributed under |
* This file may be modified and redistributed under |
8 |
* the terms of the GNU Public License. |
* the terms of the GNU Public License. |
9 |
*/ |
*/ |
10 |
|
|
11 |
|
#define SGI_VOLHDR 0x00 |
12 |
|
/* 1 and 2 were used for drive types no longer supported by SGI */ |
13 |
|
#define SGI_SWAP 0x03 |
14 |
|
/* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */ |
15 |
|
#define SGI_VOLUME 0x06 |
16 |
|
#define SGI_EFS 0x07 |
17 |
|
#define SGI_LVOL 0x08 |
18 |
|
#define SGI_RLVOL 0x09 |
19 |
|
#define SGI_XFS 0x0a |
20 |
|
#define SGI_XFSLOG 0x0b |
21 |
|
#define SGI_XLV 0x0c |
22 |
|
#define SGI_XVM 0x0d |
23 |
|
#define SGI_ENTIRE_DISK SGI_VOLUME |
24 |
|
|
25 |
struct device_parameter { /* 48 bytes */ |
struct device_parameter { /* 48 bytes */ |
26 |
unsigned char skew; |
unsigned char skew; |
27 |
unsigned char gap1; |
unsigned char gap1; |
119 |
*/ |
*/ |
120 |
|
|
121 |
|
|
122 |
static int sgi_other_endian; |
static smallint sgi_other_endian; /* bool */ |
123 |
static int debug; |
static smallint sgi_volumes = 1; /* max 15 */ |
|
static short sgi_volumes = 1; |
|
124 |
|
|
125 |
/* |
/* |
126 |
* only dealing with free blocks here |
* only dealing with free blocks here |
143 |
add2freelist(unsigned int f, unsigned int l) |
add2freelist(unsigned int f, unsigned int l) |
144 |
{ |
{ |
145 |
int i; |
int i; |
146 |
for (i = 0; i < 17 ; i++) |
for (i = 0; i < 17; i++) |
147 |
if (freelist[i].last == 0) |
if (freelist[i].last == 0) |
148 |
break; |
break; |
149 |
setfreelist(i, f, l); |
setfreelist(i, f, l); |
154 |
{ |
{ |
155 |
int i; |
int i; |
156 |
|
|
157 |
for (i = 0; i < 17 ; i++) |
for (i = 0; i < 17; i++) |
158 |
setfreelist(i, 0, 0); |
setfreelist(i, 0, 0); |
159 |
} |
} |
160 |
|
|
163 |
{ |
{ |
164 |
int i; |
int i; |
165 |
|
|
166 |
for (i = 0; i < 17 ; i++) |
for (i = 0; i < 17; i++) |
167 |
if (freelist[i].first <= b && freelist[i].last >= b) |
if (freelist[i].first <= b && freelist[i].last >= b) |
168 |
return freelist[i].last; |
return freelist[i].last; |
169 |
return 0; |
return 0; |
174 |
* end of free blocks section |
* end of free blocks section |
175 |
*/ |
*/ |
176 |
|
|
177 |
static const struct systypes sgi_sys_types[] = { |
static const char *const sgi_sys_types[] = { |
178 |
/* SGI_VOLHDR */ { "\x00" "SGI volhdr" }, |
/* SGI_VOLHDR */ "\x00" "SGI volhdr" , |
179 |
/* 0x01 */ { "\x01" "SGI trkrepl" }, |
/* 0x01 */ "\x01" "SGI trkrepl" , |
180 |
/* 0x02 */ { "\x02" "SGI secrepl" }, |
/* 0x02 */ "\x02" "SGI secrepl" , |
181 |
/* SGI_SWAP */ { "\x03" "SGI raw" }, |
/* SGI_SWAP */ "\x03" "SGI raw" , |
182 |
/* 0x04 */ { "\x04" "SGI bsd" }, |
/* 0x04 */ "\x04" "SGI bsd" , |
183 |
/* 0x05 */ { "\x05" "SGI sysv" }, |
/* 0x05 */ "\x05" "SGI sysv" , |
184 |
/* SGI_ENTIRE_DISK */ { "\x06" "SGI volume" }, |
/* SGI_ENTIRE_DISK */ "\x06" "SGI volume" , |
185 |
/* SGI_EFS */ { "\x07" "SGI efs" }, |
/* SGI_EFS */ "\x07" "SGI efs" , |
186 |
/* 0x08 */ { "\x08" "SGI lvol" }, |
/* 0x08 */ "\x08" "SGI lvol" , |
187 |
/* 0x09 */ { "\x09" "SGI rlvol" }, |
/* 0x09 */ "\x09" "SGI rlvol" , |
188 |
/* SGI_XFS */ { "\x0a" "SGI xfs" }, |
/* SGI_XFS */ "\x0a" "SGI xfs" , |
189 |
/* SGI_XFSLOG */ { "\x0b" "SGI xfslog" }, |
/* SGI_XFSLOG */ "\x0b" "SGI xfslog" , |
190 |
/* SGI_XLV */ { "\x0c" "SGI xlv" }, |
/* SGI_XLV */ "\x0c" "SGI xlv" , |
191 |
/* SGI_XVM */ { "\x0d" "SGI xvm" }, |
/* SGI_XVM */ "\x0d" "SGI xvm" , |
192 |
/* LINUX_SWAP */ { "\x82" "Linux swap" }, |
/* LINUX_SWAP */ "\x82" "Linux swap" , |
193 |
/* LINUX_NATIVE */ { "\x83" "Linux native" }, |
/* LINUX_NATIVE */ "\x83" "Linux native", |
194 |
/* LINUX_LVM */ { "\x8d" "Linux LVM" }, |
/* LINUX_LVM */ "\x8d" "Linux LVM" , |
195 |
/* LINUX_RAID */ { "\xfd" "Linux RAID" }, |
/* LINUX_RAID */ "\xfd" "Linux RAID" , |
196 |
{ NULL } |
NULL |
197 |
}; |
}; |
198 |
|
|
199 |
|
|
221 |
return sum; |
return sum; |
222 |
} |
} |
223 |
|
|
224 |
|
void BUG_bad_sgi_partition_size(void); |
225 |
|
|
226 |
static int |
static int |
227 |
check_sgi_label(void) |
check_sgi_label(void) |
228 |
{ |
{ |
229 |
if (sizeof(sgilabel) > 512) { |
if (sizeof(sgi_partition) > 512) { |
230 |
fprintf(stderr, |
/* According to MIPS Computer Systems, Inc the label |
231 |
_("According to MIPS Computer Systems, Inc the " |
* must not contain more than 512 bytes */ |
232 |
"Label must not contain more than 512 bytes\n")); |
BUG_bad_sgi_partition_size(); |
|
exit(1); |
|
233 |
} |
} |
234 |
|
|
235 |
if (sgilabel->magic != SGI_LABEL_MAGIC |
if (sgilabel->magic != SGI_LABEL_MAGIC |
236 |
&& sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED) { |
&& sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED |
237 |
current_label_type = label_dos; |
) { |
238 |
|
current_label_type = LABEL_DOS; |
239 |
return 0; |
return 0; |
240 |
} |
} |
241 |
|
|
245 |
*/ |
*/ |
246 |
if (two_s_complement_32bit_sum((unsigned int*)sgilabel, |
if (two_s_complement_32bit_sum((unsigned int*)sgilabel, |
247 |
sizeof(*sgilabel))) { |
sizeof(*sgilabel))) { |
248 |
fprintf(stderr, |
printf("Detected sgi disklabel with wrong checksum\n"); |
|
_("Detected sgi disklabel with wrong checksum.\n")); |
|
249 |
} |
} |
250 |
update_units(); |
update_units(); |
251 |
current_label_type = label_sgi; |
current_label_type = LABEL_SGI; |
252 |
partitions = 16; |
g_partitions = 16; |
253 |
sgi_volumes = 15; |
sgi_volumes = 15; |
254 |
return 1; |
return 1; |
255 |
} |
} |
290 |
int i, w, wd; |
int i, w, wd; |
291 |
int kpi = 0; /* kernel partition ID */ |
int kpi = 0; /* kernel partition ID */ |
292 |
|
|
293 |
if(xtra) { |
if (xtra) { |
294 |
printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n" |
printf("\nDisk %s (SGI disk label): %d heads, %d sectors\n" |
295 |
"%d cylinders, %d physical cylinders\n" |
"%d cylinders, %d physical cylinders\n" |
296 |
"%d extra sects/cyl, interleave %d:1\n" |
"%d extra sects/cyl, interleave %d:1\n" |
297 |
"%s\n" |
"%s\n" |
298 |
"Units = %s of %d * 512 bytes\n\n"), |
"Units = %s of %d * 512 bytes\n\n", |
299 |
disk_device, heads, sectors, cylinders, |
disk_device, g_heads, g_sectors, g_cylinders, |
300 |
SGI_SSWAP16(sgiparam.pcylcount), |
SGI_SSWAP16(sgiparam.pcylcount), |
301 |
SGI_SSWAP16(sgiparam.sparecyl), |
SGI_SSWAP16(sgiparam.sparecyl), |
302 |
SGI_SSWAP16(sgiparam.ilfact), |
SGI_SSWAP16(sgiparam.ilfact), |
303 |
(char *)sgilabel, |
(char *)sgilabel, |
304 |
str_units(PLURAL), units_per_sector); |
str_units(PLURAL), units_per_sector); |
305 |
} else { |
} else { |
306 |
printf( _("\nDisk %s (SGI disk label): " |
printf("\nDisk %s (SGI disk label): " |
307 |
"%d heads, %d sectors, %d cylinders\n" |
"%d heads, %d sectors, %d cylinders\n" |
308 |
"Units = %s of %d * 512 bytes\n\n"), |
"Units = %s of %d * 512 bytes\n\n", |
309 |
disk_device, heads, sectors, cylinders, |
disk_device, g_heads, g_sectors, g_cylinders, |
310 |
str_units(PLURAL), units_per_sector ); |
str_units(PLURAL), units_per_sector ); |
311 |
} |
} |
312 |
|
|
313 |
w = strlen(disk_device); |
w = strlen(disk_device); |
314 |
wd = strlen(_("Device")); |
wd = sizeof("Device") - 1; |
315 |
if (w < wd) |
if (w < wd) |
316 |
w = wd; |
w = wd; |
317 |
|
|
318 |
printf(_("----- partitions -----\n" |
printf("----- partitions -----\n" |
319 |
"Pt# %*s Info Start End Sectors Id System\n"), |
"Pt# %*s Info Start End Sectors Id System\n", |
320 |
w + 2, _("Device")); |
w + 2, "Device"); |
321 |
for (i = 0 ; i < partitions; i++) { |
for (i = 0; i < g_partitions; i++) { |
322 |
if( sgi_get_num_sectors(i) || debug ) { |
if (sgi_get_num_sectors(i) || SGI_DEBUG) { |
323 |
uint32_t start = sgi_get_start_sector(i); |
uint32_t start = sgi_get_start_sector(i); |
324 |
uint32_t len = sgi_get_num_sectors(i); |
uint32_t len = sgi_get_num_sectors(i); |
325 |
kpi++; /* only count nonempty partitions */ |
kpi++; /* only count nonempty partitions */ |
336 |
/* type name */ partition_type(sgi_get_sysid(i))); |
/* type name */ partition_type(sgi_get_sysid(i))); |
337 |
} |
} |
338 |
} |
} |
339 |
printf(_("----- Bootinfo -----\nBootfile: %s\n" |
printf("----- Bootinfo -----\nBootfile: %s\n" |
340 |
"----- Directory Entries -----\n"), |
"----- Directory Entries -----\n", |
341 |
sgilabel->boot_file); |
sgilabel->boot_file); |
342 |
for (i = 0 ; i < sgi_volumes; i++) { |
for (i = 0; i < sgi_volumes; i++) { |
343 |
if (sgilabel->directory[i].vol_file_size) { |
if (sgilabel->directory[i].vol_file_size) { |
344 |
uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start); |
uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start); |
345 |
uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size); |
uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size); |
346 |
unsigned char *name = sgilabel->directory[i].vol_file_name; |
unsigned char *name = sgilabel->directory[i].vol_file_name; |
347 |
|
|
348 |
printf(_("%2d: %-10s sector%5u size%8u\n"), |
printf("%2d: %-10s sector%5u size%8u\n", |
349 |
i, (char*)name, (unsigned int) start, (unsigned int) len); |
i, (char*)name, (unsigned int) start, (unsigned int) len); |
350 |
} |
} |
351 |
} |
} |
360 |
static unsigned int |
static unsigned int |
361 |
sgi_get_lastblock(void) |
sgi_get_lastblock(void) |
362 |
{ |
{ |
363 |
return heads * sectors * cylinders; |
return g_heads * g_sectors * g_cylinders; |
364 |
} |
} |
365 |
|
|
366 |
static void |
static void |
372 |
static int |
static int |
373 |
sgi_check_bootfile(const char* aFile) |
sgi_check_bootfile(const char* aFile) |
374 |
{ |
{ |
375 |
if (strlen(aFile) < 3) /* "/a\n" is minimum */ { |
if (strlen(aFile) < 3) /* "/a\n" is minimum */ { |
376 |
printf(_("\nInvalid Bootfile!\n" |
printf("\nInvalid Bootfile!\n" |
377 |
"\tThe bootfile must be an absolute non-zero pathname,\n" |
"\tThe bootfile must be an absolute non-zero pathname,\n" |
378 |
"\te.g. \"/unix\" or \"/unix.save\".\n")); |
"\te.g. \"/unix\" or \"/unix.save\".\n"); |
379 |
return 0; |
return 0; |
380 |
} else { |
} |
381 |
if (strlen(aFile) > 16) { |
if (strlen(aFile) > 16) { |
382 |
printf(_("\n\tName of Bootfile too long: " |
printf("\nName of Bootfile too long (>16 bytes)\n"); |
383 |
"16 bytes maximum.\n")); |
return 0; |
384 |
return 0; |
} |
385 |
} else { |
if (aFile[0] != '/') { |
386 |
if (aFile[0] != '/') { |
printf("\nBootfile must have a fully qualified pathname\n"); |
387 |
printf(_("\n\tBootfile must have a " |
return 0; |
388 |
"fully qualified pathname.\n")); |
} |
|
return 0; |
|
|
} |
|
|
} |
|
|
} |
|
389 |
if (strncmp(aFile, (char*)sgilabel->boot_file, 16)) { |
if (strncmp(aFile, (char*)sgilabel->boot_file, 16)) { |
390 |
printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t" |
printf("\nBe aware, that the bootfile is not checked for existence.\n" |
391 |
"SGI's default is \"/unix\" and for backup \"/unix.save\".\n")); |
"\tSGI's default is \"/unix\" and for backup \"/unix.save\".\n"); |
392 |
/* filename is correct and did change */ |
/* filename is correct and did change */ |
393 |
return 1; |
return 1; |
394 |
} |
} |
415 |
sgilabel->boot_file[i] = 0; |
sgilabel->boot_file[i] = 0; |
416 |
i++; |
i++; |
417 |
} |
} |
418 |
printf(_("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file); |
printf("\n\tBootfile is changed to \"%s\"\n", sgilabel->boot_file); |
419 |
} |
} |
420 |
} |
} |
421 |
|
|
439 |
assert(two_s_complement_32bit_sum( |
assert(two_s_complement_32bit_sum( |
440 |
(unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); |
(unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); |
441 |
|
|
442 |
if (lseek(fd, 0, SEEK_SET) < 0) |
write_sector(0, sgilabel); |
|
fdisk_fatal(unable_to_seek); |
|
|
if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE) |
|
|
fdisk_fatal(unable_to_write); |
|
443 |
if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { |
if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { |
444 |
/* |
/* |
445 |
* keep this habit of first writing the "sgilabel". |
* keep this habit of first writing the "sgilabel". |
447 |
*/ |
*/ |
448 |
sgiinfo *info = fill_sgiinfo(); |
sgiinfo *info = fill_sgiinfo(); |
449 |
int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); |
int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); |
450 |
if (lseek(fd, infostartblock*SECTOR_SIZE, SEEK_SET) < 0) |
write_sector(infostartblock, info); |
|
fdisk_fatal(unable_to_seek); |
|
|
if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE) |
|
|
fdisk_fatal(unable_to_write); |
|
451 |
free(info); |
free(info); |
452 |
} |
} |
453 |
} |
} |
490 |
if (sgi_get_sysid(i) == SGI_ENTIRE_DISK) { |
if (sgi_get_sysid(i) == SGI_ENTIRE_DISK) { |
491 |
if (entire++ == 1) { |
if (entire++ == 1) { |
492 |
if (verbose) |
if (verbose) |
493 |
printf(_("More than one entire disk entry present.\n")); |
printf("More than one entire disk entry present\n"); |
494 |
} |
} |
495 |
} |
} |
496 |
} |
} |
497 |
} |
} |
498 |
if (sortcount == 0) { |
if (sortcount == 0) { |
499 |
if (verbose) |
if (verbose) |
500 |
printf(_("No partitions defined\n")); |
printf("No partitions defined\n"); |
501 |
return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; |
return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; |
502 |
} |
} |
503 |
qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start); |
qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start); |
504 |
if (sgi_get_sysid(Index[0]) == SGI_ENTIRE_DISK) { |
if (sgi_get_sysid(Index[0]) == SGI_ENTIRE_DISK) { |
505 |
if ((Index[0] != 10) && verbose) |
if ((Index[0] != 10) && verbose) |
506 |
printf(_("IRIX likes when Partition 11 covers the entire disk.\n")); |
printf("IRIX likes when Partition 11 covers the entire disk\n"); |
507 |
if ((sgi_get_start_sector(Index[0]) != 0) && verbose) |
if ((sgi_get_start_sector(Index[0]) != 0) && verbose) |
508 |
printf(_("The entire disk partition should start " |
printf("The entire disk partition should start " |
509 |
"at block 0,\n" |
"at block 0,\n" |
510 |
"not at diskblock %d.\n"), |
"not at diskblock %d\n", |
511 |
sgi_get_start_sector(Index[0])); |
sgi_get_start_sector(Index[0])); |
512 |
if (debug) /* I do not understand how some disks fulfil it */ |
if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ |
513 |
if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) |
if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) |
514 |
printf(_("The entire disk partition is only %d diskblock large,\n" |
printf("The entire disk partition is only %d diskblock large,\n" |
515 |
"but the disk is %d diskblocks long.\n"), |
"but the disk is %d diskblocks long\n", |
516 |
sgi_get_num_sectors(Index[0]), lastblock); |
sgi_get_num_sectors(Index[0]), lastblock); |
517 |
lastblock = sgi_get_num_sectors(Index[0]); |
lastblock = sgi_get_num_sectors(Index[0]); |
518 |
} else { |
} else { |
519 |
if (verbose) |
if (verbose) |
520 |
printf(_("One Partition (#11) should cover the entire disk.\n")); |
printf("One Partition (#11) should cover the entire disk\n"); |
521 |
if (debug > 2) |
if (SGI_DEBUG > 2) |
522 |
printf("sysid=%d\tpartition=%d\n", |
printf("sysid=%d\tpartition=%d\n", |
523 |
sgi_get_sysid(Index[0]), Index[0]+1); |
sgi_get_sysid(Index[0]), Index[0]+1); |
524 |
} |
} |
526 |
int cylsize = sgi_get_nsect() * sgi_get_ntrks(); |
int cylsize = sgi_get_nsect() * sgi_get_ntrks(); |
527 |
|
|
528 |
if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { |
if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { |
529 |
if (debug) /* I do not understand how some disks fulfil it */ |
if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ |
530 |
if (verbose) |
if (verbose) |
531 |
printf(_("Partition %d does not start on cylinder boundary.\n"), |
printf("Partition %d does not start on cylinder boundary\n", |
532 |
Index[i]+1); |
Index[i]+1); |
533 |
} |
} |
534 |
if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { |
if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { |
535 |
if (debug) /* I do not understand how some disks fulfil it */ |
if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ |
536 |
if (verbose) |
if (verbose) |
537 |
printf(_("Partition %d does not end on cylinder boundary.\n"), |
printf("Partition %d does not end on cylinder boundary\n", |
538 |
Index[i]+1); |
Index[i]+1); |
539 |
} |
} |
540 |
/* We cannot handle several "entire disk" entries. */ |
/* We cannot handle several "entire disk" entries. */ |
541 |
if (sgi_get_sysid(Index[i]) == SGI_ENTIRE_DISK) continue; |
if (sgi_get_sysid(Index[i]) == SGI_ENTIRE_DISK) continue; |
542 |
if (start > sgi_get_start_sector(Index[i])) { |
if (start > sgi_get_start_sector(Index[i])) { |
543 |
if (verbose) |
if (verbose) |
544 |
printf(_("The Partition %d and %d overlap by %d sectors.\n"), |
printf("Partitions %d and %d overlap by %d sectors\n", |
545 |
Index[i-1]+1, Index[i]+1, |
Index[i-1]+1, Index[i]+1, |
546 |
start - sgi_get_start_sector(Index[i])); |
start - sgi_get_start_sector(Index[i])); |
547 |
if (gap > 0) gap = -gap; |
if (gap > 0) gap = -gap; |
548 |
if (gap == 0) gap = -1; |
if (gap == 0) gap = -1; |
549 |
} |
} |
550 |
if (start < sgi_get_start_sector(Index[i])) { |
if (start < sgi_get_start_sector(Index[i])) { |
551 |
if (verbose) |
if (verbose) |
552 |
printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), |
printf("Unused gap of %8u sectors - sectors %8u-%8u\n", |
553 |
sgi_get_start_sector(Index[i]) - start, |
sgi_get_start_sector(Index[i]) - start, |
554 |
start, sgi_get_start_sector(Index[i])-1); |
start, sgi_get_start_sector(Index[i])-1); |
555 |
gap += sgi_get_start_sector(Index[i]) - start; |
gap += sgi_get_start_sector(Index[i]) - start; |
557 |
} |
} |
558 |
start = sgi_get_start_sector(Index[i]) |
start = sgi_get_start_sector(Index[i]) |
559 |
+ sgi_get_num_sectors(Index[i]); |
+ sgi_get_num_sectors(Index[i]); |
560 |
if (debug > 1) { |
if (SGI_DEBUG > 1) { |
561 |
if (verbose) |
if (verbose) |
562 |
printf("%2d:%12d\t%12d\t%12d\n", Index[i], |
printf("%2d:%12d\t%12d\t%12d\n", Index[i], |
563 |
sgi_get_start_sector(Index[i]), |
sgi_get_start_sector(Index[i]), |
567 |
} |
} |
568 |
if (start < lastblock) { |
if (start < lastblock) { |
569 |
if (verbose) |
if (verbose) |
570 |
printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), |
printf("Unused gap of %8u sectors - sectors %8u-%8u\n", |
571 |
lastblock - start, start, lastblock-1); |
lastblock - start, start, lastblock-1); |
572 |
gap += lastblock - start; |
gap += lastblock - start; |
573 |
add2freelist(start, lastblock); |
add2freelist(start, lastblock); |
578 |
*/ |
*/ |
579 |
if (verbose) { |
if (verbose) { |
580 |
if (!sgi_get_num_sectors(sgi_get_bootpartition())) { |
if (!sgi_get_num_sectors(sgi_get_bootpartition())) { |
581 |
printf(_("\nThe boot partition does not exist.\n")); |
printf("\nThe boot partition does not exist\n"); |
582 |
} |
} |
583 |
if (!sgi_get_num_sectors(sgi_get_swappartition())) { |
if (!sgi_get_num_sectors(sgi_get_swappartition())) { |
584 |
printf(_("\nThe swap partition does not exist.\n")); |
printf("\nThe swap partition does not exist\n"); |
585 |
} else { |
} else { |
586 |
if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP) |
if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP) |
587 |
&& (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP)) |
&& (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP)) |
588 |
printf(_("\nThe swap partition has no swap type.\n")); |
printf("\nThe swap partition has no swap type\n"); |
589 |
} |
} |
590 |
if (sgi_check_bootfile("/unix")) |
if (sgi_check_bootfile("/unix")) |
591 |
printf(_("\tYou have chosen an unusual boot file name.\n")); |
printf("\tYou have chosen an unusual boot file name\n"); |
592 |
} |
} |
593 |
return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; |
return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; |
594 |
} |
} |
608 |
static void |
static void |
609 |
sgi_change_sysid(int i, int sys) |
sgi_change_sysid(int i, int sys) |
610 |
{ |
{ |
611 |
if( sgi_get_num_sectors(i) == 0 ) { /* caught already before, ... */ |
if (sgi_get_num_sectors(i) == 0) { /* caught already before, ... */ |
612 |
printf(_("Sorry You may change the Tag of non-empty partitions.\n")); |
printf("Sorry you may change the Tag of non-empty partitions\n"); |
613 |
return; |
return; |
614 |
} |
} |
615 |
if (((sys != SGI_ENTIRE_DISK) && (sys != SGI_VOLHDR)) |
if ((sys != SGI_ENTIRE_DISK) && (sys != SGI_VOLHDR) |
616 |
&& (sgi_get_start_sector(i) < 1) ) { |
&& (sgi_get_start_sector(i) < 1) |
617 |
|
) { |
618 |
read_maybe_empty( |
read_maybe_empty( |
619 |
_("It is highly recommended that the partition at offset 0\n" |
"It is highly recommended that the partition at offset 0\n" |
620 |
"is of type \"SGI volhdr\", the IRIX system will rely on it to\n" |
"is of type \"SGI volhdr\", the IRIX system will rely on it to\n" |
621 |
"retrieve from its directory standalone tools like sash and fx.\n" |
"retrieve from its directory standalone tools like sash and fx.\n" |
622 |
"Only the \"SGI volume\" entire disk section may violate this.\n" |
"Only the \"SGI volume\" entire disk section may violate this.\n" |
623 |
"Type YES if you are sure about tagging this partition differently.\n")); |
"Type YES if you are sure about tagging this partition differently.\n"); |
624 |
if (strcmp(line_ptr, _("YES\n"))) |
if (strcmp(line_ptr, "YES\n") != 0) |
625 |
return; |
return; |
626 |
} |
} |
627 |
sgilabel->partitions[i].id = SGI_SSWAP32(sys); |
sgilabel->partitions[i].id = SGI_SSWAP32(sys); |
647 |
sgilabel->partitions[i].start_sector = SGI_SSWAP32(start); |
sgilabel->partitions[i].start_sector = SGI_SSWAP32(start); |
648 |
set_changed(i); |
set_changed(i); |
649 |
if (sgi_gaps() < 0) /* rebuild freelist */ |
if (sgi_gaps() < 0) /* rebuild freelist */ |
650 |
printf(_("Do You know, You got a partition overlap on the disk?\n")); |
printf("Partition overlap detected\n"); |
651 |
} |
} |
652 |
|
|
653 |
static void |
static void |
655 |
{ |
{ |
656 |
int n; |
int n; |
657 |
|
|
658 |
for (n = 10; n < partitions; n++) { |
for (n = 10; n < g_partitions; n++) { |
659 |
if(!sgi_get_num_sectors(n) ) { |
if (!sgi_get_num_sectors(n) ) { |
660 |
sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME); |
sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME); |
661 |
break; |
break; |
662 |
} |
} |
668 |
{ |
{ |
669 |
int n; |
int n; |
670 |
|
|
671 |
for (n = 8; n < partitions; n++) { |
for (n = 8; n < g_partitions; n++) { |
672 |
if (!sgi_get_num_sectors(n)) { |
if (!sgi_get_num_sectors(n)) { |
673 |
/* |
/* |
674 |
* 5 cylinders is an arbitrary value I like |
* 5 cylinders is an arbitrary value I like |
676 |
* (like sash, symmon, fx, ide) with ca. 3200 |
* (like sash, symmon, fx, ide) with ca. 3200 |
677 |
* sectors. |
* sectors. |
678 |
*/ |
*/ |
679 |
if (heads * sectors * 5 < sgi_get_lastblock()) |
if (g_heads * g_sectors * 5 < sgi_get_lastblock()) |
680 |
sgi_set_partition(n, 0, heads * sectors * 5, SGI_VOLHDR); |
sgi_set_partition(n, 0, g_heads * g_sectors * 5, SGI_VOLHDR); |
681 |
break; |
break; |
682 |
} |
} |
683 |
} |
} |
700 |
} else if (n == 8) { |
} else if (n == 8) { |
701 |
sys = 0; |
sys = 0; |
702 |
} |
} |
703 |
if(sgi_get_num_sectors(n)) { |
if (sgi_get_num_sectors(n)) { |
704 |
printf(_("Partition %d is already defined. Delete " |
printf(msg_part_already_defined, n + 1); |
|
"it before re-adding it.\n"), n + 1); |
|
705 |
return; |
return; |
706 |
} |
} |
707 |
if ((sgi_entire() == -1) && (sys != SGI_VOLUME)) { |
if ((sgi_entire() == -1) && (sys != SGI_VOLUME)) { |
708 |
printf(_("Attempting to generate entire disk entry automatically.\n")); |
printf("Attempting to generate entire disk entry automatically\n"); |
709 |
sgi_set_entire(); |
sgi_set_entire(); |
710 |
sgi_set_volhdr(); |
sgi_set_volhdr(); |
711 |
} |
} |
712 |
if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) { |
if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) { |
713 |
printf(_("The entire disk is already covered with partitions.\n")); |
printf("The entire disk is already covered with partitions\n"); |
714 |
return; |
return; |
715 |
} |
} |
716 |
if (sgi_gaps() < 0) { |
if (sgi_gaps() < 0) { |
717 |
printf(_("You got a partition overlap on the disk. Fix it first!\n")); |
printf("You got a partition overlap on the disk. Fix it first!\n"); |
718 |
return; |
return; |
719 |
} |
} |
720 |
snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); |
snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); |
721 |
while (1) { |
while (1) { |
722 |
if(sys == SGI_VOLUME) { |
if (sys == SGI_VOLUME) { |
723 |
last = sgi_get_lastblock(); |
last = sgi_get_lastblock(); |
724 |
first = read_int(0, 0, last-1, 0, mesg); |
first = read_int(0, 0, last-1, 0, mesg); |
725 |
if (first != 0) { |
if (first != 0) { |
726 |
printf(_("It is highly recommended that eleventh partition\n" |
printf("It is highly recommended that eleventh partition\n" |
727 |
"covers the entire disk and is of type 'SGI volume'\n")); |
"covers the entire disk and is of type 'SGI volume'\n"); |
728 |
} |
} |
729 |
} else { |
} else { |
730 |
first = freelist[0].first; |
first = freelist[0].first; |
736 |
first *= units_per_sector; |
first *= units_per_sector; |
737 |
else |
else |
738 |
first = first; /* align to cylinder if you know how ... */ |
first = first; /* align to cylinder if you know how ... */ |
739 |
if(!last ) |
if (!last ) |
740 |
last = isinfreelist(first); |
last = isinfreelist(first); |
741 |
if(last == 0) { |
if (last != 0) |
|
printf(_("You will get a partition overlap on the disk. " |
|
|
"Fix it first!\n")); |
|
|
} else |
|
742 |
break; |
break; |
743 |
|
printf("You will get a partition overlap on the disk. " |
744 |
|
"Fix it first!\n"); |
745 |
} |
} |
746 |
snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR)); |
snprintf(mesg, sizeof(mesg), " Last %s", str_units(SINGULAR)); |
747 |
last = read_int(scround(first), scround(last)-1, scround(last)-1, |
last = read_int(scround(first), scround(last)-1, scround(last)-1, |
748 |
scround(first), mesg)+1; |
scround(first), mesg)+1; |
749 |
if (display_in_cyl_units) |
if (display_in_cyl_units) |
751 |
else |
else |
752 |
last = last; /* align to cylinder if You know how ... */ |
last = last; /* align to cylinder if You know how ... */ |
753 |
if ( (sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock() ) ) |
if ( (sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock() ) ) |
754 |
printf(_("It is highly recommended that eleventh partition\n" |
printf("It is highly recommended that eleventh partition\n" |
755 |
"covers the entire disk and is of type 'SGI volume'\n")); |
"covers the entire disk and is of type 'SGI volume'\n"); |
756 |
sgi_set_partition(n, first, last-first, sys); |
sgi_set_partition(n, first, last-first, sys); |
757 |
} |
} |
758 |
|
|
773 |
|
|
774 |
sec_fac = sector_size / 512; /* determine the sector factor */ |
sec_fac = sector_size / 512; /* determine the sector factor */ |
775 |
|
|
776 |
fprintf( stderr, |
printf(msg_building_new_label, "SGI disklabel"); |
777 |
_("Building a new SGI disklabel. Changes will remain in memory only,\n" |
|
778 |
"until you decide to write them. After that, of course, the previous\n" |
sgi_other_endian = BB_LITTLE_ENDIAN; |
779 |
"content will be unrecoverably lost.\n\n")); |
res = ioctl(dev_fd, BLKGETSIZE, &longsectors); |
780 |
|
if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { |
781 |
sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN); |
g_heads = geometry.heads; |
782 |
res = ioctl(fd, BLKGETSIZE, &longsectors); |
g_sectors = geometry.sectors; |
|
if (!ioctl(fd, HDIO_GETGEO, &geometry)) { |
|
|
heads = geometry.heads; |
|
|
sectors = geometry.sectors; |
|
783 |
if (res == 0) { |
if (res == 0) { |
784 |
/* the get device size ioctl was successful */ |
/* the get device size ioctl was successful */ |
785 |
cylinders = longsectors / (heads * sectors); |
g_cylinders = longsectors / (g_heads * g_sectors); |
786 |
cylinders /= sec_fac; |
g_cylinders /= sec_fac; |
787 |
} else { |
} else { |
788 |
/* otherwise print error and use truncated version */ |
/* otherwise print error and use truncated version */ |
789 |
cylinders = geometry.cylinders; |
g_cylinders = geometry.cylinders; |
790 |
fprintf(stderr, |
printf( |
791 |
_("Warning: BLKGETSIZE ioctl failed on %s. " |
"Warning: BLKGETSIZE ioctl failed on %s. Using geometry cylinder value of %d.\n" |
792 |
"Using geometry cylinder value of %d.\n" |
"This value may be truncated for devices > 33.8 GB.\n", disk_device, g_cylinders); |
|
"This value may be truncated for devices" |
|
|
" > 33.8 GB.\n"), disk_device, cylinders); |
|
793 |
} |
} |
794 |
} |
} |
795 |
for (i = 0; i < 4; i++) { |
for (i = 0; i < 4; i++) { |
796 |
old[i].sysid = 0; |
old[i].sysid = 0; |
797 |
if (valid_part_table_flag(MBRbuffer)) { |
if (valid_part_table_flag(MBRbuffer)) { |
798 |
if(get_part_table(i)->sys_ind) { |
if (get_part_table(i)->sys_ind) { |
799 |
old[i].sysid = get_part_table(i)->sys_ind; |
old[i].sysid = get_part_table(i)->sys_ind; |
800 |
old[i].start = get_start_sect(get_part_table(i)); |
old[i].start = get_start_sect(get_part_table(i)); |
801 |
old[i].nsect = get_nr_sects(get_part_table(i)); |
old[i].nsect = get_nr_sects(get_part_table(i)); |
802 |
printf(_("Trying to keep parameters of partition %d.\n"), i); |
printf("Trying to keep parameters of partition %d\n", i); |
803 |
if (debug) |
if (SGI_DEBUG) |
804 |
printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), |
printf("ID=%02x\tSTART=%d\tLENGTH=%d\n", |
805 |
old[i].sysid, old[i].start, old[i].nsect); |
old[i].sysid, old[i].start, old[i].nsect); |
806 |
} |
} |
807 |
} |
} |
845 |
//sgilabel->devparam.xylogics_writecont = SGI_SSWAP16(0); |
//sgilabel->devparam.xylogics_writecont = SGI_SSWAP16(0); |
846 |
//memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 ); |
//memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 ); |
847 |
//memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partinfo)*16 ); |
//memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partinfo)*16 ); |
848 |
current_label_type = label_sgi; |
current_label_type = LABEL_SGI; |
849 |
partitions = 16; |
g_partitions = 16; |
850 |
sgi_volumes = 15; |
sgi_volumes = 15; |
851 |
sgi_set_entire(); |
sgi_set_entire(); |
852 |
sgi_set_volhdr(); |
sgi_set_volhdr(); |
853 |
for (i = 0; i < 4; i++) { |
for (i = 0; i < 4; i++) { |
854 |
if(old[i].sysid) { |
if (old[i].sysid) { |
855 |
sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); |
sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); |
856 |
} |
} |
857 |
} |
} |