summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2014-10-22 13:29:49 +0200
committerDidier Raboud <odyx@debian.org>2014-10-22 13:37:06 +0200
commitd98901483ff61a45b5cf11ad62d51c723fbd99b7 (patch)
tree8a0ea528056b64fdfebe5b2088acce57fcabcb9d
parente5d9d01a5ebbd40d5456ed5f859995b9889d3717 (diff)
downloadcups-d98901483ff61a45b5cf11ad62d51c723fbd99b7.tar.gz
Add upstream patch to limit Get-Jobs replies to 500 jobs
STR: #2913
-rw-r--r--debian/patches/color-management-extension.patch6
-rw-r--r--debian/patches/no-conffile-timestamp.patch2
-rw-r--r--debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch4
-rw-r--r--debian/patches/series1
-rw-r--r--debian/patches/str2913-limit-Get-Jobs-replies-to-500-jobs.patch407
-rw-r--r--debian/patches/str4461-restore-access-to-logfiles.patch6
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);