mirror of
https://github.com/ceph/ceph
synced 2025-02-23 19:17:37 +00:00
rbd-mirror: delay retrieval of remote tag class on bootstrap
This will help move the journal-related bootstrap logic together as a preliminary step for handling snapshot mirroring. Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
e0170aa226
commit
53455eebdf
@ -503,16 +503,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteSyncingState) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -532,7 +522,9 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteSyncingState) {
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
|
||||
mock_local_image_ctx.id};
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
|
||||
librbd::journal::ClientData client_data;
|
||||
client_data.client_meta = mirror_peer_client_meta;
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_update_client(mock_journaler, client_data, 0);
|
||||
|
||||
MockCloseImageRequest mock_close_image_request;
|
||||
@ -557,16 +549,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteNotTagOwner) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -605,6 +587,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteNotTagOwner) {
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
|
||||
mock_local_image_ctx.id};
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
|
||||
::journal::MockJournaler mock_journaler;
|
||||
MockBootstrapRequest *request = create_request(
|
||||
&mock_threads, &mock_instance_watcher, mock_journaler,
|
||||
mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id",
|
||||
@ -619,16 +602,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, RemoteDemotePromote) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -654,6 +627,16 @@ TEST_F(TestMockImageReplayerBootstrapRequest, RemoteDemotePromote) {
|
||||
expect_journal_get_tag_tid(mock_journal, 345);
|
||||
expect_journal_get_tag_data(mock_journal, {"remote mirror uuid"});
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// remote demotion / promotion event
|
||||
Tags tags = {
|
||||
{2, 123, encode_tag_data({librbd::Journal<>::LOCAL_MIRROR_UUID,
|
||||
@ -695,16 +678,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, MultipleRemoteDemotePromotes) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -731,6 +704,16 @@ TEST_F(TestMockImageReplayerBootstrapRequest, MultipleRemoteDemotePromotes) {
|
||||
expect_journal_get_tag_data(mock_journal, {librbd::Journal<>::ORPHAN_MIRROR_UUID,
|
||||
"remote mirror uuid", true, 4, 1});
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// remote demotion / promotion event
|
||||
Tags tags = {
|
||||
{2, 123, encode_tag_data({librbd::Journal<>::LOCAL_MIRROR_UUID,
|
||||
@ -781,16 +764,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalDemoteRemotePromote) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -819,6 +792,16 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalDemoteRemotePromote) {
|
||||
librbd::Journal<>::LOCAL_MIRROR_UUID,
|
||||
true, 345, 1});
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// remote demotion / promotion event
|
||||
Tags tags = {
|
||||
{2, 123, encode_tag_data({"local mirror uuid", "local mirror uuid",
|
||||
@ -855,16 +838,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, SplitBrainForcePromote) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -892,6 +865,16 @@ TEST_F(TestMockImageReplayerBootstrapRequest, SplitBrainForcePromote) {
|
||||
librbd::Journal<>::ORPHAN_MIRROR_UUID,
|
||||
true, 344, 0});
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// remote demotion / promotion event
|
||||
Tags tags = {
|
||||
{2, 123, encode_tag_data({librbd::Journal<>::LOCAL_MIRROR_UUID,
|
||||
@ -929,16 +912,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ResyncRequested) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -976,6 +949,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ResyncRequested) {
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
|
||||
mock_local_image_ctx.id};
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
|
||||
::journal::MockJournaler mock_journaler;
|
||||
MockBootstrapRequest *request = create_request(
|
||||
&mock_threads, &mock_instance_watcher, mock_journaler,
|
||||
mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id",
|
||||
@ -992,16 +966,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -1024,9 +988,11 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) {
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
|
||||
mirror_peer_client_meta.image_id = mock_local_image_ctx.id;
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
|
||||
librbd::journal::ClientData client_data;
|
||||
client_data.client_meta = mirror_peer_client_meta;
|
||||
client.data.clear();
|
||||
cls::journal::Client client;
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_update_client(mock_journaler, client_data, 0);
|
||||
|
||||
// create the local image
|
||||
@ -1068,16 +1034,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -1098,10 +1054,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
|
||||
"missing image id", nullptr, -ENOENT);
|
||||
|
||||
// re-register the client
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_unregister_client(mock_journaler, 0);
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
|
||||
mirror_peer_client_meta.image_id = "";
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
|
||||
librbd::journal::ClientData client_data;
|
||||
client_data.client_meta = mirror_peer_client_meta;
|
||||
expect_journaler_register_client(mock_journaler, client_data, 0);
|
||||
|
||||
@ -1119,7 +1077,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
|
||||
mirror_peer_client_meta.image_id = mock_local_image_ctx.id;
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
|
||||
client_data.client_meta = mirror_peer_client_meta;
|
||||
client.data.clear();
|
||||
cls::journal::Client client;
|
||||
encode(client_data, client.data);
|
||||
expect_journaler_update_client(mock_journaler, client_data, 0);
|
||||
|
||||
@ -1161,16 +1119,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
|
||||
|
||||
InSequence seq;
|
||||
|
||||
// lookup remote image tag class
|
||||
cls::journal::Client client;
|
||||
librbd::journal::ClientData client_data{
|
||||
librbd::journal::ImageClientMeta{123}};
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_get_client(mock_journaler,
|
||||
librbd::Journal<>::IMAGE_CLIENT_ID,
|
||||
client, 0);
|
||||
|
||||
// open the remote image
|
||||
librbd::MockJournal mock_journal;
|
||||
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
|
||||
@ -1193,9 +1141,11 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
|
||||
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
|
||||
mirror_peer_client_meta.image_id = mock_local_image_ctx.id;
|
||||
mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
|
||||
librbd::journal::ClientData client_data;
|
||||
client_data.client_meta = mirror_peer_client_meta;
|
||||
client.data.clear();
|
||||
cls::journal::Client client;
|
||||
encode(client_data, client.data);
|
||||
::journal::MockJournaler mock_journaler;
|
||||
expect_journaler_update_client(mock_journaler, client_data, 0);
|
||||
|
||||
// create the local image
|
||||
|
@ -85,7 +85,7 @@ template <typename I>
|
||||
void BootstrapRequest<I>::send() {
|
||||
*m_do_resync = false;
|
||||
|
||||
get_remote_tag_class();
|
||||
open_remote_image();
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
@ -100,53 +100,6 @@ void BootstrapRequest<I>::cancel() {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::get_remote_tag_class() {
|
||||
dout(15) << dendl;
|
||||
|
||||
update_progress("GET_REMOTE_TAG_CLASS");
|
||||
|
||||
Context *ctx = create_context_callback<
|
||||
BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_remote_tag_class>(
|
||||
this);
|
||||
m_journaler->get_client(librbd::Journal<>::IMAGE_CLIENT_ID, &m_client, ctx);
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::handle_get_remote_tag_class(int r) {
|
||||
dout(15) << "r=" << r << dendl;
|
||||
|
||||
if (r < 0) {
|
||||
derr << "failed to retrieve remote client: " << cpp_strerror(r) << dendl;
|
||||
finish(r);
|
||||
return;
|
||||
}
|
||||
|
||||
librbd::journal::ClientData client_data;
|
||||
auto it = m_client.data.cbegin();
|
||||
try {
|
||||
decode(client_data, it);
|
||||
} catch (const buffer::error &err) {
|
||||
derr << "failed to decode remote client meta data: " << err.what()
|
||||
<< dendl;
|
||||
finish(-EBADMSG);
|
||||
return;
|
||||
}
|
||||
|
||||
librbd::journal::ImageClientMeta *client_meta =
|
||||
boost::get<librbd::journal::ImageClientMeta>(&client_data.client_meta);
|
||||
if (client_meta == nullptr) {
|
||||
derr << "unknown remote client registration" << dendl;
|
||||
finish(-EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
m_remote_tag_class = client_meta->tag_class;
|
||||
dout(10) << "remote tag class=" << m_remote_tag_class << dendl;
|
||||
|
||||
open_remote_image();
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::open_remote_image() {
|
||||
dout(15) << "remote_image_id=" << m_remote_image_id << dendl;
|
||||
@ -378,7 +331,7 @@ void BootstrapRequest<I>::handle_open_local_image(int r) {
|
||||
return;
|
||||
}
|
||||
|
||||
get_remote_tags();
|
||||
get_remote_tag_class();
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
@ -534,7 +487,7 @@ void BootstrapRequest<I>::handle_create_local_image(int r) {
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::get_remote_tags() {
|
||||
void BootstrapRequest<I>::get_remote_tag_class() {
|
||||
if (m_client_meta->state == librbd::journal::MIRROR_PEER_STATE_SYNCING) {
|
||||
// optimization -- no need to compare remote tags if we just created
|
||||
// the image locally or sync was interrupted
|
||||
@ -542,6 +495,56 @@ void BootstrapRequest<I>::get_remote_tags() {
|
||||
return;
|
||||
}
|
||||
|
||||
dout(15) << dendl;
|
||||
|
||||
update_progress("GET_REMOTE_TAG_CLASS");
|
||||
|
||||
Context *ctx = create_context_callback<
|
||||
BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_remote_tag_class>(
|
||||
this);
|
||||
m_journaler->get_client(librbd::Journal<>::IMAGE_CLIENT_ID, &m_client, ctx);
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::handle_get_remote_tag_class(int r) {
|
||||
dout(15) << "r=" << r << dendl;
|
||||
|
||||
if (r < 0) {
|
||||
derr << "failed to retrieve remote client: " << cpp_strerror(r) << dendl;
|
||||
m_ret_val = r;
|
||||
close_local_image();
|
||||
return;
|
||||
}
|
||||
|
||||
librbd::journal::ClientData client_data;
|
||||
auto it = m_client.data.cbegin();
|
||||
try {
|
||||
decode(client_data, it);
|
||||
} catch (const buffer::error &err) {
|
||||
derr << "failed to decode remote client meta data: " << err.what()
|
||||
<< dendl;
|
||||
m_ret_val = -EBADMSG;
|
||||
close_local_image();
|
||||
return;
|
||||
}
|
||||
|
||||
librbd::journal::ImageClientMeta *client_meta =
|
||||
boost::get<librbd::journal::ImageClientMeta>(&client_data.client_meta);
|
||||
if (client_meta == nullptr) {
|
||||
derr << "unknown remote client registration" << dendl;
|
||||
m_ret_val = -EINVAL;
|
||||
close_local_image();
|
||||
return;
|
||||
}
|
||||
|
||||
m_remote_tag_class = client_meta->tag_class;
|
||||
dout(10) << "remote tag class=" << m_remote_tag_class << dendl;
|
||||
|
||||
get_remote_tags();
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BootstrapRequest<I>::get_remote_tags() {
|
||||
dout(15) << dendl;
|
||||
update_progress("GET_REMOTE_TAGS");
|
||||
|
||||
|
@ -96,10 +96,7 @@ private:
|
||||
* <start>
|
||||
* |
|
||||
* v
|
||||
* GET_REMOTE_TAG_CLASS * * * * * * * * * * * * * * * * * *
|
||||
* | * (error)
|
||||
* v *
|
||||
* OPEN_REMOTE_IMAGE * * * * * * * * * * * * * * * * * * *
|
||||
* OPEN_REMOTE_IMAGE * * * * * * * * * * * * * * * * * * * (error)
|
||||
* | *
|
||||
* |/--------------------------------------------------*---\
|
||||
* v * |
|
||||
@ -125,6 +122,9 @@ private:
|
||||
* | | \-----------------------*---*---/
|
||||
* | | * *
|
||||
* | v (skip if not needed) * *
|
||||
* | GET_REMOTE_TAG_CLASS * * * * * * *
|
||||
* | | * * *
|
||||
* | v (skip if not needed) * * *
|
||||
* | GET_REMOTE_TAGS * * * * * * * * *
|
||||
* | | * * *
|
||||
* | v (skip if not needed) v * *
|
||||
@ -182,9 +182,6 @@ private:
|
||||
|
||||
bufferlist m_out_bl;
|
||||
|
||||
void get_remote_tag_class();
|
||||
void handle_get_remote_tag_class(int r);
|
||||
|
||||
void open_remote_image();
|
||||
void handle_open_remote_image(int r);
|
||||
|
||||
@ -209,6 +206,9 @@ private:
|
||||
void update_client_image();
|
||||
void handle_update_client_image(int r);
|
||||
|
||||
void get_remote_tag_class();
|
||||
void handle_get_remote_tag_class(int r);
|
||||
|
||||
void get_remote_tags();
|
||||
void handle_get_remote_tags(int r);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user