Пример #1
0
void list_disk_geometry(struct fdisk_context *cxt)
{
	char *id = NULL;
	uint64_t bytes = cxt->total_sectors * cxt->sector_size;
	char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE
					   | SIZE_SUFFIX_3LETTER, bytes);

	fdisk_colon(cxt,	_("Disk %s: %s, %ju bytes, %ju sectors"),
			cxt->dev_path, strsz,
			bytes, (uintmax_t) cxt->total_sectors);
	free(strsz);

	if (fdisk_require_geometry(cxt) || fdisk_context_use_cylinders(cxt))
		fdisk_colon(cxt, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
			       cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);

	fdisk_colon(cxt, _("Units: %s of %d * %ld = %ld bytes"),
	       fdisk_context_get_unit(cxt, PLURAL),
	       fdisk_context_get_units_per_sector(cxt),
	       cxt->sector_size,
	       fdisk_context_get_units_per_sector(cxt) * cxt->sector_size);

	fdisk_colon(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
				cxt->sector_size, cxt->phy_sector_size);
	fdisk_colon(cxt, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
				cxt->min_io_size, cxt->io_size);
	if (cxt->alignment_offset)
		fdisk_colon(cxt, _("Alignment offset: %lu bytes"),
				cxt->alignment_offset);
	if (fdisk_dev_has_disklabel(cxt))
		fdisk_colon(cxt, _("Disklabel type: %s"), cxt->label->name);

	if (fdisk_get_disklabel_id(cxt, &id) == 0 && id)
		fdisk_colon(cxt, _("Disk identifier: %s"), id);
}
Пример #2
0
static void print_device_pt(struct fdisk_context *cxt, char *device)
{
	if (fdisk_context_assign_device(cxt, device, 1) != 0)	/* read-only */
		err(EXIT_FAILURE, _("cannot open %s"), device);

	list_disk_geometry(cxt);

	if (fdisk_dev_has_disklabel(cxt))
		fdisk_list_disklabel(cxt);
	fputc('\n', stdout);
}
Пример #3
0
/**
 * fdisk_context_assign_device:
 * @fname: path to the device to be handled
 * @readonly: how to open the device
 *
 * If the @readonly flag is set to false, fdisk will attempt to open
 * the device with read-write mode and will fallback to read-only if
 * unsuccessful.
 *
 * Returns: 0 on success, < 0 on error.
 */
int fdisk_context_assign_device(struct fdisk_context *cxt,
				const char *fname, int readonly)
{
	int fd;

	DBG(CONTEXT, dbgprint("assigning device %s", fname));
	assert(cxt);

	reset_context(cxt);

	if (readonly == 1 || (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
		if ((fd = open(fname, O_RDONLY|O_CLOEXEC)) < 0)
			return -errno;
		readonly = 1;
	}

	cxt->dev_fd = fd;
	cxt->dev_path = strdup(fname);
	if (!cxt->dev_path)
		goto fail;

	fdisk_discover_topology(cxt);
	fdisk_discover_geometry(cxt);

	if (fdisk_read_firstsector(cxt) < 0)
		goto fail;

	/* detect labels and apply labes specific stuff (e.g geomery)
	 * to the context */
	fdisk_probe_labels(cxt);

	/* let's apply user geometry *after* label prober
	 * to make it possible to override in-label setting */
	fdisk_apply_user_device_properties(cxt);

	/* warn about obsolete stuff on the device if we aren't in
	 * list-only mode and there is not PT yet */
	if (!fdisk_context_listonly(cxt) && !fdisk_dev_has_disklabel(cxt))
		warn_wipe(cxt);

	DBG(CONTEXT, dbgprint("context %p initialized for %s [%s]",
			      cxt, fname,
			      readonly ? "READ-ONLY" : "READ-WRITE"));
	return 0;
fail:
	DBG(CONTEXT, dbgprint("failed to assign device"));
	return -errno;
}
Пример #4
0
/*
 * This function prints a warning if the device is not wiped (e.g. wipefs(8).
 * Please don't call this function if there is already a PT.
 *
 * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
 */
static int warn_wipe(struct fdisk_context *cxt)
{
#ifdef HAVE_LIBBLKID
	blkid_probe pr;
#endif
	int rc = 0;

	assert(cxt);

	if (fdisk_dev_has_disklabel(cxt) || cxt->dev_fd < 0)
		return -EINVAL;
#ifdef HAVE_LIBBLKID
	DBG(LABEL, dbgprint("wipe check: initialize libblkid prober"));

	pr = blkid_new_probe();
	if (!pr)
		return -ENOMEM;
	rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
	if (rc)
		return rc;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
	blkid_probe_enable_partitions(pr, 1);

	/* we care about the first found FS/raid, so don't call blkid_do_probe()
	 * in loop or don't use blkid_do_fullprobe() ... */
	rc = blkid_do_probe(pr);
	if (rc == 0) {
		const char *name = NULL;

		if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0 ||
		    blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
			fdisk_warnx(cxt, _(
				"%s: device contains a valid '%s' signature, it's "
				"strongly recommended to wipe the device by command wipefs(8) "
				"if this setup is unexpected to avoid "
				"possible collisions."), cxt->dev_path, name);
			rc = 1;
		}
	}

	blkid_free_probe(pr);
#endif
	return rc;
}
Пример #5
0
int main(int argc, char **argv)
{
	int i, c, act = ACT_FDISK;
	int colormode = UL_COLORMODE_AUTO;
	struct fdisk_context *cxt;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	fdisk_init_debug(0);
	cxt = fdisk_new_context();
	if (!cxt)
		err(EXIT_FAILURE, _("failed to allocate libfdisk context"));

	fdisk_context_set_ask(cxt, ask_callback, NULL);

	while ((c = getopt(argc, argv, "b:c::C:hH:lL::sS:t:u::vV")) != -1) {
		switch (c) {
		case 'b':
		{
			size_t sz = strtou32_or_err(optarg,
					_("invalid sector size argument"));
			if (sz != 512 && sz != 1024 && sz != 2048 && sz != 4096)
				usage(stderr);
			fdisk_save_user_sector_size(cxt, sz, sz);
			break;
		}
		case 'C':
			fdisk_save_user_geometry(cxt,
				strtou32_or_err(optarg,
						_("invalid cylinders argument")),
				0, 0);
			break;
		case 'c':
			if (optarg) {
				/* this setting is independent on the current
				 * actively used label */
				struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos");
				if (!lb)
					err(EXIT_FAILURE, _("not found DOS label driver"));
				if (strcmp(optarg, "=dos") == 0)
					fdisk_dos_enable_compatible(lb, TRUE);
				else if (strcmp(optarg, "=nondos") == 0)
					fdisk_dos_enable_compatible(lb, FALSE);
				else
					usage(stderr);
			}
			/* use default if no optarg specified */
			break;
		case 'H':
			fdisk_save_user_geometry(cxt, 0,
				strtou32_or_err(optarg,
						_("invalid heads argument")),
				0);
			break;
		case 'S':
			fdisk_save_user_geometry(cxt, 0, 0,
				strtou32_or_err(optarg,
					_("invalid sectors argument")));
			break;
		case 'l':
			act = ACT_LIST;
			break;
		case 'L':
			if (optarg)
				colormode = colormode_or_err(optarg,
						_("unsupported color mode"));
			break;
		case 's':
			act = ACT_SHOWSIZE;
			break;
		case 't':
		{
			struct fdisk_label *lb = NULL;

			while (fdisk_context_next_label(cxt, &lb) == 0)
				fdisk_label_set_disabled(lb, 1);

			lb = fdisk_context_get_label(cxt, optarg);
			if (!lb)
				errx(EXIT_FAILURE, _("unsupported disklabel: %s"), optarg);
			fdisk_label_set_disabled(lb, 0);
		}
		case 'u':
			if (optarg && *optarg == '=')
				optarg++;
			if (fdisk_context_set_unit(cxt, optarg) != 0)
				usage(stderr);
			break;
		case 'V':
		case 'v':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}

	if (argc-optind != 1 && fdisk_has_user_device_properties(cxt))
		warnx(_("The device properties (sector size and geometry) should"
			" be used with one specified device only."));

	colors_init(colormode);

	switch (act) {
	case ACT_LIST:
		fdisk_context_enable_listonly(cxt, 1);

		if (argc > optind) {
			int k;
			for (k = optind; k < argc; k++)
				print_device_pt(cxt, argv[k]);
		} else
			print_all_devices_pt(cxt);
		break;

	case ACT_SHOWSIZE:
		/* deprecated */
		if (argc - optind <= 0)
			usage(stderr);

		for (i = optind; i < argc; i++) {
			if (argc - optind == 1)
				printf("%llu\n", get_dev_blocks(argv[i]));
			else
				printf("%s: %llu\n", argv[i], get_dev_blocks(argv[i]));
		}
		break;

	case ACT_FDISK:
		if (argc-optind != 1)
			usage(stderr);

		if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0)
			err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);

		/* Here starts interactive mode, use fdisk_{warn,info,..} functions */
		color_enable(UL_COLOR_GREEN);
		fdisk_info(cxt, _("Welcome to fdisk (%s)."), PACKAGE_STRING);
		color_disable();
		fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n"
				  "Be careful before using the write command.\n"));
		fflush(stdout);

		if (!fdisk_dev_has_disklabel(cxt)) {
			fdisk_warnx(cxt, _("Device does not contain a recognized partition table."));
			fdisk_create_disklabel(cxt, NULL);
		}

		while (1)
			process_fdisk_menu(&cxt);
	}

	fdisk_free_context(cxt);
	return EXIT_SUCCESS;
}