mirror of https://github.com/xemu-project/xemu.git
Virtiofsd pull 2021-10-26
New 'unsupported' feature for xattr mapping Good for hiding selinux Plus some tidy ups and error handling. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAmF32FwACgkQBRYzHrxb /ecd7g/+JiFBnOhP6a8Vh2L5P4juGRVDHibKmT7FlQIBga47Cn6EtUTRBlI12aKl LVOrEkicpEeg1f/xMJRICO/XSDfH6NTz1VPJtofpIdK9+vLr6Ny5An2VtO4zgPxq 1dswxGlr2qt1rxyXtiuC9FI+7zKpz8ynvDFPGVWmfnJBY8UIPb7fAxoL/+yM5x0M 1xI33xCzpzXvQMXRiB8fmH9F+kmF/HInz4hcZktuL/36bqFGeCkj15vdtfTuH+h9 qecSUmgBIPK+nYchjvbt0EeTO4jABc48Pmd7f7HHk7HkJc5r5iaMMXA+JTTcT37L AE4EAdS9DhUr8XMMYf+1NC3UE0YrYg4PRWScdS5bmF9xwxaMklNDZUpmLylVJQ5F QCoLUZQBEPaYnwAqrB5djQsxYDaKSk46ezeqeo8lbmyMU6hNe6l51V5k1e1YhDI/ 0j4maCk36Ma7aWGJGOKxZE1tT2mqkLtAe/cWb8tqwy0L7MJ8kJ8JgQYqc12HlRuL 6wtakDjLjxMLEQ3dqqgu+SjqxdMvhL/siqyYJTsrohSYlQmWmZwXkcL54fNDy6+k NDLtb502R7piM3VdM7yqQEL+5Z4w6u5Rgeklo8xb6hWiS0gEdgsyC069SHLKRE4+ jxp9izFOzUqFDpxv7aWT7CkzwFkJgIE9Grn00GBwVeYWT5oenhA= =HDue -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dagrh/tags/pull-virtiofs-20211026' into staging Virtiofsd pull 2021-10-26 New 'unsupported' feature for xattr mapping Good for hiding selinux Plus some tidy ups and error handling. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> # gpg: Signature made Tue 26 Oct 2021 03:28:44 AM PDT # gpg: using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7 # gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full] * remotes/dagrh/tags/pull-virtiofs-20211026: virtiofsd: Error on bad socket group name virtiofsd: Add a helper to stop all queues virtiofsd: Add a helper to send element on virtqueue virtiofsd: Remove unused virtio_fs_config definition virtiofsd: xattr mapping add a new type "unsupported" Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
931ce30859
|
@ -183,6 +183,12 @@ Using ':' as the separator a rule is of the form:
|
|||
'ok' as either an explicit terminator or for special handling of certain
|
||||
patterns.
|
||||
|
||||
- 'unsupported' - If a client tries to use a name matching 'key' it's
|
||||
denied using ENOTSUP; when the server passes an attribute
|
||||
name matching 'prepend' it's hidden. In many ways it's use is very like
|
||||
'ok' as either an explicit terminator or for special handling of certain
|
||||
patterns.
|
||||
|
||||
**key** is a string tested as a prefix on an attribute name originating
|
||||
on the client. It maybe empty in which case a 'client' rule
|
||||
will always match on client names.
|
||||
|
|
|
@ -82,12 +82,6 @@ struct fv_VuDev {
|
|||
struct fv_QueueInfo **qi;
|
||||
};
|
||||
|
||||
/* From spec */
|
||||
struct virtio_fs_config {
|
||||
char tag[36];
|
||||
uint32_t num_queues;
|
||||
};
|
||||
|
||||
/* Callback from libvhost-user */
|
||||
static uint64_t fv_get_features(VuDev *dev)
|
||||
{
|
||||
|
@ -249,6 +243,21 @@ static void vu_dispatch_unlock(struct fv_VuDev *vud)
|
|||
assert(ret == 0);
|
||||
}
|
||||
|
||||
static void vq_send_element(struct fv_QueueInfo *qi, VuVirtqElement *elem,
|
||||
ssize_t len)
|
||||
{
|
||||
struct fuse_session *se = qi->virtio_dev->se;
|
||||
VuDev *dev = &se->virtio_dev->dev;
|
||||
VuVirtq *q = vu_get_queue(dev, qi->qidx);
|
||||
|
||||
vu_dispatch_rdlock(qi->virtio_dev);
|
||||
pthread_mutex_lock(&qi->vq_lock);
|
||||
vu_queue_push(dev, q, elem, len);
|
||||
vu_queue_notify(dev, q);
|
||||
pthread_mutex_unlock(&qi->vq_lock);
|
||||
vu_dispatch_unlock(qi->virtio_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called back by ll whenever it wants to send a reply/message back
|
||||
* The 1st element of the iov starts with the fuse_out_header
|
||||
|
@ -259,8 +268,6 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
|
|||
{
|
||||
FVRequest *req = container_of(ch, FVRequest, ch);
|
||||
struct fv_QueueInfo *qi = ch->qi;
|
||||
VuDev *dev = &se->virtio_dev->dev;
|
||||
VuVirtq *q = vu_get_queue(dev, qi->qidx);
|
||||
VuVirtqElement *elem = &req->elem;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -302,13 +309,7 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
|
|||
|
||||
copy_iov(iov, count, in_sg, in_num, tosend_len);
|
||||
|
||||
vu_dispatch_rdlock(qi->virtio_dev);
|
||||
pthread_mutex_lock(&qi->vq_lock);
|
||||
vu_queue_push(dev, q, elem, tosend_len);
|
||||
vu_queue_notify(dev, q);
|
||||
pthread_mutex_unlock(&qi->vq_lock);
|
||||
vu_dispatch_unlock(qi->virtio_dev);
|
||||
|
||||
vq_send_element(qi, elem, tosend_len);
|
||||
req->reply_sent = true;
|
||||
|
||||
err:
|
||||
|
@ -327,8 +328,6 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
|
|||
{
|
||||
FVRequest *req = container_of(ch, FVRequest, ch);
|
||||
struct fv_QueueInfo *qi = ch->qi;
|
||||
VuDev *dev = &se->virtio_dev->dev;
|
||||
VuVirtq *q = vu_get_queue(dev, qi->qidx);
|
||||
VuVirtqElement *elem = &req->elem;
|
||||
int ret = 0;
|
||||
g_autofree struct iovec *in_sg_cpy = NULL;
|
||||
|
@ -436,12 +435,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
|
|||
out_sg->len = tosend_len;
|
||||
}
|
||||
|
||||
vu_dispatch_rdlock(qi->virtio_dev);
|
||||
pthread_mutex_lock(&qi->vq_lock);
|
||||
vu_queue_push(dev, q, elem, tosend_len);
|
||||
vu_queue_notify(dev, q);
|
||||
pthread_mutex_unlock(&qi->vq_lock);
|
||||
vu_dispatch_unlock(qi->virtio_dev);
|
||||
vq_send_element(qi, elem, tosend_len);
|
||||
req->reply_sent = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -453,7 +447,6 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
|
|||
{
|
||||
struct fv_QueueInfo *qi = user_data;
|
||||
struct fuse_session *se = qi->virtio_dev->se;
|
||||
struct VuDev *dev = &qi->virtio_dev->dev;
|
||||
FVRequest *req = data;
|
||||
VuVirtqElement *elem = &req->elem;
|
||||
struct fuse_buf fbuf = {};
|
||||
|
@ -595,17 +588,9 @@ out:
|
|||
|
||||
/* If the request has no reply, still recycle the virtqueue element */
|
||||
if (!req->reply_sent) {
|
||||
struct VuVirtq *q = vu_get_queue(dev, qi->qidx);
|
||||
|
||||
fuse_log(FUSE_LOG_DEBUG, "%s: elem %d no reply sent\n", __func__,
|
||||
elem->index);
|
||||
|
||||
vu_dispatch_rdlock(qi->virtio_dev);
|
||||
pthread_mutex_lock(&qi->vq_lock);
|
||||
vu_queue_push(dev, q, elem, 0);
|
||||
vu_queue_notify(dev, q);
|
||||
pthread_mutex_unlock(&qi->vq_lock);
|
||||
vu_dispatch_unlock(qi->virtio_dev);
|
||||
vq_send_element(qi, elem, 0);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&req->ch.lock);
|
||||
|
@ -755,6 +740,18 @@ static void fv_queue_cleanup_thread(struct fv_VuDev *vud, int qidx)
|
|||
vud->qi[qidx] = NULL;
|
||||
}
|
||||
|
||||
static void stop_all_queues(struct fv_VuDev *vud)
|
||||
{
|
||||
for (int i = 0; i < vud->nqueues; i++) {
|
||||
if (!vud->qi[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fuse_log(FUSE_LOG_INFO, "%s: Stopping queue %d thread\n", __func__, i);
|
||||
fv_queue_cleanup_thread(vud, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback from libvhost-user on start or stop of a queue */
|
||||
static void fv_queue_set_started(VuDev *dev, int qidx, bool started)
|
||||
{
|
||||
|
@ -885,15 +882,7 @@ int virtio_loop(struct fuse_session *se)
|
|||
* Make sure all fv_queue_thread()s quit on exit, as we're about to
|
||||
* free virtio dev and fuse session, no one should access them anymore.
|
||||
*/
|
||||
for (int i = 0; i < se->virtio_dev->nqueues; i++) {
|
||||
if (!se->virtio_dev->qi[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fuse_log(FUSE_LOG_INFO, "%s: Stopping queue %d thread\n", __func__, i);
|
||||
fv_queue_cleanup_thread(se->virtio_dev, i);
|
||||
}
|
||||
|
||||
stop_all_queues(se->virtio_dev);
|
||||
fuse_log(FUSE_LOG_INFO, "%s: Exit\n", __func__);
|
||||
|
||||
return 0;
|
||||
|
@ -999,6 +988,13 @@ static int fv_create_listen_socket(struct fuse_session *se)
|
|||
"vhost socket failed to set group to %s (%d): %m\n",
|
||||
se->vu_socket_group, g->gr_gid);
|
||||
}
|
||||
} else {
|
||||
fuse_log(FUSE_LOG_ERR,
|
||||
"vhost socket: unable to find group '%s'\n",
|
||||
se->vu_socket_group);
|
||||
close(listen_sock);
|
||||
umask(old_umask);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
umask(old_umask);
|
||||
|
|
|
@ -2465,6 +2465,11 @@ static void lo_flock(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
|
|||
* Automatically reversed on read
|
||||
*/
|
||||
#define XATTR_MAP_FLAG_PREFIX (1 << 2)
|
||||
/*
|
||||
* The attribute is unsupported;
|
||||
* ENOTSUP on write, hidden on read.
|
||||
*/
|
||||
#define XATTR_MAP_FLAG_UNSUPPORTED (1 << 3)
|
||||
|
||||
/* scopes */
|
||||
/* Apply rule to get/set/remove */
|
||||
|
@ -2636,6 +2641,8 @@ static void parse_xattrmap(struct lo_data *lo)
|
|||
tmp_entry.flags |= XATTR_MAP_FLAG_OK;
|
||||
} else if (strstart(map, "bad", &map)) {
|
||||
tmp_entry.flags |= XATTR_MAP_FLAG_BAD;
|
||||
} else if (strstart(map, "unsupported", &map)) {
|
||||
tmp_entry.flags |= XATTR_MAP_FLAG_UNSUPPORTED;
|
||||
} else if (strstart(map, "map", &map)) {
|
||||
/*
|
||||
* map is sugar that adds a number of rules, and must be
|
||||
|
@ -2646,8 +2653,8 @@ static void parse_xattrmap(struct lo_data *lo)
|
|||
} else {
|
||||
fuse_log(FUSE_LOG_ERR,
|
||||
"%s: Unexpected type;"
|
||||
"Expecting 'prefix', 'ok', 'bad' or 'map' in rule %zu\n",
|
||||
__func__, lo->xattr_map_nentries);
|
||||
"Expecting 'prefix', 'ok', 'bad', 'unsupported' or 'map'"
|
||||
" in rule %zu\n", __func__, lo->xattr_map_nentries);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -2749,6 +2756,9 @@ static int xattr_map_client(const struct lo_data *lo, const char *client_name,
|
|||
if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
|
||||
return -EPERM;
|
||||
}
|
||||
if (cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
|
||||
/* Unmodified name */
|
||||
return 0;
|
||||
|
@ -2788,7 +2798,8 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name,
|
|||
|
||||
if ((cur_entry->flags & XATTR_MAP_FLAG_SERVER) &&
|
||||
(strstart(server_name, cur_entry->prepend, &end))) {
|
||||
if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
|
||||
if (cur_entry->flags & XATTR_MAP_FLAG_BAD ||
|
||||
cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
|
||||
return -ENODATA;
|
||||
}
|
||||
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
|
||||
|
|
Loading…
Reference in New Issue