Exemple #1
0
static sector_t get_dev_blocks(char *dev)
{
	int fd;
	sector_t size;

	if ((fd = open(dev, O_RDONLY)) < 0)
		err(EXIT_FAILURE, _("cannot open %s"), dev);
	if (blkdev_get_sectors(fd, &size) == -1) {
		close(fd);
		err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), dev);
	}
	close(fd);
	return size/2;
}
Exemple #2
0
static int get_size(const char *dev, int silent, uintmax_t *sz)
{
	int fd, rc = 0;

	fd = open(dev, O_RDONLY);
	if (fd < 0) {
		if (!silent)
			warn(_("cannot open %s"), dev);
		return -errno;
	}

	if (blkdev_get_sectors(fd, (unsigned long long *) sz) == -1) {
		if (!silent)
			warn(_("Cannot get size of %s"), dev);
		rc = -errno;
	}

	close(fd);
	return rc;
}
Exemple #3
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 */
	int rc = 0;

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

	/* map first sector to header */
	rc = fdisk_init_firstsector_buffer(cxt, 0, 0);
	if (rc)
		return rc;

	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) {
		fdisk_sector_t llsectors;

		if (blkdev_get_sectors(cxt->dev_fd, (unsigned long long *) &llsectors) == 0) {
			int sec_fac = cxt->sector_size / 512;
			fdisk_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 %ju alt %u hd %u sec %ju",
		 (uintmax_t) cxt->geom.cylinders,
		 be16_to_cpu(sunlabel->acyl),
		 cxt->geom.heads,
		 (uintmax_t) 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;

	/* create the default layout only if no-script defined */
	if (!cxt->script) {
		set_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_LINUX_NATIVE);
		set_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_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_info(cxt, _("Created a new Sun disklabel."));
	return 0;
}
Exemple #4
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;
}
Exemple #5
0
int
main(int argc, char **argv) {
    int fd, fd2, c, i, j, k, n;
    unsigned long long size;
    struct hd_geometry g;
    struct slice all;
    struct blkpg_ioctl_arg a;
    struct blkpg_partition pt;
    struct pt *ptp;
    enum action what = LIST;
    char *p, *type, *diskdevice, *device;
    int lower, upper;
    int verbose = 0;
    int ret = 0;

    initpts();
    init_crc32();

    lower = upper = 0;
    type = device = diskdevice = NULL;

    while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL))
            != -1) switch(c) {
        case 'l':
            what = LIST;
            break;
        case 'a':
            what = ADD;
            break;
        case 'd':
            what = DELETE;
            break;
        case 'g':
            force_gpt = 1;
            break;
        case 'n':
            p = optarg;
            lower = atoi(p);
            p = strchr(p, '-');
            if (p)
                upper = atoi(p+1);
            else
                upper = lower;
            break;
        case 't':
            type = optarg;
            break;
        case 'v':
            verbose = 1;
            break;
        case '?':
        default:
            fprintf(stderr, "unknown option\n");
            exit(1);
        }

    if (optind == argc-2) {
        device = argv[optind];
        diskdevice = argv[optind+1];
    } else if (optind == argc-1) {
        diskdevice = device = argv[optind];
    } else {
        fprintf(stderr, "call: partx -opts [device] wholedisk\n");
        exit(1);
    }

    fd = open(diskdevice, O_RDONLY);
    if (fd == -1) {
        perror(diskdevice);
        exit(1);
    }

    /* remove the indicated partitions from the kernel partition tables */
    if (what == DELETE) {
        if (device != diskdevice) {
            fprintf(stderr,
                    "call: partx -d [--nr M-N] wholedisk\n");
            exit(1);
        }

        if (!lower)
            lower = 1;

        while (upper == 0 || lower <= upper) {
            int err;

            if (lower > MAXSLICES)
                break;
            pt.pno = lower;
            pt.start = 0;
            pt.length = 0;
            pt.devname[0] = 0;
            pt.volname[0] = 0;
            a.op = BLKPG_DEL_PARTITION;
            a.flags = 0;
            a.datalen = sizeof(pt);
            a.data = &pt;
            if (ioctl(fd, BLKPG, &a) == -1)
                err = errno;
            else
                err = 0;
            errmerge(err, lower,
                     "error deleting partition %d: ",
                     "error deleting partitions %d-%d: ");
            /* expected errors:
               EBUSY: mounted or in use as swap
               ENXIO: no such nonempty partition
               EINVAL: not wholedisk, or bad pno
               EACCES/EPERM: permission denied
            */
            if (err && err != EBUSY && err != ENXIO) {
                ret = 1;
                break;
            }
            if (err == 0 && verbose)
                printf("deleted partition %d\n", lower);
            lower++;
        }
        errmerge(0, 0,
                 "error deleting partition %d: ",
                 "error deleting partitions %d-%d: ");
        return ret;
    }

    if (device != diskdevice) {
        fd2 = open(device, O_RDONLY);
        if (fd2 == -1) {
            perror(device);
            exit(1);
        }
    } else {
        fd2 = fd;
    }

    if (ioctl(fd, HDIO_GETGEO, &g)) {
        perror("HDIO_GETGEO");
        exit(1);
    }
    if (g.start != 0) {
        fprintf(stderr, "last arg is not the whole disk\n");
        fprintf(stderr, "call: partx -opts device wholedisk\n");
        exit(1);
    }

    if (ioctl(fd2, HDIO_GETGEO, &g)) {
        perror("HDIO_GETGEO");
        exit(1);
    }
    all.start = g.start;

    if (blkdev_get_sectors(fd2, &size) != 0) {
        perror("partx");
        exit(1);
    }
    all.size = (unsigned int) size;

    if (verbose)
        printf("device %s: start %d size %d\n",
               device, all.start, all.size);

    if (all.size == 0) {
        fprintf(stderr, "That disk slice has size 0\n");
        exit(0);
    }
    if (all.size == 2)
        all.size = 0;	/* probably extended partition */

    /* add the indicated partitions to the kernel partition tables */
    if (!lower)
        lower = 1;
    for (i = 0; i < ptct; i++) {
        ptp = &pts[i];
        if (!type || !strcmp(type, ptp->type)) {
            n = ptp->fn(fd, all, slices, ARRAY_SIZE(slices));
            if (n >= 0 && verbose)
                printf("%s: %d slices\n", ptp->type, n);
            if (n > 0 && (verbose || what == LIST)) {
                for (j=0; j<n; j++)
                    printf("#%2d: %9d-%9d (%9d sectors, %6d MB)\n",
                           lower+j,
                           slices[j].start,
                           slices[j].start+slices[j].size-1,
                           slices[j].size,
                           (int)((512 * (long long) slices[j].size)
                                 / 1000000));
            }
            if (n > 0 && what == ADD) {
                /* test for overlap, as in the case of an
                   extended partition, and reduce size */
                for (j=0; j<n; j++) {
                    for (k=j+1; k<n; k++) {
                        if (slices[k].start > slices[j].start &&
                                slices[k].start < slices[j].start +
                                slices[j].size) {
                            slices[j].size = slices[k].start -
                                             slices[j].start;
                            if (verbose)
                                printf("reduced size of "
                                       "partition #%d to %d\n",
                                       lower+j,
                                       slices[j].size);
                        }
                    }
                }
                for (j=0; j<n; j++) {
                    /* skip unused/empty partitions */
                    if (slices[j].size == 0)
                        continue;
                    pt.pno = lower+j;
                    pt.start = 512 * (long long) slices[j].start;
                    pt.length = 512 * (long long) slices[j].size;
                    pt.devname[0] = 0;
                    pt.volname[0] = 0;
                    a.op = BLKPG_ADD_PARTITION;
                    a.flags = 0;
                    a.datalen = sizeof(pt);
                    a.data = &pt;
                    if (ioctl(fd, BLKPG, &a) == -1) {
                        perror("BLKPG");
                        fprintf(stderr,
                                "error adding partition %d\n",
                                lower+j);
                    } else if (verbose)
                        printf("added partition %d\n", lower+j);
                }
            }
        }
    }

    return 0;
}
Exemple #6
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;
}
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);
		}
	}
}
Exemple #8
0
int
main(int argc, char *argv[]) {
	char *device, *volume, *fsname;
	int inodes;
	unsigned long long total_blocks, ino_bytes, ino_blocks, data_blocks;
	unsigned long long user_specified_total_blocks = 0;
	int verbose = 0;
	int fd;
	struct bfssb sb;
	struct bfsi ri;
	struct bfsde de;
	struct stat statbuf;
	time_t now;
	int c, i, len;
	char *p;

	progname = argv[0];
	if ((p = strrchr(progname, '/')) != NULL)
		progname = p+1;

	if (argc < 2)
		usage();

	if (argc == 2 &&
	    (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
		printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
		exit(0);
	}

	volume = fsname = "      ";	/* is there a default? */
	inodes = 0;

	while ((c = getopt(argc, argv, "vF:N:V:cl:")) != -1) {
		switch (c) {
		case 'N':
			inodes = atol(optarg);
			break;

		case 'V':
			len = strlen(optarg);
			if (len <= 0 || len > 6)
				fatal(_("volume name too long"));
			volume = strdup(optarg);
			break;

		case 'F':
			len = strlen(optarg);
			if (len <= 0 || len > 6)
				fatal(_("fsname name too long"));
			fsname = strdup(optarg);
			break;

		case 'v':
			verbose = 1;
			break;

			/* when called via mkfs we may get options c,l,v */
		case 'c':
		case 'l':
			break;

		default:
			usage();
		}
	}

	if (optind == argc)
		usage();

	device = argv[optind++];

	if (stat(device, &statbuf) == -1) {
		perror(device);
		fatal(_("cannot stat device %s"), device);
	}

	if (!S_ISBLK(statbuf.st_mode))
		fatal(_("%s is not a block special device"), device);

	fd = open(device, O_RDWR | O_EXCL);
	if (fd == -1) {
		perror(device);
		fatal(_("cannot open %s"), device);
	}

	if (optind == argc-1)
		user_specified_total_blocks = atoll(argv[optind]);
	else if (optind != argc)
		usage();

	if (blkdev_get_sectors(fd, &total_blocks) == -1) {
		if (!user_specified_total_blocks) {
			perror("blkdev_get_sectors");
			fatal(_("cannot get size of %s"), device);
		}
		total_blocks = user_specified_total_blocks;
	} else if (user_specified_total_blocks) {
		if (user_specified_total_blocks > total_blocks)
			fatal(_("blocks argument too large, max is %llu"),
			      total_blocks);
		total_blocks = user_specified_total_blocks;
	}

	if (!inodes) {
		/* pick some reasonable default */
		inodes = 8*(total_blocks/800);
		if (inodes < 48)
			inodes = 48;
		if (inodes > 512)
			inodes = 512;
	} else {
		/* believe the user */
		if (inodes > 512)
			fatal(_("too many inodes - max is 512"));
	}

	ino_bytes = inodes * sizeof(struct bfsi);
	ino_blocks = (ino_bytes + BFS_BLOCKSIZE - 1) / BFS_BLOCKSIZE;
	data_blocks = total_blocks - ino_blocks - 1;

	/* mimic the behaviour of SCO's mkfs - maybe this limit is needed */
	if (data_blocks < 32)
		fatal(_("not enough space, need at least %llu blocks"),
		      ino_blocks + 33);

	memset(&sb, 0, sizeof(sb));
	sb.s_magic = BFS_SUPER_MAGIC;
	sb.s_start = ino_bytes + sizeof(struct bfssb);
	sb.s_end = total_blocks * BFS_BLOCKSIZE - 1;
	sb.s_from = sb.s_to = sb.s_backup_from = sb.s_backup_to = -1;
	memcpy(sb.s_fsname, fsname, 6);
	memcpy(sb.s_volume, volume, 6);

	if (verbose) {
		fprintf(stderr, _("Device: %s\n"), device);
		fprintf(stderr, _("Volume: <%-6s>\n"), volume);
		fprintf(stderr, _("FSname: <%-6s>\n"), fsname);
		fprintf(stderr, _("BlockSize: %d\n"), BFS_BLOCKSIZE);
		if (ino_blocks==1)
			fprintf(stderr, _("Inodes: %d (in 1 block)\n"),
				inodes);
		else
			fprintf(stderr, _("Inodes: %d (in %lld blocks)\n"),
				inodes, ino_blocks);
		fprintf(stderr, _("Blocks: %lld\n"), total_blocks);
		fprintf(stderr, _("Inode end: %d, Data end: %d\n"),
			sb.s_start-1, sb.s_end);
	}

	if (write(fd, &sb, sizeof(sb)) != sizeof(sb))
		fatal(_("error writing superblock"));

	memset(&ri, 0, sizeof(ri));
	ri.i_ino = BFS_ROOT_INO;
	ri.i_first_block = 1 + ino_blocks;
	ri.i_last_block = ri.i_first_block +
		(inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
	ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE
		+ 2 * sizeof(struct bfsde) - 1;
	ri.i_type = BFS_DIR_TYPE;
	ri.i_mode = S_IFDIR | 0755; 	/* or just 0755 */
	ri.i_uid = 0;
	ri.i_gid = 1;			/* random */
	ri.i_nlinks = 2;
	time(&now);
	ri.i_atime = now;
	ri.i_mtime = now;
	ri.i_ctime = now;

	if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
		fatal(_("error writing root inode"));

	memset(&ri, 0, sizeof(ri));
	for (i=1; i<inodes; i++)
		if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
			fatal(_("error writing inode"));

	if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1)
		fatal(_("seek error"));

	memset(&de, 0, sizeof(de));
	de.d_ino = BFS_ROOT_INO;
	memcpy(de.d_name, ".", 1);
	if (write(fd, &de, sizeof(de)) != sizeof(de))
		fatal(_("error writing . entry"));

	memcpy(de.d_name, "..", 2);
	if (write(fd, &de, sizeof(de)) != sizeof(de))
		fatal(_("error writing .. entry"));

	if (close(fd) == -1) {
		perror(device);
		fatal(_("error closing %s"), device);
	}

	return 0;
}
Exemple #9
0
static int sun_create_disklabel(struct fdisk_context *cxt)
{
    struct hd_geometry geometry;
    sector_t llsectors, llcyls;
    unsigned int ndiv, sec_fac;
    int res;

    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);

    res = blkdev_get_sectors(cxt->dev_fd, &llsectors);
    sec_fac = cxt->sector_size / 512;

#ifdef HDIO_GETGEO
    if (!ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry)) {
        cxt->geom.heads = geometry.heads;
        cxt->geom.sectors = geometry.sectors;
        if (res == 0) {
            llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
            cxt->geom.cylinders = llcyls;
            if (cxt->geom.cylinders != llcyls)
                cxt->geom.cylinders = ~0;
        } else {
            cxt->geom.cylinders = geometry.cylinders;
            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;
}
Exemple #10
0
static int sgi_create_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_sgi_label *sgi;
	struct sgi_disklabel *sgilabel;
	int rc;

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

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

		if (blkdev_get_sectors(cxt->dev_fd, (unsigned long long *) &llsectors) == 0) {
			/* the get device size ioctl was successful */
			fdisk_sector_t llcyls;
			int sec_fac = cxt->sector_size / 512;

			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 */
			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);
		}
	}
#endif
	rc = fdisk_init_firstsector_buffer(cxt, 0, 0);
	if (rc)
		return rc;

	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(cxt->geom.cylinders);
	sgilabel->devparam.head_vol0	= cpu_to_be16(0);
	sgilabel->devparam.ntrks	= cpu_to_be16(cxt->geom.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(cxt->geom.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;

	/* don't create default layout when a script defined */
	if (!cxt->script) {
		sgi_set_entire(cxt);
		sgi_set_volhdr(cxt);
	}
	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_info(cxt, _("Created a new SGI disklabel."));
	return 0;
}