Beispiel #1
0
/* 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;
}
Beispiel #2
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 */
		}
	}
}
Beispiel #10
0
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;
}
Beispiel #12
0
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);
		}
	}
}