OSDN Git Service

d1dc5dbeaacc0f61812814536cc6c78299fcdc5a
[pg-rex/syncrep.git] / contrib / pg_upgrade / check.c
1 /*
2  *      check.c
3  *
4  *      server checks and output routines
5  *
6  *      Copyright (c) 2010-2011, PostgreSQL Global Development Group
7  *      contrib/pg_upgrade/check.c
8  */
9
10 #include "pg_upgrade.h"
11
12
13 static void set_locale_and_encoding(ClusterInfo *cluster);
14 static void check_new_cluster_is_empty(void);
15 static void check_old_cluster_has_new_cluster_dbs(void);
16 static void check_locale_and_encoding(ControlData *oldctrl,
17                                                   ControlData *newctrl);
18 static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
19 static void check_for_reg_data_type_usage(ClusterInfo *cluster);
20
21
22 void
23 output_check_banner(bool *live_check)
24 {
25         if (user_opts.check && is_server_running(old_cluster.pgdata))
26         {
27                 *live_check = true;
28                 if (old_cluster.port == new_cluster.port)
29                         pg_log(PG_FATAL, "When checking a live server, "
30                                    "the old and new port numbers must be different.\n");
31                 pg_log(PG_REPORT, "PerForming Consistency Checks on Old Live Server\n");
32                 pg_log(PG_REPORT, "------------------------------------------------\n");
33         }
34         else
35         {
36                 pg_log(PG_REPORT, "Performing Consistency Checks\n");
37                 pg_log(PG_REPORT, "-----------------------------\n");
38         }
39 }
40
41
42 void
43 check_old_cluster(bool live_check,
44                                   char **sequence_script_file_name)
45 {
46         /* -- OLD -- */
47
48         if (!live_check)
49                 start_postmaster(&old_cluster, false);
50
51         set_locale_and_encoding(&old_cluster);
52
53         get_pg_database_relfilenode(&old_cluster);
54
55         /* Extract a list of databases and tables from the old cluster */
56         get_db_and_rel_infos(&old_cluster);
57
58         init_tablespaces();
59
60         get_loadable_libraries();
61
62
63         /*
64          * Check for various failure cases
65          */
66
67         check_for_reg_data_type_usage(&old_cluster);
68         check_for_isn_and_int8_passing_mismatch(&old_cluster);
69
70         /* old = PG 8.3 checks? */
71         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
72         {
73                 old_8_3_check_for_name_data_type_usage(&old_cluster);
74                 old_8_3_check_for_tsquery_usage(&old_cluster);
75                 if (user_opts.check)
76                 {
77                         old_8_3_rebuild_tsvector_tables(&old_cluster, true);
78                         old_8_3_invalidate_hash_gin_indexes(&old_cluster, true);
79                         old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true);
80                 }
81                 else
82
83                         /*
84                          * While we have the old server running, create the script to
85                          * properly restore its sequence values but we report this at the
86                          * end.
87                          */
88                         *sequence_script_file_name =
89                                 old_8_3_create_sequence_script(&old_cluster);
90         }
91
92         /* Pre-PG 9.0 had no large object permissions */
93         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
94                 new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
95
96         /*
97          * While not a check option, we do this now because this is the only time
98          * the old server is running.
99          */
100         if (!user_opts.check)
101         {
102                 generate_old_dump();
103                 split_old_dump();
104         }
105
106         if (!live_check)
107                 stop_postmaster(false, false);
108 }
109
110
111 void
112 check_new_cluster(void)
113 {
114         set_locale_and_encoding(&new_cluster);
115
116         get_db_and_rel_infos(&new_cluster);
117
118         check_new_cluster_is_empty();
119         check_old_cluster_has_new_cluster_dbs();
120
121         check_loadable_libraries();
122
123         check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
124
125         if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
126                 check_hard_link();
127 }
128
129
130 void
131 report_clusters_compatible(void)
132 {
133         if (user_opts.check)
134         {
135                 pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
136                 /* stops new cluster */
137                 stop_postmaster(false, false);
138                 exit(0);
139         }
140
141         pg_log(PG_REPORT, "\n"
142                    "| If pg_upgrade fails after this point, you must\n"
143                    "| re-initdb the new cluster before continuing.\n"
144                    "| You will also need to remove the \".old\" suffix\n"
145                    "| from %s/global/pg_control.old.\n", old_cluster.pgdata);
146 }
147
148
149 void
150 issue_warnings(char *sequence_script_file_name)
151 {
152         /* old = PG 8.3 warnings? */
153         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
154         {
155                 start_postmaster(&new_cluster, true);
156
157                 /* restore proper sequence values using file created from old server */
158                 if (sequence_script_file_name)
159                 {
160                         prep_status("Adjusting sequences");
161                         exec_prog(true,
162                                           SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
163                                           "--no-psqlrc --port %d --username \"%s\" "
164                                           "-f \"%s\" --dbname template1 >> \"%s\"" SYSTEMQUOTE,
165                                           new_cluster.bindir, new_cluster.port, os_info.user,
166                                           sequence_script_file_name, log_opts.filename);
167                         unlink(sequence_script_file_name);
168                         check_ok();
169                 }
170
171                 old_8_3_rebuild_tsvector_tables(&new_cluster, false);
172                 old_8_3_invalidate_hash_gin_indexes(&new_cluster, false);
173                 old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false);
174                 stop_postmaster(false, true);
175         }
176
177         /* Create dummy large object permissions for old < PG 9.0? */
178         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
179         {
180                 start_postmaster(&new_cluster, true);
181                 new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
182                 stop_postmaster(false, true);
183         }
184 }
185
186
187 void
188 output_completion_banner(char *deletion_script_file_name)
189 {
190         /* Did we copy the free space files? */
191         if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
192                 pg_log(PG_REPORT,
193                            "| Optimizer statistics are not transferred by pg_upgrade\n"
194                            "| so consider running:\n"
195                            "| \tvacuumdb --all --analyze-only\n"
196                            "| on the newly-upgraded cluster.\n\n");
197         else
198                 pg_log(PG_REPORT,
199                            "| Optimizer statistics and free space information\n"
200                            "| are not transferred by pg_upgrade so consider\n"
201                            "| running:\n"
202                            "| \tvacuumdb --all --analyze\n"
203                            "| on the newly-upgraded cluster.\n\n");
204
205         pg_log(PG_REPORT,
206                    "| Running this script will delete the old cluster's data files:\n"
207                    "| \t%s\n",
208                    deletion_script_file_name);
209 }
210
211
212 void
213 check_cluster_versions(void)
214 {
215         /* get old and new cluster versions */
216         old_cluster.major_version = get_major_server_version(&old_cluster);
217         new_cluster.major_version = get_major_server_version(&new_cluster);
218
219         /*
220          * We allow upgrades from/to the same major version for alpha/beta
221          * upgrades
222          */
223
224         if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
225                 pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
226
227         /* Only current PG version is supported as a target */
228         if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
229                 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
230                            PG_MAJORVERSION);
231
232         /*
233          * We can't allow downgrading because we use the target pg_dumpall, and
234          * pg_dumpall cannot operate on new datbase versions, only older versions.
235          */
236         if (old_cluster.major_version > new_cluster.major_version)
237                 pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
238 }
239
240
241 void
242 check_cluster_compatibility(bool live_check)
243 {
244         char            libfile[MAXPGPATH];
245         FILE       *lib_test;
246
247         /*
248          * Test pg_upgrade_support.so is in the proper place.    We cannot copy it
249          * ourselves because install directories are typically root-owned.
250          */
251         snprintf(libfile, sizeof(libfile), "%s/pg_upgrade_support%s", new_cluster.libpath,
252                          DLSUFFIX);
253
254         if ((lib_test = fopen(libfile, "r")) == NULL)
255                 pg_log(PG_FATAL,
256                            "\npg_upgrade_support%s must be created and installed in %s\n", DLSUFFIX, libfile);
257         else
258                 fclose(lib_test);
259
260         /* get/check pg_control data of servers */
261         get_control_data(&old_cluster, live_check);
262         get_control_data(&new_cluster, false);
263         check_control_data(&old_cluster.controldata, &new_cluster.controldata);
264
265         /* Is it 9.0 but without tablespace directories? */
266         if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
267                 new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS)
268                 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
269                            "because of backend API changes made during development.\n");
270 }
271
272
273 /*
274  * set_locale_and_encoding()
275  *
276  * query the database to get the template0 locale
277  */
278 static void
279 set_locale_and_encoding(ClusterInfo *cluster)
280 {
281         ControlData *ctrl = &cluster->controldata;
282         PGconn     *conn;
283         PGresult   *res;
284         int                     i_encoding;
285         int                     cluster_version = cluster->major_version;
286
287         conn = connectToServer(cluster, "template1");
288
289         /* for pg < 80400, we got the values from pg_controldata */
290         if (cluster_version >= 80400)
291         {
292                 int                     i_datcollate;
293                 int                     i_datctype;
294
295                 res = executeQueryOrDie(conn,
296                                                                 "SELECT datcollate, datctype "
297                                                                 "FROM   pg_catalog.pg_database "
298                                                                 "WHERE  datname = 'template0' ");
299                 assert(PQntuples(res) == 1);
300
301                 i_datcollate = PQfnumber(res, "datcollate");
302                 i_datctype = PQfnumber(res, "datctype");
303
304                 ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
305                 ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
306
307                 PQclear(res);
308         }
309
310         res = executeQueryOrDie(conn,
311                                                         "SELECT pg_catalog.pg_encoding_to_char(encoding) "
312                                                         "FROM   pg_catalog.pg_database "
313                                                         "WHERE  datname = 'template0' ");
314         assert(PQntuples(res) == 1);
315
316         i_encoding = PQfnumber(res, "pg_encoding_to_char");
317         ctrl->encoding = pg_strdup(PQgetvalue(res, 0, i_encoding));
318
319         PQclear(res);
320
321         PQfinish(conn);
322 }
323
324
325 /*
326  * check_locale_and_encoding()
327  *
328  *      locale is not in pg_controldata in 8.4 and later so
329  *      we probably had to get via a database query.
330  */
331 static void
332 check_locale_and_encoding(ControlData *oldctrl,
333                                                   ControlData *newctrl)
334 {
335         if (strcmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
336                 pg_log(PG_FATAL,
337                            "old and new cluster lc_collate values do not match\n");
338         if (strcmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
339                 pg_log(PG_FATAL,
340                            "old and new cluster lc_ctype values do not match\n");
341         if (strcmp(oldctrl->encoding, newctrl->encoding) != 0)
342                 pg_log(PG_FATAL,
343                            "old and new cluster encoding values do not match\n");
344 }
345
346
347 static void
348 check_new_cluster_is_empty(void)
349 {
350         int                     dbnum;
351
352         for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
353         {
354                 int                     relnum;
355                 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
356
357                 for (relnum = 0; relnum < rel_arr->nrels;
358                          relnum++)
359                 {
360                         /* pg_largeobject and its index should be skipped */
361                         if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
362                                 pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
363                                         new_cluster.dbarr.dbs[dbnum].db_name);
364                 }
365         }
366
367 }
368
369
370 /*
371  *      If someone removes the 'postgres' database from the old cluster and
372  *      the new cluster has a 'postgres' database, the number of databases
373  *      will not match.  We actually could upgrade such a setup, but it would
374  *      violate the 1-to-1 mapping of database counts, so we throw an error
375  *      instead.  We would detect this as a database count mismatch during
376  *      upgrade, but we want to detect it during the check phase and report
377  *      the database name.
378  */
379 static void
380 check_old_cluster_has_new_cluster_dbs(void)
381 {
382         int                     old_dbnum, new_dbnum;
383
384         for (new_dbnum = 0; new_dbnum < new_cluster.dbarr.ndbs; new_dbnum++)
385         {
386                 for (old_dbnum = 0; old_dbnum < old_cluster.dbarr.ndbs; old_dbnum++)
387                         if (strcmp(old_cluster.dbarr.dbs[old_dbnum].db_name,
388                                 new_cluster.dbarr.dbs[new_dbnum].db_name) == 0)
389                                 break;
390                 if (old_dbnum == old_cluster.dbarr.ndbs)
391                         pg_log(PG_FATAL, "New cluster database \"%s\" does not exist in the old cluster\n",
392                                 new_cluster.dbarr.dbs[new_dbnum].db_name);
393         }
394 }
395
396
397 /*
398  * create_script_for_old_cluster_deletion()
399  *
400  *      This is particularly useful for tablespace deletion.
401  */
402 void
403 create_script_for_old_cluster_deletion(
404                                                                            char **deletion_script_file_name)
405 {
406         FILE       *script = NULL;
407         int                     tblnum;
408
409         *deletion_script_file_name = pg_malloc(MAXPGPATH);
410
411         prep_status("Creating script to delete old cluster");
412
413         snprintf(*deletion_script_file_name, MAXPGPATH, "%s/delete_old_cluster.%s",
414                          os_info.cwd, SCRIPT_EXT);
415
416         if ((script = fopen(*deletion_script_file_name, "w")) == NULL)
417                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n",
418                            *deletion_script_file_name);
419
420 #ifndef WIN32
421         /* add shebang header */
422         fprintf(script, "#!/bin/sh\n\n");
423 #endif
424
425         /* delete old cluster's default tablespace */
426         fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
427
428         /* delete old cluster's alternate tablespaces */
429         for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
430         {
431                 /*
432                  * Do the old cluster's per-database directories share a directory
433                  * with a new version-specific tablespace?
434                  */
435                 if (strlen(old_cluster.tablespace_suffix) == 0)
436                 {
437                         /* delete per-database directories */
438                         int                     dbnum;
439
440                         fprintf(script, "\n");
441                         /* remove PG_VERSION? */
442                         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
443                                 fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
444                                  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
445
446                         for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
447                         {
448                                 fprintf(script, RMDIR_CMD " %s%s/%d\n",
449                                   os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
450                                                 old_cluster.dbarr.dbs[dbnum].db_oid);
451                         }
452                 }
453                 else
454
455                         /*
456                          * Simply delete the tablespace directory, which might be ".old"
457                          * or a version-specific subdirectory.
458                          */
459                         fprintf(script, RMDIR_CMD " %s%s\n",
460                                  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
461         }
462
463         fclose(script);
464
465 #ifndef WIN32
466         if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
467                 pg_log(PG_FATAL, "Could not add execute permission to file:  %s\n",
468                            *deletion_script_file_name);
469 #endif
470
471         check_ok();
472 }
473
474
475 /*
476  *      check_for_isn_and_int8_passing_mismatch()
477  *
478  *      /contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
479  *      by value.  The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
480  *      it must match for the old and new servers.
481  */
482 static void
483 check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
484 {
485         int                     dbnum;
486         FILE       *script = NULL;
487         bool            found = false;
488         char            output_path[MAXPGPATH];
489
490         prep_status("Checking for /contrib/isn with bigint-passing mismatch");
491
492         if (old_cluster.controldata.float8_pass_by_value ==
493                 new_cluster.controldata.float8_pass_by_value)
494         {
495                 /* no mismatch */
496                 check_ok();
497                 return;
498         }
499
500         snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
501                          os_info.cwd);
502
503         for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
504         {
505                 PGresult   *res;
506                 bool            db_used = false;
507                 int                     ntups;
508                 int                     rowno;
509                 int                     i_nspname,
510                                         i_proname;
511                 DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
512                 PGconn     *conn = connectToServer(cluster, active_db->db_name);
513
514                 /* Find any functions coming from contrib/isn */
515                 res = executeQueryOrDie(conn,
516                                                                 "SELECT n.nspname, p.proname "
517                                                                 "FROM   pg_catalog.pg_proc p, "
518                                                                 "               pg_catalog.pg_namespace n "
519                                                                 "WHERE  p.pronamespace = n.oid AND "
520                                                                 "               p.probin = '$libdir/isn'");
521
522                 ntups = PQntuples(res);
523                 i_nspname = PQfnumber(res, "nspname");
524                 i_proname = PQfnumber(res, "proname");
525                 for (rowno = 0; rowno < ntups; rowno++)
526                 {
527                         found = true;
528                         if (script == NULL && (script = fopen(output_path, "w")) == NULL)
529                                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n", output_path);
530                         if (!db_used)
531                         {
532                                 fprintf(script, "Database:  %s\n", active_db->db_name);
533                                 db_used = true;
534                         }
535                         fprintf(script, "  %s.%s\n",
536                                         PQgetvalue(res, rowno, i_nspname),
537                                         PQgetvalue(res, rowno, i_proname));
538                 }
539
540                 PQclear(res);
541
542                 PQfinish(conn);
543         }
544
545         if (script)
546                 fclose(script);
547
548         if (found)
549         {
550                 pg_log(PG_REPORT, "fatal\n");
551                 pg_log(PG_FATAL,
552                            "| Your installation contains \"/contrib/isn\" functions\n"
553                            "| which rely on the bigint data type.  Your old and\n"
554                            "| new clusters pass bigint values differently so this\n"
555                            "| cluster cannot currently be upgraded.  You can\n"
556                            "| manually upgrade data that use \"/contrib/isn\"\n"
557                            "| facilities and remove \"/contrib/isn\" from the\n"
558                            "| old cluster and restart the upgrade.  A list\n"
559                            "| of the problem functions is in the file:\n"
560                            "| \t%s\n\n", output_path);
561         }
562         else
563                 check_ok();
564 }
565
566
567 /*
568  * check_for_reg_data_type_usage()
569  *      pg_upgrade only preserves these system values:
570  *              pg_class.relfilenode
571  *              pg_type.oid
572  *              pg_enum.oid
573  *
574  *      Most of the reg* data types reference system catalog info that is
575  *      not preserved, and hence these data types cannot be used in user
576  *      tables upgraded by pg_upgrade.
577  */
578 static void
579 check_for_reg_data_type_usage(ClusterInfo *cluster)
580 {
581         int                     dbnum;
582         FILE       *script = NULL;
583         bool            found = false;
584         char            output_path[MAXPGPATH];
585
586         prep_status("Checking for reg* system oid user data types");
587
588         snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
589                          os_info.cwd);
590
591         for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
592         {
593                 PGresult   *res;
594                 bool            db_used = false;
595                 int                     ntups;
596                 int                     rowno;
597                 int                     i_nspname,
598                                         i_relname,
599                                         i_attname;
600                 DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
601                 PGconn     *conn = connectToServer(cluster, active_db->db_name);
602
603                 res = executeQueryOrDie(conn,
604                                                                 "SELECT n.nspname, c.relname, a.attname "
605                                                                 "FROM   pg_catalog.pg_class c, "
606                                                                 "               pg_catalog.pg_namespace n, "
607                                                                 "               pg_catalog.pg_attribute a "
608                                                                 "WHERE  c.oid = a.attrelid AND "
609                                                                 "               NOT a.attisdropped AND "
610                                                                 "               a.atttypid IN ( "
611                   "                     'pg_catalog.regproc'::pg_catalog.regtype, "
612                                                                 "                       'pg_catalog.regprocedure'::pg_catalog.regtype, "
613                   "                     'pg_catalog.regoper'::pg_catalog.regtype, "
614                                                                 "                       'pg_catalog.regoperator'::pg_catalog.regtype, "
615                  "                      'pg_catalog.regclass'::pg_catalog.regtype, "
616                 /* regtype.oid is preserved, so 'regtype' is OK */
617                 "                       'pg_catalog.regconfig'::pg_catalog.regtype, "
618                                                                 "                       'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
619                                                                 "               c.relnamespace = n.oid AND "
620                                                           "             n.nspname != 'pg_catalog' AND "
621                                                  "              n.nspname != 'information_schema'");
622
623                 ntups = PQntuples(res);
624                 i_nspname = PQfnumber(res, "nspname");
625                 i_relname = PQfnumber(res, "relname");
626                 i_attname = PQfnumber(res, "attname");
627                 for (rowno = 0; rowno < ntups; rowno++)
628                 {
629                         found = true;
630                         if (script == NULL && (script = fopen(output_path, "w")) == NULL)
631                                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n", output_path);
632                         if (!db_used)
633                         {
634                                 fprintf(script, "Database:  %s\n", active_db->db_name);
635                                 db_used = true;
636                         }
637                         fprintf(script, "  %s.%s.%s\n",
638                                         PQgetvalue(res, rowno, i_nspname),
639                                         PQgetvalue(res, rowno, i_relname),
640                                         PQgetvalue(res, rowno, i_attname));
641                 }
642
643                 PQclear(res);
644
645                 PQfinish(conn);
646         }
647
648         if (script)
649                 fclose(script);
650
651         if (found)
652         {
653                 pg_log(PG_REPORT, "fatal\n");
654                 pg_log(PG_FATAL,
655                            "| Your installation contains one of the reg* data types in\n"
656                            "| user tables.  These data types reference system oids that\n"
657                            "| are not preserved by pg_upgrade, so this cluster cannot\n"
658                            "| currently be upgraded.  You can remove the problem tables\n"
659                            "| and restart the upgrade.  A list of the problem columns\n"
660                            "| is in the file:\n"
661                            "| \t%s\n\n", output_path);
662         }
663         else
664                 check_ok();
665 }