Beispiel #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;
}
Beispiel #2
0
/**
 * fdisk_deassign_device:
 * @cxt: context
 * @nosync: disable fsync()
 *
 * Close device and call fsync(). If the @cxt is nested context than the
 * request is redirected to the parent.
 *
 * Returns: 0 on success, < 0 on error.
 */
int fdisk_deassign_device(struct fdisk_context *cxt, int nosync)
{
	assert(cxt);
	assert(cxt->dev_fd >= 0);

	if (cxt->parent) {
		int rc = fdisk_deassign_device(cxt->parent, nosync);

		if (!rc)
			rc = init_nested_from_parent(cxt, 0);
		return rc;
	}

	if (cxt->readonly)
		close(cxt->dev_fd);
	else {
		if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
			fdisk_warn(cxt, _("%s: close device failed"),
					cxt->dev_path);
			return -errno;
		}

		if (!nosync) {
			fdisk_info(cxt, _("Syncing disks."));
			sync();
		}
	}

	free(cxt->dev_path);
	cxt->dev_path = NULL;

	cxt->dev_fd = -1;

	return 0;
}
Beispiel #3
0
static void dump_blkdev(struct fdisk_context *cxt, const char *name,
			off_t offset, size_t size, int all)
{
	fdisk_colon(cxt, _("\n%s: offset = %ju, size = %zu bytes."),
			name, offset, size);

	if (lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1)
		fdisk_warn(cxt, _("cannot seek"));
	else {
		unsigned char *buf = xmalloc(size);

		if (read_all(cxt->dev_fd, (char *) buf, size) != (ssize_t) size)
			fdisk_warn(cxt, _("cannot read"));
		else
			dump_buffer(offset, buf, size, all);
		free(buf);
	}
}
Beispiel #4
0
static void backup_sectors(struct sfdisk *sf,
			   const char *tpl,
			   const char *name,
			   const char *devname,
			   uint64_t offset, size_t size)
{
	char *fname;
	int fd, devfd;

	devfd = fdisk_get_devfd(sf->cxt);
	assert(devfd >= 0);

	xasprintf(&fname, "%s0x%08jx.bak", tpl, offset);

	fd = open(fname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (fd < 0)
		goto fail;

	if (lseek(devfd, (off_t) offset, SEEK_SET) == (off_t) -1) {
		fdisk_warn(sf->cxt, _("cannot seek %s"), devname);
		goto fail;
	} else {
		unsigned char *buf = xmalloc(size);

		if (read_all(devfd, (char *) buf, size) != (ssize_t) size) {
			fdisk_warn(sf->cxt, _("cannot read %s"), devname);
			goto fail;
		}
		if (write_all(fd, buf, size) != 0) {
			fdisk_warn(sf->cxt, _("cannot write %s"), fname);
			goto fail;
		}
		free(buf);
	}

	fdisk_info(sf->cxt, _("%12s (offset %5ju, size %5ju): %s"),
			name, (uintmax_t) offset, (uintmax_t) size, fname);
	close(fd);
	free(fname);
	return;
fail:
	errx(EXIT_FAILURE, _("%s: failed to create a backup"), devname);
}
Beispiel #5
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;
}
Beispiel #6
0
int fdisk_context_deassign_device(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->dev_fd >= 0);

	if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
		fdisk_warn(cxt, _("%s: close device failed"), cxt->dev_path);
		return -errno;
	}

	fdisk_info(cxt, _("Syncing disks."));
	sync();

	cxt->dev_fd = -1;
	return 0;
}
Beispiel #7
0
void list_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_table *tb = NULL;
	struct fdisk_partition *pa = NULL;
	struct fdisk_iter *itr = NULL;
	struct fdisk_label *lb;
	struct libscols_table *out = NULL;
	const char *bold = NULL;
	int *ids = NULL;		/* IDs of fdisk_fields */
	size_t	nids = 0, i;
	int post = 0;

	/* print label specific stuff by libfdisk FDISK_ASK_INFO API */
	fdisk_list_disklabel(cxt);

	/* get partitions and generate output */
	if (fdisk_get_partitions(cxt, &tb) || fdisk_table_get_nents(tb) <= 0)
		goto done;

	ids = init_fields(cxt, NULL, &nids);
	if (!ids)
		goto done;

	itr = fdisk_new_iter(FDISK_ITER_FORWARD);
	if (!itr) {
		fdisk_warn(cxt, _("faild to allocate iterator"));
		goto done;
	}

	out = scols_new_table();
	if (!out) {
		fdisk_warn(cxt, _("faild to allocate output table"));
		goto done;
	}

	if (colors_wanted()) {
		scols_table_enable_colors(out, 1);
		bold = color_scheme_get_sequence("header", UL_COLOR_BOLD);
	}

	lb = fdisk_get_label(cxt, NULL);
	assert(lb);

	/* define output table columns */
	for (i = 0; i < nids; i++) {
		int fl = 0;
		struct libscols_column *co;
		const struct fdisk_field *field =
				fdisk_label_get_field(lb, ids[i]);
		if (!field)
			continue;
		if (fdisk_field_is_number(field))
			fl |= SCOLS_FL_RIGHT;
		if (fdisk_field_get_id(field) == FDISK_FIELD_TYPE)
			fl |= SCOLS_FL_TRUNC;

		co = scols_table_new_column(out,
				fdisk_field_get_name(field),
				fdisk_field_get_width(field), fl);
		if (!co)
			goto done;

		/* set colum header color */
		if (bold)
			scols_cell_set_color(scols_column_get_header(co), bold);
	}

	/* fill-in output table */
	while (fdisk_table_next_partition(tb, itr, &pa) == 0) {
		struct libscols_line *ln = scols_table_new_line(out, NULL);

		if (!ln) {
			fdisk_warn(cxt, _("faild to allocate output line"));
			goto done;
		}

		for (i = 0; i < nids; i++) {
			char *data = NULL;

			if (fdisk_partition_to_string(pa, cxt, ids[i], &data))
				continue;
			scols_line_refer_data(ln, i, data);
		}
	}

	/* print */
	if (!scols_table_is_empty(out)) {
		fputc('\n', stdout);
		scols_print_table(out);
	}

	/* print warnings */
	fdisk_reset_iter(itr, FDISK_ITER_FORWARD);
	while (itr && fdisk_table_next_partition(tb, itr, &pa) == 0) {
		if (!fdisk_partition_has_start(pa))
			continue;
		if (!fdisk_lba_is_phy_aligned(cxt, fdisk_partition_get_start(pa))) {
			if (!post)
				fputc('\n', stdout);
			fdisk_warnx(cxt, _("Partition %zu does not start on physical sector boundary."),
					  fdisk_partition_get_partno(pa) + 1);
			post++;
		}
	}

	if (fdisk_table_wrong_order(tb)) {
		if (!post)
			fputc('\n', stdout);
		fdisk_info(cxt, _("Partition table entries are not in disk order."));
	}
done:
	scols_unref_table(out);
	fdisk_unref_table(tb);
	fdisk_free_iter(itr);
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
0
void list_freespace(struct fdisk_context *cxt)
{
	struct fdisk_table *tb = NULL;
	struct fdisk_partition *pa = NULL;
	struct fdisk_iter *itr = NULL;
	struct libscols_table *out = NULL;
	const char *bold = NULL;
	size_t i;
	uintmax_t sumsize = 0, bytes = 0;
	char *strsz;

	static const char *colnames[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
	static const int colids[] = { FDISK_FIELD_START, FDISK_FIELD_END, FDISK_FIELD_SECTORS, FDISK_FIELD_SIZE };

	if (fdisk_get_freespaces(cxt, &tb))
		goto done;

	itr = fdisk_new_iter(FDISK_ITER_FORWARD);
	if (!itr) {
		fdisk_warn(cxt, _("failed to allocate iterator"));
		goto done;
	}

	out = scols_new_table();
	if (!out) {
		fdisk_warn(cxt, _("failed to allocate output table"));
		goto done;
	}

	if (colors_wanted()) {
		scols_table_enable_colors(out, 1);
		bold = color_scheme_get_sequence("header", UL_COLOR_BOLD);
	}

	for (i = 0; i < ARRAY_SIZE(colnames); i++) {
		struct libscols_column *co = scols_table_new_column(out, _(colnames[i]), 5, SCOLS_FL_RIGHT);

		if (!co)
			goto done;
		if (bold)
			scols_cell_set_color(scols_column_get_header(co), bold);
	}

	/* fill-in output table */
	while (fdisk_table_next_partition(tb, itr, &pa) == 0) {
		struct libscols_line *ln = scols_table_new_line(out, NULL);
		char *data;

		if (!ln) {
			fdisk_warn(cxt, _("failed to allocate output line"));
			goto done;
		}
		for (i = 0; i < ARRAY_SIZE(colids); i++) {
			if (fdisk_partition_to_string(pa, cxt, colids[i], &data))
				continue;
			scols_line_refer_data(ln, i, data);
		}

		if (fdisk_partition_has_size(pa))
			sumsize += fdisk_partition_get_size(pa);
	}

	bytes = sumsize * fdisk_get_sector_size(cxt);
	strsz = size_to_human_string(SIZE_SUFFIX_SPACE
					   | SIZE_SUFFIX_3LETTER, bytes);

	color_scheme_enable("header", UL_COLOR_BOLD);
	fdisk_info(cxt,	_("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
			fdisk_get_devname(cxt), strsz,
			bytes, sumsize);
	color_disable();
	free(strsz);

	fdisk_info(cxt, _("Units: %s of %d * %ld = %ld bytes"),
	       fdisk_get_unit(cxt, FDISK_PLURAL),
	       fdisk_get_units_per_sector(cxt),
	       fdisk_get_sector_size(cxt),
	       fdisk_get_units_per_sector(cxt) * fdisk_get_sector_size(cxt));

	fdisk_info(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
				fdisk_get_sector_size(cxt),
				fdisk_get_physector_size(cxt));

	/* print */
	if (!scols_table_is_empty(out)) {
		fdisk_info(cxt, "");	/* line break */
		scols_print_table(out);
	}
done:
	scols_unref_table(out);
	fdisk_unref_table(tb);
	fdisk_free_iter(itr);
}