diff options
| author | Stefan Weinhuber <wein@de.ibm.com> | 2010-11-10 04:05:54 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-11-10 04:05:54 -0500 |
| commit | ca768b663131ca644689fcadc9ca092dcc96a758 (patch) | |
| tree | aaf4136000d7f0204830978f304636beb4fd2368 | |
| parent | 16d2ce271c6b8b3527ed1461d03b5f373d53f78f (diff) | |
[S390] vmlogrdr: purge after recording is switched off
If automatic purge is enabled for a vmlogrdr device, old records are
purged before an IUCV recording service is switched on or off. If z/VM
generates a large number of records between purging and switching the
recording service off, these records remain queued, and may have a
negative performance impact on the z/VM system. To avoid this problem,
we need to purge the records after recording is switched off.
Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
| -rw-r--r-- | drivers/s390/char/vmlogrdr.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 9f661426e4a1..1cc726b98ec8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
| @@ -249,27 +249,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, | |||
| 249 | char cp_command[80]; | 249 | char cp_command[80]; |
| 250 | char cp_response[160]; | 250 | char cp_response[160]; |
| 251 | char *onoff, *qid_string; | 251 | char *onoff, *qid_string; |
| 252 | int rc; | ||
| 252 | 253 | ||
| 253 | memset(cp_command, 0x00, sizeof(cp_command)); | 254 | onoff = ((action == 1) ? "ON" : "OFF"); |
| 254 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
| 255 | |||
| 256 | onoff = ((action == 1) ? "ON" : "OFF"); | ||
| 257 | qid_string = ((recording_class_AB == 1) ? " QID * " : ""); | 255 | qid_string = ((recording_class_AB == 1) ? " QID * " : ""); |
| 258 | 256 | ||
| 259 | /* | 257 | /* |
| 260 | * The recording commands needs to be called with option QID | 258 | * The recording commands needs to be called with option QID |
| 261 | * for guests that have previlege classes A or B. | 259 | * for guests that have previlege classes A or B. |
| 262 | * Purging has to be done as separate step, because recording | 260 | * Purging has to be done as separate step, because recording |
| 263 | * can't be switched on as long as records are on the queue. | 261 | * can't be switched on as long as records are on the queue. |
| 264 | * Doing both at the same time doesn't work. | 262 | * Doing both at the same time doesn't work. |
| 265 | */ | 263 | */ |
| 266 | 264 | if (purge && (action == 1)) { | |
| 267 | if (purge) { | 265 | memset(cp_command, 0x00, sizeof(cp_command)); |
| 266 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
| 268 | snprintf(cp_command, sizeof(cp_command), | 267 | snprintf(cp_command, sizeof(cp_command), |
| 269 | "RECORDING %s PURGE %s", | 268 | "RECORDING %s PURGE %s", |
| 270 | logptr->recording_name, | 269 | logptr->recording_name, |
| 271 | qid_string); | 270 | qid_string); |
| 272 | |||
| 273 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | 271 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
| 274 | } | 272 | } |
| 275 | 273 | ||
| @@ -279,19 +277,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, | |||
| 279 | logptr->recording_name, | 277 | logptr->recording_name, |
| 280 | onoff, | 278 | onoff, |
| 281 | qid_string); | 279 | qid_string); |
| 282 | |||
| 283 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | 280 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
| 284 | /* The recording command will usually answer with 'Command complete' | 281 | /* The recording command will usually answer with 'Command complete' |
| 285 | * on success, but when the specific service was never connected | 282 | * on success, but when the specific service was never connected |
| 286 | * before then there might be an additional informational message | 283 | * before then there might be an additional informational message |
| 287 | * 'HCPCRC8072I Recording entry not found' before the | 284 | * 'HCPCRC8072I Recording entry not found' before the |
| 288 | * 'Command complete'. So I use strstr rather then the strncmp. | 285 | * 'Command complete'. So I use strstr rather then the strncmp. |
| 289 | */ | 286 | */ |
| 290 | if (strstr(cp_response,"Command complete")) | 287 | if (strstr(cp_response,"Command complete")) |
| 291 | return 0; | 288 | rc = 0; |
| 292 | else | 289 | else |
| 293 | return -EIO; | 290 | rc = -EIO; |
| 291 | /* | ||
| 292 | * If we turn recording off, we have to purge any remaining records | ||
| 293 | * afterwards, as a large number of queued records may impact z/VM | ||
| 294 | * performance. | ||
| 295 | */ | ||
| 296 | if (purge && (action == 0)) { | ||
| 297 | memset(cp_command, 0x00, sizeof(cp_command)); | ||
| 298 | memset(cp_response, 0x00, sizeof(cp_response)); | ||
| 299 | snprintf(cp_command, sizeof(cp_command), | ||
| 300 | "RECORDING %s PURGE %s", | ||
| 301 | logptr->recording_name, | ||
| 302 | qid_string); | ||
| 303 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); | ||
| 304 | } | ||
| 294 | 305 | ||
| 306 | return rc; | ||
| 295 | } | 307 | } |
| 296 | 308 | ||
| 297 | 309 | ||
