示例#1
0
文件: dvh.c 项目: Distrotech/parted
/* YUCK
 *
 *  If you remove a boot/root/swap partition, the disk->disk_specific
 * thing isn't updated.  (Probably reflects a design bug somewhere...)
 * Anyway, the workaround is: flush stale flags whenever we allocate
 * new partition numbers, and before we write to disk.
 */
static void
_flush_stale_flags (const PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;

	if (dvh_disk_data->root
		       && !ped_disk_get_partition (disk, dvh_disk_data->root))
		dvh_disk_data->root = 0;
	if (dvh_disk_data->swap
		       && !ped_disk_get_partition (disk, dvh_disk_data->swap))
		dvh_disk_data->swap = 0;
	if (dvh_disk_data->boot
		       && !ped_disk_get_partition (disk, dvh_disk_data->boot))
		dvh_disk_data->boot = 0;
}
示例#2
0
文件: loop.c 项目: Excito/parted
static int
loop_write (const PedDisk* disk)
{
	size_t buflen = disk->dev->sector_size;
	char *buf = ped_malloc (buflen);
	if (buf == NULL)
		return 0;

	if (ped_disk_get_partition (disk, 1)) {
		if (!ped_device_read (disk->dev, buf, 0, 1)) {
			free (buf);
			return 0;
		}
		if (strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE)) != 0) {
			free (buf);
			return 1;
                }
		memset (buf, 0, strlen (LOOP_SIGNATURE));
		return ped_device_write (disk->dev, buf, 0, 1);
	}

	memset (buf, 0, buflen);
	strcpy (buf, LOOP_SIGNATURE);

        int write_ok = ped_device_write (disk->dev, buf, 0, 1);
        free (buf);
	return write_ok;
}
示例#3
0
文件: rdb.c 项目: inteos/WBSAirback
static int
amiga_partition_enumerate (PedPartition* part)
{
	int i;
	PedPartition* p;

	PED_ASSERT (part != NULL);
	PED_ASSERT (part->disk != NULL);

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;
	for (i = 1; i <= AMIGA_MAX_PARTITIONS; i++) {
		p = ped_disk_get_partition (part->disk, i);
		if (!p) {
			part->num = i;
			return 1;
		}
	}

	/* failed to allocate a number */
#ifndef DISCOVER_ONLY
	ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
		_("Unable to allocate a partition number."));
#endif
	return 0;
}
示例#4
0
文件: pc98.c 项目: Excito/parted
static int
next_primary (PedDisk* disk)
{
	int	i;
	for (i=1; i<=MAX_PART_COUNT; i++) {
		if (!ped_disk_get_partition (disk, i))
			return i;
	}
	return 0;
}
示例#5
0
文件: dvh.c 项目: Distrotech/parted
static int
dvh_partition_enumerate (PedPartition* part)
{
	int i;

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;

	_flush_stale_flags (part->disk);

	if (part->type & PED_PARTITION_LOGICAL) {
		/* Bootfile */
		for (i = 1 + NPARTAB; i <= NPARTAB + NVDIR; i++) {
			if (!ped_disk_get_partition (part->disk, i)) {
				part->num = i;
				return 1;
			}
		}
		PED_ASSERT (0);
	} else if (part->type & PED_PARTITION_EXTENDED) {
		/* Volheader */
		part->num = PNUM_VOLHDR + 1;
	} else {
		for (i = 1; i <= NPARTAB; i++) {
			/* reserved for full volume partition */
			if (i == PNUM_VOLUME + 1)
				continue;

			if (!ped_disk_get_partition (part->disk, i)) {
				part->num = i;
				return 1;
			}
		}
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Too many primary partitions"));
	}

	return 0;
}
示例#6
0
文件: ui.c 项目: bcl/parted
static int
_can_create_primary (const PedDisk* disk)
{
        int    i;

        for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {
                if (!ped_disk_get_partition (disk, i))
                        return 1;
        }

        return 0;
}
示例#7
0
static int
bsd_write (const PedDisk* disk)
{
	BSDDiskData*		bsd_specific;
	BSDRawLabel*		label;
	BSDPartitionData*	bsd_data;
	PedPartition*		part;
	int			i;
	int			max_part = 0;

	PED_ASSERT (disk != NULL);
	PED_ASSERT (disk->dev != NULL);

	bsd_specific = (BSDDiskData*) disk->disk_specific;
	label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET);

	if (!bsd_specific->boot_code [0])
		_probe_and_add_boot_code (disk);

	memset (label->d_partitions, 0,
		sizeof (BSDRawPartition) * BSD_MAXPARTITIONS);

	for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
		part = ped_disk_get_partition (disk, i);
		if (!part)
			continue;
		bsd_data = part->disk_specific;
		label->d_partitions[i - 1].p_fstype = bsd_data->type;
		label->d_partitions[i - 1].p_offset
			= PED_CPU_TO_LE32 (part->geom.start);
		label->d_partitions[i - 1].p_size
			= PED_CPU_TO_LE32 (part->geom.length);
		max_part = i;
	}

	label->d_npartitions = PED_CPU_TO_LE16 (max_part) + 1;
	label->d_checksum = xbsd_dkcksum (label);

	alpha_bootblock_checksum (bsd_specific->boot_code);

        if (!ptt_write_sector (disk, bsd_specific->boot_code,
                               sizeof (BSDDiskData)))
                goto error;
	return ped_device_sync (disk->dev);

error:
	return 0;
}
示例#8
0
文件: ui.c 项目: bcl/parted
int
command_line_get_partition (const char* prompt, PedDisk* disk,
                            PedPartition** value)
{
        PedPartition*    part;
        int ret;

        /* Flawed logic, doesn't seem to work?!
        check = ped_disk_next_partition (disk, part);
        part  = ped_disk_next_partition (disk, check);

        if (part == NULL) {

        *value = check;
        printf (_("The (only) primary partition has "
                  "been automatically selected\n"));
        return 1;

        } else {
        */
        int num = (*value) ? (*value)->num : 0;

        ret = command_line_get_integer (prompt, &num);
        if ((!ret) || (num < 0)) {
                ped_exception_throw (PED_EXCEPTION_ERROR,
                                     PED_EXCEPTION_CANCEL,
                                     _("Expecting a partition number."));
                return 0;
        }

        part = ped_disk_get_partition (disk, num);

        if (!part) {
                ped_exception_throw (PED_EXCEPTION_ERROR,
                                     PED_EXCEPTION_CANCEL,
                                     _("Partition doesn't exist."));
            return 0;
        }

        *value = part;
        return 1;
        //}
}
示例#9
0
文件: dasd.c 项目: bcl/parted
static int
dasd_partition_enumerate (PedPartition* part)
{
	int i;
	PedPartition* p;

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;

	for (i = 1; i <= USABLE_PARTITIONS; i++) {
		p = ped_disk_get_partition (part->disk, i);
		if (!p) {
			part->num = i;
			return 1;
		}
	}

	/* failed to allocate a number */
	ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
						_("Unable to allocate a dasd disklabel slot"));
	return 0;
}
示例#10
0
文件: pc98.c 项目: Excito/parted
static int
pc98_write (const PedDisk* disk)
{
	PedPartition*		part;
	int			i;

	PED_ASSERT (disk != NULL);
	PED_ASSERT (disk->dev != NULL);

	void *s0;
	if (!ptt_read_sectors (disk->dev, 0, 2, &s0))
		return 0;
	PC98RawTable *table = s0;

	if (!pc98_check_ipl_signature (table)) {
		memset (table->boot_code, 0, sizeof(table->boot_code));
		memcpy (table->boot_code, MBR_BOOT_CODE, sizeof(MBR_BOOT_CODE));
	}

	memset (table->partitions, 0, sizeof (table->partitions));
	table->magic = PED_CPU_TO_LE16(PC9800_EXTFMT_MAGIC);

	for (i = 1; i <= MAX_PART_COUNT; i++) {
		part = ped_disk_get_partition (disk, i);
		if (!part)
			continue;

		if (!fill_raw_part (&table->partitions [i - 1], part))
			return 0;
	}

	int write_ok = ped_device_write (disk->dev, table, 0, 2);
	free (s0);
	if (!write_ok)
		return 0;
	return ped_device_sync (disk->dev);
}
示例#11
0
static int
bsd_partition_enumerate (PedPartition* part)
{
	int i;
	PedPartition* p;

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;
	for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
		p = ped_disk_get_partition (part->disk, i);
		if (!p) {
			part->num = i;
			return 1;
		}
	}

	/* failed to allocate a number */
#ifndef DISCOVER_ONLY
	ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			     _("Unable to allocate a bsd disklabel slot."));
#endif
	return 0;
}
示例#12
0
文件: dasd.c 项目: bcl/parted
static int
dasd_alloc_metadata (PedDisk* disk)
{
	PedPartition* new_part;
	PedConstraint* constraint_any = NULL;
	PedSector vtoc_end;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;
	PedPartition* part = NULL; /* initialize solely to placate gcc */
	PedPartition* new_part2;
	PedSector trailing_meta_start, trailing_meta_end;

	PED_ASSERT (disk != NULL);
	PED_ASSERT (disk->dev != NULL);

	arch_specific = LINUX_SPECIFIC (disk->dev);
	disk_specific = disk->disk_specific;

	constraint_any = ped_constraint_any (disk->dev);

	/* For LDL or CMS, the leading metadata ends at the sector before
	   the start of the first partition */
	if (disk_specific->format_type == 1) {
	        part = ped_disk_get_partition(disk, 1);
		if (part)
			vtoc_end = part->geom.start - 1;
		else
			vtoc_end = (PedSector) arch_specific->real_sector_size /
				   (PedSector) disk->dev->sector_size *
				   (PedSector) disk_specific->label_block;
	}
	else {
                if (disk->dev->type == PED_DEVICE_FILE)
                        arch_specific->real_sector_size = disk->dev->sector_size;
        /* Mark the start of the disk as metadata. */
		vtoc_end = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors
				   * (long long) arch_specific->real_sector_size
				   / (long long) disk->dev->sector_size) - 1;
        }

	new_part = ped_partition_new (disk,PED_PARTITION_METADATA,NULL,0,vtoc_end);
	if (!new_part)
		goto error;

	if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
		ped_partition_destroy (new_part);
		goto error;
	}

	if (disk_specific->format_type == 1 && part) {
	   /*
	      For LDL or CMS there may be trailing metadata as well.
	      For example: the last block of a CMS reserved file,
	      the "recomp" area of a CMS minidisk that has been
	      formatted and then formatted again with the RECOMP
	      option specifying fewer than the maximum number of
	      cylinders, a disk that was formatted at one size,
	      backed up, then restored to a larger size disk, etc.
	   */
	   trailing_meta_start = part->geom.end + 1;
	   trailing_meta_end = (long long) disk->dev->length - 1;
	   if (trailing_meta_end >= trailing_meta_start) {
		new_part2 = ped_partition_new (disk,PED_PARTITION_METADATA,
		   NULL, trailing_meta_start, trailing_meta_end);
		if (!new_part2) {
		   ped_partition_destroy (new_part);
		   goto error;
		}
		if (!ped_disk_add_partition (disk, new_part2,
		   constraint_any)) {
		   ped_partition_destroy (new_part2);
		   ped_partition_destroy (new_part);
		   goto error;
		}
	   }
	}

	ped_constraint_destroy (constraint_any);
	return 1;

error:
	ped_constraint_destroy (constraint_any);
	return 0;
}
示例#13
0
文件: dasd.c 项目: bcl/parted
static int
dasd_write (const PedDisk* disk)
{
	DasdPartitionData* dasd_data;
	PedPartition* part;
	int i;
	partition_info_t *p;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;
	struct fdasd_anchor anchor;
	partition_info_t *part_info[USABLE_PARTITIONS];

	PED_ASSERT(disk != NULL);
	PED_ASSERT(disk->dev != NULL);

	arch_specific = LINUX_SPECIFIC (disk->dev);
	disk_specific = disk->disk_specific;

	PDEBUG;

	/* If not formated in CDL, don't write anything. */
	if (disk_specific->format_type == 1) {
		ped_exception_throw (PED_EXCEPTION_ERROR,
				     PED_EXCEPTION_CANCEL,
				     _("The partition table of DASD-LDL device cannot be changed.\n"));
		return 1;
	}

	/* initialize the anchor */
	fdasd_initialize_anchor(&anchor);
	if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0)
                goto error;

	fdasd_check_volume(&anchor, arch_specific->fd);
	memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
	anchor.vlabel_changed++;

	if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
		anchor.big_disk++;

	fdasd_recreate_vtoc(&anchor);

	for (i = 1; i <= USABLE_PARTITIONS; i++) {
		unsigned int start, stop;

		PDEBUG;
		part = ped_disk_get_partition(disk, i);
		if (!part)
			continue;

		PDEBUG;

		start = part->geom.start * disk->dev->sector_size
				/ arch_specific->real_sector_size / disk->dev->hw_geom.sectors;
		stop = (part->geom.end + 1)
			   * disk->dev->sector_size / arch_specific->real_sector_size
			   / disk->dev->hw_geom.sectors - 1;

		PDEBUG;
		dasd_data = part->disk_specific;

		p = fdasd_add_partition(&anchor, start, stop);
		if (!p) {
			PDEBUG;
			goto error;
		}
		part_info[i - 1] = p;
		p->type = dasd_data->system;
	}

	PDEBUG;

	if (!fdasd_prepare_labels(&anchor, arch_specific->fd))
		goto error;

	dasd_update_type(disk, &anchor, part_info);
	PDEBUG;

	if (!fdasd_write_labels(&anchor, arch_specific->fd))
		goto error;

	fdasd_cleanup(&anchor);
	return 1;

error:
	PDEBUG;
	fdasd_cleanup(&anchor);
	return 0;
}
示例#14
0
文件: dasd.c 项目: bcl/parted
static int
dasd_update_type (const PedDisk* disk, struct fdasd_anchor *anchor,
		  partition_info_t *part_info[USABLE_PARTITIONS])
{
	PedPartition* part;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;

	arch_specific = LINUX_SPECIFIC(disk->dev);
	disk_specific = disk->disk_specific;

	PDEBUG;

	unsigned int i;
	for (i = 1; i <= USABLE_PARTITIONS; i++) {
		partition_info_t *p;
		char *ch = NULL;
		DasdPartitionData* dasd_data;

		PDEBUG;

		part = ped_disk_get_partition(disk, i);
		if (!part)
			continue;

		PDEBUG;

		dasd_data = part->disk_specific;
		p = part_info[i - 1];

		if (!p ) {
			PDEBUG;
			continue;
		}

		vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
		ch = strstr(p->f1->DS1DSNAM, "PART");

		PDEBUG;
		if (ch == NULL) {
			vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
			PDEBUG;
			continue;
		}

		ch += 9;

		switch (dasd_data->system) {
			case PARTITION_LINUX_LVM:
				PDEBUG;
				strncpy(ch, PART_TYPE_LVM, 6);
				break;
			case PARTITION_LINUX_RAID:
				PDEBUG;
				strncpy(ch, PART_TYPE_RAID, 6);
				break;
			case PARTITION_LINUX:
				PDEBUG;
				strncpy(ch, PART_TYPE_NATIVE, 6);
				break;
			case PARTITION_LINUX_SWAP:
				PDEBUG;
				strncpy(ch, PART_TYPE_SWAP, 6);
				break;
			default:
				PDEBUG;
				strncpy(ch, PART_TYPE_NATIVE, 6);
				break;
		}

		anchor->vtoc_changed++;
		vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
	}

	return 1;
}
示例#15
0
文件: dvh.c 项目: Distrotech/parted
static int
dvh_write (const PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;
	struct volume_header	vh;
	int			i;

	PED_ASSERT (dvh_disk_data != NULL);

	_flush_stale_flags (disk);

	memset (&vh, 0, sizeof (struct volume_header));

	vh.vh_magic = PED_CPU_TO_BE32 (VHMAGIC);
	vh.vh_rootpt = PED_CPU_TO_BE16 (dvh_disk_data->root - 1);
	vh.vh_swappt = PED_CPU_TO_BE16 (dvh_disk_data->swap - 1);

	if (dvh_disk_data->boot) {
		PedPartition* boot_part;
		boot_part = ped_disk_get_partition (disk, dvh_disk_data->boot);
		strcpy (vh.vh_bootfile, ped_partition_get_name (boot_part));
	}

	vh.vh_dp = dvh_disk_data->dev_params;
	/* Set up rudimentary device geometry */
	vh.vh_dp.dp_cyls
		= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.cylinders);
	vh.vh_dp.dp_trks0 = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.heads);
	vh.vh_dp.dp_secs
		= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.sectors);
	vh.vh_dp.dp_secbytes = PED_CPU_TO_BE16 ((short)disk->dev->sector_size);

	for (i = 0; i < NPARTAB; i++) {
		PedPartition* part = ped_disk_get_partition (disk, i + 1);
		if (part)
			_generate_partition (part, &vh.vh_pt[i]);
	}

	/* whole disk partition
	 * This is only ever written here, and never modified
	 * (or even shown) as it must contain the entire disk,
	 * and parted does not like overlapping partitions
	 */
	vh.vh_pt[PNUM_VOLUME].pt_nblks = PED_CPU_TO_BE32 (disk->dev->length);
	vh.vh_pt[PNUM_VOLUME].pt_firstlbn = PED_CPU_TO_BE32 (0);
	vh.vh_pt[PNUM_VOLUME].pt_type = PED_CPU_TO_BE32 (PTYPE_VOLUME);

	for (i = 0; i < NVDIR; i++) {
		PedPartition* part = ped_disk_get_partition (disk,
							     i + 1 + NPARTAB);
		if (part)
			_generate_boot_file (part, &vh.vh_vd[i]);
	}

	vh.vh_csum = 0;
	vh.vh_csum = PED_CPU_TO_BE32 (_checksum ((uint32_t*) &vh,
			       	      sizeof (struct volume_header)));

        return (ptt_write_sector (disk, &vh, sizeof vh)
                && ped_device_sync (disk->dev));
}
示例#16
0
gboolean disk_resize_grow(const gchar* disk_path, GChildWatchFunc async_func_watcher, gpointer data) {
	char command[LINE_MAX] = { 0 };
	int last_partition_num;
	const gchar* partition_path;
	PedDevice* dev = NULL;
	PedDisk* disk = NULL;
	gboolean result = false;
	PedPartition* partition;
	PedSector start;
	PedSector end;
	PedGeometry geometry_start;
	PedGeometry* geometry_end;
	PedConstraint* constraint;

	resize_fs = false;

	/* to handle exceptions, i.e Fix PMBR */
	ped_exception_set_handler(disk_exception_handler);

	if (!disk_path) {
		LOG(MOD "Disk path is empty\n");
		return false;
	}

	dev = ped_device_get(disk_path);

	if (!dev) {
		LOG(MOD "Cannot get device '%s'\n", disk_path);
		return false;
	}

	/*
	* verify disk, disk_exception_handler will called
	* if the disk has problems and it needs to be fixed
	* and resized
	*/
	disk = ped_disk_new(dev);

	if (!disk) {
		LOG(MOD "Cannot create a new disk '%s'\n", disk_path);
		return false;
	}

	if (!resize_fs) {
		/* do not resize filesystem, it is ok */
		LOG(MOD "Nothing to do with '%s' disk\n", disk_path);
		return false;
	}

	LOG(MOD "Resizing filesystem disk '%s'\n", disk_path);

	last_partition_num = ped_disk_get_last_partition_num(disk);
	partition = ped_disk_get_partition(disk, last_partition_num);

	if (!partition) {
		LOG(MOD "Cannot get partition '%d' disk '%s'\n", last_partition_num, disk_path);
		return false;
	}

	start = partition->geom.start;
	end = (-PED_MEGABYTE_SIZE) / dev->sector_size + dev->length;

	geometry_start.dev = dev;
	geometry_start.start = start;
	geometry_start.end = end;
	geometry_start.length = 1;

	geometry_end = ped_geometry_new(dev, end, 1);

	if (!geometry_end) {
		LOG(MOD "Cannot get partition '%d' disk '%s'\n", last_partition_num, disk_path);
		return false;
	}

	constraint = ped_constraint_new(ped_alignment_any, ped_alignment_any, &geometry_start, geometry_end, 1, dev->length);

	if (!constraint) {
		LOG(MOD "Cannot create a new constraint disk '%s'\n", disk_path);
		goto fail1;
	}

	if (!ped_disk_set_partition_geom(disk, partition, constraint, start, end)) {
		LOG(MOD "Cannot set partition geometry disk '%s'\n", disk_path);
		goto fail2;
	}

	if (!ped_disk_commit(disk)) {
		LOG(MOD "Cannot write the partition table to disk '%s'\n", disk_path);
		goto fail2;
	}

	partition_path = ped_partition_get_path(partition);

	if (!partition_path) {
		LOG(MOD "Cannot get partition path disk '%s'\n", disk_path);
		goto fail2;
	}

	snprintf(command, LINE_MAX, RESIZEFS_PATH " %s", partition_path);
	exec_task_async(command, async_func_watcher, data);

	result = true;
	LOG(MOD "Resizing filesystem done\n");

fail2:
	ped_constraint_destroy (constraint);
fail1:
	ped_geometry_destroy (geometry_end);
	return result;
}