Example #1
0
int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) {
	int rv;
	rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
	rv |= sysfs_set_num(info, NULL, "suspend_hi", 0);
	rv |= sysfs_set_num(info, NULL, "suspend_lo", 0);

	signal(SIGQUIT, sig[2]);
	signal(SIGINT, sig[1]);
	signal(SIGTERM, sig[0]);

	if(munlockall() != 0)
		return 3;
	return rv * 256;
}
Example #2
0
int lock_stripe(struct mdinfo *info, unsigned long long start,
		int chunk_size, int data_disks, sighandler_t *sig) {
	int rv;
	if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
		return 2;
	}

	sig[0] = signal(SIGTERM, SIG_IGN);
	sig[1] = signal(SIGINT, SIG_IGN);
	sig[2] = signal(SIGQUIT, SIG_IGN);

	rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks);
	rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks);
	return rv * 256;
}
Example #3
0
int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
{
	char dv[PATH_MAX];
	char nm[PATH_MAX];
	char *dname;
	int rv;

	sprintf(dv, "%d:%d", sd->disk.major, sd->disk.minor);
	rv = sysfs_set_str(sra, NULL, "new_dev", dv);
	if (rv)
		return rv;

	memset(nm, 0, sizeof(nm));
	sprintf(dv, "/sys/dev/block/%d:%d", sd->disk.major, sd->disk.minor);
	rv = readlink(dv, nm, sizeof(nm)-1);
	if (rv <= 0)
		return -1;
	nm[rv] = '\0';
	dname = strrchr(nm, '/');
	if (dname) dname++;
	strcpy(sd->sys_name, "dev-");
	strcpy(sd->sys_name+4, dname);

	/* test write to see if 'recovery_start' is available */
	if (resume && sd->recovery_start < MaxSector &&
	    sysfs_set_num(sra, sd, "recovery_start", 0)) {
		sysfs_set_str(sra, sd, "state", "remove");
		return -1;
	}

	rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
	rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
	if (sra->array.level != LEVEL_CONTAINER) {
		if (sd->recovery_start == MaxSector)
			/* This can correctly fail if array isn't started,
			 * yet, so just ignore status for now.
			 */
			sysfs_set_str(sra, sd, "state", "insync");
		if (sd->disk.raid_disk >= 0)
			rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
		if (resume)
			sysfs_set_num(sra, sd, "recovery_start", sd->recovery_start);
	}
	return rv;
}
Example #4
0
int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
{
    char dv[PATH_MAX];
    char nm[PATH_MAX];
    char *dname;
    int rv;
    int i;

    sprintf(dv, "%d:%d", sd->disk.major, sd->disk.minor);
    rv = sysfs_set_str(sra, NULL, "new_dev", dv);
    if (rv)
        return rv;

    memset(nm, 0, sizeof(nm));
    dname = devid2kname(makedev(sd->disk.major, sd->disk.minor));
    strcpy(sd->sys_name, "dev-");
    strcpy(sd->sys_name+4, dname);

    /* test write to see if 'recovery_start' is available */
    if (resume && sd->recovery_start < MaxSector &&
            sysfs_set_num(sra, sd, "recovery_start", 0)) {
        sysfs_set_str(sra, sd, "state", "remove");
        return -1;
    }

    rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
    rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
    if (sra->array.level != LEVEL_CONTAINER) {
        if (sd->recovery_start == MaxSector)
            /* This can correctly fail if array isn't started,
             * yet, so just ignore status for now.
             */
            sysfs_set_str(sra, sd, "state", "insync");
        if (sd->disk.raid_disk >= 0)
            rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
        if (resume)
            sysfs_set_num(sra, sd, "recovery_start", sd->recovery_start);
    }
    if (sd->bb.supported) {
        if (sysfs_set_str(sra, sd, "state", "external_bbl")) {
            /*
             * backward compatibility - if kernel doesn't support
             * bad blocks for external metadata, let it continue
             * as long as there are none known so far
             */
            if (sd->bb.count) {
                pr_err("The kernel has no support for bad blocks in external metadata\n");
                return -1;
            }
        }

        for (i = 0; i < sd->bb.count; i++) {
            char s[30];
            const struct md_bb_entry *entry = &sd->bb.entries[i];

            snprintf(s, sizeof(s) - 1, "%llu %d\n", entry->sector,
                     entry->length);
            rv |= sysfs_set_str(sra, sd, "bad_blocks", s);
        }
    }
    return rv;
}
Example #5
0
int sysfs_set_array(struct mdinfo *info, int vers)
{
    int rv = 0;
    char ver[100];
    int raid_disks = info->array.raid_disks;

    ver[0] = 0;
    if (info->array.major_version == -1 &&
            info->array.minor_version == -2) {
        char buf[1024];

        strcat(strcpy(ver, "external:"), info->text_version);

        /* meta version might already be set if we are setting
         * new geometry for a reshape.  In that case we don't
         * want to over-write the 'readonly' flag that is
         * stored in the metadata version.  So read the current
         * version first, and preserve the flag
         */
        if (sysfs_get_str(info, NULL, "metadata_version",
                          buf, 1024) > 0)
            if (strlen(buf) >= 9 && buf[9] == '-')
                ver[9] = '-';

        if ((vers % 100) < 2 ||
                sysfs_set_str(info, NULL, "metadata_version",
                              ver) < 0) {
            pr_err("This kernel does not support external metadata.\n");
            return 1;
        }
    }
    if (info->array.level < 0)
        return 0; /* FIXME */
    rv |= sysfs_set_str(info, NULL, "level",
                        map_num(pers, info->array.level));
    if (info->reshape_active && info->delta_disks != UnSet)
        raid_disks -= info->delta_disks;
    rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks);
    rv |= sysfs_set_num(info, NULL, "chunk_size", info->array.chunk_size);
    rv |= sysfs_set_num(info, NULL, "layout", info->array.layout);
    rv |= sysfs_set_num(info, NULL, "component_size", info->component_size/2);
    if (info->custom_array_size) {
        int rc;

        rc = sysfs_set_num(info, NULL, "array_size",
                           info->custom_array_size/2);
        if (rc && errno == ENOENT) {
            pr_err("This kernel does not have the md/array_size attribute, the array may be larger than expected\n");
            rc = 0;
        }
        rv |= rc;
    }

    if (info->array.level > 0)
        rv |= sysfs_set_num(info, NULL, "resync_start", info->resync_start);

    if (info->reshape_active) {
        rv |= sysfs_set_num(info, NULL, "reshape_position",
                            info->reshape_progress);
        rv |= sysfs_set_num(info, NULL, "chunk_size", info->new_chunk);
        rv |= sysfs_set_num(info, NULL, "layout", info->new_layout);
        rv |= sysfs_set_num(info, NULL, "raid_disks",
                            info->array.raid_disks);
        /* We don't set 'new_level' here.  That can only happen
         * once the reshape completes.
         */
    }
    return rv;
}