Bug #31164 Solaris 10 postinstall script fails to create system tables
Submitted: 24 Sep 2007 3:30 Modified: 26 Feb 2009 18:37
Reporter: Stian Oksavik Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Packaging Severity:S2 (Serious)
Version:5.0.45, 5.0.51a, 5.0.56 OS:Solaris (64-bit sparc pkg)
Assigned to: Jonathan Perkin CPU Architecture:Any
Tags: Contribution, pkgadd, postinstall
Triage: Triaged: D3 (Medium) / R2 (Low) / E2 (Low)

[24 Sep 2007 3:30] Stian Oksavik
Description:
When installing the Solaris package using pkgadd (tested on a Solaris 10/sparc64 system in the global zone), the install succeeds, but the postinstall script fails, apparently due to an inability to write to a temporary directory in /var/tmp:

ERROR: 1004  Can't create file '/var/tmp//install31aW6L/#sql4bed_1_0.frm' (errno: 13)

According to /usr/include/sys/errno.h, error 13 means:
#define EACCES  13      /* Permission denied                    */

This failure results in the mysql_install_db script not being executed properly, which in turn means system tables do not get created. When I connected to the resulting mysqld using --skip-grant-tables, both the mysql and test databases were completely empty -- no tables.

How to repeat:
root@peterbilt# pkgadd -d /lusr/software/mysql/mysql-5.0.45-solaris10-sparc-64bit.pkg 

The following packages are available:
  1  mysql     MySQL Community Server (GPL)
               (sun4u) 5.0.45

Select package(s) you wish to process (or 'all' to process
all packages). (default: all) [?,??,q]: 

Processing package instance <mysql> from </lusr/software/mysql/mysql-5.0.45-solaris10-sparc-64bit.pkg>

MySQL Community Server (GPL)(sun4u) 5.0.45
Copyright (C) 2000-2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
Using </opt/mysql> as the package base directory.
## Processing package information.
## Processing system information.
   3 package pathnames are already properly installed.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

This package contains scripts which will be executed with super-user
permission during the process of installing this package.

Do you want to continue with the installation of <mysql> [y,n,?] y

Installing MySQL Community Server (GPL) as <mysql>

## Installing part 1 of 1.

<list of files omitted>

[ verifying class <none> ]
## Executing postinstall script.
ERROR: 1004  Can't create file '/var/tmp//install31aW6L/#sql4bed_1_0.frm' (errno: 13)
070923 21:10:18 [ERROR] Aborting

070923 21:10:18 [Note] /opt/mysql/mysql/bin/mysqld: Shutdown complete

Installation of system tables failed!

Examine the logs in /var/lib/mysql for more information.
You can try to start the mysqld daemon with:
/opt/mysql/mysql/bin/mysqld --skip-grant &
and use the command line tool
/opt/mysql/mysql/bin/mysql to connect to the mysql
database and look at the grant tables:

shell> /opt/mysql/mysql/bin/mysql -u root mysql
mysql> show tables

Try 'mysqld --help' if you have problems with paths. Using --log
gives you a log in /var/lib/mysql that may be helpful.

The latest information about MySQL is available on the web at
http://www.mysql.com
Please consult the MySQL manual section: 'Problems running mysql_install_db',
and the manual section that describes problems on your OS.
Another information source is the MySQL email archive.
Please check all of the above before mailing us!
And if you do mail us, you MUST use the ./bin/mysqlbug script!

Installation of <mysql> was successful.

Suggested fix:
One possible reason why the permission denied error would occur is if the pkgadd mechanism fails to create the parent directory. I have not yet found where in the postinstall script this gets created. I also tried running the mysql_install_db script manually, which also failed to create the system tables.

While I'm not certain exactly where the bug occurs, it does seem to be a packaging problem. I'll be attempt to install from source and see if that succeeds.
[26 Sep 2007 9:02] Valeriy Kravchuk
Sorry, but I was not able to repeat the behaviour described on our Solaris 10 box:

...
## Executing postinstall script.
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/opt/mysql/mysql/bin/mysqladmin -u root password 'new-password'
/opt/mysql/mysql/bin/mysqladmin -u root -h sol10-sparc-c password 'new-password'
See the manual for more instructions.
Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at
http://www.mysql.com
Support MySQL by buying support/licenses at http://shop.mysql.com

Installation of <mysql> was successful.
-bash-3.00$ uname -a
SunOS sol10-sparc-c 5.10 Generic_118833-33 sun4u sparc SUNW,Sun-Fire-V245
-bash-3.00$ ls -F /var/tmp
dstreAAARlaWCk/     dstreAAAsyaaDk/     gconfd-root/        orbit-root/
dstreAAAgWaOQX/     gconfd-hfisk/       orbit-hfisk/        sh-thd-1184132364
-bash-3.00$ pkginfo | grep mysql
system      SUNWmysqlr                       mysql - MySQL Database Management System (root component)
system      SUNWmysqlt                       mysql - MySQL Database Management System (test component)
system      SUNWmysqlu                       mysql - MySQL Database Management System (usr component)
application mysql                            MySQL Community Server (GPL)
-bash-3.00$ pkginfo -l mysql
   PKGINST:  mysql
      NAME:  MySQL Community Server (GPL)
  CATEGORY:  application
      ARCH:  sun4u
   VERSION:  5.0.45
   BASEDIR:  /opt/mysql
    VENDOR:  MySQL AB
    PSTAMP:  MySQL AB Build Engineers
  INSTDATE:  Sep 26 2007 10:57
     EMAIL:  build@mysql.com
    STATUS:  completely installed
     FILES:     2355 installed pathnames
                  85 directories
                 181 executables
              395539 blocks used (approx)
[26 Sep 2007 9:05] Stian Oksavik
If you wish, I'd be happy to grant access to the Solaris box on which I encountered the problem.
[28 Sep 2007 3:14] Quentin Narferao
I too can confirm this error on Solaris 10 SPARC 08/07. Installing the 32 bit sparc package produces the same error.

# pkgadd -G -d mysql-5.0.45-solaris10-sparc.pkg              

The following packages are available:
  1  mysql     MySQL Community Server (GPL)
               (sun4u) 5.0.45

Select package(s) you wish to process (or 'all' to process
all packages). (default: all) [?,??,q]: 

Processing package instance <mysql> from </<path>/mysql-5.0.45-solaris10-sparc.pkg>

MySQL Community Server (GPL)(sun4u) 5.0.45
Copyright (C) 2000-2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

The selected base directory </opt/mysql> must exist before
installation is attempted.

Do you want this directory created now [y,n,?,q] y
Using </opt/mysql> as the package base directory.
## Processing package information.
## Processing system information.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

This package contains scripts which will be executed with super-user
permission during the process of installing this package.

Do you want to continue with the installation of <mysql> [y,n,?] y

Installing MySQL Community Server (GPL) as <mysql>

## Installing part 1 of 1.

<files>

[ verifying class <none> ]
## Executing postinstall script.
ERROR: 1004  Can't create file '/var/tmp//installHraa6n/#sql1be7_1_0.frm' (errno: 13)
070927 21:01:13 [ERROR] Aborting

070927 21:01:13 [Note] /opt/mysql/mysql/bin/mysqld: Shutdown complete

Installation of system tables failed!

Examine the logs in /var/lib/mysql for more information.
You can try to start the mysqld daemon with:
/opt/mysql/mysql/bin/mysqld --skip-grant &
and use the command line tool
/opt/mysql/mysql/bin/mysql to connect to the mysql
database and look at the grant tables:

shell> /opt/mysql/mysql/bin/mysql -u root mysql
mysql> show tables

Try 'mysqld --help' if you have problems with paths. Using --log
gives you a log in /var/lib/mysql that may be helpful.

The latest information about MySQL is available on the web at
http://www.mysql.com
Please consult the MySQL manual section: 'Problems running mysql_install_db',
and the manual section that describes problems on your OS.
Another information source is the MySQL email archive.
Please check all of the above before mailing us!
And if you do mail us, you MUST use the ./bin/mysqlbug script!

Installation of <mysql> was successful.
[3 Oct 2007 12:29] S L
I too received the same type of error on Solaris 10 x86

## Executing postinstall script.
ERROR: 1004  Can't create file '/var/tmp//installmgaW9c/#sql609_1_0.frm' (errno: 13)
071003  8:30:37 [ERROR] Aborting
[9 Oct 2007 18:29] Jonathan Perkin
This appears to be a Solaris bug in pkgadd(1M), present in either Solaris 10 Update 4, or Update 3 systems patched with 119255-42.

I've yet to narrow the patch revision further to see which fix caused the problem, but the problem is:

  - mysqld uses the TMPDIR variable, if set in the environment, for the directory where it creates temporary tables, such as those in the scripts used by mysql_install_db.  If this variable is unset, it uses the system defaults, usually /var/tmp, which point to a world-writeable directory.
  - we specify --user=mysql in mysql_install_db to ensure the datadir is created with the correct permissions, so mysqld tries to create the temporary table files as this user.

However, it appears that the versions of Solaris mentioned above alter the $TMPDIR variable internally, pointing it at the root-owned, non-world-writeable temporary package installation directory used by pkgadd, and this is passed to the postinstall script.  As a result, mysqld tries to write as the mysql user to this directory and fails, causing the errors shown in the reports.

I would be interested to find out if any other combinations of Solaris versions hit this issue too so that I can narrow down further in reporting the bug to Sun.

For now, workarounds include:

  - using pkgtrans(1) to modify the MySQL package, and insert 'unset TMPDIR' in the postinstall script
  - chmod 777 the installation directory while the package is installing (when it asks questions is a good time), this will likely be /var/tmp/install* followed by a random string created by mktemp(1)
  - let the package install, then re-run mysql_install_db using "--user=mysql --basedir=/opt/mysql/mysql --datadir=/var/lib/mysql", although I have not yet verified that the system table creation is the only thing broken with this TMPDIR issue.
[26 Oct 2007 2:21] Karl Bunch
Same here on: SunOS 5.10 Generic_127112-01 i86pc i386 i86pc

64bit version. Workaround, window 1:

cd /var/tmp
while :
do
chmod 777 install*
sleep 1
done

window 2: pkgadd ... 

:-)  Worked like a charm.
[27 Nov 2007 18:50] Stian Oksavik
The workaround works (thanks) but the proposed fix above does not appear to have been added to the MySQL 5.1.22 release candidate. Will this be added in the final version?
[28 Nov 2007 12:28] Jonathan Perkin
No, unfortunately none of the workarounds are suitable for inclusion into the packages.  They either introduce security issues or have the potential to break configurations the administrator has set.  As such they are included here only for users to pick one which is suitable for their policies and use it.

The only legitimate fix is for Sun to fix pkgadd(1M).  I submitted a bug report to them but this does not appear to be registered in their bug database so I will try again.  Until then, my best recommendation is to revert patch 119255 on your system back to a working pkgadd.

I am hoping to narrow down this issue further so that we can properly document this issue for our users in the release notes.
[29 Dec 2007 22:32] Stephen Boyd
Same issue, using Solaris Nevada build 74 (basically, the kernel at opensolaris.org.) . You might put a bug in at opensolaris.org against pkgadd and try and get it fixed there; fixes like this in Nevada (the OpenSolaris code base) tend to perk back into Solaris 10, too.
[29 Dec 2007 22:45] Stephen Boyd
Also note that (since I just hit this) pkgtransing the archive, and changing the postinstall script "corrupts" the postinstall script from the package's point of view; you need to also cksum the new postinstall file, then  edit the pkgmap file in the base directory of the package and update the checksum and filesize for postinstall. 

If I had the package downloaded from mysql in /tmp:
#cd /tmp

#pkgtrans mysql-5.0.45.pkg .
#cd /tmp/mysql/install
#vi postinstall
(make change, save & exit postinstall)
#cksum postinstall
1857056391      2633    postinstall
#sum postinstall 
15526 6 postinstall
#cd /tmp/mysql
#grep postinstall pkgmap
1 i postinstall 2620 14439 1183565790
#vi pkgmap
(replace postinstall line with)
1 i postinstall 2633 15526 1857056391

where the 4th field is the file size, the 5th is the output from sum, and the 6th is the output from cksum. 

After doing all that, it works as expected:

(file installs which worked before) 
## Executing postinstall script.
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/opt/mysql/mysql/bin/mysqladmin -u root password 'new-password'
/opt/mysql/mysql/bin/mysqladmin -u root -h falcon password 'new-password'
See the manual for more instructions.
Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at
http://www.mysql.com
Support MySQL by buying support/licenses at http://shop.mysql.com

Installation of <mysql> was successful.
bash-3.2#
[1 Feb 2008 20:02] Matt Fioravante
I ran into this same problem when I was creating my own mysql package.

One workaround is in the postinstall script, find the line that runs the mysql_install_db command and change it like so. Substitue prefix for wherever mysql is installed.

TMPDIR=/var/tmp /bin/bash <prefix>/mysql_install_db

I also set it to use bash because the script is written to run with /bin/sh, which complains about !: command not found

/bin/sh on solaris does not like lines like this in the install_db script:
if ! test -x ....
[4 Feb 2008 10:09] Jonathan Perkin
Yep, that workaround will also work, but is unsuitable for inclusion into our package as the admin may explicitly not want to use /var/tmp on their system for TMPDIR.

The shell syntax has since been fixed in newer versions of mysql_install_db so will run fine with Solaris /bin/sh.
[11 Mar 2008 15:06] Yoni Girard
_ "pkgadd -d mysql-5.0.51a-solaris10-sparc-64bit.pkg"

After the installation, do the folowing:

_ "rm /var/lib/mysql/mysql".
_ edit the script /opt/mysql/mysql/scripts/mysql_install_db to run ksh instead of sh.
_ "/opt/mysql/mysql/scripts/mysql_install_db --user=mysql".
_ "/opt/mysql/mysql/bin/mysqld --user=mysql --datadir=/var/lib/mysql &"
_ "mysqladmin -u root password your_new_password".

Ready to play!
[15 May 2008 18:12] Sveta Smirnova
Bug #35778 was marked as duplicate of this one.
[20 May 2008 9:56] moises alonso
This same problem happens with OpenSolaris 1.0 (bash-3.2# uname -a
SunOS acero 5.11 snv_86 i86pc i386 i86pc ) 
, but the do while loop workaround worked like a charm!
[24 Jul 2008 19:59] Hugh sutton-gee
I am still hitting this error with:

mysql 5.0.51a + Solaris 10 5/08 s10x_u5wos_10 X86 (5.10 Generic_127128-11 i86pc i386 i86pc)
[3 Sep 2008 8:28] Sam Sexton
I hit the same problem while installing 5.0.67 on Solaris 10 08/07:

SunOS ntm-igdev02 5.10 Generic_137111-05 sun4v sparc SUNW,SPARC-Enterprise-T5120

Patch 119255 is not applied.

Sam Sexton
[11 Sep 2008 9:30] Valeriy Kravchuk
Bug #39383 was marked as a duplicate of this one.
[3 Oct 2008 18:10] Ben Hekster
I may have a solution for you that is acceptable.  Inside your postinstall script, simply create a subdirectory inside TMPDIR which is owned by MySQL:

TMPDIR=$TMPDIR/mysql.$$
export TMPDIR
mkdir $TMPDIR
chown mysql:mysql $TMPDIR

Now, the mysql_install_db works.  This works no matter what TMPDIR is, or whether it was or was not modified by 'pkgadd'.
[28 Nov 2008 1:19] Mikiya Okuno
Hi Jonathan,

The problem seems that mysql_install_db is executed using mysql user or by specifying --user option for that command. Why don't you let root user to execute mysql_install_db command and change owner afterward?

shell> mysql_install_db --datadir=$DATADIR

This command will work anyway if the current user is root. After executing this command, change the owner for the data directory.

shell> chown -R mysql:mysql $DATADIR

This fix doesn't require any intervention against tmpdir.
[1 Dec 2008 16:39] Jonathan Perkin
Thanks Ben, that could be a legitimate workaround.  I've implemented it internally and will run some tests to ensure it doesn't break anything.

Mikiya, I think your solution could also be legitimate, but my only concern is that the install-then-chown method breaks if using a custom my.cnf with e.g. log-bin set to an alternate location.  This shouldn't be the case during pkgadd but there may be a corner case I haven't thought of.
[3 Dec 2008 11:38] Adam Thompson
Not sure if this is entirely the same bug or not... I ran into the same TMPFILE creation problem as mentioned above, but then I also experienced what may be a different bug in mysql_install_db and mysql_secure_installation:

mysql_install_db fails to populate the grant tables!  It creates them but does not fill them.  Line 347 of /opt/mysql/mysql/scripts/mysql_install_db reads:

        if { echo "use mysql;"; cat $create_system_tables $fill_system_tables; } | eval "$filter_cmd_line" | $mysqld_install_cmd_line > /dev/null

I've found that if I run this script under Solaris /sbin/sh (/bin/sh is a symlink to /sbin/sh) then the script fails.  If I run it under /usr/sfw/bin/bash, it works fine.  I believe I also tested it under /bin/ksh but I'm not 100% certain now - been banging my head against this wall for several hours now.

The script /opt/mysql/mysql/mysql_secure_installation seems to suffer from the same problem - I didn't bother isolating it beyond the fact that running under ANY other shell seemed to work fine.
-Adam Thompson <athompso@athompso.net>
[13 Jan 2009 15:01] Giuseppe Maxia
Verified again on OpenSolaris 2008-11 with MySQL 5.1.30.
The installation creates an empty user.MYD file.
[13 Jan 2009 19:47] Adam Thompson
I strongly believe there are/were two different bugs here:
 1. TMPFILE creation permission problem
 2. shell syntax problem

Solaris /bin/sh has varied greatly in performance, conformance and features over the years.  While I haven't tested a Community build in the last 5 minutes, I recall that I had the shell syntax issue even when building from source!
One contributor here ([1 Feb 2008 21:02] Matt Fioravante) mentioned the "!" syntax problem, I documented another.
IMHO it's fair to say that on Solaris 10 and up, /bin/sh is not sufficient to run your scripts.  Which is pathetic, yes, but a fairly simple test a the top of the script to see if it can re-exec itself under /bin/ksh would suffice to protect us from brain-dead shells.
I'm curious why this hasn't come up on some other OSes, like Gentoo Linux, which links /bin/ash to /bin/sh - and is truly one of the dumbest and most featureless Bourne-style shells I've ever seen..
[13 Jan 2009 22:17] Jonathan Perkin
No, the shell syntax problem was a very simple fix and was solved many months ago.

As for the TMPDIR issue, I have fixed the problem in MySQL 6.0.9-alpha and, assuming there are no issues with it, it will also be available in the next 5.0 and 5.1 releases.
[26 Feb 2009 15:15] Jonathan Perkin
This has been fixed in 5.0.78, 5.1.32 and 6.0.9-alpha.
[26 Feb 2009 18:37] Paul Dubois
Noted in 5.0.78, 5.1.32, 6.0.9 changelogs.

For Solaris package installation using pkgadd, the postinstall script
failed, causing the system tables in the mysql database not to be
created.