/* Scans The partitions */ int scan_partitions(struct disk_info *dsk) { static unsigned char sector[SECTOR_SIZE]; struct MBRpartition *part; struct partition_info *current = NULL; int sector_size; int ret, i; ret = read_disk(dsk->fd, sector, 0, 1, dsk->sector_size); if(ret < 0) return ret; if(ret < sector_size) { LOG_INFO("Error Reading the MBR on %s \n", path); return -1; } if(!valid_part_table_flag(sector)) { LOG_INFO("Partition Table Error on %s\n", dsk->device_file); LOG_INFO("Invalid End of sector marker"); return -INVALID_TABLE; } /* First Scan primary Partitions */ for(i = 0; i < 4; i++) { part = pt_offset(sector, i); if((part->sys_ind != 0x00) || (get_nr_sects(part) != 0x00)) { LOG_INFO("index %d ID %X size %Ld \n", i, part->sys_ind, get_nr_sects(part)); if(!dsk->partition) { current = malloc(sizeof(struct partition_info)); memset(current, 0, sizeof(struct partition_info)); dsk->partition = current; } else { current->next = malloc(sizeof(struct partition_info)); memset(current->next, 0, sizeof(struct partition_info)); current = current->next; } current->fstype = part->sys_ind; current->base = get_start_sect(part); current->size = get_nr_sects(part) * dsk->sector_size; if(is_extended(part->sys_ind)) { current->flag = PARTITION_TYPE_EXTENDED; scan_ebr(dsk, current); } else { current->flag = PARTITION_TYPE_PRIMARY; } } } return 0; }
/* Reads The Extended Partitions */ int scan_ebr(struct disk_info *dsk, struct partition_info *ext) { static unsigned char sector[SECTOR_SIZE]; struct MBRpartition *part, *part1; struct partition_info *current = NULL, *pt; int logical = 4, ret; lloff_t ebrBase, nextPart, ebr2=0; ebrBase = ext->base; nextPart = ext->base; while (1) { ret = read_disk(dsk->fd, sector, nextPart, 1, dsk->sector_size); if (ret < 0) return ret; if (ret < dsk->sector_size) { LOG_INFO("Error Reading the EBR \n"); return -1; } part = pt_offset(sector, 0); LOG_INFO("index %d ID %X size %Ld \n", logical, part->sys_ind, get_nr_sects(part)); if (is_extended(part->sys_ind)) { // special case. ebr has extended partition with offset to another ebr. ebr2 += get_start_sect(part); nextPart = (ebr2 + ebrBase); continue; } part1 = pt_offset(sector, 1); ebr2 = get_start_sect(part1); nextPart = (ebr2 + ebrBase); pt = malloc(sizeof(struct partition_info)); if (!pt) { LOG_INFO("Allocation Error\n"); } memset(pt, 0, sizeof(struct partition_info)); if (!current) { current = pt; ext->ext = pt; } else { current->next = pt; current = current->next; } pt->fstype = part->sys_ind; pt->base = get_start_sect(part); pt->size = get_nr_sects(part) * dsk->sector_size; logical++; if (part1->sys_ind == 0) break; } return logical; }
void dos_delete_partition(int i) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; struct partition *q = pe->ext_pointer; /* Note that for the fifth partition (i == 4) we don't actually decrement partitions. */ if (i < 4) { if (IS_EXTENDED (p->sys_ind) && i == ext_index) { partitions = 4; ptes[ext_index].ext_pointer = NULL; extended_offset = 0; } clear_partition(p); } else if (!q->sys_ind && i > 4) { /* the last one in the chain - just delete */ --partitions; --i; clear_partition(ptes[i].ext_pointer); ptes[i].changed = 1; } else { /* not the last one - further ones will be moved down */ if (i > 4) { /* delete this link in the chain */ p = ptes[i-1].ext_pointer; *p = *q; set_start_sect(p, get_start_sect(q)); set_nr_sects(p, get_nr_sects(q)); ptes[i-1].changed = 1; } else if (partitions > 5) { /* 5 will be moved to 4 */ /* the first logical in a longer chain */ struct pte *pe = &ptes[5]; if (pe->part_table) /* prevent SEGFAULT */ set_start_sect(pe->part_table, get_partition_start(pe) - extended_offset); pe->offset = extended_offset; pe->changed = 1; } if (partitions > 5) { partitions--; while (i < partitions) { ptes[i] = ptes[i+1]; i++; } } else /* the only logical: clear only */ clear_partition(ptes[i].part_table); } }
static void xbsd_link_part(void) { int k, i; struct partition *p; k = get_partition(1, g_partitions); if (!xbsd_check_new_partition(&i)) return; p = get_part_table(k); xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p); xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p); xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind); }
static void xbsd_new_part(void) { off_t begin, end; char mesg[256]; int i; if (!xbsd_check_new_partition(&i)) return; #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__) begin = get_start_sect(xbsd_part); end = begin + get_nr_sects(xbsd_part) - 1; #else begin = 0; end = xbsd_dlabel.d_secperunit - 1; #endif snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), 0, mesg); if (display_in_cyl_units) begin = (begin - 1) * xbsd_dlabel.d_secpercyl; snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK", str_units(SINGULAR)); end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end), bsd_cround(begin), mesg); if (display_in_cyl_units) end = end * xbsd_dlabel.d_secpercyl - 1; xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; xbsd_dlabel.d_partitions[i].p_offset = begin; xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; }
static void create_sgilabel(void) { struct hd_geometry geometry; struct { unsigned int start; unsigned int nsect; int sysid; } old[4]; int i = 0; long longsectors; /* the number of sectors on the device */ int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ sec_fac = sector_size / 512; /* determine the sector factor */ printf(msg_building_new_label, "SGI disklabel"); sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN); res = ioctl(fd, BLKGETSIZE, &longsectors); if (!ioctl(fd, HDIO_GETGEO, &geometry)) { heads = geometry.heads; sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ cylinders = longsectors / (heads * sectors); cylinders /= sec_fac; } else { /* otherwise print error and use truncated version */ cylinders = geometry.cylinders; printf( "Warning: BLKGETSIZE ioctl failed on %s. Using geometry cylinder value of %d.\n" "This value may be truncated for devices > 33.8 GB.\n", disk_device, cylinders); } } for (i = 0; i < 4; i++) { old[i].sysid = 0; if (valid_part_table_flag(MBRbuffer)) { if (get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; old[i].start = get_start_sect(get_part_table(i)); old[i].nsect = get_nr_sects(get_part_table(i)); printf("Trying to keep parameters of partition %d\n", i); if (debug) printf("ID=%02x\tSTART=%d\tLENGTH=%d\n", old[i].sysid, old[i].start, old[i].nsect); } } } memset(MBRbuffer, 0, sizeof(MBRbuffer)); /* fields with '//' are already zeroed out by memset above */ sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC); //sgilabel->boot_part = SGI_SSWAP16(0); sgilabel->swap_part = SGI_SSWAP16(1); //memset(sgilabel->boot_file, 0, 16); strcpy((char*)sgilabel->boot_file, "/unix"); /* sizeof(sgilabel->boot_file) == 16 > 6 */ //sgilabel->devparam.skew = (0); //sgilabel->devparam.gap1 = (0); //sgilabel->devparam.gap2 = (0); //sgilabel->devparam.sparecyl = (0); sgilabel->devparam.pcylcount = SGI_SSWAP16(geometry.cylinders); //sgilabel->devparam.head_vol0 = SGI_SSWAP16(0); /* tracks/cylinder (heads) */ sgilabel->devparam.ntrks = SGI_SSWAP16(geometry.heads); //sgilabel->devparam.cmd_tag_queue_depth = (0); //sgilabel->devparam.unused0 = (0); //sgilabel->devparam.unused1 = SGI_SSWAP16(0); /* sectors/track */ sgilabel->devparam.nsect = SGI_SSWAP16(geometry.sectors); sgilabel->devparam.bytes = SGI_SSWAP16(512); sgilabel->devparam.ilfact = SGI_SSWAP16(1); sgilabel->devparam.flags = SGI_SSWAP32(TRACK_FWD| IGNORE_ERRORS|RESEEK); //sgilabel->devparam.datarate = SGI_SSWAP32(0); sgilabel->devparam.retries_on_error = SGI_SSWAP32(1); //sgilabel->devparam.ms_per_word = SGI_SSWAP32(0); //sgilabel->devparam.xylogics_gap1 = SGI_SSWAP16(0); //sgilabel->devparam.xylogics_syncdelay = SGI_SSWAP16(0); //sgilabel->devparam.xylogics_readdelay = SGI_SSWAP16(0); //sgilabel->devparam.xylogics_gap2 = SGI_SSWAP16(0); //sgilabel->devparam.xylogics_readgate = SGI_SSWAP16(0); //sgilabel->devparam.xylogics_writecont = SGI_SSWAP16(0); //memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 ); //memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partinfo)*16 ); current_label_type = label_sgi; partitions = 16; sgi_volumes = 15; sgi_set_entire(); sgi_set_volhdr(); for (i = 0; i < 4; i++) { if (old[i].sysid) { sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); } } }
static int xbsd_initlabel(struct partition *p) { struct xbsd_disklabel *d = &xbsd_dlabel; struct xbsd_partition *pp; get_geometry(); memset(d, 0, sizeof(struct xbsd_disklabel)); d->d_magic = BSD_DISKMAGIC; if (is_prefixed_with(disk_device, "/dev/sd")) d->d_type = BSD_DTYPE_SCSI; else d->d_type = BSD_DTYPE_ST506; #if !defined(__alpha__) d->d_flags = BSD_D_DOSPART; #else d->d_flags = 0; #endif d->d_secsize = SECTOR_SIZE; /* bytes/sector */ d->d_nsectors = g_sectors; /* sectors/track */ d->d_ntracks = g_heads; /* tracks/cylinder (heads) */ d->d_ncylinders = g_cylinders; d->d_secpercyl = g_sectors * g_heads;/* sectors/cylinder */ if (d->d_secpercyl == 0) d->d_secpercyl = 1; /* avoid segfaults */ d->d_secperunit = d->d_secpercyl * d->d_ncylinders; d->d_rpm = 3600; d->d_interleave = 1; d->d_trackskew = 0; d->d_cylskew = 0; d->d_headswitch = 0; d->d_trkseek = 0; d->d_magic2 = BSD_DISKMAGIC; d->d_bbsize = BSD_BBSIZE; d->d_sbsize = BSD_SBSIZE; #if !defined(__alpha__) d->d_npartitions = 4; pp = &d->d_partitions[2]; /* Partition C should be NetBSD partition */ pp->p_offset = get_start_sect(p); pp->p_size = get_nr_sects(p); pp->p_fstype = BSD_FS_UNUSED; pp = &d->d_partitions[3]; /* Partition D should be whole disk */ pp->p_offset = 0; pp->p_size = d->d_secperunit; pp->p_fstype = BSD_FS_UNUSED; #else d->d_npartitions = 3; pp = &d->d_partitions[2]; /* Partition C should be the whole disk */ pp->p_offset = 0; pp->p_size = d->d_secperunit; pp->p_fstype = BSD_FS_UNUSED; #endif return 1; }
void dos_add_partition(struct fdisk_context *cxt, int n, int sys) { char mesg[256]; /* 48 does not suffice in Japanese */ int i, read = 0; struct partition *p = ptes[n].part_table; struct partition *q = ptes[ext_index].part_table; sector_t start, stop = 0, limit, temp, first[partitions], last[partitions]; if (p && p->sys_ind) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; } fill_bounds(first, last); if (n < 4) { start = sector_offset; if (display_in_cyl_units || !cxt->total_sectors) limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1; else limit = cxt->total_sectors - 1; if (limit > UINT_MAX) limit = UINT_MAX; if (extended_offset) { first[ext_index] = extended_offset; last[ext_index] = get_start_sect(q) + get_nr_sects(q) - 1; } } else { start = extended_offset + sector_offset; limit = get_start_sect(q) + get_nr_sects(q) - 1; } if (display_in_cyl_units) for (i = 0; i < partitions; i++) first[i] = (cround(first[i]) - 1) * units_per_sector; snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); do { sector_t dflt, aligned; temp = start; dflt = start = get_unused_start(n, start, first, last); /* the default sector should be aligned and unused */ do { aligned = align_lba_in_range(cxt, dflt, dflt, limit); dflt = get_unused_start(n, aligned, first, last); } while (dflt != aligned && dflt > aligned && dflt < limit); if (dflt >= limit) dflt = start; if (start > limit) break; if (start >= temp+units_per_sector && read) { printf(_("Sector %llu is already allocated\n"), temp); temp = start; read = 0; } if (!read && start == temp) { sector_t i = start; start = read_int(cxt, cround(i), cround(dflt), cround(limit), 0, mesg); if (display_in_cyl_units) { start = (start - 1) * units_per_sector; if (start < i) start = i; } read = 1; } } while (start != temp || !read); if (n > 4) { /* NOT for fifth partition */ struct pte *pe = &ptes[n]; pe->offset = start - sector_offset; if (pe->offset == extended_offset) { /* must be corrected */ pe->offset++; if (sector_offset == 1) start++; } } for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; if (start < pe->offset && limit >= pe->offset) limit = pe->offset - 1; if (start < first[i] && limit >= first[i]) limit = first[i] - 1; } if (start > limit) { printf(_("No free sectors available\n")); if (n > 4) partitions--; return; } if (cround(start) == cround(limit)) { stop = limit; } else { int is_suffix_used = 0; snprintf(mesg, sizeof(mesg), _("Last %1$s, +%2$s or +size{K,M,G}"), str_units(SINGULAR), str_units(PLURAL)); stop = read_int_with_suffix(cxt, cround(start), cround(limit), cround(limit), cround(start), mesg, &is_suffix_used); if (display_in_cyl_units) { stop = stop * units_per_sector - 1; if (stop >limit) stop = limit; } if (is_suffix_used && alignment_required) { /* the last sector has not been exactly requested (but * defined by +size{K,M,G} convention), so be smart * and align the end of the partition. The next * partition will start at phy.block boundary. */ stop = align_lba_in_range(cxt, stop, start, limit) - 1; if (stop > limit) stop = limit; } } set_partition(cxt, n, 0, start, stop, sys); if (n > 4) set_partition(cxt, n - 1, 1, ptes[n].offset, stop, EXTENDED); if (IS_EXTENDED (sys)) { struct pte *pe4 = &ptes[4]; struct pte *pen = &ptes[n]; ext_index = n; pen->ext_pointer = p; pe4->offset = extended_offset = start; pe4->sectorbuffer = xcalloc(1, cxt->sector_size); pe4->part_table = pt_offset(pe4->sectorbuffer, 0); pe4->ext_pointer = pe4->part_table + 1; pe4->changed = 1; partitions = 5; } }
static void read_extended(struct fdisk_context *cxt, int ext) { int i; struct pte *pex; struct partition *p, *q; ext_index = ext; pex = &ptes[ext]; pex->ext_pointer = pex->part_table; p = pex->part_table; if (!get_start_sect(p)) { fprintf(stderr, _("Bad offset in primary extended partition\n")); return; } while (IS_EXTENDED (p->sys_ind)) { struct pte *pe = &ptes[partitions]; if (partitions >= MAXIMUM_PARTS) { /* This is not a Linux restriction, but this program uses arrays of size MAXIMUM_PARTS. Do not try to `improve' this test. */ struct pte *pre = &ptes[partitions-1]; fprintf(stderr, _("Warning: omitting partitions after #%d.\n" "They will be deleted " "if you save this partition table.\n"), partitions); clear_partition(pre->ext_pointer); pre->changed = 1; return; } read_pte(cxt, partitions, extended_offset + get_start_sect(p)); if (!extended_offset) extended_offset = get_start_sect(p); q = p = pt_offset(pe->sectorbuffer, 0); for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) { if (IS_EXTENDED (p->sys_ind)) { if (pe->ext_pointer) fprintf(stderr, _("Warning: extra link " "pointer in partition table" " %d\n"), partitions + 1); else pe->ext_pointer = p; } else if (p->sys_ind) { if (pe->part_table) fprintf(stderr, _("Warning: ignoring extra " "data in partition table" " %d\n"), partitions + 1); else pe->part_table = p; } } /* very strange code here... */ if (!pe->part_table) { if (q != pe->ext_pointer) pe->part_table = q; else pe->part_table = q + 1; } if (!pe->ext_pointer) { if (q != pe->part_table) pe->ext_pointer = q; else pe->ext_pointer = q + 1; } p = pe->ext_pointer; partitions++; } /* remove empty links */ remove: for (i = 4; i < partitions; i++) { struct pte *pe = &ptes[i]; if (!get_nr_sects(pe->part_table) && (partitions > 5 || ptes[4].part_table->sys_ind)) { printf(_("omitting empty partition (%d)\n"), i+1); dos_delete_partition(i); goto remove; /* numbering changed */ } } }
static int sgi_create_disklabel(struct fdisk_context *cxt) { struct hd_geometry geometry; struct { unsigned int start; unsigned int nsect; int sysid; } old[4]; int i=0; sector_t llsectors; int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ sec_fac = cxt->sector_size / 512; /* determine the sector factor */ fprintf(stderr, _("Building a new SGI disklabel.\n")); other_endian = (BYTE_ORDER == LITTLE_ENDIAN); res = blkdev_get_sectors(cxt->dev_fd, &llsectors); #ifdef HDIO_GETGEO if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0) err(EXIT_FAILURE, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path); cxt->geom.heads = geometry.heads; cxt->geom.sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ sector_t llcyls; llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac); cxt->geom.cylinders = llcyls; if (cxt->geom.cylinders != llcyls) /* truncated? */ cxt->geom.cylinders = ~0; } else { /* otherwise print error and use truncated version */ cxt->geom.cylinders = geometry.cylinders; fprintf(stderr, _("Warning: BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %llu.\n" "This value may be truncated for devices" " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders); } #endif /* * Convert old MBR to SGI label, make it DEPRECATED, this feature * has to be handled in by any top-level fdisk command. */ for (i = 0; i < 4; i++) { old[i].sysid = 0; if (mbr_is_valid_magic(cxt->firstsector)) { if (get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; old[i].start = get_start_sect(get_part_table(i)); old[i].nsect = get_nr_sects(get_part_table(i)); if (debug) printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), old[i].sysid, old[i].start, old[i].nsect); } } } for (i = 0; i < 4; i++) if (old[i].sysid) { printf(_("Trying to keep parameters of partitions already set.\n")); break; } fdisk_zeroize_firstsector(cxt); sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SSWAP16(0); sgilabel->swap_part = SSWAP16(1); /* sizeof(sgilabel->boot_file) = 16 > 6 */ memset(sgilabel->boot_file, 0, 16); strcpy((char *) sgilabel->boot_file, "/unix"); sgilabel->devparam.skew = (0); sgilabel->devparam.gap1 = (0); sgilabel->devparam.gap2 = (0); sgilabel->devparam.sparecyl = (0); sgilabel->devparam.pcylcount = SSWAP16(geometry.cylinders); sgilabel->devparam.head_vol0 = SSWAP16(0); sgilabel->devparam.ntrks = SSWAP16(geometry.heads); /* tracks/cylinder (heads) */ sgilabel->devparam.cmd_tag_queue_depth = (0); sgilabel->devparam.unused0 = (0); sgilabel->devparam.unused1 = SSWAP16(0); sgilabel->devparam.nsect = SSWAP16(geometry.sectors); /* sectors/track */ sgilabel->devparam.bytes = SSWAP16(cxt->sector_size); sgilabel->devparam.ilfact = SSWAP16(1); sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\ IGNORE_ERRORS|RESEEK); sgilabel->devparam.datarate = SSWAP32(0); sgilabel->devparam.retries_on_error = SSWAP32(1); sgilabel->devparam.ms_per_word = SSWAP32(0); sgilabel->devparam.xylogics_gap1 = SSWAP16(0); sgilabel->devparam.xylogics_syncdelay = SSWAP16(0); sgilabel->devparam.xylogics_readdelay = SSWAP16(0); sgilabel->devparam.xylogics_gap2 = SSWAP16(0); sgilabel->devparam.xylogics_readgate = SSWAP16(0); sgilabel->devparam.xylogics_writecont = SSWAP16(0); memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15); memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16); cxt->disklabel = FDISK_DISKLABEL_SGI; partitions = 16; volumes = 15; sgi_set_entire(cxt); sgi_set_volhdr(cxt); for (i = 0; i < 4; i++) { if (old[i].sysid) { sgi_set_partition(cxt, i, old[i].start, old[i].nsect, old[i].sysid); } } return 0; }
static int xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex) { struct xbsd_partition *pp; struct geom g; get_geometry (fd, &g); bzero (d, sizeof (struct xbsd_disklabel)); d -> d_magic = BSD_DISKMAGIC; if (strncmp (disk_device, "/dev/sd", 7) == 0) d -> d_type = BSD_DTYPE_SCSI; else d -> d_type = BSD_DTYPE_ST506; #if 0 /* not used (at least not written to disk) by NetBSD/i386 1.0 */ d -> d_subtype = BSD_DSTYPE_INDOSPART & pindex; #endif #if !defined (__alpha__) d -> d_flags = BSD_D_DOSPART; #else d -> d_flags = 0; #endif d -> d_secsize = SECTOR_SIZE; /* bytes/sector */ d -> d_nsectors = g.sectors; /* sectors/track */ d -> d_ntracks = g.heads; /* tracks/cylinder (heads) */ d -> d_ncylinders = g.cylinders; d -> d_secpercyl = g.sectors * g.heads; /* sectors/cylinder */ if (d -> d_secpercyl == 0) d -> d_secpercyl = 1; /* avoid segfaults */ d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders; d -> d_rpm = 3600; d -> d_interleave = 1; d -> d_trackskew = 0; d -> d_cylskew = 0; d -> d_headswitch = 0; d -> d_trkseek = 0; d -> d_magic2 = BSD_DISKMAGIC; d -> d_bbsize = BSD_BBSIZE; d -> d_sbsize = BSD_SBSIZE; #if !defined (__alpha__) d -> d_npartitions = 4; pp = &d -> d_partitions[2]; /* Partition C should be the NetBSD partition */ pp -> p_offset = get_start_sect(p); pp -> p_size = get_nr_sects(p); pp -> p_fstype = BSD_FS_UNUSED; pp = &d -> d_partitions[3]; /* Partition D should be the whole disk */ pp -> p_offset = 0; pp -> p_size = d -> d_secperunit; pp -> p_fstype = BSD_FS_UNUSED; #elif defined (__alpha__) d -> d_npartitions = 3; pp = &d -> d_partitions[2]; /* Partition C should be the whole disk */ pp -> p_offset = 0; pp -> p_size = d -> d_secperunit; pp -> p_fstype = BSD_FS_UNUSED; #endif return 1; }
void create_sgilabel(void) { struct hd_geometry geometry; struct { unsigned int start; unsigned int nsect; int sysid; } old[4]; int i=0; unsigned long long llsectors; int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ sec_fac = sector_size / 512; /* determine the sector factor */ fprintf(stderr, _("Building a new SGI disklabel.\n")); other_endian = (BYTE_ORDER == LITTLE_ENDIAN); res = blkdev_get_sectors(fd, &llsectors); #ifdef HDIO_GETGEO if (!ioctl(fd, HDIO_GETGEO, &geometry)) { heads = geometry.heads; sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ unsigned long long llcyls; llcyls = llsectors / (heads * sectors * sec_fac); cylinders = llcyls; if (cylinders != llcyls) /* truncated? */ cylinders = ~0; } else { /* otherwise print error and use truncated version */ cylinders = geometry.cylinders; fprintf(stderr, _("Warning: BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %d.\n" "This value may be truncated for devices" " > 33.8 GB.\n"), disk_device, cylinders); } } #endif for (i = 0; i < 4; i++) { old[i].sysid = 0; if (valid_part_table_flag(MBRbuffer)) { if (get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; old[i].start = get_start_sect(get_part_table(i)); old[i].nsect = get_nr_sects(get_part_table(i)); if (debug) printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), old[i].sysid, old[i].start, old[i].nsect); } } } for (i = 0; i < 4; i++) if (old[i].sysid) { printf(_("Trying to keep parameters of partitions already set.\n")); break; } zeroize_mbr_buffer(); sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SSWAP16(0); sgilabel->swap_part = SSWAP16(1); /* sizeof(sgilabel->boot_file) = 16 > 6 */ memset(sgilabel->boot_file, 0, 16); strcpy((char *) sgilabel->boot_file, "/unix"); sgilabel->devparam.skew = (0); sgilabel->devparam.gap1 = (0); sgilabel->devparam.gap2 = (0); sgilabel->devparam.sparecyl = (0); sgilabel->devparam.pcylcount = SSWAP16(geometry.cylinders); sgilabel->devparam.head_vol0 = SSWAP16(0); sgilabel->devparam.ntrks = SSWAP16(geometry.heads); /* tracks/cylinder (heads) */ sgilabel->devparam.cmd_tag_queue_depth = (0); sgilabel->devparam.unused0 = (0); sgilabel->devparam.unused1 = SSWAP16(0); sgilabel->devparam.nsect = SSWAP16(geometry.sectors); /* sectors/track */ sgilabel->devparam.bytes = SSWAP16(sector_size); sgilabel->devparam.ilfact = SSWAP16(1); sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\ IGNORE_ERRORS|RESEEK); sgilabel->devparam.datarate = SSWAP32(0); sgilabel->devparam.retries_on_error = SSWAP32(1); sgilabel->devparam.ms_per_word = SSWAP32(0); sgilabel->devparam.xylogics_gap1 = SSWAP16(0); sgilabel->devparam.xylogics_syncdelay = SSWAP16(0); sgilabel->devparam.xylogics_readdelay = SSWAP16(0); sgilabel->devparam.xylogics_gap2 = SSWAP16(0); sgilabel->devparam.xylogics_readgate = SSWAP16(0); sgilabel->devparam.xylogics_writecont = SSWAP16(0); memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15); memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16); disklabel = SGI_LABEL; partitions = 16; volumes = 15; sgi_set_entire(); sgi_set_volhdr(); for (i = 0; i < 4; i++) { if (old[i].sysid) { sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); } } }