sheepdog: Fix error handling in sd_snapshot_delete()

As a bdrv_snapshot_delete() method, sd_snapshot_delete() must set an
error and return negative errno on failure.  It sometimes returns -1,
and sometimes neglects to set an error.  It also prints error messages
with error_report().  Fix all that.

Moreover, its handling of an attempt to delete a nonexistent snapshot
is wrong: it error_report()s and succeeds.  Fix it to set an error and
return -ENOENT instead.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Markus Armbruster 2017-03-06 20:00:36 +01:00 committed by Kevin Wolf
parent cbc488ee2a
commit e25cad6921
1 changed files with 19 additions and 22 deletions

View File

@ -2405,18 +2405,15 @@ out:
#define NR_BATCHED_DISCARD 128 #define NR_BATCHED_DISCARD 128
static bool remove_objects(BDRVSheepdogState *s) static int remove_objects(BDRVSheepdogState *s, Error **errp)
{ {
int fd, i = 0, nr_objs = 0; int fd, i = 0, nr_objs = 0;
Error *local_err = NULL; int ret;
int ret = 0;
bool result = true;
SheepdogInode *inode = &s->inode; SheepdogInode *inode = &s->inode;
fd = connect_to_sdog(s, &local_err); fd = connect_to_sdog(s, errp);
if (fd < 0) { if (fd < 0) {
error_report_err(local_err); return fd;
return false;
} }
nr_objs = count_data_objs(inode); nr_objs = count_data_objs(inode);
@ -2446,15 +2443,15 @@ static bool remove_objects(BDRVSheepdogState *s)
data_vdi_id[start_idx]), data_vdi_id[start_idx]),
false, s->cache_flags); false, s->cache_flags);
if (ret < 0) { if (ret < 0) {
error_report("failed to discard snapshot inode."); error_setg(errp, "Failed to discard snapshot inode");
result = false;
goto out; goto out;
} }
} }
ret = 0;
out: out:
closesocket(fd); closesocket(fd);
return result; return ret;
} }
static int sd_snapshot_delete(BlockDriverState *bs, static int sd_snapshot_delete(BlockDriverState *bs,
@ -2464,7 +2461,6 @@ static int sd_snapshot_delete(BlockDriverState *bs,
{ {
unsigned long snap_id = 0; unsigned long snap_id = 0;
char snap_tag[SD_MAX_VDI_TAG_LEN]; char snap_tag[SD_MAX_VDI_TAG_LEN];
Error *local_err = NULL;
int fd, ret; int fd, ret;
char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
BDRVSheepdogState *s = bs->opaque; BDRVSheepdogState *s = bs->opaque;
@ -2477,8 +2473,9 @@ static int sd_snapshot_delete(BlockDriverState *bs,
}; };
SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
if (!remove_objects(s)) { ret = remove_objects(s, errp);
return -1; if (ret) {
return ret;
} }
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
@ -2498,36 +2495,36 @@ static int sd_snapshot_delete(BlockDriverState *bs,
pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag); pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag);
} }
ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true, ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true, errp);
&local_err);
if (ret) { if (ret) {
return ret; return ret;
} }
fd = connect_to_sdog(s, &local_err); fd = connect_to_sdog(s, errp);
if (fd < 0) { if (fd < 0) {
error_report_err(local_err); return fd;
return -1;
} }
ret = do_req(fd, s->bs, (SheepdogReq *)&hdr, ret = do_req(fd, s->bs, (SheepdogReq *)&hdr,
buf, &wlen, &rlen); buf, &wlen, &rlen);
closesocket(fd); closesocket(fd);
if (ret) { if (ret) {
error_setg_errno(errp, -ret, "Couldn't send request to server");
return ret; return ret;
} }
switch (rsp->result) { switch (rsp->result) {
case SD_RES_NO_VDI: case SD_RES_NO_VDI:
error_report("%s was already deleted", s->name); error_setg(errp, "Can't find the snapshot");
return -ENOENT;
case SD_RES_SUCCESS: case SD_RES_SUCCESS:
break; break;
default: default:
error_report("%s, %s", sd_strerror(rsp->result), s->name); error_setg(errp, "%s", sd_strerror(rsp->result));
return -1; return -EIO;
} }
return ret; return 0;
} }
static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)