Ejemplo n.º 1
0
void
write_partition_map(partition_map_header *map)
{
    MEDIA m;
    char *block;
    partition_map * entry;
    int i = 0;
    int result = 0;

    m = map->m;
    if (map->misc != NULL) {
	convert_block0(map->misc, 0);
	result = write_block(map, 0, (char *)map->misc);
	convert_block0(map->misc, 1);
    } else {
	block = (char *) calloc(1, PBLOCK_SIZE);
	if (block != NULL) {
	    result = write_block(map, 0, block);
	    free(block);
	}
    }
    if (result == 0) {
	error(errno, "Unable to write block zero");
    }
    for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
	convert_dpme(entry->data, 0);
	result = write_block(map, entry->disk_address, (char *)entry->data);
	convert_dpme(entry->data, 1);
	i = entry->disk_address;
	if (result == 0) {
	    error(errno, "Unable to write block %d", i);
	}
    }

#ifdef __linux__
	// zap the block after the map (if possible) to get around a bug.
    if (map->maximum_in_map > 0 &&  i < map->maximum_in_map) {
	i += 1;
	block = (char *) malloc(PBLOCK_SIZE);
	if (block != NULL) {
	    if (read_block(map, i, block)) {
		block[0] = 0;
		write_block(map, i, block);
	    }
	    free(block);
	}
    }
#endif

    if (interactive)
	printf("The partition table has been altered!\n\n");

    os_reload_media(map->m);
}
Ejemplo n.º 2
0
//
// Routines
//
int
get_block_zero(void)
{
    int rtn_value;
    
    if (the_map != NULL) {
	b0 = the_map->misc;
	rtn_value = 1;
    } else {
	if (read_media(the_media, (long long) 0, PBLOCK_SIZE, buffer) == 0) {
	    rtn_value = 0;
	} else {
	    b0 = (Block0 *) buffer;
	    convert_block0(b0, 1);
	    rtn_value = 1;
	}
    }
    return rtn_value;
}
Ejemplo n.º 3
0
void
write_partition_map(partition_map_header *map)
{
    int fd;
    char *block;
    partition_map * entry;
    int i = 0;

    fd = map->fd->fd;
    if (map->misc != NULL) {
	convert_block0(map->misc, 0);
	write_block(map, 0, (char *)map->misc);
	convert_block0(map->misc, 1);
    } else {
	block = (char *) calloc(1, PBLOCK_SIZE);
	if (block != NULL) {
	    write_block(map, 0, block);
	    free(block);
	}
    }
    for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
	convert_dpme(entry->data, 0);
	write_block(map, entry->disk_address, (char *)entry->data);
	convert_dpme(entry->data, 1);
	i = entry->disk_address;
    }

#ifdef __linux__
	// zap the block after the map (if possible) to get around a bug.
    if (map->maximum_in_map > 0 &&  i < map->maximum_in_map) {
	i += 1;
	block = (char *) malloc(PBLOCK_SIZE);
	if (block != NULL) {
	    if (read_block(map, i, block, 1)) {
		block[0] = 0;
		write_block(map, i, block);
	    }
	    free(block);
	}
    }
#endif /* __linux __ */

    if (interactive)
	printf("The partition table has been altered!\n\n");

#ifdef __linux__
    if (map->regular_file) {
	close_media(map->fd);
    } else {
	// printf("Calling ioctl() to re-read partition table.\n"
	//       "(Reboot to ensure the partition table has been updated.)\n");
	sync();
	sleep(2);
	if ((i = ioctl(fd, BLKRRPART)) != 0) {
	    saved_errno = errno;
	} else {
	    // some kernel versions (1.2.x) seem to have trouble
	    // rereading the partition table, but if asked to do it
	    // twice, the second time works. - [email protected] */
	    sync();
	    sleep(2);
	    if ((i = ioctl(fd, BLKRRPART)) != 0) {
		saved_errno = errno;
	    }
	}
	close_media(map->fd);

	// printf("Syncing disks.\n");
	sync();
	sleep(4);		/* for sync() */

	if (i < 0) {
	    error(saved_errno, "Re-read of partition table failed");
	    printf("Reboot your system to ensure the "
		    "partition table is updated.\n");
	}
    }
#else
    close_media(map->fd);
#endif
    map->fd = open_media(map->name, (map->writeable)?O_RDWR:O_RDONLY);
    if (map->fd == 0) {
	fatal(errno, "can't re-open file '%s' for %sing", map->name,
		(rflag)?"read":"writ");
    }

}
Ejemplo n.º 4
0
//
// Routines
//
partition_map_header *
open_partition_map(char *name, int *valid_file, int ask_logical_size)
{
    media *fd;
    partition_map_header * map;
    int writeable;
#ifdef __linux__
    struct stat info;
#endif
    int size;

    fd = open_media(name, (rflag)?O_RDONLY:O_RDWR);
    if (fd == 0) {
	fd = open_media(name, O_RDONLY);
	if (fd == 0) {
	    error(errno, "can't open file '%s'", name);
	    *valid_file = 0;
	    return NULL;
	} else {
	    writeable = 0;
	}
    } else {
	writeable = 1;
    }
    *valid_file = 1;

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(fd);
	return NULL;
    }
    map->fd = fd;
    map->name = name;
    map->writeable = (rflag)?0:writeable;
    map->changed = 0;
    map->disk_order = NULL;
    map->base_order = NULL;

    map->physical_block = fd->block_size;	/* preflight */
    map->misc = (Block0 *) malloc(PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
	close_media(map->fd);
	free(map);
	return NULL;
    } else if (read_media(map->fd, 0, (char *)map->misc, 0) == 0
	    || convert_block0(map->misc, 1)
	    || coerce_block0(map)) {
	// if I can't read block 0 I might as well give up
	close_partition_map(map);
	return NULL;
    }
    map->physical_block = map->misc->sbBlkSize;
    // printf("physical block size is %d\n", map->physical_block);

    if (ask_logical_size && interactive) {
	size = PBLOCK_SIZE;
	printf("A logical block is %d bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the logical block size? ",
		(long *)&size, size);
	map->logical_block = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
    } else {
	map->logical_block = PBLOCK_SIZE;
    }
    if (map->logical_block > MAXIOSIZE) {
	map->logical_block = MAXIOSIZE;
    }
    if (map->logical_block > map->physical_block) {
	map->physical_block = map->logical_block;
    }
    map->blocks_in_map = 0;
    map->maximum_in_map = -1;
    map->media_size = compute_device_size(map, map);
    sync_device_size(map);

#ifdef __linux__
    if (fstat(fd, &info) < 0) {
	error(errno, "can't stat file '%s'", name);
	map->regular_file = 0;
    } else {
	map->regular_file = S_ISREG(info.st_mode);
    }
#else
    map->regular_file = 0;
#endif

    if (read_partition_map(map) < 0) {
	// some sort of failure reading the map
    } else {
	// got it!
	;
	return map;
    }
    close_partition_map(map);
    return NULL;
}
Ejemplo n.º 5
0
//
// Routines
//
partition_map_header *
open_partition_map(char *name, int *valid_file, int ask_logical_size, int oflag)
{
    MEDIA m;
    partition_map_header * map;
    int writable;
    long size;

    m = open_pathname_as_media(name, oflag);
    if (m == 0) {
	m = open_pathname_as_media(name, O_RDONLY);
	if (m == 0) {
	    error(errno, "can't open file '%s'", name);
	    *valid_file = 0;
	    return NULL;
	} else {
	    writable = 0;
	}
    } else {
	writable = 1;
    }
    *valid_file = 1;

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(m);
	return NULL;
    }
    map->name = name;
    map->writable = (oflag == O_RDONLY)?0:writable;
    map->changed = 0;
    map->written = 0;
    map->disk_order = NULL;
    map->base_order = NULL;

    map->physical_block = media_granularity(m);	/* preflight */
    m = open_deblock_media(PBLOCK_SIZE, m);
    map->m = m;
    map->misc = (Block0 *) malloc(PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
	close_media(map->m);
	free(map);
	return NULL;
    } else if (read_media(map->m, (long long) 0, PBLOCK_SIZE, (char *)map->misc) == 0
	    || convert_block0(map->misc, 1)
	    || coerce_block0(map)) {
	// if I can't read block 0 I might as well give up
	error(-1, "Can't read block 0 from '%s'", name);
	close_partition_map(map);
	return NULL;
    }
    map->physical_block = map->misc->sbBlkSize;
    //printf("physical block size is %d\n", map->physical_block);

    if (ask_logical_size && interactive) {
	size = PBLOCK_SIZE;
	printf("A logical block is %ld bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the logical block size? ",
		&size, size);
	size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	if (size < PBLOCK_SIZE) {
	    size = PBLOCK_SIZE;
	}
	map->logical_block = size;
    } else {
	map->logical_block = PBLOCK_SIZE;
    }
    if (map->logical_block > MAXIOSIZE) {
	map->logical_block = MAXIOSIZE;
    }
    if (map->logical_block > map->physical_block) {
	map->physical_block = map->logical_block;
    }
    map->blocks_in_map = 0;
    map->maximum_in_map = -1;
    map->media_size = compute_device_size(map, map);

    if (read_partition_map(map) < 0) {
	// some sort of failure reading the map
    } else {
	// got it!
	;
	return map;
    }
    close_partition_map(map);
    return NULL;
}