Ejemplo n.º 1
0
int
dz_get_zones(void)
{
    unsigned int nr_zones;
    int ret;

    ret = zbc_report_nr_zones(dz.dev, 0, ZBC_RO_ALL, &nr_zones);
    if ( ret != 0 ) {
        return( ret );
    }

    if ( dz.nr_zones
         && (dz.nr_zones != nr_zones) ) {
        /* Zone list changed: clean it */
        free(dz.zones);
        dz.zones = NULL;
        dz.nr_zones = 0;
    }

    if ( ! dz.nr_zones ) {
        printf("Device \"%s\": %llu sectors of %u B, %d zones\n",
               dz.filename,
               (unsigned long long) dz.info.zbd_physical_blocks,
               (unsigned int) dz.info.zbd_physical_block_size,
               nr_zones);
    }

    /* Get/refresh zone list */
    ret = zbc_list_zones(dz.dev, 0, ZBC_RO_ALL, &dz.zones, &dz.nr_zones);
    if ( ret != 0 ) {
        ret = errno;
        fprintf(stderr, "zbc_list_zones failed %d (%s)\n",
                errno,
                strerror(errno));
        if ( dz.zones ) {
            free(dz.zones);
            dz.zones = NULL;
            dz.nr_zones = 0;
        }
        goto out;
    }

out:

    return( ret );

}
Ejemplo n.º 2
0
/**
 * zbc_list_zones - report zones for a ZBC device
 * @dev:                (IN) ZBC device handle to report on
 * @start_lba:          (IN) start LBA for the first zone to reported
 * @ro:                 (IN) Reporting options
 * @zones:              (OUT) pointer for reported zones
 * @nr_zones:           (OUT) number of returned zones
 *
 * Reports the number and details of available zones.  The @zones
 * parameter is used to return an array of zones which is allocated using
 * malloc(3) internally and needs to be freed using free(3).  The number
 * of zones in @zones is returned in @nr_zones.
 *
 * Returns -EIO if an error happened when communicating to the device.
 * Returns -ENOMEM if memory could not be allocated for @zones.
 */
int
zbc_list_zones(struct zbc_device *dev,
               uint64_t start_lba,
               enum zbc_reporting_options ro,
               struct zbc_zone **pzones,
               unsigned int *pnr_zones)
{
    zbc_zone_t *zones = NULL;
    unsigned int nr_zones;
    int ret;

    /* Get total number of zones */
    ret = zbc_report_nr_zones(dev, start_lba, ro, &nr_zones);
    if ( ret < 0 ) {
        return( ret );
    }

    zbc_debug("Device %s: %d zones\n",
              dev->zbd_filename,
              nr_zones);

    /* Allocate zone array */
    zones = (zbc_zone_t *) malloc(sizeof(zbc_zone_t) * nr_zones);
    if ( ! zones ) {
        zbc_error("No memory\n");
        return( -ENOMEM );
    }
    memset(zones, 0, sizeof(zbc_zone_t) * nr_zones);

    /* Get zones info */
    ret = zbc_report_zones(dev, start_lba, ro, zones, &nr_zones);
    if ( ret != 0 ) {
        zbc_error("zbc_report_zones failed\n");
        free(zones);
    } else {
        *pzones = zones;
        *pnr_zones = nr_zones;
    }

    return( ret );

}
Ejemplo n.º 3
0
int main(int argc,
         char **argv)
{
    struct zbc_device_info info;
    unsigned long long lba = 0;
    struct zbc_device *dev;
    enum zbc_reporting_options ro = ZBC_RO_ALL;
    int i, ret = 1;
    zbc_zone_t *z, *zones = NULL;
    unsigned int nr_zones, nz = 0;
    int num = 0;
    char *path;

    /* Check command line */
    if ( argc < 2 ) {
usage:
        printf("Usage: %s [options] <dev>\n"
               "Options:\n"
               "    -v         : Verbose mode\n"
               "    -n         : Get only the number of zones\n"
               "    -nz <num>  : Get at most <num> zones\n"
               "    -lba <lba> : Specify zone start LBA (default is 0)\n"
               "    -ro <opt>  : Specify reporting option: \"all\", \"empty\",\n"
               "                 \"imp_open\", \"exp_open\", \"closed\", \"full\",\n"
               "                 \"rdonly\", \"offline\", \"reset\", \"non_seq\" or \"not_wp\".\n"
               "                 Default is \"all\"\n",
               argv[0]);
        return( 1 );
    }

    /* Parse options */
    for(i = 1; i < (argc - 1); i++) {

        if ( strcmp(argv[i], "-v") == 0 ) {

            zbc_set_log_level("debug");

        } else if ( strcmp(argv[i], "-n") == 0 ) {

            num = 1;

	} else if ( strcmp(argv[i], "-nz") == 0 ) {

            if ( i >= (argc - 1) ) {
                goto usage;
            }
            i++;

            nz = strtol(argv[i], NULL, 10);
	    if ( nz <= 0 ) {
		goto usage;
	    }

        } else if ( strcmp(argv[i], "-lba") == 0 ) {

            if ( i >= (argc - 1) ) {
                goto usage;
            }
            i++;

            lba = strtoll(argv[i], NULL, 10);

        } else if ( strcmp(argv[i], "-ro") == 0 ) {

            if ( i >= (argc - 1) ) {
                goto usage;
            }
            i++;

            if ( strcmp(argv[i], "all") == 0 ) {
                ro = ZBC_RO_ALL;
            } else if ( strcmp(argv[i], "empty") == 0 ) {
                ro = ZBC_RO_EMPTY;
            } else if ( strcmp(argv[i], "imp_open") == 0 ) {
                ro = ZBC_RO_IMP_OPEN;
            } else if ( strcmp(argv[i], "exp_open") == 0 ) {
                ro = ZBC_RO_EXP_OPEN;
            } else if ( strcmp(argv[i], "closed") == 0 ) {
                ro = ZBC_RO_CLOSED;
            } else if ( strcmp(argv[i], "full") == 0 ) {
                ro = ZBC_RO_FULL;
            } else if ( strcmp(argv[i], "rdonly") == 0 ) {
                ro = ZBC_RO_RDONLY;
            } else if ( strcmp(argv[i], "offline") == 0 ) {
                ro = ZBC_RO_OFFLINE;
            } else if ( strcmp(argv[i], "reset") == 0 ) {
                ro = ZBC_RO_RESET;
            } else if ( strcmp(argv[i], "non_seq") == 0 ) {
                ro = ZBC_RO_NON_SEQ;
            } else if ( strcmp(argv[i], "not_wp") == 0 ) {
                ro = ZBC_RO_NOT_WP;
            } else {
                fprintf(stderr, "Unknown zone reporting option \"%s\"\n",
                        argv[i]);
                goto usage;
            }

        } else if ( argv[i][0] == '-' ) {

            printf("Unknown option \"%s\"\n",
                   argv[i]);
            goto usage;

        } else {

            break;

        }

    }

    if ( i != (argc - 1) ) {
        goto usage;
    }

    /* Open device */
    path = argv[i];
    ret = zbc_open(path, O_RDONLY, &dev);
    if ( ret != 0 ) {
        return( 1 );
    }

    ret = zbc_get_device_info(dev, &info);
    if ( ret < 0 ) {
        fprintf(stderr,
                "zbc_get_device_info failed\n");
        goto out;
    }

    printf("Device %s: %s\n",
           path,
           info.zbd_vendor_id);
    printf("    %s interface, %s disk model\n",
           zbc_disk_type_str(info.zbd_type),
           zbc_disk_model_str(info.zbd_model));
    printf("    %llu logical blocks of %u B\n",
           (unsigned long long) info.zbd_logical_blocks,
           (unsigned int) info.zbd_logical_block_size);
    printf("    %llu physical blocks of %u B\n",
           (unsigned long long) info.zbd_physical_blocks,
           (unsigned int) info.zbd_physical_block_size);
    printf("    %.03F GB capacity\n",
           (double) (info.zbd_physical_blocks * info.zbd_physical_block_size) / 1000000000);

    /* Get the number of zones */
    ret = zbc_report_nr_zones(dev, lba, ro, &nr_zones);
    if ( ret != 0 ) {
	fprintf(stderr, "zbc_report_nr_zones at lba %llu, ro 0x%02x failed %d\n",
		(unsigned long long) lba,
		(unsigned int) ro,
		ret);
	ret = 1;
	goto out;
    }

    /* Print zone info */
    printf("    %u zones from LBA %llu, reporting option 0x%02x\n",
	   nr_zones,
	   lba,
	   ro);

    if ( num ) {
	goto out;
    }

    if ( (! nz) || (nz > nr_zones) ) {
	nz = nr_zones;
    }

    /* Allocate zone array */
    zones = (zbc_zone_t *) malloc(sizeof(zbc_zone_t) * nz);
    if ( ! zones ) {
	fprintf(stderr, "No memory\n");
	ret = 1;
	goto out;
    }
    memset(zones, 0, sizeof(zbc_zone_t) * nz);

    /* Get zone information */
    ret = zbc_report_zones(dev, lba, ro, zones, &nz);
    if ( ret != 0 ) {
	fprintf(stderr, "zbc_list_zones failed %d\n", ret);
	ret = 1;
	goto out;
    }

    printf("%u / %u zones:\n", nz, nr_zones);
    for(i = 0; i < (int)nz; i++) {
        z = &zones[i];
        if ( zbc_zone_conventional(z) ) {
            printf("Zone %05d: type 0x%x (%s), cond 0x%x (%s), LBA %llu, %llu sectors, wp N/A\n",
                   i,
                   zbc_zone_type(z),
                   zbc_zone_type_str(z),
                   zbc_zone_condition(z),
                   zbc_zone_condition_str(z),
                   zbc_zone_start_lba(z),
                   zbc_zone_length(z));
        } else {
            printf("Zone %05d: type 0x%x (%s), cond 0x%x (%s), need_reset %d, non_seq %d, LBA %llu, %llu sectors, wp %llu\n",
                   i,
                   zbc_zone_type(z),
                   zbc_zone_type_str(z),
                   zbc_zone_condition(z),
                   zbc_zone_condition_str(z),
                   zbc_zone_need_reset(z),
                   zbc_zone_non_seq(z),
                   zbc_zone_start_lba(z),
                   zbc_zone_length(z),
                   zbc_zone_wp_lba(z));
        }
    }

out:

    if ( zones ) {
        free(zones);
    }

    zbc_close(dev);

    return( ret );

}
Ejemplo n.º 4
0
int
main(int argc,
     char **argv)
{
    struct zbc_device_info info;
    unsigned long long lba = 0;
    struct zbc_device *dev;
    enum zbc_reporting_options ro = ZBC_RO_ALL;
    int i, ret = 1;
    zbc_zone_t *z, *zones = NULL;
    unsigned int nr_zones, nz = 0, prtl = 0;
    int num = 0;
    char *path;

    /* Check command line */
    if ( argc < 2 ) {
usage:
        printf("Usage: %s [options] <dev>\n"
               "Options:\n"
               "    -v         : Verbose mode\n"
               "    -lba <lba> : Specify zone start LBA (default is 0)\n"
               "    -ro <opt>  : Reporting Option\n"
               "    -p         : Partial bit\n",
               argv[0]);
        return( 1 );
    }

    /* Parse options */
    for(i = 1; i < (argc - 1); i++) {

        if ( strcmp(argv[i], "-v") == 0 ) {

            zbc_set_log_level("debug");

        } else if ( strcmp(argv[i], "-lba") == 0 ) {

            if ( i >= (argc - 1) ) {
                goto usage;
            }
            i++;

            lba = strtoll(argv[i], NULL, 10);

        } else if ( strcmp(argv[i], "-ro") == 0 ) {

            if ( i >= (argc - 1) ) {
                goto usage;
            }
            i++;

            ro = atoi(argv[i]);

            if ( ro < 0 ) {
                goto usage;
            }

        } else if ( strcmp(argv[i], "-p") == 0 ) {

            prtl = ZBC_RO_PARTIAL; 

        } else if ( argv[i][0] == '-' ) {

            printf("Unknown option \"%s\"\n",
                   argv[i]);
            goto usage;

        } else {

            break;

        }

    }

    if ( i != (argc - 1) ) {
        goto usage;
    }

    /* Merging ro */
    ro |= prtl;

    /* Open device */
    path = argv[i];
    ret = zbc_open(path, O_RDONLY, &dev);
    if ( ret != 0 ) {
        fprintf(stderr, "[TEST][ERROR],open device failed\n");
	printf("[TEST][ERROR][SENSE_KEY],open-device-failed\n");
	printf("[TEST][ERROR][ASC_ASCQ],open-device-failed\n");
        return( 1 );
    }

    ret = zbc_get_device_info(dev, &info);
    if ( ret < 0 ) {
        fprintf(stderr,
                "[TEST][ERROR],zbc_get_device_info failed\n");
        goto out;
    }

    /* Get the number of zones */
    ret = zbc_report_nr_zones(dev, lba, ro, &nr_zones);
    if ( ret != 0 ) {
	fprintf(stderr, "[TEST][ERROR],zbc_report_nr_zones at lba %llu, ro 0x%02x failed %d\n",
		(unsigned long long) lba,
		(unsigned int) ro,
		ret);
	ret = 1;
	goto out;
    }

    if ( num ) {
	goto out;
    }

    if ( (! nz) || (nz > nr_zones) ) {
	nz = nr_zones;
    }

    /* Allocate zone array */
    zones = (zbc_zone_t *) malloc(sizeof(zbc_zone_t) * nz);
    if ( ! zones ) {
	fprintf(stderr,
                "[TEST][ERROR],No memory\n");
	ret = 1;
	goto out;
    }
    memset(zones, 0, sizeof(zbc_zone_t) * nz);

    /* Get zone information */
    ret = zbc_report_zones(dev, lba, ro, zones, &nz);
    if ( ret != 0 ) {
	fprintf(stderr,
                "[TEST][ERROR],zbc_report_zones failed %d\n", ret);
	ret = 1;
	goto out;
    }

    for(i = 0; i < (int)nz; i++) {
        z = &zones[i];
        if ( zbc_zone_conventional(z) ) {
            printf("[ZONE_INFO],%05d,0x%x,0x%x,%llu,%llu,N/A\n",
                   i,
                   zbc_zone_type(z),
                   zbc_zone_condition(z),
                   zbc_zone_start_lba(z),
                   zbc_zone_length(z));
        } else {
            printf("[ZONE_INFO],%05d,0x%x,0x%x,%llu,%llu,%llu\n",
                   i,
                   zbc_zone_type(z),
                   zbc_zone_condition(z),
                   zbc_zone_start_lba(z),
                   zbc_zone_length(z),
                   zbc_zone_wp_lba(z));
        }
    }

out:

    if ( ret ) {

            zbc_errno_t zbc_err;
            const char *sk_name;
            const char *ascq_name;

            zbc_errno(dev, &zbc_err);
            sk_name = zbc_sk_str(zbc_err.sk);
            ascq_name = zbc_asc_ascq_str(zbc_err.asc_ascq);

            printf("[TEST][ERROR][SENSE_KEY],%s\n", sk_name);
            printf("[TEST][ERROR][ASC_ASCQ],%s\n", ascq_name);

    }

    if ( zones ) {
        free(zones);
    }

    zbc_close(dev);

    return( ret );

}