Пример #1
0
static int bsd_write_disklabel(struct fdisk_context *cxt)
{
    off_t offset = 0;
    struct fdisk_bsd_label *l = self_label(cxt);
    struct bsd_disklabel *d = self_disklabel(cxt);


    if (l->dos_part)
        offset = dos_partition_get_start(l->dos_part) * cxt->sector_size;

    d->d_checksum = 0;
    d->d_checksum = bsd_dkcksum(d);

    /* Update label within boot block. */
    memmove(&l->bsdbuffer[BSD_LABELSECTOR * DEFAULT_SECTOR_SIZE
                          + BSD_LABELOFFSET], d, sizeof(*d));

#if defined (__alpha__) && BSD_LABELSECTOR == 0
    /* Write the checksum to the end of the first sector. */
    alpha_bootblock_checksum(l->bsdbuffer);
#endif
    if (lseek(cxt->dev_fd, offset, SEEK_SET) == -1) {
        fdisk_warn(cxt, _("seek on %s failed"), cxt->dev_path);
        return -errno;
    }
    if (write_all(cxt->dev_fd, l->bsdbuffer, sizeof(l->bsdbuffer))) {
        fdisk_warn(cxt, _("cannot write %s"), cxt->dev_path);
        return -errno;
    }
    sync_disks(cxt);

    fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
                _("Disklabel written to %s."), cxt->dev_path);
    return 0;
}
Пример #2
0
int fdisk_sgi_set_bootfile(struct fdisk_context *cxt)
{
	int rc = 0;
	size_t sz;
	char *name = NULL;
	struct sgi_disklabel *sgilabel = self_disklabel(cxt);

	fdisk_info(cxt, _("The current boot file is: %s"), sgilabel->boot_file);

	rc = fdisk_ask_string(cxt, _("Enter of the new boot file"), &name);
	if (rc == 0)
		rc = sgi_check_bootfile(cxt, name);
	if (rc) {
		if (rc == 1)
			fdisk_info(cxt, _("Boot file unchanged"));
		goto done;
	}

	memset(sgilabel->boot_file, 0, sizeof(sgilabel->boot_file));
	sz = strlen(name);

	assert(sz <= sizeof(sgilabel->boot_file));	/* see sgi_check_bootfile() */

	memcpy(sgilabel->boot_file, name, sz);

	fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
			_("Bootfile is changed to \"%s\"."), name);
done:
	free(name);
	return rc;
}
Пример #3
0
void change_partition_type(struct fdisk_context *cxt)
{
	size_t i;
	struct fdisk_parttype *t = NULL, *org_t = NULL;

	assert(cxt);
	assert(cxt->label);

	if (fdisk_ask_partnum(cxt, &i, FALSE))
		return;

	org_t = t = fdisk_get_partition_type(cxt, i);
	if (!t)
                fdisk_warnx(cxt, _("Partition %zu does not exist yet!"), i + 1);
        else {
		do {
			t = ask_partition_type(cxt);
		} while (!t);

		if (fdisk_set_partition_type(cxt, i, t) == 0)
			fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
				_("Changed type of partition '%s' to '%s'."),
				org_t ? org_t->name : _("Unknown"),
				    t ?     t->name : _("Unknown"));
		else
			fdisk_info(cxt,
				_("Type of partition %zu is unchanged: %s."),
				i + 1,
				org_t ? org_t->name : _("Unknown"));
        }

	fdisk_free_parttype(t);
	fdisk_free_parttype(org_t);
}
Пример #4
0
int fdisk_info_new_partition(
			struct fdisk_context *cxt,
			int num, sector_t start, sector_t stop,
			struct fdisk_parttype *t)
{
	int rc;
	char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
				     (uint64_t)(stop - start + 1) * cxt->sector_size);

	rc = fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
			_("Created a new partition %d of type '%s' and of size %s."),
			num, t ? t->name : _("Unknown"), str);
	free(str);
	return rc;
}
Пример #5
0
/*
 * link partition from parent (DOS) to nested BSD partition table
 */
int fdisk_bsd_link_partition(struct fdisk_context *cxt)
{
    size_t k, i;
    int rc;
    struct dos_partition *p;
    struct bsd_disklabel *d = self_disklabel(cxt);

    if (!cxt->parent || !fdisk_is_disklabel(cxt->parent, DOS)) {
        fdisk_warnx(cxt, _("BSD label is not nested within a DOS partition."));
        return -EINVAL;
    }

    /* ask for DOS partition */
    rc = fdisk_ask_partnum(cxt->parent, &k, FALSE);
    if (rc)
        return rc;
    /* ask for BSD partition */
    rc = fdisk_ask_partnum(cxt, &i, TRUE);
    if (rc)
        return rc;

    if (i >= BSD_MAXPARTITIONS)
        return -EINVAL;

    p = fdisk_dos_get_partition(cxt->parent, k);

    d->d_partitions[i].p_size   = dos_partition_get_size(p);
    d->d_partitions[i].p_offset = dos_partition_get_start(p);
    d->d_partitions[i].p_fstype = bsd_translate_fstype(p->sys_ind);

    if (i >= d->d_npartitions)
        d->d_npartitions = i + 1;

    cxt->label->nparts_cur = d->d_npartitions;
    fdisk_label_set_changed(cxt->label, 1);

    fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
                _("BSD partition '%c' linked to DOS partition %zu."),
                'a' + (int) i, k + 1);
    return 0;
}
Пример #6
0
static int bsd_get_bootstrap(struct fdisk_context *cxt,
                             char *path, void *ptr, int size)
{
    int fd;

    if ((fd = open(path, O_RDONLY)) < 0) {
        fdisk_warn(cxt, _("cannot open %s"), path);
        return -errno;
    }

    if (read_all(fd, ptr, size) != size) {
        fdisk_warn(cxt, _("cannot read %s"), path);
        close(fd);
        return -errno;
    }

    fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
                _("The bootstrap file %s successfully loaded."), path);
    close (fd);
    return 0;
}
Пример #7
0
int fdisk_bsd_write_bootstrap(struct fdisk_context *cxt)
{
    struct bsd_disklabel dl, *d = self_disklabel(cxt);
    struct fdisk_bsd_label *l = self_label(cxt);
    char *name = d->d_type == BSD_DTYPE_SCSI ? "sd" : "wd";
    char buf[BUFSIZ];
    char *res, *dp, *p;
    int rc;
    sector_t sector;

    snprintf(buf, sizeof(buf),
             _("Bootstrap: %1$sboot -> boot%1$s (default %1$s)"),
             name);
    rc = fdisk_ask_string(cxt, buf, &res);
    if (rc)
        goto done;
    if (res && *res)
        name = res;

    snprintf(buf, sizeof(buf), "%s/%sboot", BSD_LINUX_BOOTDIR, name);
    rc = bsd_get_bootstrap(cxt, buf, l->bsdbuffer,	(int) d->d_secsize);
    if (rc)
        goto done;

    /* We need a backup of the disklabel (might have changed). */
    dp = &l->bsdbuffer[BSD_LABELSECTOR * DEFAULT_SECTOR_SIZE];
    memmove(&dl, dp, sizeof(struct bsd_disklabel));

    /* The disklabel will be overwritten by 0's from bootxx anyway */
    memset(dp, 0, sizeof(struct bsd_disklabel));

    snprintf(buf, sizeof(buf), "%s/boot%s", BSD_LINUX_BOOTDIR, name);
    rc = bsd_get_bootstrap(cxt, buf,
                           &l->bsdbuffer[d->d_secsize],
                           (int) d->d_bbsize - d->d_secsize);
    if (rc)
        goto done;

    /* check end of the bootstrap */
    for (p = dp; p < dp + sizeof(struct bsd_disklabel); p++) {
        if (!*p)
            continue;
        fdisk_warnx(cxt, _("Bootstrap overlaps with disklabel!"));
        return -EINVAL;
    }

    /* move disklabel back */
    memmove(dp, &dl, sizeof(struct bsd_disklabel));

    sector = 0;
    if (l->dos_part)
        sector = dos_partition_get_start(l->dos_part);
#if defined (__alpha__)
    alpha_bootblock_checksum(l->bsdbuffer);
#endif
    if (lseek(cxt->dev_fd, (off_t) sector * DEFAULT_SECTOR_SIZE, SEEK_SET) == -1) {
        fdisk_warn(cxt, _("seek on %s failed"), cxt->dev_path);
        rc = -errno;
        goto done;
    }
    if (write_all(cxt->dev_fd, l->bsdbuffer, BSD_BBSIZE)) {
        fdisk_warn(cxt, _("cannot write %s"), cxt->dev_path);
        rc = -errno;
        goto done;
    }

    fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
                _("Bootstrap installed on %s."), cxt->dev_path);
    sync_disks(cxt);

    rc = 0;
done:
    free(res);
    return rc;
}
Пример #8
0
static int sgi_create_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_sgi_label *sgi;
	struct sgi_disklabel *sgilabel;
	struct hd_geometry geometry;
	sector_t llsectors;
	int res; 		/* the result from the ioctl */
	int sec_fac; 		/* the sector factor */

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_disklabel(cxt, SGI));

	sec_fac = cxt->sector_size / 512;	/* determine the sector factor */
	res = blkdev_get_sectors(cxt->dev_fd, &llsectors);

#ifdef HDIO_GETGEO
	/* TODO: it seems unnecessary, geometry is already set in the context */
	if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0) {
		fdisk_warn(cxt, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path);
		return -1;
	}
	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;
		fdisk_warnx(cxt,
			_("Warning:  BLKGETSIZE ioctl failed on %s.  "
			  "Using geometry cylinder value of %llu."
			  "This value may be truncated for devices"
			  " > 33.8 GB."), cxt->dev_path, cxt->geom.cylinders);
	}
#endif
	fdisk_zeroize_firstsector(cxt);
	sgi = (struct fdisk_sgi_label *) cxt->label;
	sgi->header = (struct sgi_disklabel *) cxt->firstsector;

	sgilabel = sgi->header;

	sgilabel->magic = cpu_to_be32(SGI_LABEL_MAGIC);
	sgilabel->root_part_num = cpu_to_be16(0);
	sgilabel->swap_part_num = cpu_to_be16(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	= cpu_to_be16(geometry.cylinders);
	sgilabel->devparam.head_vol0	= cpu_to_be16(0);
	sgilabel->devparam.ntrks	= cpu_to_be16(geometry.heads);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.cmd_tag_queue_depth	= (0);
	sgilabel->devparam.unused0			= (0);
	sgilabel->devparam.unused1	= cpu_to_be16(0);
	sgilabel->devparam.nsect	= cpu_to_be16(geometry.sectors);
	/* sectors/track */
	sgilabel->devparam.bytes	= cpu_to_be16(cxt->sector_size);
	sgilabel->devparam.ilfact	= cpu_to_be16(1);
	sgilabel->devparam.flags	= cpu_to_be32(
			SGI_DEVPARAM_TRACK_FWD
			| SGI_DEVPARAM_IGNORE_ERRORS
			| SGI_DEVPARAM_RESEEK);
	sgilabel->devparam.datarate	= cpu_to_be32(0);
	sgilabel->devparam.retries_on_error	= cpu_to_be32(1);
	sgilabel->devparam.ms_per_word		= cpu_to_be32(0);
	sgilabel->devparam.xylogics_gap1	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_syncdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_gap2	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readgate	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_writecont	= cpu_to_be16(0);

	memset(&(sgilabel->volume), 0,
			sizeof(struct sgi_volume) * SGI_MAXVOLUMES);
	memset(&(sgilabel->partitions), 0,
			sizeof(struct sgi_partition) * SGI_MAXPARTITIONS);
	cxt->label->nparts_max = SGI_MAXPARTITIONS;
	sgi_set_entire(cxt);
	sgi_set_volhdr(cxt);

	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
			_("Created a new SGI disklabel."));
	return 0;
}
Пример #9
0
static int sun_create_disklabel(struct fdisk_context *cxt)
{
	unsigned int ndiv;
	struct fdisk_sun_label *sun;		/* libfdisk sun handler */
	struct sun_disklabel *sunlabel;	/* on disk data */

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_disklabel(cxt, SUN));

	/* map first sector to header */
	fdisk_zeroize_firstsector(cxt);
	sun = (struct fdisk_sun_label *) cxt->label;
	sun->header = (struct sun_disklabel *) cxt->firstsector;

	sunlabel = sun->header;

	cxt->label->nparts_max = SUN_MAXPARTITIONS;

	sunlabel->magic = cpu_to_be16(SUN_LABEL_MAGIC);
	sunlabel->vtoc.version = cpu_to_be32(SUN_VTOC_VERSION);
	sunlabel->vtoc.sanity = cpu_to_be32(SUN_VTOC_SANITY);
	sunlabel->vtoc.nparts = cpu_to_be16(SUN_MAXPARTITIONS);

#ifdef HDIO_GETGEO
	if (cxt->geom.heads && cxt->geom.sectors) {
		sector_t llsectors;

		if (blkdev_get_sectors(cxt->dev_fd, &llsectors) == 0) {
			int sec_fac = cxt->sector_size / 512;
			sector_t llcyls;

			llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
			cxt->geom.cylinders = llcyls;
			if (cxt->geom.cylinders != llcyls)
				cxt->geom.cylinders = ~0;
		} else {
			fdisk_warnx(cxt,
				_("BLKGETSIZE ioctl failed on %s. "
				  "Using geometry cylinder value of %llu. "
				  "This value may be truncated for devices "
				  "> 33.8 GB."),
				cxt->dev_path, cxt->geom.cylinders);
		}
	} else
#endif
		ask_geom(cxt);

	sunlabel->acyl   = cpu_to_be16(0);
	sunlabel->pcyl   = cpu_to_be16(cxt->geom.cylinders);
	sunlabel->rpm    = cpu_to_be16(5400);
	sunlabel->intrlv = cpu_to_be16(1);
	sunlabel->apc    = cpu_to_be16(0);

	sunlabel->nhead  = cpu_to_be16(cxt->geom.heads);
	sunlabel->nsect  = cpu_to_be16(cxt->geom.sectors);
	sunlabel->ncyl   = cpu_to_be16(cxt->geom.cylinders);

	snprintf((char *) sunlabel->label_id, sizeof(sunlabel->label_id),
		 "Linux cyl %llu alt %u hd %u sec %llu",
		 cxt->geom.cylinders, be16_to_cpu(sunlabel->acyl),
		 cxt->geom.heads, cxt->geom.sectors);

	if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) {
	        ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */
	} else
	        ndiv = cxt->geom.cylinders * 2 / 3;

	set_sun_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_LINUX_NATIVE);
	set_sun_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors,
			  cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_LINUX_SWAP);
	sunlabel->vtoc.infos[1].flags |= cpu_to_be16(SUN_FLAG_UNMNT);

	set_sun_partition(cxt, 2, 0,
			  cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_WHOLEDISK);

	{
		unsigned short *ush = (unsigned short *)sunlabel;
		unsigned short csum = 0;
		while(ush < (unsigned short *)(&sunlabel->csum))
			csum ^= *ush++;
		sunlabel->csum = csum;
	}

	fdisk_label_set_changed(cxt->label, 1);
	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
			_("Created a new Sun disklabel."));
	return 0;
}