Exemple #1
0
static int fail_all_paths(int fd)
{
        unsigned char fail_paths_pg[118];
        struct rdac_legacy_page *rdac_page;
        int res;
        char b[80];

        memset(fail_paths_pg, 0, 118);
        memcpy(fail_paths_pg, mode6_hdr, 4);
        memcpy(fail_paths_pg + 4, block_descriptor, 8);
        rdac_page = (struct rdac_legacy_page *)(fail_paths_pg + 4 + 8);
        rdac_page->page_code = RDAC_CONTROLLER_PAGE | 0x40;
        rdac_page->page_length = RDAC_CONTROLLER_PAGE_LEN;
        rdac_page->quiescence = RDAC_QUIESCENCE_TIME;
        rdac_page->options = RDAC_FORCE_QUIESCENCE;
        rdac_page->current_mode_lsb = RDAC_FAIL_ALL_PATHS;

        res = sg_ll_mode_select6(fd, 1 /* pf */, 0 /* sp */,
                                 fail_paths_pg, 118,
                                 1, (do_verbose ? 2 : 0));

        switch (res) {
        case 0:
                if (do_verbose)
                        fprintf(stderr, "fail paths successful\n");
                break;
        default:
                sg_get_category_sense_str(res, sizeof(b), b, do_verbose);
                fprintf(stderr, "fail paths failed: %s\n", b);
                break;
        }

        return res;
}
Exemple #2
0
static int fail_all_paths(int fd, int use_6_byte)
{
        unsigned char fail_paths_pg[308];
        struct rdac_legacy_page *rdac_page;
        struct rdac_expanded_page *rdac_page_exp;
        struct rdac_page_common *rdac_common = NULL;

        int res;
        char b[80];

        memset(fail_paths_pg, 0, 308);
        if (use_6_byte) {
                memcpy(fail_paths_pg, mode6_hdr, 4);
                memcpy(fail_paths_pg + 4, block_descriptor, 8);
                rdac_page = (struct rdac_legacy_page *)(fail_paths_pg + 4 + 8);
                rdac_page->page_code = RDAC_CONTROLLER_PAGE;
                rdac_page->page_length = RDAC_CONTROLLER_PAGE_LEN;
                rdac_common = &rdac_page->attr;
        } else {
                memcpy(fail_paths_pg, mode10_hdr, 8);
                rdac_page_exp = (struct rdac_expanded_page *)
                                (fail_paths_pg + 8);
                rdac_page_exp->page_code = RDAC_CONTROLLER_PAGE | 0x40;
                rdac_page_exp->subpage_code = 0x1;
                rdac_page_exp->page_length[0] =
                                EXPANDED_LUN_SPACE_PAGE_LEN >> 8;
                rdac_page_exp->page_length[1] =
                                EXPANDED_LUN_SPACE_PAGE_LEN & 0xFF;
                rdac_common = &rdac_page_exp->attr;
        }

        rdac_common->current_mode_lsb =  RDAC_FAIL_ALL_PATHS;
        rdac_common->quiescence = RDAC_QUIESCENCE_TIME;
        rdac_common->options = RDAC_FORCE_QUIESCENCE;

        if (use_6_byte) {
                res = sg_ll_mode_select6(fd, 1 /* pf */, 0 /* sp */,
                                        fail_paths_pg, 118,
                                        1, (do_verbose ? 2 : 0));
        } else {
                res = sg_ll_mode_select10(fd, 1 /* pf */, 0 /* sp */,
                                        fail_paths_pg, 308,
                                        1, (do_verbose ? 2: 0));
        }

        switch (res) {
        case 0:
                if (do_verbose)
                        fprintf(stderr, "fail paths successful\n");
                break;
        default:
                sg_get_category_sense_str(res, sizeof(b), b, do_verbose);
                fprintf(stderr, "fail paths failed: %s\n", b);
                break;
        }

        return res;
}
Exemple #3
0
int main(int argc, char * argv[])
{
    int sg_fd, res, c, num, alloc_len, off, pdt;
    int k, md_len, hdr_len, bd_len, mask_in_len;
    unsigned u, uu;
    int dbd = 0;
    int got_contents = 0;
    int force = 0;
    int got_mask = 0;
    int mode_6 = 0;
    int pg_code = -1;
    int sub_pg_code = 0;
    int save = 0;
    int verbose = 0;
    int read_in_len = 0;
    const char * device_name = NULL;
    unsigned char read_in[MX_ALLOC_LEN];
    unsigned char mask_in[MX_ALLOC_LEN];
    unsigned char ref_md[MX_ALLOC_LEN];
    char ebuff[EBUFF_SZ];
    struct sg_simple_inquiry_resp inq_data;
    int ret = 0;

    while (1) {
        int option_index = 0;

        c = getopt_long(argc, argv, "c:dfhl:m:p:svV", long_options,
                        &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'c':
            memset(read_in, 0, sizeof(read_in));
            if (0 != build_mode_page(optarg, read_in, &read_in_len,
                                     sizeof(read_in))) {
                fprintf(stderr, "bad argument to '--contents'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            got_contents = 1;
            break;
        case 'd':
            dbd = 1;
            break;
        case 'f':
            force = 1;
            break;
        case 'h':
        case '?':
            usage();
            return 0;
        case 'l':
            num = sscanf(optarg, "%d", &res);
            if ((1 == num) && ((6 == res) || (10 == res)))
                mode_6 = (6 == res) ? 1 : 0;
            else {
                fprintf(stderr, "length (of cdb) must be 6 or 10\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'm':
            memset(mask_in, 0xff, sizeof(mask_in));
            if (0 != build_mask(optarg, mask_in, &mask_in_len,
                                sizeof(mask_in))) {
                fprintf(stderr, "bad argument to '--mask'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            got_mask = 1;
            break;
        case 'p':
           if (NULL == strchr(optarg, ',')) {
                num = sscanf(optarg, "%x", &u);
                if ((1 != num) || (u > 62)) {
                    fprintf(stderr, "Bad page code value after '--page' "
                            "switch\n");
                    return SG_LIB_SYNTAX_ERROR;
                }
                pg_code = u;
            } else if (2 == sscanf(optarg, "%x,%x", &u, &uu)) {
                if (uu > 254) {
                    fprintf(stderr, "Bad sub page code value after '--page'"
                            " switch\n");
                    return SG_LIB_SYNTAX_ERROR;
                }
                pg_code = u;
                sub_pg_code = uu;
            } else {
                fprintf(stderr, "Bad page code, subpage code sequence after "
                        "'--page' switch\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 's':
            save = 1;
            break;
        case 'v':
            ++verbose;
            break;
        case 'V':
            fprintf(stderr, ME "version: %s\n", version_str);
            return 0;
        default:
            fprintf(stderr, "unrecognised option code 0x%x ??\n", c);
            usage();
            return SG_LIB_SYNTAX_ERROR;
        }
    }
    if (optind < argc) {
        if (NULL == device_name) {
            device_name = argv[optind];
            ++optind;
        }
        if (optind < argc) {
            for (; optind < argc; ++optind)
                fprintf(stderr, "Unexpected extra argument: %s\n",
                        argv[optind]);
            usage();
            return SG_LIB_SYNTAX_ERROR;
        }
    }
    if (NULL == device_name) {
        fprintf(stderr, "missing device name!\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (pg_code < 0) {
        fprintf(stderr, "need page code (see '--page=')\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (got_mask && force) {
        fprintf(stderr, "cannot use both '--force' and '--mask'\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }

    sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose);
    if (sg_fd < 0) {
        fprintf(stderr, ME "open error: %s: %s\n", device_name,
                safe_strerror(-sg_fd));
        return SG_LIB_FILE_ERROR;
    }
    if (0 == sg_simple_inquiry(sg_fd, &inq_data, 0, verbose))
        pdt = inq_data.peripheral_type;
    else
        pdt = 0x1f;

    /* do MODE SENSE to fetch current values */
    memset(ref_md, 0, MX_ALLOC_LEN);
    alloc_len = mode_6 ? SHORT_ALLOC_LEN : MX_ALLOC_LEN;
    if (mode_6)
        res = sg_ll_mode_sense6(sg_fd, dbd, 0 /*current */, pg_code,
                                sub_pg_code, ref_md, alloc_len, 1, verbose);
     else
        res = sg_ll_mode_sense10(sg_fd, 0 /* llbaa */, dbd, 0 /* current */,
                                 pg_code, sub_pg_code, ref_md, alloc_len, 1,
                                 verbose);
    ret = res;
    if (SG_LIB_CAT_INVALID_OP == res) {
        fprintf(stderr, "MODE SENSE (%d) not supported, try '--len=%d'\n",
                (mode_6 ? 6 : 10), (mode_6 ? 10 : 6));
        goto err_out;
    } else if (SG_LIB_CAT_NOT_READY == res) {
        fprintf(stderr, "MODE SENSE (%d) failed, device not ready\n",
                (mode_6 ? 6 : 10));
        goto err_out;
    } else if (SG_LIB_CAT_UNIT_ATTENTION == res) {
        fprintf(stderr, "MODE SENSE (%d) failed, unit attention\n",
                (mode_6 ? 6 : 10));
        goto err_out;
    } else if (SG_LIB_CAT_ABORTED_COMMAND == res) {
        fprintf(stderr, "MODE SENSE (%d) failed, aborted command\n",
                (mode_6 ? 6 : 10));
        goto err_out;
    } else if (SG_LIB_CAT_ILLEGAL_REQ == res) {
        fprintf(stderr, "bad field in MODE SENSE (%d) command\n",
                (mode_6 ? 6 : 10));
        goto err_out;
    } else if (0 != res) {
        fprintf(stderr, "MODE SENSE (%d) failed\n", (mode_6 ? 6 : 10));
        goto err_out;
    }
    off = sg_mode_page_offset(ref_md, alloc_len, mode_6, ebuff, EBUFF_SZ);
    if (off < 0) {
        fprintf(stderr, "MODE SENSE (%d): %s\n", (mode_6 ? 6 : 10), ebuff);
        goto err_out;
    }
    if (mode_6) {
        hdr_len = 4;
        md_len = ref_md[0] + 1;
        bd_len = ref_md[3];
    } else {
        hdr_len = 8;
        md_len = (ref_md[0] << 8) + ref_md[1] + 2;
        bd_len = (ref_md[6] << 8) + ref_md[7];
    }
    if (got_contents) {
        if (read_in_len < 2) {
            fprintf(stderr, "contents length=%d too short\n", read_in_len);
            goto err_out;
        }
        ref_md[0] = 0;  /* mode data length reserved for mode select */
        if (! mode_6)
            ref_md[1] = 0;    /* mode data length reserved for mode select */
        if (0 == pdt)   /* for disks mask out DPOFUA bit */
            ref_md[mode_6 ? 2 : 3] &= 0xef;
        if (md_len > alloc_len) {
            fprintf(stderr, "mode data length=%d exceeds allocation "
                    "length=%d\n", md_len, alloc_len);
            goto err_out;
        }
        if (got_mask) {
            for (k = 0; k < (md_len - off); ++k) {
                if ((0x0 == mask_in[k]) || (k > read_in_len))
                   read_in[k] = ref_md[off + k];
                else if (mask_in[k] < 0xff) {
                   c = (ref_md[off + k] & (0xff & ~mask_in[k]));
                   read_in[k] = (c | (read_in[k] & mask_in[k]));
                }
            }
            read_in_len = md_len - off;
        }
        if (! force) {
            if ((! (ref_md[off] & 0x80)) && save) {
                fprintf(stderr, "PS bit in existing mode page indicates that "
                        "it is not saveable\n    but '--save' option given\n");
                goto err_out;
            }
            read_in[0] &= 0x7f; /* mask out PS bit, reserved in mode select */
            if ((md_len - off) != read_in_len) {
                fprintf(stderr, "contents length=%d but reference mode page "
                        "length=%d\n", read_in_len, md_len - off);
                goto err_out;
            }
            if (pg_code != (read_in[0] & 0x3f)) {
                fprintf(stderr, "contents page_code=0x%x but reference "
                        "page_code=0x%x\n", (read_in[0] & 0x3f), pg_code);
                goto err_out;
            }
            if ((read_in[0] & 0x40) != (ref_md[off] & 0x40)) {
                fprintf(stderr, "contents flags subpage but reference page"
                        "does not (or vice versa)\n");
                goto err_out;
            }
            if ((read_in[0] & 0x40) && (read_in[1] != sub_pg_code)) {
                fprintf(stderr, "contents subpage_code=0x%x but reference "
                        "sub_page_code=0x%x\n", read_in[1], sub_pg_code);
                goto err_out;
            }
        } else
            md_len = off + read_in_len; /* force length */

        memcpy(ref_md + off, read_in, read_in_len);
        if (mode_6)
            res = sg_ll_mode_select6(sg_fd, 1, save, ref_md, md_len, 1,
                                     verbose);
        else
            res = sg_ll_mode_select10(sg_fd, 1, save, ref_md, md_len, 1,
                                      verbose);
        ret = res;
        if (SG_LIB_CAT_INVALID_OP == res) {
            fprintf(stderr, "MODE SELECT (%d) not supported\n",
                    (mode_6 ? 6 : 10));
            goto err_out;
        } else if (SG_LIB_CAT_NOT_READY == res) {
            fprintf(stderr, "MODE SELECT (%d) failed, device not ready\n",
                    (mode_6 ? 6 : 10));
            goto err_out;
        } else if (SG_LIB_CAT_UNIT_ATTENTION == res) {
            fprintf(stderr, "MODE SELECT (%d) failed, unit attention\n",
                    (mode_6 ? 6 : 10));
            goto err_out;
        } else if (SG_LIB_CAT_ABORTED_COMMAND == res) {
            fprintf(stderr, "MODE SELECT (%d) failed, aborted command\n",
                    (mode_6 ? 6 : 10));
            goto err_out;
        } else if (SG_LIB_CAT_ILLEGAL_REQ == res) {
            fprintf(stderr, "bad field in MODE SELECT (%d) command\n",
                    (mode_6 ? 6 : 10));
            goto err_out;
        } else if (0 != res) {
            fprintf(stderr, "MODE SELECT (%d) failed\n", (mode_6 ? 6 : 10));
            goto err_out;
        }
    } else {
        printf(">>> No contents given, so show current mode page data:\n");
        printf("  header:\n");
        dStrHex((const char *)ref_md, hdr_len, -1);
        if (bd_len) {
            printf("  block descriptor(s):\n");
            dStrHex((const char *)(ref_md + hdr_len), bd_len, -1);
        } else
            printf("  << no block descriptors >>\n");
        printf("  mode page:\n");
        dStrHex((const char *)(ref_md + off), md_len - off, -1);
    }
err_out:
    res = sg_cmds_close_device(sg_fd);
    if (res < 0) {
        fprintf(stderr, "close error: %s\n", safe_strerror(-res));
        if (0 == ret)
            return SG_LIB_FILE_ERROR;
    }
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
Exemple #4
0
static int fail_this_path(int fd, int lun, int use_6_byte)
{
    unsigned char fail_paths_pg[308];
    struct rdac_legacy_page *rdac_page;
    struct rdac_expanded_page *rdac_page_exp;
    struct rdac_page_common *rdac_common = NULL;
    int res;
    char b[80];

    if (use_6_byte && lun > 32) {
        pr2serr("must use 10 byte cdb to fail luns over 32\n");
        return -1;
    }

    memset(fail_paths_pg, 0, 308);
    if (use_6_byte) {
        memcpy(fail_paths_pg, mode6_hdr, 4);
        memcpy(fail_paths_pg + 4, block_descriptor, 8);
        rdac_page = (struct rdac_legacy_page *)(fail_paths_pg + 4 + 8);
        rdac_page->page_code = RDAC_CONTROLLER_PAGE;
        rdac_page->page_length = RDAC_CONTROLLER_PAGE_LEN;
        rdac_common = &rdac_page->attr;
        memset(rdac_page->lun_table, 0x0, 32);
        rdac_page->lun_table[lun] = 0x81;
    } else {
        memcpy(fail_paths_pg, mode10_hdr, 8);
        rdac_page_exp = (struct rdac_expanded_page *)
                        (fail_paths_pg + 8);
        rdac_page_exp->page_code = RDAC_CONTROLLER_PAGE | 0x40;
        rdac_page_exp->subpage_code = 0x1;
        sg_put_unaligned_be16(EXPANDED_LUN_SPACE_PAGE_LEN,
                              rdac_page_exp->page_length + 0);
        rdac_common = &rdac_page_exp->attr;
        memset(rdac_page_exp->lun_table, 0x0, 256);
        rdac_page_exp->lun_table[lun] = 0x81;
    }

    rdac_common->current_mode_lsb =  RDAC_FAIL_SELECTED_PATHS;
    rdac_common->quiescence = RDAC_QUIESCENCE_TIME;
    rdac_common->options = RDAC_FORCE_QUIESCENCE;

    if (use_6_byte) {
        res = sg_ll_mode_select6(fd, 1 /* pf */, 0 /* sp */,
                                 fail_paths_pg, 118,
                                 1, (do_verbose ? 2 : 0));
    } else {
        res = sg_ll_mode_select10(fd, 1 /* pf */, 0 /* sp */,
                                  fail_paths_pg, 308,
                                  1, (do_verbose ? 2: 0));
    }

    switch (res) {
    case 0:
        if (do_verbose)
            pr2serr("fail paths successful\n");
        break;
    default:
        sg_get_category_sense_str(res, sizeof(b), b, do_verbose);
        pr2serr("fail paths page (lun=%d) failed: %s\n", lun, b);
        break;
    }

    return res;
}