Re: [HACKERS] Cannot initdb in cvs tip - Mailing list pgsql-patches

From John Hansen
Subject Re: [HACKERS] Cannot initdb in cvs tip
Date
Msg-id 1087694856.3356.3.camel@localhost
Whole thread Raw
In response to Re: [HACKERS] Cannot initdb in cvs tip  ("Dave Page" <dpage@vale-housing.co.uk>)
Responses Re: [HACKERS] Cannot initdb in cvs tip
List pgsql-patches
On Sun, 2004-06-20 at 08:04, Dave Page wrote:
>
> > -----Original Message-----
> > From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
> > Sent: 19 June 2004 00:22
> > To: Dave Page
> > Cc: PostgreSQL-development
> > Subject: Re: [HACKERS] Cannot initdb in cvs tip
> >
> > "Dave Page" <dpage@vale-housing.co.uk> writes:
> > > I'm getting the following error when trying to initdb with CVS tip.
> >
> > > creating template1 database in
> > C:/msys/1.0/local/pgsql/data/base/1 ...
> > > ERROR:  could not open segment 1 of relation 1663/1/1255
> > (target block
> > > 26189776): No such file or directory
> >
> > The target block number is obviously broken :-(.  But maybe
> > you have a build consistency problem --- did you try a make
> > distclean and full rebuild?
>
> OK, that cured that one - thanks.
>
> > > although it says it's clearing the contents of the directory, in
> > > actual fact it leaves the directory structure in place, thus a
> > > subsequent initdb will not run without a manual clearup.
> >
> > Hm.  The rmtree() function in initdb.c is responsible for
> > this, and I see it has WIN32-specific behavior, which is
> > evidently wrong.
> > Can you recommend a fix?
>
> The current solution does an "rmdir /q /s $PGDATA" if the datadir was
> created, and "del /q /s $PGDATA" if the directory already existed. The
> second case  will not work, as del will not remove directories. AFAICS,
> there is no easy way to do this using system() as rmdir won't accept
> wildcards, so we can't do "del $PGDATA/* && rmdir $PGDATA/*".
>
> It seems to me that the simple answer is to put Andrew's recursive
> unlink code back in (as he suggested), which Bruce removed as rm etc.
> were being used in commands/dbcommands.c (which should work fine under
> Windows). Patch below....
>

you could of course rmdir /s /q $PGDATA && mkdir $PGDATA if the purpose
is to leave the directory intact if it already existed prior to install.

Regards,

John
> Regards, Dave
>
> *** initdb.c.orig    Sat Jun 19 22:15:28 2004
> --- initdb.c    Sat Jun 19 23:02:10 2004
> ***************
> *** 132,137 ****
> --- 132,144 ----
>   static void *xmalloc(size_t size);
>   static char *xstrdup(const char *s);
>   static bool rmtree(char *path, bool rmtopdir);
> +
> + #ifdef WIN32
> + static int  init_unlink(const char *);
> + #else
> + #define init_unlink(x) unlink( (x) )
> + #endif   /* WIN32 */
> +
>   static char **replace_token(char **lines, char *token, char
> *replacement);
>   static char **readfile(char *path);
>   static void writefile(char *path, char **lines);
> ***************
> *** 245,264 ****
>   static bool
>   rmtree(char *path, bool rmtopdir)
>   {
> !     char        buf[MAXPGPATH + 64];
>
> ! #ifndef WIN32
> !     /* doesn't handle .* files, but we don't make any... */
> !     snprintf(buf, sizeof(buf), "rm -rf \"%s\"%s", path,
> !              rmtopdir ? "" : "/*");
> ! #else
> !     snprintf(buf, sizeof(buf), "%s /s /q \"%s\"",
> !              rmtopdir ? "rmdir" : "del", path);
> ! #endif
>
> !     return !system(buf);
>   }
>
>
>   /*
>    * make a copy of the array of lines, with token replaced by
> replacement
> --- 252,349 ----
>   static bool
>   rmtree(char *path, bool rmtopdir)
>   {
> !     char        filepath[MAXPGPATH];
> !     DIR           *dir;
> !     struct dirent *file;
> !     char      **filenames;
> !     char      **filename;
> !     int            numnames = 0;
> !     struct stat statbuf;
>
> !     /*
> !      * we copy all the names out of the directory before we start
> modifying
> !      * it.
> !      *
> !      */
> !
> !     dir = opendir(path);
> !     if (dir == NULL)
> !         return false;
>
> !     while ((file = readdir(dir)) != NULL)
> !     {
> !         if (strcmp(file->d_name, ".") != 0 &&
> strcmp(file->d_name, "..") != 0)
> !             numnames++;
> !     }
> !
> !     rewinddir(dir);
> !
> !     filenames = xmalloc((numnames + 2) * sizeof(char *));
> !     numnames = 0;
> !
> !     while ((file = readdir(dir)) != NULL)
> !     {
> !         if (strcmp(file->d_name, ".") != 0 &&
> strcmp(file->d_name, "..") != 0)
> !             filenames[numnames++] = xstrdup(file->d_name);
> !     }
> !
> !     filenames[numnames] = NULL;
> !
> !     closedir(dir);
> !
> !     /* now we have the names we can start removing things */
> !
> !     for (filename = filenames; *filename; filename++)
> !     {
> !         snprintf(filepath, MAXPGPATH, "%s/%s", path, *filename);
> !
> !         if (stat(filepath, &statbuf) != 0)
> !             return false;
> !
> !         if (S_ISDIR(statbuf.st_mode))
> !         {
> !             /* call ourselves recursively for a directory */
> !             if (!rmtree(filepath, true))
> !                 return false;
> !         }
> !         else
> !         {
> !             if (init_unlink(filepath) != 0)
> !                 return false;
> !         }
> !     }
> !
> !     if (rmtopdir)
> !     {
> !         if (rmdir(path) != 0)
> !             return false;
> !     }
> !
> !     return true;
>   }
>
> + #ifdef WIN32
> +
> + /* workaround for win32 unlink bug, not using logging like in
> port/dirmod.c */
> +
> + /* make sure we call the real unlink from MSVCRT */
> +
> + #ifdef unlink
> + #undef unlink
> + #endif
> +
> + static int
> + init_unlink(const char *path)
> + {
> +     while (unlink(path))
> +     {
> +         if (errno != EACCES)
> +             return -1;
> +         Sleep(100);             /* ms */
> +     }
> +     return 0;
> + }
> + #endif   /* WIN32 */
>
>   /*
>    * make a copy of the array of lines, with token replaced by
> replacement
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
>                http://archives.postgresql.org

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: Compiling libpq with VisualC
Next
From: Bruce Momjian
Date:
Subject: Re: eventlog fix