xattr: set creation_time xattr when creating a lvol

Longhorn 6604

Signed-off-by: Derek Su <derek.su@suse.com>
This commit is contained in:
Derek Su 2023-08-30 15:02:52 +08:00 committed by Damiano Cipriani
parent 4142a43052
commit 950822cae1
9 changed files with 70 additions and 4 deletions

View File

@ -497,6 +497,14 @@ const char *spdk_bdev_get_name(const struct spdk_bdev *bdev);
*/
const char *spdk_bdev_get_product_name(const struct spdk_bdev *bdev);
/**
* Get block device creation time.
*
* \param bdev Block device to query.
* \return Creation time of bdev as a null-terminated string, or NULL if not present.
*/
const char *spdk_bdev_get_creation_time(const struct spdk_bdev *bdev);
/**
* Get block device logical block size.
*

View File

@ -513,6 +513,13 @@ struct spdk_bdev {
*/
struct spdk_uuid uuid;
/**
* Creation time for this bdev.
*
* If not provided, it will be NULL.
*/
const char *creation_time;
/** Size in bytes of a metadata for the backend */
uint32_t md_len;

View File

@ -322,6 +322,25 @@ spdk_is_divisible_by(uint64_t dividend, uint64_t divisor)
return (dividend & (divisor - 1)) == 0;
}
/*
* Get the UTC time string in RFC3339 format.
*
* \param buf Buffer to store the UTC time string.
* \param buf_size Size of the buffer.
*
* \return void
*/
static inline void
spdk_current_utc_time_rfc3339(char *buf, size_t buf_size) {
struct tm *utc;
time_t rawtime;
time(&rawtime);
utc = gmtime(&rawtime);
strftime(buf, buf_size, "%Y-%m-%dT%H:%M:%SZ", utc);
}
#ifdef __cplusplus
}
#endif

View File

@ -16,6 +16,9 @@
/* Default size of blobstore cluster */
#define SPDK_LVS_OPTS_CLUSTER_SZ (4 * 1024 * 1024)
/* Creation time format in RFC 3339 format */
#define SPDK_CREATION_TIME_MAX 21 /* 20 characters + null terminator */
/* UUID + '_' + blobid (20 characters for uint64_t).
* Null terminator is already included in SPDK_UUID_STRING_LEN. */
#define SPDK_LVOL_UNIQUE_ID_MAX (SPDK_UUID_STRING_LEN + 1 + 20)
@ -106,6 +109,7 @@ struct spdk_lvol {
char name[SPDK_LVOL_NAME_MAX];
struct spdk_uuid uuid;
char uuid_str[SPDK_UUID_STRING_LEN];
char creation_time[SPDK_CREATION_TIME_MAX];
struct spdk_bdev *bdev;
int ref_count;
bool action_in_progress;

View File

@ -4569,6 +4569,12 @@ spdk_bdev_get_aliases(const struct spdk_bdev *bdev)
return &bdev->aliases;
}
const char *
spdk_bdev_get_creation_time(const struct spdk_bdev *bdev)
{
return bdev->creation_time;
}
uint32_t
spdk_bdev_get_block_size(const struct spdk_bdev *bdev)
{

View File

@ -664,6 +664,7 @@ rpc_dump_bdev_info(void *ctx, struct spdk_bdev *bdev)
uint64_t qos_limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES];
struct spdk_memory_domain **domains;
char uuid_str[SPDK_UUID_STRING_LEN];
const char *creation_time_str;
int i, rc;
spdk_json_write_object_begin(w);
@ -687,6 +688,12 @@ rpc_dump_bdev_info(void *ctx, struct spdk_bdev *bdev)
spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid);
spdk_json_write_named_string(w, "uuid", uuid_str);
creation_time_str = spdk_bdev_get_creation_time(bdev);
if (creation_time_str == NULL) {
creation_time_str = "";
}
spdk_json_write_named_string(w, "creation_time", creation_time_str);
if (spdk_bdev_get_md_size(bdev) != 0) {
spdk_json_write_named_uint32(w, "md_size", spdk_bdev_get_md_size(bdev));
spdk_json_write_named_bool(w, "md_interleave", spdk_bdev_is_md_interleaved(bdev));

View File

@ -16,6 +16,7 @@
#define SPDK_LVOL_BLOB_OPTS_CHANNEL_OPS 512
#define LVOL_NAME "name"
#define LVOL_CREATION_TIME "creation_time"
SPDK_LOG_REGISTER_COMPONENT(lvol)
@ -114,6 +115,7 @@ lvol_alloc(struct spdk_lvol_store *lvs, const char *name, bool thin_provision,
spdk_uuid_generate(&lvol->uuid);
spdk_uuid_fmt_lower(lvol->uuid_str, sizeof(lvol->uuid_str), &lvol->uuid);
spdk_uuid_fmt_lower(lvol->unique_id, sizeof(lvol->uuid_str), &lvol->uuid);
spdk_current_utc_time_rfc3339(lvol->creation_time, sizeof(lvol->creation_time));
TAILQ_INSERT_TAIL(&lvs->pending_lvols, lvol, link);
@ -278,6 +280,11 @@ load_next_lvol(void *cb_arg, struct spdk_blob *blob, int lvolerrno)
snprintf(lvol->name, sizeof(lvol->name), "%s", attr);
rc = spdk_blob_get_xattr_value(blob, "creation_time", (const void **)&attr, &value_len);
if (rc == 0 && value_len <= SPDK_CREATION_TIME_MAX) {
snprintf(lvol->creation_time, sizeof(lvol->creation_time), "%s", attr);
}
TAILQ_INSERT_TAIL(&lvs->lvols, lvol, link);
lvs->lvol_count++;
@ -1139,6 +1146,12 @@ lvol_get_xattr_value(void *xattr_ctx, const char *name,
*value_len = sizeof(lvol->uuid_str);
return;
}
if (!strcmp(LVOL_CREATION_TIME, name)) {
*value = lvol->creation_time;
*value_len = sizeof(lvol->creation_time);
return;
}
*value = NULL;
*value_len = 0;
}
@ -1184,7 +1197,7 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
struct spdk_blob_store *bs;
struct spdk_lvol *lvol;
struct spdk_blob_opts opts;
char *xattr_names[] = {LVOL_NAME, "uuid"};
char *xattr_names[] = {LVOL_NAME, "uuid", LVOL_CREATION_TIME};
int rc;
if (lvs == NULL) {
@ -1239,7 +1252,7 @@ spdk_lvol_create_esnap_clone(const void *esnap_id, uint32_t id_len, uint64_t siz
struct spdk_lvol *lvol;
struct spdk_blob_opts opts;
uint64_t cluster_sz;
char *xattr_names[] = {LVOL_NAME, "uuid"};
char *xattr_names[] = {LVOL_NAME, "uuid", LVOL_CREATION_TIME};
int rc;
if (lvs == NULL) {
@ -1303,7 +1316,7 @@ spdk_lvol_create_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name,
struct spdk_blob *origblob;
struct spdk_lvol_with_handle_req *req;
struct spdk_blob_xattr_opts snapshot_xattrs;
char *xattr_names[] = {LVOL_NAME, "uuid"};
char *xattr_names[] = {LVOL_NAME, "uuid", LVOL_CREATION_TIME};
int rc;
if (origlvol == NULL) {
@ -1364,7 +1377,7 @@ spdk_lvol_create_clone(struct spdk_lvol *origlvol, const char *clone_name,
struct spdk_lvol_store *lvs;
struct spdk_blob *origblob;
struct spdk_blob_xattr_opts clone_xattrs;
char *xattr_names[] = {LVOL_NAME, "uuid"};
char *xattr_names[] = {LVOL_NAME, "uuid", LVOL_CREATION_TIME};
int rc;
if (origlvol == NULL) {

View File

@ -1144,6 +1144,7 @@ _create_lvol_disk(struct spdk_lvol *lvol, bool destroy)
assert((total_size % bdev->blocklen) == 0);
bdev->blockcnt = total_size / bdev->blocklen;
bdev->uuid = lvol->uuid;
bdev->creation_time = lvol->creation_time;
bdev->required_alignment = lvs_bdev->bdev->required_alignment;
bdev->split_on_optimal_io_boundary = true;
bdev->optimal_io_boundary = spdk_bs_get_cluster_size(lvol->lvol_store->blobstore) / bdev->blocklen;

View File

@ -1350,6 +1350,7 @@ rpc_dump_lvol(struct spdk_json_write_ctx *w, struct spdk_lvol *lvol)
spdk_json_write_named_string_fmt(w, "alias", "%s/%s", lvs->name, lvol->name);
spdk_json_write_named_string(w, "uuid", lvol->uuid_str);
spdk_json_write_named_string(w, "name", lvol->name);
spdk_json_write_named_string(w, "creation_time", lvol->creation_time);
spdk_json_write_named_bool(w, "is_thin_provisioned", spdk_blob_is_thin_provisioned(lvol->blob));
spdk_json_write_named_bool(w, "is_snapshot", spdk_blob_is_snapshot(lvol->blob));
spdk_json_write_named_bool(w, "is_clone", spdk_blob_is_clone(lvol->blob));