/* fdisk_get_partition() backend */ static int sgi_get_partition(struct fdisk_context *cxt, size_t n, struct fdisk_partition *pa) { uint64_t start, len; pa->used = sgi_get_num_sectors(cxt, n) > 0; if (!pa->used) return 0; start = sgi_get_start_sector(cxt, n); len = sgi_get_num_sectors(cxt, n); pa->type = sgi_get_parttype(cxt, n); pa->size = len; pa->start = start; pa->end = start + len - (len ? 1 : 0); if (pa->type && pa->type->type == SGI_TYPE_ENTIRE_DISK) pa->wholedisk = 1; pa->attrs = sgi_get_swappartition(cxt) == (int) n ? "swap" : sgi_get_bootpartition(cxt) == (int) n ? "boot" : NULL; if (pa->attrs) pa->attrs = strdup(pa->attrs); return 0; }
static int verify_sgi(int verbose) { int Index[16]; /* list of valid partitions */ int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ int entire = 0, i = 0; unsigned int start = 0; long long gap = 0; /* count unused blocks */ unsigned int lastblock = sgi_get_lastblock(); clearfreelist(); for (i = 0; i < 16; i++) { if (sgi_get_num_sectors(i) != 0) { Index[sortcount++] = i; if (sgi_get_sysid(i) == SGI_ENTIRE_DISK) { if (entire++ == 1) { if (verbose) printf("More than one entire disk entry present\n"); } } } } if (sortcount == 0) { if (verbose) printf("No partitions defined\n"); return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; } qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start); if (sgi_get_sysid(Index[0]) == SGI_ENTIRE_DISK) { if ((Index[0] != 10) && verbose) printf("IRIX likes when Partition 11 covers the entire disk\n"); if ((sgi_get_start_sector(Index[0]) != 0) && verbose) printf("The entire disk partition should start " "at block 0,\n" "not at diskblock %d\n", sgi_get_start_sector(Index[0])); if (debug) /* I do not understand how some disks fulfil it */ if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) printf("The entire disk partition is only %d diskblock large,\n" "but the disk is %d diskblocks long\n", sgi_get_num_sectors(Index[0]), lastblock); lastblock = sgi_get_num_sectors(Index[0]); } else { if (verbose) printf("One Partition (#11) should cover the entire disk\n"); if (debug > 2) printf("sysid=%d\tpartition=%d\n", sgi_get_sysid(Index[0]), Index[0]+1); } for (i = 1, start = 0; i < sortcount; i++) { int cylsize = sgi_get_nsect() * sgi_get_ntrks(); if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { if (debug) /* I do not understand how some disks fulfil it */ if (verbose) printf("Partition %d does not start on cylinder boundary\n", Index[i]+1); } if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { if (debug) /* I do not understand how some disks fulfil it */ if (verbose) printf("Partition %d does not end on cylinder boundary\n", Index[i]+1); } /* We cannot handle several "entire disk" entries. */ if (sgi_get_sysid(Index[i]) == SGI_ENTIRE_DISK) continue; if (start > sgi_get_start_sector(Index[i])) { if (verbose) printf("Partitions %d and %d overlap by %d sectors\n", Index[i-1]+1, Index[i]+1, start - sgi_get_start_sector(Index[i])); if (gap > 0) gap = -gap; if (gap == 0) gap = -1; } if (start < sgi_get_start_sector(Index[i])) { if (verbose) printf("Unused gap of %8u sectors - sectors %8u-%8u\n", sgi_get_start_sector(Index[i]) - start, start, sgi_get_start_sector(Index[i])-1); gap += sgi_get_start_sector(Index[i]) - start; add2freelist(start, sgi_get_start_sector(Index[i])); } start = sgi_get_start_sector(Index[i]) + sgi_get_num_sectors(Index[i]); if (debug > 1) { if (verbose) printf("%2d:%12d\t%12d\t%12d\n", Index[i], sgi_get_start_sector(Index[i]), sgi_get_num_sectors(Index[i]), sgi_get_sysid(Index[i])); } } if (start < lastblock) { if (verbose) printf("Unused gap of %8u sectors - sectors %8u-%8u\n", lastblock - start, start, lastblock-1); gap += lastblock - start; add2freelist(start, lastblock); } /* * Done with arithmetics * Go for details now */ if (verbose) { if (!sgi_get_num_sectors(sgi_get_bootpartition())) { printf("\nThe boot partition does not exist\n"); } if (!sgi_get_num_sectors(sgi_get_swappartition())) { printf("\nThe swap partition does not exist\n"); } else { if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP) && (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP)) printf("\nThe swap partition has no swap type\n"); } if (sgi_check_bootfile("/unix")) printf("\tYou have chosen an unusual boot file name\n"); } return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; }
static void sgi_list_table(int xtra) { int i, w, wd; int kpi = 0; /* kernel partition ID */ if (xtra) { printf("\nDisk %s (SGI disk label): %d heads, %d sectors\n" "%d cylinders, %d physical cylinders\n" "%d extra sects/cyl, interleave %d:1\n" "%s\n" "Units = %s of %d * 512 bytes\n\n", disk_device, heads, sectors, cylinders, SGI_SSWAP16(sgiparam.pcylcount), SGI_SSWAP16(sgiparam.sparecyl), SGI_SSWAP16(sgiparam.ilfact), (char *)sgilabel, str_units(PLURAL), units_per_sector); } else { printf("\nDisk %s (SGI disk label): " "%d heads, %d sectors, %d cylinders\n" "Units = %s of %d * 512 bytes\n\n", disk_device, heads, sectors, cylinders, str_units(PLURAL), units_per_sector ); } w = strlen(disk_device); wd = sizeof("Device") - 1; if (w < wd) w = wd; printf("----- partitions -----\n" "Pt# %*s Info Start End Sectors Id System\n", w + 2, "Device"); for (i = 0 ; i < partitions; i++) { if (sgi_get_num_sectors(i) || debug ) { uint32_t start = sgi_get_start_sector(i); uint32_t len = sgi_get_num_sectors(i); kpi++; /* only count nonempty partitions */ printf( "%2d: %s %4s %9ld %9ld %9ld %2x %s\n", /* fdisk part number */ i+1, /* device */ partname(disk_device, kpi, w+3), /* flags */ (sgi_get_swappartition() == i) ? "swap" : /* flags */ (sgi_get_bootpartition() == i) ? "boot" : " ", /* start */ (long) scround(start), /* end */ (long) scround(start+len)-1, /* no odd flag on end */(long) len, /* type id */ sgi_get_sysid(i), /* type name */ partition_type(sgi_get_sysid(i))); } } printf("----- Bootinfo -----\nBootfile: %s\n" "----- Directory Entries -----\n", sgilabel->boot_file); for (i = 0 ; i < sgi_volumes; i++) { if (sgilabel->directory[i].vol_file_size) { uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start); uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size); unsigned char *name = sgilabel->directory[i].vol_file_name; printf("%2d: %-10s sector%5u size%8u\n", i, (char*)name, (unsigned int) start, (unsigned int) len); } } }
static int verify_disklabel(struct fdisk_context *cxt, int verbose) { int Index[SGI_MAXPARTITIONS]; /* list of valid partitions */ int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ int entire = 0, i = 0; unsigned int start = 0; long long gap = 0; /* count unused blocks */ unsigned int lastblock = sgi_get_lastblock(cxt); assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, SGI)); clear_freelist(cxt); memset(Index, 0, sizeof(Index)); for (i=0; i < SGI_MAXPARTITIONS; i++) { if (sgi_get_num_sectors(cxt, i) != 0) { Index[sortcount++] = i; if (sgi_get_sysid(cxt, i) == SGI_TYPE_ENTIRE_DISK && entire++ == 1) { if (verbose) fdisk_info(cxt, _("More than one entire " "disk entry present.")); } } } if (sortcount == 0) { if (verbose) fdisk_info(cxt, _("No partitions defined")); return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; } sort(Index, sortcount, sizeof(Index[0]), cxt, compare_start); if (sgi_get_sysid(cxt, Index[0]) == SGI_TYPE_ENTIRE_DISK) { if (verbose && Index[0] != 10) fdisk_info(cxt, _("IRIX likes when Partition 11 " "covers the entire disk.")); if (verbose && sgi_get_start_sector(cxt, Index[0]) != 0) fdisk_info(cxt, _("The entire disk partition should " "start at block 0, not at diskblock %d."), sgi_get_start_sector(cxt, Index[0])); if (verbose && sgi_get_num_sectors(cxt, Index[0]) != lastblock) DBG(LABEL, dbgprint( "entire disk partition=%ds, but disk=%ds", sgi_get_num_sectors(cxt, Index[0]), lastblock)); lastblock = sgi_get_num_sectors(cxt, Index[0]); } else if (verbose) { fdisk_info(cxt, _("Partition 11 should cover the entire disk.")); DBG(LABEL, dbgprint("sysid=%d\tpartition=%d", sgi_get_sysid(cxt, Index[0]), Index[0]+1)); } for (i=1, start=0; i<sortcount; i++) { int cylsize = sgi_get_nsect(cxt) * sgi_get_ntrks(cxt); if (verbose && cylsize && (sgi_get_start_sector(cxt, Index[i]) % cylsize) != 0) DBG(LABEL, dbgprint("partition %d does not start on " "cylinder boundary.", Index[i]+1)); if (verbose && cylsize && sgi_get_num_sectors(cxt, Index[i]) % cylsize != 0) DBG(LABEL, dbgprint("partition %d does not end on " "cylinder boundary.", Index[i]+1)); /* We cannot handle several "entire disk" entries. */ if (sgi_get_sysid(cxt, Index[i]) == SGI_TYPE_ENTIRE_DISK) continue; if (start > sgi_get_start_sector(cxt, Index[i])) { if (verbose) fdisk_info(cxt, _("The Partition %d and %d overlap " "by %d sectors."), Index[i-1]+1, Index[i]+1, start - sgi_get_start_sector(cxt, Index[i])); if (gap > 0) gap = -gap; if (gap == 0) gap = -1; } if (start < sgi_get_start_sector(cxt, Index[i])) { if (verbose) fdisk_info(cxt, _("Unused gap of %8u sectors " "- sectors %8u-%u"), sgi_get_start_sector(cxt, Index[i]) - start, start, sgi_get_start_sector(cxt, Index[i])-1); gap += sgi_get_start_sector(cxt, Index[i]) - start; add_to_freelist(cxt, start, sgi_get_start_sector(cxt, Index[i])); } start = sgi_get_start_sector(cxt, Index[i]) + sgi_get_num_sectors(cxt, Index[i]); /* Align free space on cylinder boundary */ if (cylsize && start % cylsize) start += cylsize - (start % cylsize); DBG(LABEL, dbgprint("%2d:%12d\t%12d\t%12d", Index[i], sgi_get_start_sector(cxt, Index[i]), sgi_get_num_sectors(cxt, Index[i]), sgi_get_sysid(cxt, Index[i]))); } if (start < lastblock) { if (verbose) fdisk_info(cxt, _("Unused gap of %8u sectors - sectors %8u-%u"), lastblock - start, start, lastblock-1); gap += lastblock - start; add_to_freelist(cxt, start, lastblock); } /* * Done with arithmetics. Go for details now */ if (verbose) { if (sgi_get_bootpartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_bootpartition(cxt))) fdisk_info(cxt, _("The boot partition does not exist.")); if (sgi_get_swappartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_swappartition(cxt))) fdisk_info(cxt, _("The swap partition does not exist.")); else if (sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != SGI_TYPE_SWAP && sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != MBR_LINUX_SWAP_PARTITION) fdisk_info(cxt, _("The swap partition has no swap type.")); if (sgi_check_bootfile(cxt, "/unix")) fdisk_info(cxt, _("You have chosen an unusual boot " "file name.")); } return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; }
static int sgi_list_table(struct fdisk_context *cxt) { struct tt *tb = NULL; struct sgi_disklabel *sgilabel = self_disklabel(cxt); struct sgi_device_parameter *sgiparam = &sgilabel->devparam; size_t i, used; char *p; int rc; if (fdisk_context_display_details(cxt)) fdisk_colon(cxt, _( "Label geometry: %d heads, %llu sectors\n" " %llu cylinders, %d physical cylinders\n" " %d extra sects/cyl, interleave %d:1\n"), cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders, be16_to_cpu(sgiparam->pcylcount), (int) sgiparam->sparecyl, be16_to_cpu(sgiparam->ilfact)); /* * Partitions */ tb = tt_new_table(TT_FL_FREEDATA); if (!tb) return -ENOMEM; tt_define_column(tb, _("Pt#"), 3, TT_FL_RIGHT); tt_define_column(tb, _("Device"), 0.2, 0); tt_define_column(tb, _("Info"), 2, 0); tt_define_column(tb, _("Start"), 9, TT_FL_RIGHT); tt_define_column(tb, _("End"), 9, TT_FL_RIGHT); tt_define_column(tb, _("Sectors"), 9, TT_FL_RIGHT); tt_define_column(tb, _("Id"), 2, TT_FL_RIGHT); tt_define_column(tb, _("System"), 0.2, TT_FL_TRUNC); for (i = 0, used = 1; i < cxt->label->nparts_max; i++) { uint32_t start, len; struct fdisk_parttype *t; struct tt_line *ln; if (sgi_get_num_sectors(cxt, i) == 0) continue; ln = tt_add_line(tb, NULL); if (!ln) continue; start = sgi_get_start_sector(cxt, i); len = sgi_get_num_sectors(cxt, i); t = fdisk_get_partition_type(cxt, i); if (asprintf(&p, "%zu:", i + 1) > 0) tt_line_set_data(ln, 0, p); /* # */ p = fdisk_partname(cxt->dev_path, used++); if (p) tt_line_set_data(ln, 1, p); /* Device */ p = sgi_get_swappartition(cxt) == (int) i ? "swap" : sgi_get_bootpartition(cxt) == (int) i ? "boot" : NULL; if (p) tt_line_set_data(ln, 2, strdup(p)); /* Info */ if (asprintf(&p, "%ju", (uintmax_t) fdisk_scround(cxt, start)) > 0) tt_line_set_data(ln, 3, p); /* Start */ if (asprintf(&p, "%ju", (uintmax_t) fdisk_scround(cxt, start + len) - 1) > 0) tt_line_set_data(ln, 4, p); /* End */ if (asprintf(&p, "%ju", (uintmax_t) len) > 0) tt_line_set_data(ln, 5, p); /* Sectors*/ if (asprintf(&p, "%2x", t->type) > 0) tt_line_set_data(ln, 6, p); /* type ID */ if (t->name) tt_line_set_data(ln, 7, strdup(t->name)); /* type Name */ fdisk_free_parttype(t); } rc = fdisk_print_table(cxt, tb); tt_free_table(tb); if (rc) return rc; /* * Volumes */ tb = tt_new_table(TT_FL_FREEDATA); if (!tb) return -ENOMEM; tt_define_column(tb, _("#"), 3, TT_FL_RIGHT); tt_define_column(tb, _("Name"), 0.2, 0); tt_define_column(tb, _("Sector"), 2, TT_FL_RIGHT); tt_define_column(tb, _("Size"), 9, TT_FL_RIGHT); for (i = 0, used = 0; i < SGI_MAXVOLUMES; i++) { struct tt_line *ln; uint32_t start = be32_to_cpu(sgilabel->volume[i].block_num), len = be32_to_cpu(sgilabel->volume[i].num_bytes); if (!len) continue; ln = tt_add_line(tb, NULL); if (!ln) continue; if (asprintf(&p, "%zu:", i) > 0) tt_line_set_data(ln, 0, p); /* # */ if (*sgilabel->volume[i].name) tt_line_set_data(ln, 1, strndup((char *) sgilabel->volume[i].name, sizeof(sgilabel->volume[i].name))); /* Name */ if (asprintf(&p, "%ju", (uintmax_t) start) > 0) tt_line_set_data(ln, 2, p); /* Sector */ if (asprintf(&p, "%ju", (uintmax_t) len) > 0) tt_line_set_data(ln, 3, p); /* Size */ used++; } if (used) rc = fdisk_print_table(cxt, tb); tt_free_table(tb); fdisk_colon(cxt, _("Bootfile: %s"), sgilabel->boot_file); return rc; }
void sgi_list_table(struct fdisk_context *cxt, int xtra) { int i, w; int kpi = 0; /* kernel partition ID */ w = strlen(cxt->dev_path); if (xtra) { printf(_("\nDisk %s (SGI disk label): %d heads, %llu sectors\n" "%llu cylinders, %d physical cylinders\n" "%d extra sects/cyl, interleave %d:1\n" "%s\n" "Units = %s of %d * %ld bytes\n\n"), cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders, SSWAP16(sgiparam.pcylcount), (int) sgiparam.sparecyl, SSWAP16(sgiparam.ilfact), (char *)sgilabel, str_units(PLURAL), units_per_sector, cxt->sector_size); } else { printf(_("\nDisk %s (SGI disk label): " "%d heads, %llu sectors, %llu cylinders\n" "Units = %s of %d * %ld bytes\n\n"), cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders, str_units(PLURAL), units_per_sector, cxt->sector_size); } printf(_("----- partitions -----\n" "Pt# %*s Info Start End Sectors Id System\n"), w + 1, _("Device")); for (i = 0 ; i < partitions; i++) { if (sgi_get_num_sectors(cxt, i) || debug) { uint32_t start = sgi_get_start_sector(cxt, i); uint32_t len = sgi_get_num_sectors(cxt, i); struct fdisk_parttype *t = fdisk_get_partition_type(cxt, i); kpi++; /* only count nonempty partitions */ printf( "%2d: %s %4s %9ld %9ld %9ld %2x %s\n", /* fdisk part number */ i+1, /* device */ partname(cxt->dev_path, kpi, w+2), /* flags */ (sgi_get_swappartition(cxt) == i) ? "swap" : /* flags */ (sgi_get_bootpartition(cxt) == i) ? "boot" : " ", /* start */ (long) scround(start), /* end */ (long) scround(start+len)-1, /* no odd flag on end */ (long) len, /* type id */ t->type, /* type name */ t->name); fdisk_free_parttype(t); } } printf(_("----- Bootinfo -----\nBootfile: %s\n" "----- Directory Entries -----\n"), sgilabel->boot_file); for (i = 0 ; i < volumes; i++) { if (sgilabel->directory[i].vol_file_size) { uint32_t start = SSWAP32(sgilabel->directory[i].vol_file_start); uint32_t len = SSWAP32(sgilabel->directory[i].vol_file_size); unsigned char *name = sgilabel->directory[i].vol_file_name; printf(_("%2d: %-10s sector%5u size%8u\n"), i, name, (unsigned int) start, (unsigned int) len); } } }