1 /*
2  * qemu_blockjob.h: helper functions for QEMU block jobs
3  *
4  * Copyright (C) 2006-2015 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #pragma once
23 
24 #include "internal.h"
25 #include "qemu_conf.h"
26 
27 /**
28  * This enum has to map all known block job states from enum virDomainBlockJobType
29  * to the same values. All internal blockjobs can be mapped after and don't
30  * need to have stable values.
31  */
32 typedef enum {
33     /* Mapped to public enum */
34     QEMU_BLOCKJOB_STATE_COMPLETED = VIR_DOMAIN_BLOCK_JOB_COMPLETED,
35     QEMU_BLOCKJOB_STATE_FAILED = VIR_DOMAIN_BLOCK_JOB_FAILED,
36     QEMU_BLOCKJOB_STATE_CANCELLED = VIR_DOMAIN_BLOCK_JOB_CANCELED,
37     QEMU_BLOCKJOB_STATE_READY = VIR_DOMAIN_BLOCK_JOB_READY,
38     /* Additional enum values local to qemu */
39     QEMU_BLOCKJOB_STATE_NEW,
40     QEMU_BLOCKJOB_STATE_RUNNING,
41     QEMU_BLOCKJOB_STATE_CONCLUDED, /* job has finished, but it's unknown
42                                       whether it has failed or not */
43     QEMU_BLOCKJOB_STATE_ABORTING,
44     QEMU_BLOCKJOB_STATE_PIVOTING,
45     QEMU_BLOCKJOB_STATE_LAST
46 } qemuBlockjobState;
47 G_STATIC_ASSERT((int)QEMU_BLOCKJOB_STATE_NEW == VIR_DOMAIN_BLOCK_JOB_LAST);
48 
49 VIR_ENUM_DECL(qemuBlockjobState);
50 
51 /**
52  * This enum has to map all known block job types from enum virDomainBlockJobType
53  * to the same values. All internal blockjobs can be mapped after and don't
54  * need to have stable values.
55  */
56 typedef enum {
57     /* Mapped to public enum */
58     QEMU_BLOCKJOB_TYPE_NONE = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN,
59     QEMU_BLOCKJOB_TYPE_PULL = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL,
60     QEMU_BLOCKJOB_TYPE_COPY = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY,
61     QEMU_BLOCKJOB_TYPE_COMMIT = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT,
62     QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT,
63     QEMU_BLOCKJOB_TYPE_BACKUP = VIR_DOMAIN_BLOCK_JOB_TYPE_BACKUP,
64     /* Additional enum values local to qemu */
65     QEMU_BLOCKJOB_TYPE_INTERNAL,
66     QEMU_BLOCKJOB_TYPE_CREATE,
67     QEMU_BLOCKJOB_TYPE_BROKEN,
68     QEMU_BLOCKJOB_TYPE_LAST
69 } qemuBlockJobType;
70 G_STATIC_ASSERT((int)QEMU_BLOCKJOB_TYPE_INTERNAL == VIR_DOMAIN_BLOCK_JOB_TYPE_LAST);
71 
72 VIR_ENUM_DECL(qemuBlockjob);
73 
74 
75 typedef struct _qemuBlockJobPullData qemuBlockJobPullData;
76 struct _qemuBlockJobPullData {
77     virStorageSource *base;
78 };
79 
80 
81 typedef struct _qemuBlockJobCommitData qemuBlockJobCommitData;
82 struct _qemuBlockJobCommitData {
83     virStorageSource *topparent;
84     virStorageSource *top;
85     virStorageSource *base;
86     bool deleteCommittedImages;
87 };
88 
89 
90 typedef struct _qemuBlockJobCreateData qemuBlockJobCreateData;
91 struct _qemuBlockJobCreateData {
92     bool storage;
93     virStorageSource *src;
94 };
95 
96 
97 typedef struct _qemuBlockJobCopyData qemuBlockJobCopyData;
98 struct _qemuBlockJobCopyData {
99     bool shallownew;
100 };
101 
102 
103 typedef struct _qemuBlockJobBackupData qemuBlockJobBackupData;
104 struct _qemuBlockJobBackupData {
105     virStorageSource *store;
106     char *bitmap;
107 };
108 
109 
110 typedef struct _qemuBlockJobData qemuBlockJobData;
111 struct _qemuBlockJobData {
112     virObject parent;
113 
114     char *name;
115 
116     virDomainDiskDef *disk; /* may be NULL, if blockjob does not correspond to any disk */
117     virStorageSource *chain; /* Reference to the chain the job operates on. */
118     virStorageSource *mirrorChain; /* reference to 'mirror' part of the job */
119 
120     unsigned int jobflags; /* per job flags */
121     bool jobflagsmissing; /* job flags were not stored */
122 
123     union {
124         qemuBlockJobPullData pull;
125         qemuBlockJobCommitData commit;
126         qemuBlockJobCreateData create;
127         qemuBlockJobCopyData copy;
128         qemuBlockJobBackupData backup;
129     } data;
130 
131     int type; /* qemuBlockJobType */
132     int state; /* qemuBlockjobState */
133     char *errmsg;
134     bool synchronous; /* API call is waiting for this job */
135 
136     int newstate; /* qemuBlockjobState, subset of events emitted by qemu */
137 
138     int brokentype; /* the previous type of a broken blockjob qemuBlockJobType */
139 
140     bool invalidData; /* the job data (except name) is not valid */
141     bool reconnected; /* internal field for tracking whether job is live after reconnect to qemu */
142 };
143 G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuBlockJobData, virObjectUnref);
144 
145 int
146 qemuBlockJobRegister(qemuBlockJobData *job,
147                      virDomainObj *vm,
148                      virDomainDiskDef *disk,
149                      bool savestatus)
150     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
151 
152 qemuBlockJobData *
153 qemuBlockJobDataNew(qemuBlockJobType type,
154                     const char *name)
155     ATTRIBUTE_NONNULL(2);
156 
157 qemuBlockJobData *
158 qemuBlockJobDiskNew(virDomainObj *vm,
159                     virDomainDiskDef *disk,
160                     qemuBlockJobType type,
161                     const char *jobname)
162     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
163 
164 qemuBlockJobData *
165 qemuBlockJobDiskNewPull(virDomainObj *vm,
166                         virDomainDiskDef *disk,
167                         virStorageSource *base,
168                         unsigned int jobflags);
169 
170 qemuBlockJobData *
171 qemuBlockJobDiskNewCommit(virDomainObj *vm,
172                           virDomainDiskDef *disk,
173                           virStorageSource *topparent,
174                           virStorageSource *top,
175                           virStorageSource *base,
176                           bool delete_imgs,
177                           unsigned int jobflags);
178 
179 qemuBlockJobData *
180 qemuBlockJobNewCreate(virDomainObj *vm,
181                       virStorageSource *src,
182                       virStorageSource *chain,
183                       bool storage);
184 
185 qemuBlockJobData *
186 qemuBlockJobDiskNewCopy(virDomainObj *vm,
187                         virDomainDiskDef *disk,
188                         virStorageSource *mirror,
189                         bool shallow,
190                         bool reuse,
191                         unsigned int jobflags);
192 
193 qemuBlockJobData *
194 qemuBlockJobDiskNewBackup(virDomainObj *vm,
195                           virDomainDiskDef *disk,
196                           virStorageSource *store,
197                           const char *bitmap);
198 
199 qemuBlockJobData *
200 qemuBlockJobDiskGetJob(virDomainDiskDef *disk)
201     ATTRIBUTE_NONNULL(1);
202 
203 void
204 qemuBlockJobStarted(qemuBlockJobData *job,
205                     virDomainObj *vm)
206     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
207 
208 bool
209 qemuBlockJobIsRunning(qemuBlockJobData *job)
210     ATTRIBUTE_NONNULL(1);
211 
212 void
213 qemuBlockJobStartupFinalize(virDomainObj *vm,
214                             qemuBlockJobData *job);
215 
216 int
217 qemuBlockJobRefreshJobs(virQEMUDriver *driver,
218                         virDomainObj *vm);
219 
220 void
221 qemuBlockJobUpdate(virDomainObj *vm,
222                    qemuBlockJobData *job,
223                    int asyncJob);
224 
225 void qemuBlockJobSyncBegin(qemuBlockJobData *job);
226 void qemuBlockJobSyncEnd(virDomainObj *vm,
227                          qemuBlockJobData *job,
228                          int asyncJob);
229 
230 qemuBlockJobData *
231 qemuBlockJobGetByDisk(virDomainDiskDef *disk)
232     ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
233 
234 qemuBlockjobState
235 qemuBlockjobConvertMonitorStatus(int monitorstatus);
236