/* Populate an array with drives. */ static void build_array(int fd, char *arrayp, struct array_info *array_info, struct config_id_state *state, int verbose) { struct mfi_array *ar = (struct mfi_array *)arrayp; int i; ar->size = array_info->drives[0].coerced_size; ar->num_drives = array_info->drive_count; ar->array_ref = find_next_array(state); for (i = 0; i < array_info->drive_count; i++) { if (verbose) printf("Adding drive %s to array %u\n", mfi_drive_name(NULL, array_info->drives[i].ref.v.device_id, MFI_DNAME_DEVICE_ID|MFI_DNAME_HONOR_OPTS), ar->array_ref); if (ar->size > array_info->drives[i].coerced_size) ar->size = array_info->drives[i].coerced_size; ar->pd[i].ref = array_info->drives[i].ref; ar->pd[i].fw_state = MFI_PD_STATE_ONLINE; } array_info->array = ar; }
static int show_patrol(int ac, char **av) { struct mfi_pr_properties prop; struct mfi_pr_status status; struct mfi_pd_list *list; struct mfi_pd_info info; char label[24]; time_t now; uint32_t at; int error, fd; u_int i; fd = mfi_open(mfi_unit); if (fd < 0) { error = errno; warn("mfi_open"); return (error); } time(&now); mfi_get_time(fd, &at); error = patrol_get_props(fd, &prop); if (error) { close(fd); return (error); } printf("Operation Mode: "); switch (prop.op_mode) { case MFI_PR_OPMODE_AUTO: printf("auto\n"); break; case MFI_PR_OPMODE_MANUAL: printf("manual\n"); break; case MFI_PR_OPMODE_DISABLED: printf("disabled\n"); break; default: printf("??? (%02x)\n", prop.op_mode); break; } if (prop.op_mode == MFI_PR_OPMODE_AUTO) { if (at != 0 && prop.next_exec) printf(" Next Run Starts: %s", adapter_time(now, at, prop.next_exec)); if (prop.exec_freq == 0xffffffff) printf(" Runs Execute Continuously\n"); else if (prop.exec_freq != 0) printf(" Runs Start Every %u seconds\n", prop.exec_freq); } if (mfi_dcmd_command(fd, MFI_DCMD_PR_GET_STATUS, &status, sizeof(status), NULL, 0, NULL) < 0) { error = errno; warn("Failed to get patrol read properties"); close(fd); return (error); } printf("Runs Completed: %u\n", status.num_iteration); printf("Current State: "); switch (status.state) { case MFI_PR_STATE_STOPPED: printf("stopped\n"); break; case MFI_PR_STATE_READY: printf("ready\n"); break; case MFI_PR_STATE_ACTIVE: printf("active\n"); break; case MFI_PR_STATE_ABORTED: printf("aborted\n"); break; default: printf("??? (%02x)\n", status.state); break; } if (status.state == MFI_PR_STATE_ACTIVE) { if (mfi_pd_get_list(fd, &list, NULL) < 0) { error = errno; warn("Failed to get drive list"); close(fd); return (error); } for (i = 0; i < list->count; i++) { if (list->addr[i].scsi_dev_type != 0) continue; if (mfi_pd_get_info(fd, list->addr[i].device_id, &info, NULL) < 0) { error = errno; warn("Failed to fetch info for drive %u", list->addr[i].device_id); free(list); close(fd); return (error); } if (info.prog_info.active & MFI_PD_PROGRESS_PATROL) { snprintf(label, sizeof(label), " Drive %s", mfi_drive_name(NULL, list->addr[i].device_id, MFI_DNAME_DEVICE_ID|MFI_DNAME_HONOR_OPTS)); mfi_display_progress(label, &info.prog_info.patrol); } } free(list); } close(fd); return (0); }