diff options
Diffstat (limited to 'drivers/s390/char/vmlogrdr.c')
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e40a1b892866..c837d7419a6a 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/kmod.h> | 30 | #include <linux/kmod.h> |
31 | #include <linux/cdev.h> | 31 | #include <linux/cdev.h> |
32 | #include <linux/device.h> | 32 | #include <linux/device.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/string.h> | 33 | #include <linux/string.h> |
35 | 34 | ||
36 | MODULE_AUTHOR | 35 | MODULE_AUTHOR |
@@ -97,6 +96,7 @@ static const struct file_operations vmlogrdr_fops = { | |||
97 | .open = vmlogrdr_open, | 96 | .open = vmlogrdr_open, |
98 | .release = vmlogrdr_release, | 97 | .release = vmlogrdr_release, |
99 | .read = vmlogrdr_read, | 98 | .read = vmlogrdr_read, |
99 | .llseek = no_llseek, | ||
100 | }; | 100 | }; |
101 | 101 | ||
102 | 102 | ||
@@ -214,7 +214,7 @@ static void vmlogrdr_iucv_message_pending(struct iucv_path *path, | |||
214 | 214 | ||
215 | static int vmlogrdr_get_recording_class_AB(void) | 215 | static int vmlogrdr_get_recording_class_AB(void) |
216 | { | 216 | { |
217 | char cp_command[]="QUERY COMMAND RECORDING "; | 217 | static const char cp_command[] = "QUERY COMMAND RECORDING "; |
218 | char cp_response[80]; | 218 | char cp_response[80]; |
219 | char *tail; | 219 | char *tail; |
220 | int len,i; | 220 | int len,i; |
@@ -248,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, | |||
248 | char cp_command[80]; | 248 | char cp_command[80]; |
249 | char cp_response[160]; | 249 | char cp_response[160]; |
250 | char *onoff, *qid_string; | 250 | char *onoff, *qid_string; |
251 | int rc; | ||
251 | 252 | ||
252 | memset(cp_command, 0x00, sizeof(cp_command)); | 253 | onoff = ((action == 1) ? "ON" : "OFF"); |
253 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
254 | |||
255 | onoff = ((action == 1) ? "ON" : "OFF"); | ||
256 | qid_string = ((recording_class_AB == 1) ? " QID * " : ""); | 254 | qid_string = ((recording_class_AB == 1) ? " QID * " : ""); |
257 | 255 | ||
258 | /* | 256 | /* |
259 | * The recording commands needs to be called with option QID | 257 | * The recording commands needs to be called with option QID |
260 | * for guests that have previlege classes A or B. | 258 | * for guests that have previlege classes A or B. |
261 | * Purging has to be done as separate step, because recording | 259 | * Purging has to be done as separate step, because recording |
262 | * can't be switched on as long as records are on the queue. | 260 | * can't be switched on as long as records are on the queue. |
263 | * Doing both at the same time doesn't work. | 261 | * Doing both at the same time doesn't work. |
264 | */ | 262 | */ |
265 | 263 | if (purge && (action == 1)) { | |
266 | if (purge) { | 264 | memset(cp_command, 0x00, sizeof(cp_command)); |
265 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
267 | snprintf(cp_command, sizeof(cp_command), | 266 | snprintf(cp_command, sizeof(cp_command), |
268 | "RECORDING %s PURGE %s", | 267 | "RECORDING %s PURGE %s", |
269 | logptr->recording_name, | 268 | logptr->recording_name, |
270 | qid_string); | 269 | qid_string); |
271 | |||
272 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | 270 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
273 | } | 271 | } |
274 | 272 | ||
@@ -278,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, | |||
278 | logptr->recording_name, | 276 | logptr->recording_name, |
279 | onoff, | 277 | onoff, |
280 | qid_string); | 278 | qid_string); |
281 | |||
282 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | 279 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
283 | /* The recording command will usually answer with 'Command complete' | 280 | /* The recording command will usually answer with 'Command complete' |
284 | * on success, but when the specific service was never connected | 281 | * on success, but when the specific service was never connected |
285 | * before then there might be an additional informational message | 282 | * before then there might be an additional informational message |
286 | * 'HCPCRC8072I Recording entry not found' before the | 283 | * 'HCPCRC8072I Recording entry not found' before the |
287 | * 'Command complete'. So I use strstr rather then the strncmp. | 284 | * 'Command complete'. So I use strstr rather then the strncmp. |
288 | */ | 285 | */ |
289 | if (strstr(cp_response,"Command complete")) | 286 | if (strstr(cp_response,"Command complete")) |
290 | return 0; | 287 | rc = 0; |
291 | else | 288 | else |
292 | return -EIO; | 289 | rc = -EIO; |
290 | /* | ||
291 | * If we turn recording off, we have to purge any remaining records | ||
292 | * afterwards, as a large number of queued records may impact z/VM | ||
293 | * performance. | ||
294 | */ | ||
295 | if (purge && (action == 0)) { | ||
296 | memset(cp_command, 0x00, sizeof(cp_command)); | ||
297 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
298 | snprintf(cp_command, sizeof(cp_command), | ||
299 | "RECORDING %s PURGE %s", | ||
300 | logptr->recording_name, | ||
301 | qid_string); | ||
302 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | ||
303 | } | ||
293 | 304 | ||
305 | return rc; | ||
294 | } | 306 | } |
295 | 307 | ||
296 | 308 | ||
@@ -637,7 +649,7 @@ static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, | |||
637 | char *buf) | 649 | char *buf) |
638 | { | 650 | { |
639 | 651 | ||
640 | char cp_command[] = "QUERY RECORDING "; | 652 | static const char cp_command[] = "QUERY RECORDING "; |
641 | int len; | 653 | int len; |
642 | 654 | ||
643 | cpcmd(cp_command, buf, 4096, NULL); | 655 | cpcmd(cp_command, buf, 4096, NULL); |