Recently we have been hit with a new error in our multi platform builds with files stored on NAS - different build commands could fail on Unix with "not owner" error message. At first it was Solaris linker: "ild: Not owner: chmod() failed for file ...", then we switched to another machine and got:
java.io.IOException: java.io.IOException: Not owner at java.io.UnixFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:883) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
And there were no obvious changes in the build that could cause it. So we set together with IT and tried to diagnose the problem. What was even more surprising, the same commands could sometimes succeed when executed manually. After few attempts (the whole process took few hours) we found that we cannot change a permission on just created folders. Even "truss" was showing EPERM error code. When waited for about few (<30) seconds the same chmod would succeed. We tried Solaris 10 and Linux with the same result. At least we got something easily reproducible.
So the working theory became that NAS assigns some different permissions to just created folders and then changes them to correct permissions later. To remove NIS server out of the picture we tried a local account and got just created directory owned by root(!). Of cause after that chmod failed with the same "Not owner" error. We went back and forth thinking why it happened and decided that the test did not show what we needed - it is possible that NAS did not know the account and use the account we use for mount.
Google suggested changing directory permissions to 777 and it, of cause, worked. Unfortunately, sticky bits and umask did not seem working on NAS, so all new folders were created with 755 permissions. After few more experiments and cups of coffee we noticed that the build root directory is owned by root. That was odd.
And we changed its ownership to the correct account and group. We also changed its permission to 777. And it helped. It looks like our NAS uses the parent folder for initial ownership settings and then changes it to the correct once and uses parent directory permissions as-is. Now initial owner became correct (or 777 helped) and the builds are running correctly. I will try to set the builds root folder permissions to 755 to actually see what change fixed the build, but not now - now we need the builds working.
I have had a problem that Google did not have an answer for - how to search for an attribute value, if the attribute name is not case sensitive? Usually the situation arises when the original file is not case sensitive (for example, HTML files are not). In my situation the XML was processed by another code that treated it in a case-insensitive way. Surprisingly the only good answer in Google I got that XML is case sensitive and live with it. After reading that I was about to replace one search with two searches using two different cases that can actually happen in my files, but decided to look further, if it is a possible to write a condition with a node name. Of cause there was - name() function returns the current node name and it can be tested. Surprise, surprise, the query did not work at first - I used '=='instead of '=', but eventually I got it right. This is it:
/Path/To/element/@*[translate(name(), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='UPPERCASE_ATTR_NAME']
While our installer developer was busy on another project, I created a simple patch installer with WIX that just places few assemblies with their policies into GAC. It required some tweaking. My first approach of reading instructions only after all other possibilities failed did not really work. There was one positive outcome - Wix 2.0 was unusable (what is up with 8.3 names!?). I wonder how other people are using it. So I quickly downloaded Wix 3.0 beta and decided to use VisualStudio integration to create my installer. VisualStudio helped a little, but soon I was back editing the file in UltraEdit. After few minutes the installer was ready and it was installing the patch without any user interaction. That was the problem - I needed a question "do you really want to install this thing or you clicked on it by mistake?". Fortunately there were pre-built UIs and I selected WixUI_Minimal. Again it worked great, but what is up with EULA? I did not need it for a patch installer. Searching on internet did not return anything useful besides putting a readme instead of a licence. There were comments about changing standard UIs, so I downloaded WIX sources and started tweaking. Simple replacing WelcomeEulaDlg with WilcomeDlg did not work - there were messages about "next" button left without any action, but what is the "install" action? After few tries I broke my perfectly working installer into something unusable. Fortunately I foresaw that problem and put the script into ClearCase to be able to track my progress. I restored the last working revision and started gradually copying pre-built UI out of WixUI_Minimal into my script. First the UI itself, then the WelcomeEulaDlg. After each iteration I checked that the installer was still working. The last step was to update the dialog with content similar to WelcomeDlg dialog. The whole process actually was a trivial task. By the end the installer worked correctly without any funny EULA business.
This is what I have right now. I guess it can be cleaned up a little, but it should be done with care, each time checking that the installer is still working, so I am not going to do it now:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="...." Name="... HotFix 3" Language="1033" Version="3.1.0.3" Manufacturer="..." UpgradeCode="...">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="hotfix3.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="hotfix3">
<Component Id="....dll" Guid="..." DiskId="1" Feature="ProductFeature">
....
</Component>
...
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="Hotfix 3" Level="1">
</Feature>
<Property Id="WIXUI_INSTALLDIR" Value="TARGETDIR" />
<UI>
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="Minimal" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" />
<Dialog Id="WelcomeEulaDlg2" Width="370" Height="270" Title="!(loc.WelcomeEulaDlg_Title)">
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeEulaDlgBitmap)" />
<Control Id="Description" Type="Text" X="135" Y="80" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
<Control Id="Install" Type="PushButton" ElevationShield="yes" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WelcomeEulaDlgInstall)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
<Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
</Control>
<Control Id="InstallNoShield" Type="PushButton" ElevationShield="no" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WelcomeEulaDlgInstall)" Hidden="yes">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
<Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgTitle)" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
</Dialog>
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
<Property Id="ARPNOMODIFY" Value="1" />
</UI>
<InstallUISequence>
<Show Dialog="WelcomeEulaDlg2" Before="ProgressDlg">NOT Installed</Show>
</InstallUISequence>
<UIRef Id="WixUI_Common" />
</Product>
</Wix>
My primary GMail account gets very little SPAM and 99% of it is caught. I guess the spammers know that it does not make sense to spam it. So I decided to make an experiment and forwarded all my home emails to an another GMail account. At first GMail decided that most of newsletters I get is a spam (I guess many people are marking them as such instead of unsubscribing), but after writing few filters with disabled SPAM checks the things worked well. Google keeps spam messages for 30 days and now, after a month, I have the number - total 40K spam messages.
We were already running SpamAssassin on our server, so effectively I use GMail to weed extra 100 messages per day that SpamAssassin does not catch. In addition Thunderbird rules were automatically moving expected emails into subfolders, so I just had to delete [almost] all messages from inbox. I was not in a bad shape before, but now it is much better. However I wonder, how "normal" people live with it...
Unlike our previous trip there, this Saturday we were prepared. I would say even over-prepared. Last time we were driving FWD Honda CRV and had to turn back few miles east from Bowman Lake. This time we were driving real 4x4 SUV, had GPS, during daylight, together with a friend on another real SUV, and, just in case, had a strong rope...
In the morning I found a relatively inexpensive gas station in Sacramento 73 miles from home. I always like to have an almost full tank before going into woods. Car's computer also told me that there is enough gasoline for 73 miles. That was not risky - for some reason the computer believes that the tank is 2 gallons less than it is actually and we already drove several times past "0 miles" when even analog gauge showed negative gasoline level. By the time I got to the gas station, the computer still reported about 20 miles left in the tank and we pumped only 20 gallons. I wonder what my car thinks about our usual way of driving... We met with Eugene and his son Gena and continued on the path.
Driving up on highway 80 was fun, except for few slow vehicles. I was surprised to see a Prius driving together with us. We turned on highway 20 and then took Bowman Lake Road. We stopped at Jordan Creek and jumped on the rocks. There was a lot of people swimming, but we did not take our swim suits. Regardless Katya swam in the creek far from the people.
At first Bowman Lake Road was fine, then it became a 1.5 lane paved road and then the pavement ended. It looked worse than the previous time we were there, but maybe I was driving slower on CRV. It was interesting to drive on a single lane road with a cliff on one side and a possibility that another car can be driving towards you. A recent fire was still smoking near the road. There is a shortage of water in California this year and Bowman Lake, being actually a reservoir, was about 15 meters lower than the maximum level. The weather was about 22 C and the water was not comfortable. It did not stop Katya from diving. Being a young man, Gene had to swim too. Then that my wife went swimming. After that me and Eugene had to go swimming too...
After a small picnic, we prepared to go further. However the road was fixed and the drive was uneventful. We went to Truckee. Eugene and Gene went home. We stayed, ate a pizza and decided to take Donner Pass Road back. We stopped on the vista. There was so much smoke in the air, Donner Lake was almost invisible. We looked at artificial railroad tunnel - a train track covered in concrete and noticed cars driving there. Obviously the tacks were removed there and we decided to go there too. We drove into two first tunnels, but they were narrow for just a single can to pass. The big tunnel was wider, but we decided not to go there yet. Maybe next time.
Ever wondered if your policy assemblies work?
.Net assemblies remember what versions of referenced assemblies they were built with. In general it is a good thing, but it creates its own problems when building a product that consists of many separate parts. In the interest of QA we often build mismatched package builds with some of the application products built with earlier versions of core libraries. Fortunately our build scripts (directly from VisualStudio) generate all necessary policy assemblies for previous and the current releases and installer puts them into GAC.
At first there were rumors that one of applications (developed in a different office and built on its own schedule) does not start in mismatched builds. In the beginning the warnings were dismissed because the APIs were not stable, but later it became apparent that something is wrong. And finally the problem came to me...
After enabling assembly loader log, it showed that policy assembly was recognized and the redirect actually happened, but the target assembly was not found even it was right there in the GAC. However there was a message that the platform was locked to the policy assembly platform. This particular assembly had native DLLs attached to it, so its platform was not a generic "MSIL", but "x86" and this is why it could not be found.
To test this idea I regenerated policy file with matching platform, but how to install it into GAC? Removing old policy was not possible - it was locked by installer. Fortunately Cygwin`s Midnight Commander sees real file system and ignores all Microsoft crap and I was able to remove the assembly directly from hard drive and install a new one into GAC. And it helped - the application started and worked without problems.
The policy generation (and some other "black magic" staff, including support for linked resources) is done via an include in our project files and is a part of another utility project. After that project rebuild, our automatic build picked it up and certified all dependent projects to pass unit tests. Now all our policy assembly platform match their assembly's platform and everything quiet in our kingdom.
Being a mathematician (and a little bit a physicist) I always felt something is wrong with hydrogen cars idea. Besides the promise of higher cruising range, each additional transformation reduces overall efficiency factor causing even more energy to be used per unit of work (or per mile). I would prefer that all that money would be used on development of better batteries, so cars could drive about 400 miles without recharging.
The idea of using VMWare to save energy is somewhat similar - reducing overall computer efficiency to be able to pack more services on less hardware. Lets review theoretical benefits of computer virtualization:
And the cost - less VM performance.
However, if you look closer at the benefits, you will notice they are similar to benefits of Java. Instead of virtualizing the whole OS, Java virtualizes just processes while generating code that executes close to native speeds (sometimes faster, sometimes slower, depending on what you are doing) and Java code has much better portability between computers with different architectures. I know it first hand - after we moved some parts of our build processes from slow Windows VMs to a single Solaris box, we saved hours!
So what is the conclusion - use Java to save energy and adding one more level of indirection is usually not the best solution.
Today I was fixing few Windows forms. There few problems that usually should be easy to fix. However in this case none of direct approaches worked. After few attempts I found that there is a logic in a form Closing event, also in OnHandleDescroyed(). As if it was not enough, there was a secret order of calls to initialize the form. After direct approach failed, I reverted all changes and started refactoring the code to simplify internal relations, move code out of the form into custom controls... At the end the all main problems were fixed and I am preaching everybody not to program like that.
Instead of camping we went today to Muir Woods. Yesterday we have friends visiting us, so we could not go camping. Maybe it is better this way - the weather was quite cold - about 4°C. Just walking in Muir Woods is not for us - instead I with kids went on Sierra Trail down to Alice Eastwood Campground. When we came there I thought that again I did not bring any fire with me. Surprisingly, there was not a fully extinguished fire place with a lot of food and boxes thrown around. The food looked like it was spread by some animals, making the date of the fire a day before! I am bewildered by the way people do not follow simple rules with fires in the forest. Last autumn, we had a similar situation in a campground on NF-11N46 at US-50 highway near Kyburz. In any case, it was beneficial for us - we just put few empty paper boxes in a fire place and watched great fire. There was a water facet few meters away, so we watered it down at the end until there were no hot spots.
In the meantime, my wife parked the car near Muir Woods entrance (it was lucky to park so close to the entrance!) and met us at the campground. Then we took Fern Creek into Muir Woods. Kids are getting better with hiking. Maxim walked all the way and even had some strength left for evening tennis.
Next time We will try Bootjack Trail. Actually each time we wanted to go there, but my GPS does not show trails, so we chose one available trail after another. Now I printed a map....
My mother called telling that my photo server is not available any more. It looks like one of versions of mythweb broke my web server. Apache stopped running with error that "setenv" is not a valid command mythweb.conf file. After removing the package, Apache is working fine. I wonder what other unused junk should I remove...
:: Next Page >>
| Next >
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| << < | ||||||
| 1 | 1 | 2 | 3 | 4 | 5 | 6 |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | ||||