aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/vmlogrdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/vmlogrdr.c')
-rw-r--r--drivers/s390/char/vmlogrdr.c42
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
36MODULE_AUTHOR 35MODULE_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
215static int vmlogrdr_get_recording_class_AB(void) 215static 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);