mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
label: Add callback fns (partially)
This commit is contained in:
parent
5e7d3ad749
commit
6d322e68f3
@ -54,8 +54,8 @@ static int _lvm1_write(struct label *label __attribute__((unused)), void *buf __
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
static int _lvm1_read(struct labeller *l, struct device *dev, void *buf, struct label **label,
|
||||||
struct label **label)
|
lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
|
||||||
{
|
{
|
||||||
struct pv_disk *pvd = (struct pv_disk *) buf;
|
struct pv_disk *pvd = (struct pv_disk *) buf;
|
||||||
struct vg_disk vgd;
|
struct vg_disk vgd;
|
||||||
@ -63,6 +63,7 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
|||||||
const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
|
const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
|
||||||
const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
|
const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
|
||||||
unsigned exported = 0;
|
unsigned exported = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
munge_pvd(dev, pvd);
|
munge_pvd(dev, pvd);
|
||||||
|
|
||||||
@ -76,7 +77,8 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
|||||||
|
|
||||||
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
|
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
|
||||||
exported)))
|
exported)))
|
||||||
return_0;
|
goto_out;
|
||||||
|
|
||||||
*label = lvmcache_get_label(info);
|
*label = lvmcache_get_label(info);
|
||||||
|
|
||||||
lvmcache_set_device_size(info, ((uint64_t)xlate32(pvd->pv_size)) << SECTOR_SHIFT);
|
lvmcache_set_device_size(info, ((uint64_t)xlate32(pvd->pv_size)) << SECTOR_SHIFT);
|
||||||
@ -86,7 +88,13 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
|||||||
lvmcache_del_bas(info);
|
lvmcache_del_bas(info);
|
||||||
lvmcache_make_valid(info);
|
lvmcache_make_valid(info);
|
||||||
|
|
||||||
return 1;
|
r = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (read_label_callback_fn)
|
||||||
|
read_label_callback_fn(!r, read_label_callback_context, NULL);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lvm1_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
|
static int _lvm1_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
|
||||||
|
@ -55,12 +55,18 @@ static int _pool_write(struct label *label __attribute__((unused)), void *buf __
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _pool_read(struct labeller *l, struct device *dev, void *buf,
|
static int _pool_read(struct labeller *l, struct device *dev, void *buf, struct label **label,
|
||||||
struct label **label)
|
lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
|
||||||
{
|
{
|
||||||
struct pool_list pl;
|
struct pool_list pl;
|
||||||
|
int r;
|
||||||
|
|
||||||
return read_pool_label(&pl, l, dev, buf, label);
|
r = read_pool_label(&pl, l, dev, buf, label);
|
||||||
|
|
||||||
|
if (read_label_callback_fn)
|
||||||
|
read_label_callback_fn(!r, read_label_callback_context, NULL);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _pool_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
|
static int _pool_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
|
||||||
|
@ -329,6 +329,8 @@ static void _xlate_mdah(struct mda_header *mdah)
|
|||||||
struct process_raw_mda_header_params {
|
struct process_raw_mda_header_params {
|
||||||
struct mda_header *mdah;
|
struct mda_header *mdah;
|
||||||
struct device_area dev_area;
|
struct device_area dev_area;
|
||||||
|
lvm_callback_fn_t mdah_callback_fn;
|
||||||
|
void *mdah_callback_context;
|
||||||
int ret;
|
int ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -338,10 +340,13 @@ static void _process_raw_mda_header(int failed, void *context, void *data)
|
|||||||
struct mda_header *mdah = prmp->mdah;
|
struct mda_header *mdah = prmp->mdah;
|
||||||
struct device_area *dev_area = &prmp->dev_area;
|
struct device_area *dev_area = &prmp->dev_area;
|
||||||
|
|
||||||
if (!dev_close(dev_area->dev)) {
|
if (!dev_close(dev_area->dev))
|
||||||
prmp->ret = 0;
|
goto_bad;
|
||||||
goto_out;
|
|
||||||
}
|
if (failed)
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
memcpy(mdah, data, MDA_HEADER_SIZE);
|
||||||
|
|
||||||
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
|
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
|
||||||
MDA_HEADER_SIZE -
|
MDA_HEADER_SIZE -
|
||||||
@ -349,8 +354,7 @@ static void _process_raw_mda_header(int failed, void *context, void *data)
|
|||||||
log_error("Incorrect metadata area header checksum on %s"
|
log_error("Incorrect metadata area header checksum on %s"
|
||||||
" at offset " FMTu64, dev_name(dev_area->dev),
|
" at offset " FMTu64, dev_name(dev_area->dev),
|
||||||
dev_area->start);
|
dev_area->start);
|
||||||
prmp->ret = 0;
|
goto bad;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_xlate_mdah(mdah);
|
_xlate_mdah(mdah);
|
||||||
@ -359,31 +363,37 @@ static void _process_raw_mda_header(int failed, void *context, void *data)
|
|||||||
log_error("Wrong magic number in metadata area header on %s"
|
log_error("Wrong magic number in metadata area header on %s"
|
||||||
" at offset " FMTu64, dev_name(dev_area->dev),
|
" at offset " FMTu64, dev_name(dev_area->dev),
|
||||||
dev_area->start);
|
dev_area->start);
|
||||||
prmp->ret = 0;
|
goto bad;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mdah->version != FMTT_VERSION) {
|
if (mdah->version != FMTT_VERSION) {
|
||||||
log_error("Incompatible metadata area header version: %d on %s"
|
log_error("Incompatible metadata area header version: %d on %s"
|
||||||
" at offset " FMTu64, mdah->version,
|
" at offset " FMTu64, mdah->version,
|
||||||
dev_name(dev_area->dev), dev_area->start);
|
dev_name(dev_area->dev), dev_area->start);
|
||||||
prmp->ret = 0;
|
goto bad;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mdah->start != dev_area->start) {
|
if (mdah->start != dev_area->start) {
|
||||||
log_error("Incorrect start sector in metadata area header: "
|
log_error("Incorrect start sector in metadata area header: "
|
||||||
FMTu64 " on %s at offset " FMTu64, mdah->start,
|
FMTu64 " on %s at offset " FMTu64, mdah->start,
|
||||||
dev_name(dev_area->dev), dev_area->start);
|
dev_name(dev_area->dev), dev_area->start);
|
||||||
prmp->ret = 0;
|
goto bad;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
prmp->ret = 0;
|
||||||
out:
|
out:
|
||||||
;
|
if (!failed)
|
||||||
|
dm_free(data);
|
||||||
|
|
||||||
|
if (prmp->ret && prmp->mdah_callback_fn)
|
||||||
|
prmp->mdah_callback_fn(0, prmp->mdah_callback_context, mdah);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mda_header *_raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda)
|
static struct mda_header *_raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
|
||||||
|
lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context)
|
||||||
{
|
{
|
||||||
struct mda_header *mdah;
|
struct mda_header *mdah;
|
||||||
struct process_raw_mda_header_params *prmp;
|
struct process_raw_mda_header_params *prmp;
|
||||||
@ -406,15 +416,13 @@ static struct mda_header *_raw_read_mda_header(struct dm_pool *mem, struct devic
|
|||||||
|
|
||||||
prmp->mdah = mdah;
|
prmp->mdah = mdah;
|
||||||
prmp->dev_area = *dev_area;
|
prmp->dev_area = *dev_area;
|
||||||
|
prmp->mdah_callback_fn = mdah_callback_fn;
|
||||||
|
prmp->mdah_callback_context = mdah_callback_context;
|
||||||
prmp->ret = 1;
|
prmp->ret = 1;
|
||||||
|
|
||||||
if (!dev_read_buf(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, MDA_HEADER_REASON(primary_mda), mdah)) {
|
if (!dev_read_callback(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, MDA_HEADER_REASON(primary_mda),
|
||||||
if (!dev_close(dev_area->dev))
|
_process_raw_mda_header, prmp))
|
||||||
stack;
|
stack;
|
||||||
return_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_process_raw_mda_header(0, prmp, NULL);
|
|
||||||
|
|
||||||
if (!prmp->ret)
|
if (!prmp->ret)
|
||||||
return_NULL;
|
return_NULL;
|
||||||
@ -424,7 +432,16 @@ static struct mda_header *_raw_read_mda_header(struct dm_pool *mem, struct devic
|
|||||||
|
|
||||||
struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda)
|
struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda)
|
||||||
{
|
{
|
||||||
return _raw_read_mda_header(mem, dev_area, primary_mda);
|
return _raw_read_mda_header(mem, dev_area, primary_mda, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw_read_mda_header_callback(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
|
||||||
|
lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context)
|
||||||
|
{
|
||||||
|
if (!_raw_read_mda_header(mem, dev_area, primary_mda, mdah_callback_fn, mdah_callback_context))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _raw_write_mda_header(const struct format_type *fmt,
|
static int _raw_write_mda_header(const struct format_type *fmt,
|
||||||
@ -2002,7 +2019,7 @@ static int _mda_export_text_raw(struct metadata_area *mda,
|
|||||||
{
|
{
|
||||||
struct mda_context *mdc = (struct mda_context *) mda->metadata_locn;
|
struct mda_context *mdc = (struct mda_context *) mda->metadata_locn;
|
||||||
|
|
||||||
if (!mdc || !_raw_read_mda_header(cft->mem, &mdc->area, mda_is_primary(mda)))
|
if (!mdc || !_raw_read_mda_header(cft->mem, &mdc->area, mda_is_primary(mda), NULL, NULL))
|
||||||
return 1; /* pretend the MDA does not exist */
|
return 1; /* pretend the MDA does not exist */
|
||||||
|
|
||||||
return config_make_nodes(cft, parent, NULL,
|
return config_make_nodes(cft, parent, NULL,
|
||||||
|
@ -82,6 +82,8 @@ struct mda_header {
|
|||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda);
|
struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda);
|
||||||
|
int raw_read_mda_header_callback(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
|
||||||
|
lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context);
|
||||||
|
|
||||||
struct mda_lists {
|
struct mda_lists {
|
||||||
struct dm_list dirs;
|
struct dm_list dirs;
|
||||||
|
@ -322,6 +322,9 @@ static int _text_initialise_label(struct labeller *l __attribute__((unused)),
|
|||||||
struct update_mda_baton {
|
struct update_mda_baton {
|
||||||
struct lvmcache_info *info;
|
struct lvmcache_info *info;
|
||||||
struct label *label;
|
struct label *label;
|
||||||
|
int nr_outstanding_mdas;
|
||||||
|
lvm_callback_fn_t read_label_callback_fn;
|
||||||
|
void *read_label_callback_context;
|
||||||
int ret;
|
int ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -338,6 +341,8 @@ static void _process_vgsummary(int failed, void *context, void *data)
|
|||||||
struct process_mda_header_params *pmp = context;
|
struct process_mda_header_params *pmp = context;
|
||||||
struct lvmcache_vgsummary *vgsummary = data;
|
struct lvmcache_vgsummary *vgsummary = data;
|
||||||
|
|
||||||
|
--pmp->umb->nr_outstanding_mdas;
|
||||||
|
|
||||||
if (!lvmcache_update_vgname_and_id(pmp->umb->info, vgsummary)) {
|
if (!lvmcache_update_vgname_and_id(pmp->umb->info, vgsummary)) {
|
||||||
pmp->umb->ret = 0;
|
pmp->umb->ret = 0;
|
||||||
pmp->ret = 0;
|
pmp->ret = 0;
|
||||||
@ -358,12 +363,16 @@ static void _process_mda_header(int failed, void *context, void *data)
|
|||||||
struct metadata_area *mda = pmp->mda;
|
struct metadata_area *mda = pmp->mda;
|
||||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
return;
|
||||||
|
|
||||||
mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
|
mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
|
||||||
|
|
||||||
if (mda_is_ignored(mda)) {
|
if (mda_is_ignored(mda)) {
|
||||||
log_debug_metadata("Ignoring mda on device %s at offset " FMTu64,
|
log_debug_metadata("Ignoring mda on device %s at offset " FMTu64,
|
||||||
dev_name(mdac->area.dev),
|
dev_name(mdac->area.dev),
|
||||||
mdac->area.start);
|
mdac->area.start);
|
||||||
|
--pmp->umb->nr_outstanding_mdas;
|
||||||
if (!dev_close(pmp->dev))
|
if (!dev_close(pmp->dev))
|
||||||
stack;
|
stack;
|
||||||
return;
|
return;
|
||||||
@ -373,6 +382,7 @@ static void _process_mda_header(int failed, void *context, void *data)
|
|||||||
&mdac->free_sectors)) {
|
&mdac->free_sectors)) {
|
||||||
/* FIXME Separate fatal and non-fatal error cases? */
|
/* FIXME Separate fatal and non-fatal error cases? */
|
||||||
stack;
|
stack;
|
||||||
|
--pmp->umb->nr_outstanding_mdas;
|
||||||
if (!dev_close(pmp->dev))
|
if (!dev_close(pmp->dev))
|
||||||
stack;
|
stack;
|
||||||
return;
|
return;
|
||||||
@ -388,7 +398,6 @@ static int _update_mda(struct metadata_area *mda, void *baton)
|
|||||||
const struct format_type *fmt = umb->label->labeller->fmt;
|
const struct format_type *fmt = umb->label->labeller->fmt;
|
||||||
struct dm_pool *mem = umb->label->labeller->fmt->cmd->mem;
|
struct dm_pool *mem = umb->label->labeller->fmt->cmd->mem;
|
||||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||||
struct mda_header *mdah;
|
|
||||||
|
|
||||||
if (!(pmp = dm_pool_zalloc(mem, sizeof(*pmp)))) {
|
if (!(pmp = dm_pool_zalloc(mem, sizeof(*pmp)))) {
|
||||||
log_error("struct process_mda_header_params allocation failed");
|
log_error("struct process_mda_header_params allocation failed");
|
||||||
@ -408,25 +417,26 @@ static int _update_mda(struct metadata_area *mda, void *baton)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
umb->nr_outstanding_mdas++;
|
||||||
pmp->dev = mdac->area.dev;
|
pmp->dev = mdac->area.dev;
|
||||||
|
|
||||||
pmp->umb = umb;
|
pmp->umb = umb;
|
||||||
pmp->mda = mda;
|
pmp->mda = mda;
|
||||||
pmp->ret = 1;
|
pmp->ret = 1;
|
||||||
|
|
||||||
if (!(mdah = raw_read_mda_header(fmt->cmd->mem, &mdac->area, mda_is_primary(mda)))) {
|
if (!raw_read_mda_header_callback(fmt->cmd->mem, &mdac->area, mda_is_primary(mda), _process_mda_header, pmp)) {
|
||||||
stack;
|
stack;
|
||||||
|
--pmp->umb->nr_outstanding_mdas;
|
||||||
if (!dev_close(pmp->dev))
|
if (!dev_close(pmp->dev))
|
||||||
stack;
|
stack;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_process_mda_header(0, pmp, mdah);
|
|
||||||
|
|
||||||
return pmp->ret;
|
return pmp->ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _text_read(struct labeller *l, struct device *dev, void *buf, struct label **label)
|
static int _text_read(struct labeller *l, struct device *dev, void *buf, struct label **label,
|
||||||
|
lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
|
||||||
{
|
{
|
||||||
struct label_header *lh = (struct label_header *) buf;
|
struct label_header *lh = (struct label_header *) buf;
|
||||||
struct pv_header *pvhdr;
|
struct pv_header *pvhdr;
|
||||||
@ -503,17 +513,28 @@ out:
|
|||||||
|
|
||||||
umb->info = info;
|
umb->info = info;
|
||||||
umb->label = *label;
|
umb->label = *label;
|
||||||
|
umb->read_label_callback_fn = read_label_callback_fn;
|
||||||
|
umb->read_label_callback_context = read_label_callback_context;
|
||||||
|
umb->nr_outstanding_mdas = 1;
|
||||||
|
|
||||||
umb->ret = 1;
|
umb->ret = 1;
|
||||||
|
|
||||||
if (!lvmcache_foreach_mda(info, _update_mda, umb))
|
if (!lvmcache_foreach_mda(info, _update_mda, umb))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (umb->ret)
|
if (!--umb->nr_outstanding_mdas)
|
||||||
lvmcache_make_valid(info);
|
if (umb->ret)
|
||||||
|
lvmcache_make_valid(info);
|
||||||
|
|
||||||
|
if (umb->read_label_callback_fn)
|
||||||
|
umb->read_label_callback_fn(!umb->ret, umb->read_label_callback_context, NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
if (read_label_callback_fn)
|
||||||
|
read_label_callback_fn(1, read_label_callback_context, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +129,9 @@ struct find_labeller_params {
|
|||||||
int ret;
|
int ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _set_label_read_result(int failed, struct find_labeller_params *flp)
|
static void _set_label_read_result(int failed, void *context, void *data)
|
||||||
{
|
{
|
||||||
|
struct find_labeller_params *flp = context;
|
||||||
struct label **result = flp->result;
|
struct label **result = flp->result;
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
@ -219,10 +220,9 @@ static void _find_labeller(int failed, void *context, void *data)
|
|||||||
_update_lvmcache_orphan(info);
|
_update_lvmcache_orphan(info);
|
||||||
log_very_verbose("%s: No label detected", dev_name(dev));
|
log_very_verbose("%s: No label detected", dev_name(dev));
|
||||||
flp->ret = 0;
|
flp->ret = 0;
|
||||||
|
_set_label_read_result(1, flp, NULL);
|
||||||
} else
|
} else
|
||||||
flp->ret = (l->ops->read)(l, dev, labelbuf, result);
|
flp->ret = (l->ops->read)(l, dev, labelbuf, result, &_set_label_read_result, flp);
|
||||||
|
|
||||||
_set_label_read_result(!flp->ret, flp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME Also wipe associated metadata area headers? */
|
/* FIXME Also wipe associated metadata area headers? */
|
||||||
@ -339,7 +339,7 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
|
|||||||
|
|
||||||
if (!(readbuf = dev_read(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
|
if (!(readbuf = dev_read(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
|
||||||
log_debug_devs("%s: Failed to read label area", dev_name(dev));
|
log_debug_devs("%s: Failed to read label area", dev_name(dev));
|
||||||
_set_label_read_result(1, flp);
|
_set_label_read_result(1, flp, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ struct label_ops {
|
|||||||
/*
|
/*
|
||||||
* Read a label from a volume.
|
* Read a label from a volume.
|
||||||
*/
|
*/
|
||||||
int (*read) (struct labeller * l, struct device * dev,
|
int (*read) (struct labeller *l, struct device *dev, void *buf, struct label **label,
|
||||||
void *buf, struct label ** label);
|
lvm_callback_fn_t label_read_callback_fn, void *label_read_callback_context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate label_type etc.
|
* Populate label_type etc.
|
||||||
|
Loading…
Reference in New Issue
Block a user