diff options
author | Didier Raboud <odyx@debian.org> | 2014-10-22 13:29:49 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2014-10-22 13:37:06 +0200 |
commit | d98901483ff61a45b5cf11ad62d51c723fbd99b7 (patch) | |
tree | 8a0ea528056b64fdfebe5b2088acce57fcabcb9d | |
parent | e5d9d01a5ebbd40d5456ed5f859995b9889d3717 (diff) | |
download | cups-d98901483ff61a45b5cf11ad62d51c723fbd99b7.tar.gz |
Add upstream patch to limit Get-Jobs replies to 500 jobs
STR: #2913
6 files changed, 417 insertions, 9 deletions
diff --git a/debian/patches/color-management-extension.patch b/debian/patches/color-management-extension.patch index 9b49a4d9..1152a427 100644 --- a/debian/patches/color-management-extension.patch +++ b/debian/patches/color-management-extension.patch @@ -310,7 +310,7 @@ Last-Update: 2014-08-29 if ((attr = ippFindAttribute(con->request, "printer-is-shared", IPP_TAG_BOOLEAN)) != NULL) { -@@ -2491,6 +2501,16 @@ +@@ -2492,6 +2502,16 @@ printer->accepting ? "Now" : "No longer"); } @@ -327,7 +327,7 @@ Last-Update: 2014-08-29 if ((attr = ippFindAttribute(con->request, "printer-is-shared", IPP_TAG_BOOLEAN)) != NULL) { -@@ -4900,6 +4920,10 @@ +@@ -4950,6 +4970,10 @@ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", printer->accepting); @@ -338,7 +338,7 @@ Last-Update: 2014-08-29 if (!ra || cupsArrayFind(ra, "printer-is-shared")) ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", printer->shared); -@@ -4949,6 +4973,9 @@ +@@ -4999,6 +5023,9 @@ if (!printer->accepting) type |= CUPS_PRINTER_REJECTING; diff --git a/debian/patches/no-conffile-timestamp.patch b/debian/patches/no-conffile-timestamp.patch index b846eb27..16dfab8f 100644 --- a/debian/patches/no-conffile-timestamp.patch +++ b/debian/patches/no-conffile-timestamp.patch @@ -16,7 +16,7 @@ Bug-Debian: http://bugs.debian.org/549673 /* --- a/scheduler/job.c +++ b/scheduler/job.c -@@ -2118,7 +2118,7 @@ +@@ -2128,7 +2128,7 @@ strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); cupsFilePuts(fp, "# Job cache file for " CUPS_SVERSION "\n"); diff --git a/debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch b/debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch index 1456fea9..b7322ef1 100644 --- a/debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch +++ b/debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch @@ -11,7 +11,7 @@ Bug: https://www.cups.org/str.php?L4344 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c -@@ -8276,6 +8276,11 @@ +@@ -8381,6 +8381,11 @@ ipp_attribute_t *attr, /* Current attribute */ *attr2, /* Job attribute */ *prev2; /* Previous job attribute */ @@ -23,7 +23,7 @@ Bug: https://www.cups.org/str.php?L4344 /* -@@ -8337,6 +8342,85 @@ +@@ -8442,6 +8447,85 @@ } /* diff --git a/debian/patches/series b/debian/patches/series index 7dae8df5..8126b655 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,5 +1,6 @@ # patches accepted and committed upstream str4396-make-scheduler-return-completed-jobs-in-correct-order.patch +str2913-limit-Get-Jobs-replies-to-500-jobs.patch str4461-restore-access-to-logfiles.patch str4475-fix-the-spinner-imager-on-restart.patch diff --git a/debian/patches/str2913-limit-Get-Jobs-replies-to-500-jobs.patch b/debian/patches/str2913-limit-Get-Jobs-replies-to-500-jobs.patch new file mode 100644 index 00000000..a9b387be --- /dev/null +++ b/debian/patches/str2913-limit-Get-Jobs-replies-to-500-jobs.patch @@ -0,0 +1,407 @@ +Description: Performance fixes for Get-Jobs (STR #2913) + . + Cache a few additional job attributes so that we normally do not need to load + the job attributes from the 'c' files. + . + If we do need to load them, limit the returned jobs to 500 at a time. + . + Implement first-index operation attribute +Bug: https://www.cups.org/str.php?L2913 +Author: Michael Sweet <msweet@apple.com> +Last-Update: 2014-10-22 +--- a/scheduler/ipp.c ++++ b/scheduler/ipp.c +@@ -1531,8 +1531,7 @@ + } + + if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL) +- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, +- "Untitled"); ++ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled"); + else if ((attr->value_tag != IPP_TAG_NAME && + attr->value_tag != IPP_TAG_NAMELANG) || + attr->num_values != 1) +@@ -1612,6 +1611,9 @@ + ippDeleteAttribute(job->attrs, auth_info); + } + ++ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) != NULL) ++ cupsdSetString(&(job->name), attr->values[0].string.text); ++ + if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name", + IPP_TAG_ZERO)) != NULL) + { +@@ -1706,8 +1708,7 @@ + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, + printer->uri); + +- if ((attr = ippFindAttribute(job->attrs, "job-k-octets", +- IPP_TAG_INTEGER)) != NULL) ++ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer = 0; + else + ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", 0); +@@ -4348,8 +4349,9 @@ + + kbytes = (cupsFileTell(out) + 1023) / 1024; + +- if ((attr = ippFindAttribute(job->attrs, "job-k-octets", +- IPP_TAG_INTEGER)) != NULL) ++ job->koctets += kbytes; ++ ++ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + cupsFileClose(out); +@@ -4771,7 +4773,55 @@ + "job-uri", NULL, job_uri); + } + +- copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude); ++ if (job->attrs) ++ { ++ copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude); ++ } ++ else ++ { ++ /* ++ * Generate attributes from the job structure... ++ */ ++ ++ if (!ra || cupsArrayFind(ra, "job-id")) ++ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); ++ ++ if (!ra || cupsArrayFind(ra, "job-k-octets")) ++ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", job->koctets); ++ ++ if (job->name && (!ra || cupsArrayFind(ra, "job-name"))) ++ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, job->name); ++ ++ if (job->username && (!ra || cupsArrayFind(ra, "job-originating-user-name"))) ++ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-user-name", NULL, job->username); ++ ++ if (!ra || cupsArrayFind(ra, "job-state")) ++ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", (int)job->state_value); ++ ++ if (!ra || cupsArrayFind(ra, "job-state-reasons")) ++ { ++ switch (job->state_value) ++ { ++ default : /* Should never get here for processing, pending, held, or stopped jobs since they don't get unloaded... */ ++ break; ++ case IPP_JSTATE_ABORTED : ++ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-aborted-by-system"); ++ break; ++ case IPP_JSTATE_CANCELED : ++ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-canceled-by-user"); ++ break; ++ case IPP_JSTATE_COMPLETED : ++ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-completed-successfully"); ++ break; ++ } ++ } ++ ++ if (job->completed_time && (!ra || cupsArrayFind(ra, "time-at-completed"))) ++ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-completed", (int)job->completed_time); ++ ++ if (job->completed_time && (!ra || cupsArrayFind(ra, "time-at-creation"))) ++ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", (int)job->creation_time); ++ } + } + + +@@ -6124,9 +6174,13 @@ + int port; /* Port portion of URI */ + int job_comparison; /* Job comparison */ + ipp_jstate_t job_state; /* job-state value */ +- int first_job_id; /* First job ID */ +- int limit; /* Maximum number of jobs to return */ ++ int first_job_id = 1, /* First job ID */ ++ first_index = 1, /* First index */ ++ current_index = 0; /* Current index */ ++ int limit = 0; /* Maximum number of jobs to return */ + int count; /* Number of jobs that match */ ++ int need_load_job = 0; /* Do we need to load the job? */ ++ const char *job_attr; /* Job attribute requested */ + ipp_attribute_t *job_ids; /* job-ids attribute */ + cupsd_job_t *job; /* Current job pointer */ + cupsd_printer_t *printer; /* Printer */ +@@ -6292,8 +6346,7 @@ + * See if they want to limit the number of jobs reported... + */ + +- if ((attr = ippFindAttribute(con->request, "limit", +- IPP_TAG_INTEGER)) != NULL) ++ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL) + { + if (job_ids) + { +@@ -6305,11 +6358,20 @@ + + limit = attr->values[0].integer; + } +- else +- limit = 0; + +- if ((attr = ippFindAttribute(con->request, "first-job-id", +- IPP_TAG_INTEGER)) != NULL) ++ if ((attr = ippFindAttribute(con->request, "first-index", IPP_TAG_INTEGER)) != NULL) ++ { ++ if (job_ids) ++ { ++ send_ipp_status(con, IPP_CONFLICT, ++ _("The %s attribute cannot be provided with job-ids."), ++ "first-index"); ++ return; ++ } ++ ++ first_index = attr->values[0].integer; ++ } ++ else if ((attr = ippFindAttribute(con->request, "first-job-id", IPP_TAG_INTEGER)) != NULL) + { + if (job_ids) + { +@@ -6321,15 +6383,12 @@ + + first_job_id = attr->values[0].integer; + } +- else +- first_job_id = 1; + + /* + * See if we only want to see jobs for a specific user... + */ + +- if ((attr = ippFindAttribute(con->request, "my-jobs", +- IPP_TAG_BOOLEAN)) != NULL && job_ids) ++ if ((attr = ippFindAttribute(con->request, "my-jobs", IPP_TAG_BOOLEAN)) != NULL && job_ids) + { + send_ipp_status(con, IPP_CONFLICT, + _("The %s attribute cannot be provided with job-ids."), +@@ -6342,6 +6401,43 @@ + username[0] = '\0'; + + ra = create_requested_array(con->request); ++ for (job_attr = (char *)cupsArrayFirst(ra); job_attr; job_attr = (char *)cupsArrayNext(ra)) ++ if (strcmp(job_attr, "job-id") && ++ strcmp(job_attr, "job-k-octets") && ++ strcmp(job_attr, "job-media-progress") && ++ strcmp(job_attr, "job-more-info") && ++ strcmp(job_attr, "job-name") && ++ strcmp(job_attr, "job-originating-user-name") && ++ strcmp(job_attr, "job-preserved") && ++ strcmp(job_attr, "job-printer-up-time") && ++ strcmp(job_attr, "job-printer-uri") && ++ strcmp(job_attr, "job-state") && ++ strcmp(job_attr, "job-state-reasons") && ++ strcmp(job_attr, "job-uri") && ++ strcmp(job_attr, "time-at-completed") && ++ strcmp(job_attr, "time-at-creation") && ++ strcmp(job_attr, "number-of-documents")) ++ { ++ need_load_job = 1; ++ break; ++ } ++ ++ if (need_load_job && (limit == 0 || limit > 500) && (list == Jobs || delete_list)) ++ { ++ /* ++ * Limit expensive Get-Jobs for job history to 500 jobs... ++ */ ++ ++ ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "limit", 500); ++ ++ if (limit) ++ ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, "limit", limit); ++ ++ limit = 500; ++ ++ cupsdLogMessage(CUPSD_LOG_INFO, ++ "Limiting Get-Jobs response to %d jobs.", limit); ++ } + + /* + * OK, build a list of jobs for this printer... +@@ -6368,13 +6464,15 @@ + { + job = cupsdFindJob(job_ids->values[i].integer); + +- cupsdLoadJob(job); +- +- if (!job->attrs) ++ if (need_load_job && !job->attrs) + { +- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", +- job->id); +- continue; ++ cupsdLoadJob(job); ++ ++ if (!job->attrs) ++ { ++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id); ++ continue; ++ } + } + + if (i > 0) +@@ -6424,13 +6522,19 @@ + if (job->id < first_job_id) + continue; + +- cupsdLoadJob(job); ++ current_index ++; ++ if (current_index < first_index) ++ continue; + +- if (!job->attrs) ++ if (need_load_job && !job->attrs) + { +- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", +- job->id); +- continue; ++ cupsdLoadJob(job); ++ ++ if (!job->attrs) ++ { ++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id); ++ continue; ++ } + } + + if (username[0] && _cups_strcasecmp(username, job->username)) +@@ -8164,8 +8268,9 @@ + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + +- if ((attr = ippFindAttribute(job->attrs, "job-k-octets", +- IPP_TAG_INTEGER)) != NULL) ++ job->koctets += kbytes; ++ ++ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + /* +@@ -9401,8 +9506,9 @@ + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + +- if ((attr = ippFindAttribute(job->attrs, "job-k-octets", +- IPP_TAG_INTEGER)) != NULL) ++ job->koctets += kbytes; ++ ++ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, +--- a/scheduler/job.c ++++ b/scheduler/job.c +@@ -1648,9 +1648,10 @@ + job->file_time = 0; + job->history_time = 0; + +- if (job->state_value >= IPP_JOB_CANCELED && +- (attr = ippFindAttribute(job->attrs, "time-at-completed", +- IPP_TAG_INTEGER)) != NULL) ++ if ((attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) != NULL) ++ job->creation_time = attr->values[0].integer; ++ ++ if (job->state_value >= IPP_JOB_CANCELED && (attr = ippFindAttribute(job->attrs, "time-at-completed", IPP_TAG_INTEGER)) != NULL) + { + job->completed_time = attr->values[0].integer; + +@@ -1799,6 +1800,12 @@ + cupsdSetString(&job->username, attr->values[0].string.text); + } + ++ if (!job->name) ++ { ++ if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL) ++ cupsdSetString(&job->name, attr->values[0].string.text); ++ } ++ + /* + * Set the job hold-until time and state... + */ +@@ -1823,6 +1830,9 @@ + job->state_value = IPP_JOB_PENDING; + } + ++ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) ++ job->koctets = attr->values[0].integer; ++ + if (!job->num_files) + { + /* +@@ -2131,14 +2141,18 @@ + { + cupsFilePrintf(fp, "<Job %d>\n", job->id); + cupsFilePrintf(fp, "State %d\n", job->state_value); ++ cupsFilePrintf(fp, "Created %ld\n", (long)job->creation_time); + if (job->completed_time) + cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time); + cupsFilePrintf(fp, "Priority %d\n", job->priority); + if (job->hold_until) + cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until); + cupsFilePrintf(fp, "Username %s\n", job->username); ++ if (job->name) ++ cupsFilePutConf(fp, "Name", job->name); + cupsFilePrintf(fp, "Destination %s\n", job->dest); + cupsFilePrintf(fp, "DestType %d\n", job->dtype); ++ cupsFilePrintf(fp, "KOctets %d\n", job->koctets); + cupsFilePrintf(fp, "NumFiles %d\n", job->num_files); + for (i = 0; i < job->num_files; i ++) + cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super, +@@ -4079,7 +4093,7 @@ + cupsArrayAdd(ActiveJobs, job); + else if (job->state_value > IPP_JOB_STOPPED) + { +- if (!job->completed_time) ++ if (!job->completed_time || !job->creation_time || !job->name || !job->koctets) + { + cupsdLoadJob(job); + unload_job(job); +@@ -4102,6 +4116,14 @@ + else if (job->state_value > IPP_JOB_COMPLETED) + job->state_value = IPP_JOB_COMPLETED; + } ++ else if (!_cups_strcasecmp(line, "Name")) ++ { ++ cupsdSetString(&(job->name), value); ++ } ++ else if (!_cups_strcasecmp(line, "Created")) ++ { ++ job->creation_time = strtol(value, NULL, 10); ++ } + else if (!_cups_strcasecmp(line, "Completed")) + { + job->completed_time = strtol(value, NULL, 10); +@@ -4126,6 +4148,10 @@ + { + job->dtype = (cups_ptype_t)atoi(value); + } ++ else if (!_cups_strcasecmp(line, "KOctets")) ++ { ++ job->koctets = atoi(value); ++ } + else if (!_cups_strcasecmp(line, "NumFiles")) + { + job->num_files = atoi(value); +--- a/scheduler/job.h ++++ b/scheduler/job.h +@@ -39,6 +39,8 @@ + * waiting on files */ + char *username; /* Printing user */ + char *dest; /* Destination printer or class */ ++ char *name; /* Job name/title */ ++ int koctets; /* job-k-octets */ + cups_ptype_t dtype; /* Destination type */ + cupsd_printer_t *printer; /* Printer this job is assigned to */ + int num_files; /* Number of files in job */ +@@ -47,6 +49,7 @@ + ipp_attribute_t *sheets; /* job-media-sheets-completed */ + time_t access_time, /* Last access time */ + cancel_time, /* When to cancel/send SIGTERM */ ++ creation_time, /* When job was created */ + completed_time, /* When job was completed (0 if not) */ + file_time, /* Job file retain time */ + history_time, /* Job history retain time */ diff --git a/debian/patches/str4461-restore-access-to-logfiles.patch b/debian/patches/str4461-restore-access-to-logfiles.patch index b146a436..83a8aa0d 100644 --- a/debian/patches/str4461-restore-access-to-logfiles.patch +++ b/debian/patches/str4461-restore-access-to-logfiles.patch @@ -103,7 +103,7 @@ Last-Update: 2014-10-22 Group, 1, 1) < 0 || --- a/scheduler/ipp.c +++ b/scheduler/ipp.c -@@ -2734,7 +2734,6 @@ +@@ -2735,7 +2735,6 @@ cupsdLogMessage(CUPSD_LOG_DEBUG, "Copied PPD file successfully"); @@ -111,7 +111,7 @@ Last-Update: 2014-10-22 } } -@@ -4641,7 +4640,7 @@ +@@ -4643,7 +4642,7 @@ * Open the destination file for a copy... */ @@ -120,7 +120,7 @@ Last-Update: 2014-10-22 { cupsFreeOptions(num_defaults, defaults); cupsFileClose(src); -@@ -4696,7 +4695,7 @@ +@@ -4698,7 +4697,7 @@ unlink(tempfile); |