@@ -17,13 +17,11 @@ use std::{
17
17
mem,
18
18
net:: Shutdown ,
19
19
os:: unix:: { io:: AsRawFd , net:: UnixStream } ,
20
- slice,
21
20
sync:: { Arc , Condvar , Mutex } ,
22
21
thread,
23
22
thread:: JoinHandle ,
24
23
} ;
25
24
26
- use libc:: writev;
27
25
use nix:: libc:: iovec;
28
26
use vmm_sys_util:: eventfd:: { EventFd , EFD_SEMAPHORE } ;
29
27
use xen_bindings:: bindings:: xs_watch_type;
@@ -71,78 +69,79 @@ fn thread_function(
71
69
Condvar ,
72
70
) > ,
73
71
) -> Result < ( ) , std:: io:: Error > {
74
- let xen_socket_msg_size = mem:: size_of :: < XenSocketMessage > ( ) ;
75
-
76
72
loop {
77
73
let mut xen_socket_reply_msg = XenSocketMessage :: default ( ) ;
78
74
let mut buffer: Vec < u8 > = vec ! [ 0 ] ;
79
75
let mut condvar = reply_condvar. clone ( ) ;
80
76
let mut eventfd: Option < EventFd > = None ;
81
77
82
- unsafe {
83
- let xen_socket_reply_msg_slice = slice:: from_raw_parts_mut (
84
- & mut xen_socket_reply_msg as * mut _ as * mut u8 ,
85
- xen_socket_msg_size,
86
- ) ;
78
+ {
79
+ // SAFETY: `xen_socket_reply_msg` is `XenSocketMessage` bytes sized.
80
+ let xen_socket_reply_msg_slice: & mut [ u8 ] = unsafe {
81
+ std:: slice:: from_raw_parts_mut (
82
+ std:: ptr:: addr_of_mut!( xen_socket_reply_msg) . cast ( ) ,
83
+ mem:: size_of :: < XenSocketMessage > ( ) ,
84
+ )
85
+ } ;
87
86
88
87
rx_socket. read_exact ( xen_socket_reply_msg_slice) ?;
88
+ }
89
89
90
- if xen_socket_reply_msg. r#type == XS_READ && xen_socket_reply_msg. len == 0 {
91
- queue_message (
92
- & condvar,
93
- eventfd,
94
- Ok ( XenStoreMessage {
95
- r#type : xen_socket_reply_msg. r#type ,
96
- body : "" . to_string ( ) ,
97
- } ) ,
98
- ) ;
99
- continue ;
100
- }
90
+ if xen_socket_reply_msg. r#type == XS_READ && xen_socket_reply_msg. len == 0 {
91
+ queue_message (
92
+ & condvar,
93
+ eventfd,
94
+ Ok ( XenStoreMessage {
95
+ r#type : xen_socket_reply_msg. r#type ,
96
+ body : "" . to_string ( ) ,
97
+ } ) ,
98
+ ) ;
99
+ continue ;
100
+ }
101
+
102
+ buffer. resize ( xen_socket_reply_msg. len as usize , 0 ) ;
103
+
104
+ rx_socket. read_exact ( buffer. as_mut_slice ( ) ) ?;
105
+
106
+ if xen_socket_reply_msg. r#type != XS_READ
107
+ && xen_socket_reply_msg. r#type != XS_WRITE
108
+ && xen_socket_reply_msg. r#type != XS_WATCH
109
+ && xen_socket_reply_msg. r#type != XS_WATCH_EVENT
110
+ && xen_socket_reply_msg. r#type != XS_DIRECTORY
111
+ {
112
+ queue_message (
113
+ & condvar,
114
+ eventfd,
115
+ Err ( Error :: new ( ErrorKind :: Other , "Xen Store transaction error" ) ) ,
116
+ ) ;
117
+ continue ;
118
+ }
101
119
102
- buffer. resize ( xen_socket_reply_msg. len as usize , 0 ) ;
120
+ if xen_socket_reply_msg. r#type == XS_WATCH_EVENT {
121
+ condvar = watch_condvar. clone ( ) ;
122
+ eventfd = Some ( tx_eventfd. try_clone ( ) ?) ;
123
+ }
103
124
104
- rx_socket. read_exact ( buffer. as_mut_slice ( ) ) ?;
125
+ match String :: from_utf8 ( buffer) {
126
+ Ok ( result) => {
127
+ if result. len ( ) != xen_socket_reply_msg. len as usize {
128
+ queue_message ( & condvar, eventfd, Err ( Error :: from ( ErrorKind :: InvalidData ) ) ) ;
129
+ continue ;
130
+ }
105
131
106
- if xen_socket_reply_msg. r#type != XS_READ
107
- && xen_socket_reply_msg. r#type != XS_WRITE
108
- && xen_socket_reply_msg. r#type != XS_WATCH
109
- && xen_socket_reply_msg. r#type != XS_WATCH_EVENT
110
- && xen_socket_reply_msg. r#type != XS_DIRECTORY
111
- {
112
132
queue_message (
113
133
& condvar,
114
134
eventfd,
115
- Err ( Error :: new ( ErrorKind :: Other , "Xen Store transaction error" ) ) ,
135
+ Ok ( XenStoreMessage {
136
+ r#type : xen_socket_reply_msg. r#type ,
137
+ body : result,
138
+ } ) ,
116
139
) ;
117
- continue ;
118
140
}
119
-
120
- if xen_socket_reply_msg. r#type == XS_WATCH_EVENT {
121
- condvar = watch_condvar. clone ( ) ;
122
- eventfd = Some ( tx_eventfd. try_clone ( ) ?) ;
141
+ Err ( e) => {
142
+ queue_message ( & condvar, eventfd, Err ( Error :: new ( ErrorKind :: Other , e) ) ) ;
123
143
}
124
-
125
- match String :: from_utf8 ( buffer) {
126
- Ok ( result) => {
127
- if result. len ( ) != xen_socket_reply_msg. len as usize {
128
- queue_message ( & condvar, eventfd, Err ( Error :: from ( ErrorKind :: InvalidData ) ) ) ;
129
- continue ;
130
- }
131
-
132
- queue_message (
133
- & condvar,
134
- eventfd,
135
- Ok ( XenStoreMessage {
136
- r#type : xen_socket_reply_msg. r#type ,
137
- body : result,
138
- } ) ,
139
- ) ;
140
- }
141
- Err ( e) => {
142
- queue_message ( & condvar, eventfd, Err ( Error :: new ( ErrorKind :: Other , e) ) ) ;
143
- }
144
- } ;
145
- }
144
+ } ;
146
145
}
147
146
}
148
147
@@ -195,49 +194,55 @@ impl XenStoreHandle {
195
194
iovec_buffers : & mut Vec < iovec > ,
196
195
) -> Result < String , std:: io:: Error > {
197
196
let mut xen_socket_msg = XenSocketMessage :: new ( r#type, iovec_buffers) ?;
198
- let xen_socket_msg_size = mem:: size_of :: < XenSocketMessage > ( ) ;
199
197
let ( lock, cvar) = & * self . reply_condvar ;
200
198
201
- unsafe {
202
- let xen_socket_msg_slice = slice:: from_raw_parts (
203
- & mut xen_socket_msg as * mut _ as * mut u8 ,
204
- xen_socket_msg_size,
205
- ) ;
199
+ let mut tx_socket = self . tx_socket . lock ( ) . unwrap ( ) ;
200
+ {
201
+ // SAFETY: `xen_socket_msg` is `XenSocketMessage` bytes sized.
202
+ let xen_socket_msg_slice: & [ u8 ] = unsafe {
203
+ std:: slice:: from_raw_parts (
204
+ std:: ptr:: addr_of_mut!( xen_socket_msg) . cast ( ) ,
205
+ mem:: size_of :: < XenSocketMessage > ( ) ,
206
+ )
207
+ } ;
206
208
207
209
/*
208
210
* Grabbing the mutex guarantees there will only be
209
211
* one active transcation at a time.
210
212
*/
211
- let mut tx_socket = self . tx_socket . lock ( ) . unwrap ( ) ;
212
213
tx_socket. write_all ( xen_socket_msg_slice) ?;
214
+ }
213
215
214
- let ret = writev (
216
+ // SAFETY: tx_socket is a valid file descriptor and the pointer/length we pass
217
+ // are valid allocated values.
218
+ let ret = unsafe {
219
+ libc:: writev (
215
220
tx_socket. as_raw_fd ( ) ,
216
221
iovec_buffers. as_ptr ( ) ,
217
222
iovec_buffers. len ( ) as i32 ,
218
- ) ;
223
+ )
224
+ } ;
219
225
220
- if ret < 0 {
221
- return Err ( Error :: last_os_error ( ) ) ;
222
- }
226
+ if ret < 0 {
227
+ return Err ( Error :: last_os_error ( ) ) ;
228
+ }
223
229
224
- let mut reply_vec = lock. lock ( ) . unwrap ( ) ;
225
- while reply_vec. is_empty ( ) {
226
- reply_vec = cvar. wait ( reply_vec) . unwrap ( ) ;
227
- }
230
+ let mut reply_vec = lock. lock ( ) . unwrap ( ) ;
231
+ while reply_vec. is_empty ( ) {
232
+ reply_vec = cvar. wait ( reply_vec) . unwrap ( ) ;
233
+ }
228
234
229
- match reply_vec. pop_front ( ) {
230
- Some ( result) => match result {
231
- Ok ( xsm) => {
232
- if xsm. r#type != r#type {
233
- return Err ( Error :: from ( ErrorKind :: InvalidData ) ) ;
234
- }
235
- Ok ( xsm. body )
235
+ match reply_vec. pop_front ( ) {
236
+ Some ( result) => match result {
237
+ Ok ( xsm) => {
238
+ if xsm. r#type != r#type {
239
+ return Err ( Error :: from ( ErrorKind :: InvalidData ) ) ;
236
240
}
237
- Err ( e) => Err ( e) ,
238
- } ,
239
- None => Err ( Error :: new ( ErrorKind :: Other , "Xen Store transaction error" ) ) ,
240
- }
241
+ Ok ( xsm. body )
242
+ }
243
+ Err ( e) => Err ( e) ,
244
+ } ,
245
+ None => Err ( Error :: new ( ErrorKind :: Other , "Xen Store transaction error" ) ) ,
241
246
}
242
247
}
243
248
0 commit comments