diff options
author | Joshua Lock <joshua.g.lock@intel.com> | 2017-02-07 15:53:00 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-02-15 20:06:41 -0800 |
commit | 5ca7184552b35a80a0d78f06e2264502144c1faf (patch) | |
tree | 6e93acc69ca5bce906fac7d5007a8f7b799635fd /meta/recipes-devtools/pseudo/files | |
parent | d9a3ebef27979f6c3f586a3b35b07521ae1faeed (diff) | |
download | poky-5ca7184552b35a80a0d78f06e2264502144c1faf.tar.gz |
pseudo: update to 1.8.2
Update to the newly minted 1.8.2, dropping several patches we'd
backported since the last release.
(From OE-Core rev: 6437f14c9177fd7ec7a9b6bca873362b0c94abfb)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/pseudo/files')
6 files changed, 0 insertions, 373 deletions
diff --git a/meta/recipes-devtools/pseudo/files/0001-Don-t-send-SIGUSR1-to-init.patch b/meta/recipes-devtools/pseudo/files/0001-Don-t-send-SIGUSR1-to-init.patch deleted file mode 100644 index 6c694ceb0d..0000000000 --- a/meta/recipes-devtools/pseudo/files/0001-Don-t-send-SIGUSR1-to-init.patch +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | From befc6dbd6469d428c9e0830dbe51bdf7ac39d9ae Mon Sep 17 00:00:00 2001 | ||
2 | From: Seebs <seebs@seebs.net> | ||
3 | Date: Thu, 22 Sep 2016 14:35:04 -0500 | ||
4 | Subject: [PATCH] Don't send SIGUSR1 to init. | ||
5 | |||
6 | If the parent exits due to child process being slow, getppid() will return | ||
7 | 1, and we'll send SIGUSR1 to init, which can break things like dumbinit | ||
8 | which aren't adequately protected against non-root processes sending them | ||
9 | signals. | ||
10 | |||
11 | Signed-off-by: Seebs <seebs@seebs.net> | ||
12 | |||
13 | Upstream-Status: Backport (commit befc6dbd6469d428c9e0830dbe51bdf7ac39d9ae) | ||
14 | |||
15 | [YOCTO #10324] | ||
16 | |||
17 | This resolves an issue where a docker container running builds would die | ||
18 | due to it's 'mini init' being signaled by pseudo. | ||
19 | |||
20 | Signed-off-by: Mark Hatle <mark.hatle@windriver.com> | ||
21 | --- | ||
22 | pseudo_server.c | 11 ++++++++--- | ||
23 | |||
24 | diff --git a/pseudo_server.c b/pseudo_server.c | ||
25 | index 65102dd..8731d20 100644 | ||
26 | --- a/pseudo_server.c | ||
27 | +++ b/pseudo_server.c | ||
28 | @@ -358,9 +358,14 @@ pseudo_server_start(int daemonize) { | ||
29 | signal(SIGTERM, quit_now); | ||
30 | /* tell parent process to stop waiting */ | ||
31 | if (daemonize) { | ||
32 | - pseudo_diag("Setup complete, sending SIGUSR1 to pid %d.\n", | ||
33 | - getppid()); | ||
34 | - kill(getppid(), SIGUSR1); | ||
35 | + pid_t ppid = getppid(); | ||
36 | + if (ppid == 1) { | ||
37 | + pseudo_diag("Setup complete, but parent is init, not sending SIGUSR1.\n"); | ||
38 | + } else { | ||
39 | + pseudo_diag("Setup complete, sending SIGUSR1 to pid %d.\n", | ||
40 | + ppid); | ||
41 | + kill(ppid, SIGUSR1); | ||
42 | + } | ||
43 | } | ||
44 | pseudo_server_loop(); | ||
45 | return 0; | ||
46 | -- | ||
47 | 2.5.5 | ||
48 | |||
diff --git a/meta/recipes-devtools/pseudo/files/0001-Quiet-diagnostics-during-startup-for-pseudo-d.patch b/meta/recipes-devtools/pseudo/files/0001-Quiet-diagnostics-during-startup-for-pseudo-d.patch deleted file mode 100644 index d4b9f6a0f8..0000000000 --- a/meta/recipes-devtools/pseudo/files/0001-Quiet-diagnostics-during-startup-for-pseudo-d.patch +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | From eead8a505245a292c43f070c0e836cdfeb7bd7bd Mon Sep 17 00:00:00 2001 | ||
2 | From: Seebs <seebs@seebs.net> | ||
3 | Date: Wed, 28 Sep 2016 17:05:17 -0500 | ||
4 | Subject: [PATCH 1/2] Quiet diagnostics during startup for pseudo -d | ||
5 | |||
6 | When the client spawns a pseudo server, it starts out sending diagnostics | ||
7 | to stderr. This can be spammy in some cases with races during startup; | ||
8 | everything resolves, but we get scary-looking diagnostics. So shove | ||
9 | those into a log file. | ||
10 | |||
11 | Signed-off-by: Seebs <seebs@seebs.net> | ||
12 | |||
13 | Upstream-Status: Backport | ||
14 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
15 | --- | ||
16 | ChangeLog.txt | 5 +++++ | ||
17 | pseudo_server.c | 4 +++- | ||
18 | 2 files changed, 8 insertions(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/ChangeLog.txt b/ChangeLog.txt | ||
21 | index d6359ca..4cc24de 100644 | ||
22 | --- a/ChangeLog.txt | ||
23 | +++ b/ChangeLog.txt | ||
24 | @@ -1,3 +1,8 @@ | ||
25 | +2016-09-28: | ||
26 | + * (seebs) Send errors to log when daemonizing, but do that a lot | ||
27 | + sooner to prevent startup messages which can show up spuriously | ||
28 | + with multiple clients. | ||
29 | + | ||
30 | 2016-07-28: | ||
31 | * (seebs) Fix performance issue on deletion with xattr changes. | ||
32 | |||
33 | diff --git a/pseudo_server.c b/pseudo_server.c | ||
34 | index 8731d20..7c2db2f 100644 | ||
35 | --- a/pseudo_server.c | ||
36 | +++ b/pseudo_server.c | ||
37 | @@ -162,6 +162,9 @@ pseudo_server_start(int daemonize) { | ||
38 | * SIGUSR1, or until too much time has passed. */ | ||
39 | if (daemonize) { | ||
40 | int child; | ||
41 | + | ||
42 | + /* make startup messages go away when invoked-as-daemon */ | ||
43 | + pseudo_debug_logfile(PSEUDO_LOGFILE, 2); | ||
44 | child = fork(); | ||
45 | if (child == -1) { | ||
46 | pseudo_diag("Couldn't fork child process: %s\n", | ||
47 | @@ -231,7 +234,6 @@ pseudo_server_start(int daemonize) { | ||
48 | setsid(); | ||
49 | fclose(stdin); | ||
50 | fclose(stdout); | ||
51 | - pseudo_debug_logfile(PSEUDO_LOGFILE, 2); | ||
52 | /* and then just execute the server code normally. */ | ||
53 | /* Any logging will presumably go to logfile, but | ||
54 | * exit status will make it back to the parent for | ||
diff --git a/meta/recipes-devtools/pseudo/files/0002-Use-correct-file-descriptor.patch b/meta/recipes-devtools/pseudo/files/0002-Use-correct-file-descriptor.patch deleted file mode 100644 index dd6fd87ae9..0000000000 --- a/meta/recipes-devtools/pseudo/files/0002-Use-correct-file-descriptor.patch +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | From 7a0632cad851826d804db0540d9a59773e6bf29c Mon Sep 17 00:00:00 2001 | ||
2 | From: Seebs <seebs@seebs.net> | ||
3 | Date: Wed, 28 Sep 2016 22:12:29 -0500 | ||
4 | Subject: [PATCH 2/2] Use correct file descriptor | ||
5 | |||
6 | So it turns out that pseudo_logfile() was returning 0 or -1, and | ||
7 | pseudo_debug_logfile() was expecting it to be the correct file descriptor | ||
8 | to use. And it's basically a mystery that any of that ever worked. | ||
9 | |||
10 | Signed-off-by: Seebs <seebs@seebs.net> | ||
11 | |||
12 | Upstream-Status: Backport | ||
13 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
14 | --- | ||
15 | ChangeLog.txt | 3 +++ | ||
16 | pseudo_util.c | 3 ++- | ||
17 | 2 files changed, 5 insertions(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/ChangeLog.txt b/ChangeLog.txt | ||
20 | index 4cc24de..49a6c36 100644 | ||
21 | --- a/ChangeLog.txt | ||
22 | +++ b/ChangeLog.txt | ||
23 | @@ -2,6 +2,9 @@ | ||
24 | * (seebs) Send errors to log when daemonizing, but do that a lot | ||
25 | sooner to prevent startup messages which can show up spuriously | ||
26 | with multiple clients. | ||
27 | + * (seebs) return file descriptor from pseudo_logfile, so we set | ||
28 | + pseudo_util_debug_fd to the right value instead of to stdin. | ||
29 | + Nice bug. | ||
30 | |||
31 | 2016-07-28: | ||
32 | * (seebs) Fix performance issue on deletion with xattr changes. | ||
33 | diff --git a/pseudo_util.c b/pseudo_util.c | ||
34 | index 0c156cf..a60c74b 100644 | ||
35 | --- a/pseudo_util.c | ||
36 | +++ b/pseudo_util.c | ||
37 | @@ -1569,7 +1569,7 @@ pseudo_logfile(char *filename, char *defname, int prefer_fd) { | ||
38 | if (fd == -1) | ||
39 | return -1; | ||
40 | else | ||
41 | - return 0; | ||
42 | + return fd; | ||
43 | } | ||
44 | |||
45 | int | ||
46 | @@ -1579,6 +1579,7 @@ pseudo_debug_logfile(char *defname, int prefer_fd) { | ||
47 | |||
48 | fd = pseudo_logfile(filename, defname, prefer_fd); | ||
49 | if (fd > -1) { | ||
50 | + pseudo_diag("debug_logfile: fd %d\n", fd); | ||
51 | pseudo_util_debug_fd = fd; | ||
52 | return 0; | ||
53 | } | ||
diff --git a/meta/recipes-devtools/pseudo/files/0003-Fix-renameat-parallel-to-previous-fix-to-rename.patch b/meta/recipes-devtools/pseudo/files/0003-Fix-renameat-parallel-to-previous-fix-to-rename.patch deleted file mode 100644 index 739c03ee6e..0000000000 --- a/meta/recipes-devtools/pseudo/files/0003-Fix-renameat-parallel-to-previous-fix-to-rename.patch +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | From d9ab3a0acc94151048498b1ea4d69e7707df1526 Mon Sep 17 00:00:00 2001 | ||
2 | From: Seebs <seebs@seebs.net> | ||
3 | Date: Fri, 30 Sep 2016 10:56:35 -0500 | ||
4 | Subject: [PATCH 3/3] Fix renameat (parallel to previous fix to rename) | ||
5 | |||
6 | There was a bug in rename(), which was duplicated when renameat() was | ||
7 | implemented, and which got fixed two years ago for rename(), but no | ||
8 | one ever uses renameat() so it didn't get fixed there. Thanks | ||
9 | to Anton Gerasimov <anton@advancedtelematic.com> for the bug report | ||
10 | and patch. | ||
11 | |||
12 | Signed-off-by: Seebs <seebs@seebs.net> | ||
13 | |||
14 | Upstream-Status: Backport | ||
15 | Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> | ||
16 | |||
17 | --- | ||
18 | ChangeLog.txt | 4 ++++ | ||
19 | ports/unix/guts/renameat.c | 7 ++++++- | ||
20 | 2 files changed, 10 insertions(+), 1 deletion(-) | ||
21 | |||
22 | diff --git a/ChangeLog.txt b/ChangeLog.txt | ||
23 | index 65b9759..ca04cc0 100644 | ||
24 | --- a/ChangeLog.txt | ||
25 | +++ b/ChangeLog.txt | ||
26 | @@ -1,3 +1,7 @@ | ||
27 | +2016-09-30: | ||
28 | + * (seebs) Fix rename at, matching fix from ee00f63d for rename. Bug | ||
29 | + and fix provided by Anton Gerasimov <anton@advancedtelematic.com>. | ||
30 | + | ||
31 | 2016-09-28: | ||
32 | * (seebs) Send errors to log when daemonizing, but do that a lot | ||
33 | sooner to prevent startup messages which can show up spuriously | ||
34 | diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c | ||
35 | index ade0509..d5e36fa 100644 | ||
36 | --- a/ports/unix/guts/renameat.c | ||
37 | +++ b/ports/unix/guts/renameat.c | ||
38 | @@ -11,6 +11,7 @@ | ||
39 | int oldrc, newrc; | ||
40 | int save_errno; | ||
41 | int old_db_entry = 0; | ||
42 | + int may_unlinked = 0; | ||
43 | |||
44 | pseudo_debug(PDBGF_FILE, "renameat: %d,%s->%d,%s\n", | ||
45 | olddirfd, oldpath ? oldpath : "<nil>", | ||
46 | @@ -44,10 +45,14 @@ | ||
47 | /* as with unlink, we have to mark that the file may get deleted */ | ||
48 | msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, newdirfd, newpath, newrc ? NULL : &newbuf); | ||
49 | if (msg && msg->result == RESULT_SUCCEED) | ||
50 | + may_unlinked = 1; | ||
51 | + msg = pseudo_client_op(OP_STAT, 0, -1, olddirfd, oldpath, oldrc ? NULL : &oldbuf); | ||
52 | + if (msg && msg->result == RESULT_SUCCEED) | ||
53 | old_db_entry = 1; | ||
54 | + | ||
55 | rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); | ||
56 | save_errno = errno; | ||
57 | - if (old_db_entry) { | ||
58 | + if (may_unlinked) { | ||
59 | if (rc == -1) { | ||
60 | /* since we failed, that wasn't really unlinked -- put | ||
61 | * it back. | ||
62 | -- | ||
63 | 2.7.4 | ||
64 | |||
diff --git a/meta/recipes-devtools/pseudo/files/Fix-xattr-performance.patch b/meta/recipes-devtools/pseudo/files/Fix-xattr-performance.patch deleted file mode 100644 index 4e072e6c40..0000000000 --- a/meta/recipes-devtools/pseudo/files/Fix-xattr-performance.patch +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | From 0d9071f3090bbd7880558f3b488b236ac19b44fc Mon Sep 17 00:00:00 2001 | ||
2 | From: seebs <seebs@seebs.net> | ||
3 | Date: Thu, 28 Jul 2016 14:02:12 -0500 | ||
4 | Subject: [PATCH 1/2] Fix xattr performance | ||
5 | |||
6 | When deleting files, we *do* know the inode and attribute, most of the | ||
7 | time, so we pass those in whenever possible. The full purge of unmatched | ||
8 | xattrs should not happen when the correct dev/ino are believed to be known. | ||
9 | |||
10 | Signed-off-by: Seebs <seebs@seebs.net> | ||
11 | |||
12 | [YOCTO #9929] | ||
13 | Upstream-Status: Backport (0d9071f3090bbd7880558f3b488b236ac19b44fc) | ||
14 | Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> | ||
15 | --- | ||
16 | ChangeLog.txt | 3 +++ | ||
17 | pseudo.c | 11 ++++++++--- | ||
18 | pseudo_db.c | 15 +++++++++------ | ||
19 | pseudo_db.h | 2 +- | ||
20 | 4 files changed, 21 insertions(+), 10 deletions(-) | ||
21 | |||
22 | diff --git a/ChangeLog.txt b/ChangeLog.txt | ||
23 | index 131f163..d6359ca 100644 | ||
24 | --- a/ChangeLog.txt | ||
25 | +++ b/ChangeLog.txt | ||
26 | @@ -1,3 +1,6 @@ | ||
27 | +2016-07-28: | ||
28 | + * (seebs) Fix performance issue on deletion with xattr changes. | ||
29 | + | ||
30 | 2016-07-08: | ||
31 | * (RP) release 1.8.1 | ||
32 | * (joshuagl) Fix log table creation issue | ||
33 | diff --git a/pseudo.c b/pseudo.c | ||
34 | index 52f649f..db1c400 100644 | ||
35 | --- a/pseudo.c | ||
36 | +++ b/pseudo.c | ||
37 | @@ -600,7 +600,12 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon | ||
38 | if (by_path.deleting != 0) { | ||
39 | pseudo_debug(PDBGF_FILE, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n", | ||
40 | msg->path); | ||
41 | - pdb_did_unlink_file(msg->path, by_path.deleting); | ||
42 | + /* in this case, we don't trust the | ||
43 | + * existing entries, so we will do the | ||
44 | + * more expensive sweep for stray | ||
45 | + * xattrs. | ||
46 | + */ | ||
47 | + pdb_did_unlink_file(msg->path, NULL, by_path.deleting); | ||
48 | } else { | ||
49 | pseudo_diag("inode mismatch: '%s' ino %llu in db, %llu in request.\n", | ||
50 | msg->path, | ||
51 | @@ -698,7 +703,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon | ||
52 | if (by_ino.deleting != 0) { | ||
53 | pseudo_debug(PDBGF_FILE, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n", | ||
54 | msg->path); | ||
55 | - pdb_did_unlink_file(path_by_ino, by_ino.deleting); | ||
56 | + pdb_did_unlink_file(path_by_ino, &by_ino, by_ino.deleting); | ||
57 | } else { | ||
58 | pseudo_diag("path mismatch [%d link%s]: ino %llu db '%s' req '%s'.\n", | ||
59 | msg->nlink, | ||
60 | @@ -930,7 +935,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon | ||
61 | } | ||
62 | break; | ||
63 | case OP_DID_UNLINK: | ||
64 | - pdb_did_unlink_file(msg->path, msg->client); | ||
65 | + pdb_did_unlink_file(msg->path, msg, msg->client); | ||
66 | break; | ||
67 | case OP_CANCEL_UNLINK: | ||
68 | pdb_cancel_unlink_file(msg); | ||
69 | diff --git a/pseudo_db.c b/pseudo_db.c | ||
70 | index 289bb29..e7dd193 100644 | ||
71 | --- a/pseudo_db.c | ||
72 | +++ b/pseudo_db.c | ||
73 | @@ -1848,7 +1848,7 @@ pdb_did_unlink_files(int deleting) { | ||
74 | |||
75 | /* confirm deletion of a specific file by a given client */ | ||
76 | int | ||
77 | -pdb_did_unlink_file(char *path, int deleting) { | ||
78 | +pdb_did_unlink_file(char *path, pseudo_msg_t *msg, int deleting) { | ||
79 | static sqlite3_stmt *delete_exact; | ||
80 | int rc, exact; | ||
81 | char *sql_delete_exact = "DELETE FROM files WHERE path = ? AND deleting = ?;"; | ||
82 | @@ -1878,11 +1878,14 @@ pdb_did_unlink_file(char *path, int deleting) { | ||
83 | exact = sqlite3_changes(file_db); | ||
84 | pseudo_debug(PDBGF_DB, "(exact %d)\n", exact); | ||
85 | sqlite3_reset(delete_exact); | ||
86 | - sqlite3_clear_bindings(delete_exact); | ||
87 | - /* we have to clean everything because we don't know for sure the | ||
88 | - * device/inode... | ||
89 | - */ | ||
90 | - pdb_clear_unused_xattrs(); | ||
91 | + if (msg) { | ||
92 | + pdb_clear_xattrs(msg); | ||
93 | + } else { | ||
94 | + /* we have to clean everything because we don't know for sure the | ||
95 | + * device/inode... | ||
96 | + */ | ||
97 | + pdb_clear_unused_xattrs(); | ||
98 | + } | ||
99 | return rc != SQLITE_DONE; | ||
100 | } | ||
101 | |||
102 | diff --git a/pseudo_db.h b/pseudo_db.h | ||
103 | index a54f3c1..1b2599c 100644 | ||
104 | --- a/pseudo_db.h | ||
105 | +++ b/pseudo_db.h | ||
106 | @@ -39,7 +39,7 @@ typedef struct { | ||
107 | |||
108 | extern int pdb_maybe_backup(void); | ||
109 | extern int pdb_cancel_unlink_file(pseudo_msg_t *msg); | ||
110 | -extern int pdb_did_unlink_file(char *path, int deleting); | ||
111 | +extern int pdb_did_unlink_file(char *path, pseudo_msg_t *msg, int deleting); | ||
112 | extern int pdb_did_unlink_files(int deleting); | ||
113 | extern int pdb_link_file(pseudo_msg_t *msg); | ||
114 | extern int pdb_may_unlink_file(pseudo_msg_t *msg, int deleting); | ||
115 | -- | ||
116 | 2.7.4 | ||
117 | |||
diff --git a/meta/recipes-devtools/pseudo/files/More-correctly-fix-xattrs.patch b/meta/recipes-devtools/pseudo/files/More-correctly-fix-xattrs.patch deleted file mode 100644 index 3d178f9b4f..0000000000 --- a/meta/recipes-devtools/pseudo/files/More-correctly-fix-xattrs.patch +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | From 45eca34c754d416a38bee90fb2d3c110a0b6cc5f Mon Sep 17 00:00:00 2001 | ||
2 | From: Seebs <seebs@seebs.net> | ||
3 | Date: Thu, 3 Nov 2016 11:36:12 -0500 | ||
4 | Subject: [PATCH] More-correctly fix xattrs | ||
5 | |||
6 | Fix provided by Patrick Ohly <patrick.ohly@intel.com>. This resolves | ||
7 | the actual cause of the path length mismatches, and explains why | ||
8 | I couldn't quite explain why the previous one had only sometimes | ||
9 | worked, also why it showed up on directories but not plain files. | ||
10 | |||
11 | Signed-off-by: Seebs <seebs@seebs.net> | ||
12 | |||
13 | Fixes [YOCTO #10623] | ||
14 | |||
15 | Upstream-Status: Backport [commit 45eca34c754d416a38bee90fb2d3c110a0b6cc5f] | ||
16 | |||
17 | Signed-off-by: Patrick Ohly <patrick.ohly@intel.com> | ||
18 | --- | ||
19 | pseudo_client.c | 2 +- | ||
20 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
21 | |||
22 | diff --git a/pseudo_client.c b/pseudo_client.c | ||
23 | index 6a08df3..b1a00fa 100644 | ||
24 | --- a/pseudo_client.c | ||
25 | +++ b/pseudo_client.c | ||
26 | @@ -1676,7 +1676,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path | ||
27 | * empty path for that. | ||
28 | */ | ||
29 | if (path_extra_1) { | ||
30 | - size_t full_len = path_extra_1len + 1 + pathlen; | ||
31 | + size_t full_len = path_extra_1len + 1 + pathlen - strip_slash; | ||
32 | size_t partial_len = pathlen - 1 - strip_slash; | ||
33 | if (path_extra_2) { | ||
34 | full_len += path_extra_2len + 1; | ||
35 | -- | ||
36 | 2.1.4 | ||
37 | |||