Ejemplo n.º 1
0
static int
foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx, int diagnostic)
{
	struct mfi_config_data *config;
	char prefix[26];
	int error;
	uint8_t mbox[4];

	bzero(mbox, sizeof(mbox));
	mbox[0] = cfgidx;
	if (mfi_config_read_opcode(fd, opcode, &config, mbox, sizeof(mbox)) < 0) {
		error = errno;
		warn("Failed to get foreign config %d", error);
		close(fd);
		return (error);
	}

	if (opcode == MFI_DCMD_CFG_FOREIGN_PREVIEW)
		sprintf(prefix, "Foreign configuration preview %d", cfgidx);
	else
		sprintf(prefix, "Foreign configuration %d", cfgidx);
	/*
	 * MegaCli uses DCMD opcodes: 0x03100200 (which fails) followed by
	 * 0x1a721880 which returns what looks to be drive / volume info
	 * but we have no real information on what these are or what they do
	 * so we're currently relying solely on the config returned above
	 */
	if (diagnostic)
		dump_config(fd, config, prefix);
	else {
		char *ld_list;
		int i;

		ld_list = (char *)(config->array);

        	printf("%s: %d arrays, %d volumes, %d spares\n", prefix, 
		       config->array_count, config->log_drv_count,
		       config->spares_count);


		for (i = 0; i < config->array_count; i++)
			 ld_list += config->array_size;

		for (i = 0; i < config->log_drv_count; i++) {
        		const char *level;
        		char size[6], stripe[5];
			struct mfi_ld_config *ld;

			ld = (struct mfi_ld_config *)ld_list;

        		format_stripe(stripe, sizeof(stripe),
            			ld->params.stripe_size);
			/*
			 * foreign configs don't seem to have a secondary raid level
			 * but, we can use span depth here as if a LD spans multiple
			 * arrays of disks (2 raid 1 sets for example), we will have an
			 * indication based on the spam depth. swb
			 */ 
        		level = mfi_raid_level(ld->params.primary_raid_level,
            					(ld->params.span_depth - 1));

        		humanize_number(size, sizeof(size), ld->span[0].num_blocks * 512,
            			"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);

			printf(" ID%d ", i);
              		printf("(%6s) %-8s |",
				size, level);
			printf("volume spans %d %s\n",	ld->params.span_depth,
							(ld->params.span_depth > 1) ? "arrays" : "array");
			for (int j = 0; j < ld->params.span_depth; j++) {
				char *ar_list;
				struct mfi_array *ar;
				uint16_t device_id;

				printf("      array %u @ ", ld->span[j].array_ref);
        			humanize_number(size, sizeof(size), ld->span[j].num_blocks * 512,
            				"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
				
				printf("(%6s)\n",size);
				ar_list = (char *)config->array + (ld->span[j].array_ref * config->array_size);

				ar = (struct mfi_array *)ar_list;
				for (int k = 0; k < ar->num_drives; k++) {
					device_id = ar->pd[k].ref.v.device_id;
					if (device_id == 0xffff)
						printf("        drive MISSING\n");
					else {
						printf("        drive %u %s\n", device_id,
			    				mfi_pdstate(ar->pd[k].fw_state));
					}
				}

			}
			ld_list += config->log_drv_size;
		}
	}

	free(config);

	return (0);
}
Ejemplo n.º 2
0
int
mfi_config_read(int fd, struct mfi_config_data **configp)
{
	return mfi_config_read_opcode(fd, MFI_DCMD_CFG_READ, configp, NULL, 0);
}