You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.5 KiB

  1. From 5436afc9488531a5e2adff3a1a766af375e0922c Mon Sep 17 00:00:00 2001
  2. From: Willy Tarreau <w@1wt.eu>
  3. Date: Tue, 16 Sep 2014 12:17:36 +0200
  4. Subject: [PATCH 08/13] MEDIUM: config: properly propagate process binding
  5. between proxies
  6. We now recursively propagate the bind-process values between frontends
  7. and backends instead of doing it during name resolving. This ensures
  8. that we're able to properly propagate all the bind-process directives
  9. even across "listen" instances, which are not perfectly covered at the
  10. moment, depending on the declaration order.
  11. (cherry picked from commit 64ab6077b768ee02b04a36b30ee195639a2fabc1)
  12. ---
  13. src/cfgparse.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++------------
  14. 1 file changed, 65 insertions(+), 16 deletions(-)
  15. diff --git a/src/cfgparse.c b/src/cfgparse.c
  16. index 5288600..b9853ef 100644
  17. --- a/src/cfgparse.c
  18. +++ b/src/cfgparse.c
  19. @@ -5932,6 +5932,64 @@ int readcfgfile(const char *file)
  20. return err_code;
  21. }
  22. +/* This function propagates processes from frontend <from> to backend <to> so
  23. + * that it is always guaranteed that a backend pointed to by a frontend is
  24. + * bound to all of its processes. After that, if the target is a "listen"
  25. + * instance, the function recursively descends the target's own targets along
  26. + * default_backend, use_backend rules, and reqsetbe rules. Since the bits are
  27. + * checked first to ensure that <to> is already bound to all processes of
  28. + * <from>, there is no risk of looping and we ensure to follow the shortest
  29. + * path to the destination.
  30. + *
  31. + * It is possible to set <to> to NULL for the first call so that the function
  32. + * takes care of visiting the initial frontend in <from>.
  33. + *
  34. + * It is important to note that the function relies on the fact that all names
  35. + * have already been resolved.
  36. + */
  37. +void propagate_processes(struct proxy *from, struct proxy *to)
  38. +{
  39. + struct switching_rule *rule;
  40. + struct hdr_exp *exp;
  41. +
  42. + if (to) {
  43. + /* check whether we need to go down */
  44. + if (from->bind_proc &&
  45. + (from->bind_proc & to->bind_proc) == from->bind_proc)
  46. + return;
  47. +
  48. + if (!from->bind_proc && !to->bind_proc)
  49. + return;
  50. +
  51. + to->bind_proc = from->bind_proc ?
  52. + (to->bind_proc | from->bind_proc) : 0;
  53. +
  54. + /* now propagate down */
  55. + from = to;
  56. + }
  57. +
  58. + if (!from->cap & PR_CAP_FE)
  59. + return;
  60. +
  61. + /* default_backend */
  62. + if (from->defbe.be)
  63. + propagate_processes(from, from->defbe.be);
  64. +
  65. + /* use_backend */
  66. + list_for_each_entry(rule, &from->switching_rules, list) {
  67. + to = rule->be.backend;
  68. + propagate_processes(from, to);
  69. + }
  70. +
  71. + /* reqsetbe */
  72. + for (exp = from->req_exp; exp != NULL; exp = exp->next) {
  73. + if (exp->action != ACT_SETBE)
  74. + continue;
  75. + to = (struct proxy *)exp->replace;
  76. + propagate_processes(from, to);
  77. + }
  78. +}
  79. +
  80. /*
  81. * Returns the error code, 0 if OK, or any combination of :
  82. * - ERR_ABORT: must abort ASAP
  83. @@ -6162,11 +6220,6 @@ int check_config_validity()
  84. } else {
  85. free(curproxy->defbe.name);
  86. curproxy->defbe.be = target;
  87. - /* we force the backend to be present on at least all of
  88. - * the frontend's processes.
  89. - */
  90. - target->bind_proc = curproxy->bind_proc ?
  91. - (target->bind_proc | curproxy->bind_proc) : 0;
  92. /* Emit a warning if this proxy also has some servers */
  93. if (curproxy->srv) {
  94. @@ -6199,11 +6252,6 @@ int check_config_validity()
  95. } else {
  96. free((void *)exp->replace);
  97. exp->replace = (const char *)target;
  98. - /* we force the backend to be present on at least all of
  99. - * the frontend's processes.
  100. - */
  101. - target->bind_proc = curproxy->bind_proc ?
  102. - (target->bind_proc | curproxy->bind_proc) : 0;
  103. }
  104. }
  105. }
  106. @@ -6252,15 +6300,10 @@ int check_config_validity()
  107. } else {
  108. free((void *)rule->be.name);
  109. rule->be.backend = target;
  110. - /* we force the backend to be present on at least all of
  111. - * the frontend's processes.
  112. - */
  113. - target->bind_proc = curproxy->bind_proc ?
  114. - (target->bind_proc | curproxy->bind_proc) : 0;
  115. }
  116. }
  117. - /* find the target proxy for 'use_backend' rules */
  118. + /* find the target server for 'use_server' rules */
  119. list_for_each_entry(srule, &curproxy->server_rules, list) {
  120. struct server *target = findserver(curproxy, srule->srv.name);
  121. @@ -7131,6 +7174,12 @@ out_uri_auth_compat:
  122. }
  123. }
  124. + /* At this point, target names have already been resolved */
  125. + for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
  126. + if (curproxy->cap & PR_CAP_FE)
  127. + propagate_processes(curproxy, NULL);
  128. + }
  129. +
  130. /* automatically compute fullconn if not set. We must not do it in the
  131. * loop above because cross-references are not yet fully resolved.
  132. */
  133. --
  134. 1.8.5.5