Exemplo n.º 1
0
static void check_blocks(void)
{
    unsigned int current_page;
    int do_seek = 1;
    char *buffer;

    buffer = xmalloc(pagesize);
    current_page = 0;
    while (current_page < PAGES) {
        if (!check && version == 0) {
            page_ok(current_page++);
            continue;
        }
        if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) !=
                current_page * pagesize)
            bb_error_msg_and_die("seek failed in check_blocks");
        if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
            current_page++;
            if (version == 0)
                bit_test_and_clear(signature_page, current_page);
            else {
                if (badpages == MAX_BADPAGES)
                    bb_error_msg_and_die("too many bad pages");
                p->badpages[badpages] = current_page;
            }
            badpages++;
            continue;
        }
        page_ok(current_page++);
    }
    if (ENABLE_FEATURE_CLEAN_UP)
        free(buffer);
    if (badpages > 0)
        printf("%d bad page%s\n", badpages, (badpages==1)?"":"s");
}
Exemplo n.º 2
0
static inline void page_bad(int page)
{
	if (version == 0)
		bit_test_and_clear(signature_page, page);
	else {
		if (badpages == MAX_BADPAGES)
			bb_error_msg_and_die("too many bad pages");
		p->badpages[badpages] = page;
	}
	badpages++;
}
Exemplo n.º 3
0
int mkswap_main(int argc, char **argv)
{
    char *tmp;
    struct stat statbuf;
    int sz;
    int maxpages;
    int goodpages;
#ifdef __sparc__
    int force = 0;
#endif

    init_signature_page();		/* get pagesize */

    bb_opt_complementally = "?"; /* call bb_show_usage internally */
    sz = bb_getopt_ulflags(argc, argv, "+cfv:", &tmp);
    if (sz & 1)
        check = 1;
#ifdef __sparc__
    if (sz & 2)
        force = 1;
#endif
#if ENABLE_FEATURE_MKSWAP_V0
    if (sz & 4) {
        version = bb_xgetlarg(tmp, 10, 0, 1);
    } else {
        if (get_linux_version_code() < KERNEL_VERSION(2, 1, 117))
            version = 0;
        else
            version = 1;
    }
#endif

    argv += optind;
    argc -= optind;

    goodpages = pagesize / 1024; /* cache division */
    while (argc--) {
        if (device_name) {
            PAGES = bb_xgetlarg(argv[0], 0, 10, sz * goodpages) / goodpages;
            argc = 0; /* ignore any surplus args.. */
        } else {
            device_name = argv[0];
            sz = get_size(device_name);
            argv++;
        }
    }

    if (!device_name) {
        bb_error_msg_and_die("error: Nowhere to set up swap on?");
    }
    if (!PAGES) {
        PAGES = sz;
    }

#if 0
    maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
#else
    if (!version)
        maxpages = V0_MAX_PAGES;
    else if (get_linux_version_code() >= KERNEL_VERSION(2,2,1))
        maxpages = V1_MAX_PAGES;
    else {
        maxpages = V1_OLD_MAX_PAGES;
        if (maxpages > V1_MAX_PAGES)
            maxpages = V1_MAX_PAGES;
    }
#endif
    if (PAGES > maxpages) {
        PAGES = maxpages;
        bb_error_msg("warning: truncating swap area to %ldkB",
                     PAGES * goodpages);
    }

    DEV = bb_xopen3(device_name, O_RDWR, 0);
    if (fstat(DEV, &statbuf) < 0)
        bb_perror_msg_and_die("%s", device_name);
    if (!S_ISBLK(statbuf.st_mode))
        check = 0;
    else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
        bb_error_msg_and_die("Will not try to make swapdevice on '%s'", device_name);

#ifdef __sparc__
    if (!force && version == 0) {
        /* Don't overwrite partition table unless forced */
        unsigned char *buffer = (unsigned char *) signature_page;
        unsigned short *q, sum;

        if (read(DEV, buffer, 512) != 512)
            bb_error_msg_and_die("fatal: first page unreadable");
        if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
            q = (unsigned short *) (buffer + 510);
            for (sum = 0; q >= (unsigned short *) buffer;)
                sum ^= *q--;
            if (!sum) {
                bb_error_msg("Device '%s' contains a valid Sun disklabel.\n"
                             "This probably means creating v0 swap would destroy your partition table\n"
                             "No swap created. If you really want to create swap v0 on that device, use\n"
                             "the -f option to force it.", device_name);
                return EXIT_FAILURE;
            }
        }
    }
#endif

    if (version == 0 || check)
        check_blocks();
    if (version == 0 && !bit_test_and_clear(signature_page, 0))
        bb_error_msg_and_die("fatal: first page unreadable");
    if (version == 1) {
        p->swap_version = version;
        p->last_page = PAGES - 1;
        p->nr_badpages = badpages;
    }

    goodpages = PAGES - badpages - 1;
    if (goodpages <= 0)
        bb_error_msg_and_die("Unable to set up swap-space: unreadable");
    printf("Setting up swapspace version %d, size = %ld bytes\n",
           version, (long) (goodpages * pagesize));
    write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");

    sz = ((version == 0) ? 0 : 1024); /* offset */
    if (lseek(DEV, sz, SEEK_SET) != sz)
        bb_error_msg_and_die("unable to rewind swap-device");
    goodpages = pagesize - sz; /* cache substraction */
    if (write(DEV, (char *) signature_page + sz, goodpages)
            != goodpages)
        bb_error_msg_and_die("unable to write signature page");

    /*
     * A subsequent swapon() will fail if the signature
     * is not actually on disk. (This is a kernel bug.)
     */
    if (fsync(DEV))
        bb_error_msg_and_die("fsync failed");
    if (ENABLE_FEATURE_CLEAN_UP) {
        close(DEV);
        free(signature_page);
    }
    return EXIT_SUCCESS;
}
Exemplo n.º 4
0
int mkswap_main(int argc, char **argv)
{
	char *tmp;
	struct stat statbuf;
	int sz;
	int maxpages;
	int goodpages;
	int offset;
	int force = 0;

	init_signature_page();		/* get pagesize */

	while (argc-- > 1) {
		argv++;
		if (argv[0][0] != '-') {
			if (device_name) {
				int blocks_per_page = pagesize / 1024;

				PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page;
				if (*tmp)
					bb_show_usage();
			} else
				device_name = argv[0];
		} else {
			switch (argv[0][1]) {
			case 'c':
				check = 1;
				break;
			case 'f':
				force = 1;
				break;
			case 'v':
				version = atoi(argv[0] + 2);
				break;
			default:
				bb_show_usage();
			}
		}
	}
	if (!device_name) {
		bb_error_msg("error: Nowhere to set up swap on?");
		bb_show_usage();
	}
	sz = get_size(device_name);
	if (!PAGES) {
		PAGES = sz;
	} else if (PAGES > sz && !force) {
		bb_error_msg("error: size %ld is larger than device size %d",
				PAGES * (pagesize / 1024), sz * (pagesize / 1024));
		return EXIT_FAILURE;
	}

	if (version == -1) {
		if (PAGES <= V0_MAX_PAGES)
			version = 0;
		else if (get_kernel_revision() < MAKE_VERSION(2, 1, 117))
			version = 0;
		else if (pagesize < 2048)
			version = 0;
		else
			version = 1;
	}
	if (version != 0 && version != 1) {
		bb_error_msg("error: unknown version %d", version);
		bb_show_usage();
	}
	if (PAGES < 10) {
		bb_error_msg("error: swap area needs to be at least %ldkB",
				(long) (10 * pagesize / 1024));
		bb_show_usage();
	}
#if 0
	maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
#else
	if (!version)
		maxpages = V0_MAX_PAGES;
	else if (get_kernel_revision() >= MAKE_VERSION(2, 2, 1))
		maxpages = V1_MAX_PAGES;
	else {
		maxpages = V1_OLD_MAX_PAGES;
		if (maxpages > V1_MAX_PAGES)
			maxpages = V1_MAX_PAGES;
	}
#endif
	if (PAGES > maxpages) {
		PAGES = maxpages;
		bb_error_msg("warning: truncating swap area to %ldkB",
				PAGES * pagesize / 1024);
	}

	DEV = open(device_name, O_RDWR);
	if (DEV < 0 || fstat(DEV, &statbuf) < 0)
		bb_perror_msg_and_die("%s", device_name);
	if (!S_ISBLK(statbuf.st_mode))
		check = 0;
	else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
		bb_error_msg_and_die("Will not try to make swapdevice on '%s'", device_name);

#ifdef __sparc__
	if (!force && version == 0) {
		/* Don't overwrite partition table unless forced */
		unsigned char *buffer = (unsigned char *) signature_page;
		unsigned short *q, sum;

		if (read(DEV, buffer, 512) != 512)
			bb_error_msg_and_die("fatal: first page unreadable");
		if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
			q = (unsigned short *) (buffer + 510);
			for (sum = 0; q >= (unsigned short *) buffer;)
				sum ^= *q--;
			if (!sum) {
				bb_error_msg("Device '%s' contains a valid Sun disklabel.\n"
"This probably means creating v0 swap would destroy your partition table\n"
"No swap created. If you really want to create swap v0 on that device, use\n"
"the -f option to force it.", device_name);
				return EXIT_FAILURE;
			}
		}
	}
#endif

	if (version == 0 || check)
		check_blocks();
	if (version == 0 && !bit_test_and_clear(signature_page, 0))
		bb_error_msg_and_die("fatal: first page unreadable");
	if (version == 1) {
		p->version = version;
		p->last_page = PAGES - 1;
		p->nr_badpages = badpages;
	}

	goodpages = PAGES - badpages - 1;
	if (goodpages <= 0)
		bb_error_msg_and_die("Unable to set up swap-space: unreadable");
	printf("Setting up swapspace version %d, size = %ld bytes\n",
		   version, (long) (goodpages * pagesize));
	write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");

	offset = ((version == 0) ? 0 : 1024);
	if (lseek(DEV, offset, SEEK_SET) != offset)
		bb_error_msg_and_die("unable to rewind swap-device");
	if (write(DEV, (char *) signature_page + offset, pagesize - offset)
		!= pagesize - offset)
		bb_error_msg_and_die("unable to write signature page");

	/*
	 * A subsequent swapon() will fail if the signature
	 * is not actually on disk. (This is a kernel bug.)
	 */
	if (fsync(DEV))
		bb_error_msg_and_die("fsync failed");
	return EXIT_SUCCESS;
}