Wednesday, September 30, 2015

Store Relative Paths if Possible

Semi-recently, I was working with a program that managed many files as part of a project. I was collaborating on this project, so I placed the project folder and all of its files in a shared Dropbox folder. However, there was a problem - the program could not open the project file on any other computer because it stored absolute paths to the files it depended on. I was able to work around it; because the program ran under DOSBox, changing the drive and folder structure to be the same everywhere was not too difficult.

That experience was rather inconvenient, and I wish more programs that reference multiple files in a binder of some sort would make an effort to store only relative paths. That way, people can collaborate more easily, and the project can be moved around on the same computer (or backed up) without problems. Optimally, warnings should be produced if the user adds files to the project that are not in the project's root directory or a subdirectory thereof.

Monday, September 28, 2015

When Context Menus Open Slow

On several otherwise-fast Windows computers, I have noticed a delay of one or two whole seconds between when I right-click the desktop or a folder and when the context menu appears. Though two seconds might not sound like a lot, it really throws me off when something that should be instantaneous takes any noticeable amount of time.

The culprit for the slowness is virtually always the same: one of the entries is added by a program that takes a while to initialize. That misbehaving program is almost always a management application for graphics drivers, and the reason for its slowness is almost always that it is written for a high-impact framework like Java or .NET.

Relevant: Is it okay to write in-process shell extensions in managed code?

The AMD Catalyst Center is notorious for creating context menu slowness, but I've experienced it with nVidia's equivalent. Incidentally, I have never once wanted to use the context menu item that brings up graphics card settings, and I certainly don't need it there whenever I right-click any folder ever.

Uninstalling the management program (but not the drivers!) will add speed to context menus.

Sunday, September 27, 2015

Checking Whether a Dependency is Available in .NET

It may be desirable to have a .NET program that can use a library but can also function without it. Such programs are made slightly difficult to write by the fact that .NET assemblies must produce a list at compile-time of what other assemblies they depend upon. If one of those assemblies cannot be loaded at run-time, problems occur.

Fortunately, the errors are normal exceptions and can be caught and handled like any other, if you're careful. The exception for a missing dependency will be thrown when a method that references a type in the missing assembly is entered. Therefore, the presence of the optional library can be checked by wrapping in a try/catch block a call to a short method that uses one of the library's types. If the library is missing, an exception will be thrown, but execution can continue as long as you don't call any methods that involve the missing types.

Saturday, September 26, 2015

Office Document Editing "Blocked due to Policy Settings"

Today I received a strange message from Word when I opened an old (Office 95) document. It placed the document in Protected View and said something to the effect of "editing blocked due to policy settings." I had not configured any Local Group Policy settings, and the computer was not joined to a domain, so the word "policy" threw me off a little. I was not super pleased that Word refused to let me edit my document, so I poked around a little and discovered the File Block Settings.

The File Block Settings are a tab of the Trust Center, which is accessible via the Trust Center tab of Word Options. An array of checkboxes controls whether or not Word will enable the editing of certain file types. By default, it seems, Word 95, Word 6.0, and Word 2 documents are uneditable. I'm not sure what makes those versions of Word so dangerous, but unchecking the boxes removes the restriction.

The File Block Settings in Trust Center

Friday, September 25, 2015

Outlook Online's Delayed Send

I just noticed an interesting possible feature of Microsoft Outlook Online that could save somebody some embarrassment. I say "possible" because the following behavior could conceivably be a product of my sometimes-slow Internet connection, but might also be intentional behavior.

I needed to send a short reply to an e-mail, so I typed it up, checked it, and hit Send. Rather than sending the e-mail immediately, Outlook stamped the message with "[Draft]" and produced a Cancel button off to the right. After a few seconds, the unsent-message instrumentation disappeared and my reply was sent.

I can definitely see that feature being helpful if I had clicked the Send button accidentally. Outlook probably looked at the message's length (short) and the time spent composing it (also short) to guess how confident I was about sending it. I was confident that I wanted it sent in that state, but the delay was worthwhile and not onerous.

Thursday, September 24, 2015

What Happened to Outlook Online's Reply Button?

Microsoft seems to be constantly updating Office Online, and that's nice, but one recent change has annoyed me slightly. It appears that Reply is no longer accessible with one click from the normal message view. It used to be right in the menu bar, but that area seems to have been repurposed for navigation and categorization. There is a small drop-down menu off to the right with Reply All as the default, but I almost never want to reply to everybody who received the message. (Bedlam DL3 ahoy!) Pulling that menu down produces Reply as the first option, but using it doesn't make it the default action for the button/menu.

May I have the Reply button easily accessible again, please?

Wednesday, September 23, 2015

Sending Mail from Office 365 via SMTP

Yesterday and today, I grappled with the issue of sending e-mail from an Office 365 account from .NET's SmtpClient. Even though I had provided the correct username/password (I was able to log in manually) and the right host/port (I got them directly from the Outlook Online connection info page), sending messages always failed with an error about an unauthenticated FROM. EnableSsl was, well, enabled, so I was very confused about the authentication error.

It turns out that Office 365 mail servers have a Service Principal Name that must be specified in the TargetName property of the SmtpClient. Specifying that option solved the problem.

client.TargetName = "STARTTLS/smtp.office365.com"

Tuesday, September 22, 2015

Windows 10's Stricter SmartScreen

Today I discovered a rather inconvenient fact about Windows 10 while showing Zhongkey to some people in this year's Chinese class. SmartScreen, the Windows feature that warns users about unknown (i.e. rare and unsigned) apps, now outright refuses to permit such a program to run without administrator approval. That defeats a large part of the purpose of portable software for non-administrative domain users, and I am not a fan.

Fortunately, it can be disabled by administrators in the desktop Control Panel's system settings, just like in Windows 8. See one of many guides to making the change. I think - but am not sure - that the showstoppingness will be suppressed if the zone identifier is removed by pressing Unblock in the downloaded program's property sheet.

Monday, September 21, 2015

Robotics - Planning

Today's robotics meeting was focused on planning out the tasks for each role. Our first meet is in only three weeks, so we don't have a lot of time. Our goal for the meet is just to have a moving robot that can score a few points. Even so, it will take some work to do that.

The coach required that we formulate a plan for the entire season before doing anything at all. We weren't even allowed to organize the space or disassemble last year's robots. Personally, I think that's a mistake - it's not possible to plan an engineering project of this type that far out without being so vague that the plan is reduced to a guideline. Our robot has never been built before. On the plus side, people are gaining experience using the Office Online collaboration suite.

Fulfilling my mentor duties, I talked to both teams about how to arrange a plan, and informed the newbie team of how critical the engineering notebook is to getting awards. I also took some time to get a script for the teams' programmers together that installs the JDK and Android Studio in unattended mode.

Hopefully we can start actually making progress next time.

Sunday, September 20, 2015

.NET ZipFile.ExtractToDirectory Won't Merge With Existing Directories

I'm currently working on a program that deals with ZIP files, and since I'd rather not have to ship a third-party library if I can help it, I'm using .NET 4.5's System.IO.Compression features to manage ZIPs. The only downside that I've found so far is that the ZipFile.ExtractToDirectory method, which takes a ZIP file and unpacks it into the provided directory, refuses to do its work if the provided directory path already exists and has files or folders in it.

That's really inconvenient, because I'd like these ZIPs to merge with my existing file/folder structure. I would extract it to a separate directory and then move that directory onto the existing one, but Directory.Move won't overwrite/merge either. I did find a solution on Stack Overflow (using LINQ's GroupBy), though, so my program is working and I am happy.

Saturday, September 19, 2015

When HP Laptops Fail to Boot and Blink the Caps Lock Key

I was recently asked to service an HP notebook/laptop that refused to do anything at all on boot - absolutely nothing would display on the screen and the hard drive did not spin up. One thing did happen: the Caps Lock key light blinked.

Some research turned up the fact that HP laptops use the Caps Lock key light to indicate problems that stop the boot process. Their troubleshooting document lists the codes and their meanings, which will almost certainly help in problem solving.

Friday, September 18, 2015

Group Policy Management in .NET

Windows Group Policy is a powerful tool, and from time to time I have wanted to manage it with a .NET application rather than through the normal Group Policy Management Console, for automation and such. After some research, I determined that it is really difficult to do anything interesting without the official GPMC. Fortunately, there is an official .NET library called, appropriately if not creatively, the GPMC Class Library. It can legally only be obtained by installing Remote Server Administration Tools and then enabling the Group Policy management features, so it can't be redistributed, but at least it's free.

Thursday, September 17, 2015

Robotics - Obligatory Meta Meeting

Today was the first meeting of my school's two FTC robotics teams, which I am mentoring this year. The challenge/game/ruleset was announced a week or so ago, so the season has officially begun. The purpose of this meeting was to introduce the game to those who hadn't heard about it and inform the new people about important elements of FTC. The coaches have decided to explicitly assign roles to people, which I'm not quite comfortable with, but at least the roles are flexible (i.e. one can work in other areas too). I created a spreadsheet to use for attendance tracking and added it to the SharePoint group.

While the actual team members did the marshmallow challenge team-building exercise, I skimmed the official rule books and authorized the installation of Android Studio on the programmers' laptops. After the exercise, engineering methods such as iteration and prototyping were discussed. Hopefully we can start actually doing things next time.

Tuesday, September 15, 2015

Use the Local Suffix for Windows Domain DNS Names

When a Windows domain is created, two identifiers must be chosen for it: the NetBIOS name (the all-caps thing that goes before the backslash and a user SAM name) and the DNS name (the name that appears when the Ethernet icon is moused over). Neither can be changed after Active Directory Domain Services is set up. The DNS name not only looks like a DNS entry - it really is one, and its subentries are stored in and served from the Windows DNS service, which is required on at least one domain controller in the domain. Pinging the root will probably get you a domain controller.

The convention for Windows domain DNS names is to end them with ".local" rather than with a normal TLD. That is really important when the DNS name you pick is also a real website, say, your company's. If your website is "example.com" and you name your Windows domain "example.com", people will reach your domain controller instead of your public web site when they type that URL into their browsers. That's because the DNS servers in your network take priority over the ones on the Internet (to which your domain controller forwards non-local requests). You should have used "example.local".

One might try to fix the problem by manually adding an entry for the root of your domain that points to the public web site. That will appear to fix the problem, but it will be very bad for name resolution inside your network. Looking up "localmachine.example.com" will fail because localmachine is not a subdomain of the public example.com. If you try this "fix", you'll only be able to use NetBIOS name lookup, which is severely suboptimal, and some programs will break anyway. Kerberos, the Windows network authentication/encryption protocol requires a functional DNS infrastructure.

To recap: once you set up your domain, there's no going back on the name. Use a local suffix, or at least make sure you're not overriding a real Internet site.

Monday, September 14, 2015

Gash - More CGA Insight

Yesterday while using Gash (well, FMod's NextGenGraphics class) to inspect the CGAGRAPH from the Keen 5 CGA edition, I discovered a little more information about the difference between the CGA and EGA editions.

First and most obviously, there are two fewer chunks in CGAHEAD than EGAHEAD. A quick inspection of the chunk lengths revealed that the two 32KB B800 texts were right next to each other rather than spaced by the two Terminator-style texts. That makes sense, considering that smooth scrolling is impossible in CGA and therefore the CGA editions do not display the scrolling Terminator-style intro, so they have no need for the texts that represent them.

I suppose there were no placeholder chunks because the missing ones are very close to the end of the array; shifting the ones that follow down two isn't hard to work around. (It's just the universe-exploding screen and the five demos at the end.) Compare that with the missing font in CGA, which is replaced with a small unused picture so that the entire array isn't shifted.

Saturday, September 12, 2015

ActiveNav Scripting and Transcripting

Previously in this miniature series on the yet-unreleased ActiveNav tool, I mentioned "auto commands" and "transcripts." Those concepts are only tangentially related to each other, but they are both very simple, so I will cover them both in one post.

Passing a command-line parameter to ActiveNav will cause it to read commands as lines from that file and put them in the auto-command queue. That's the same queue that is accessible from ActiveNav extensions via IActiveNav.PushCommand. Therefore, each line in the script file will be executed before the user has a chance to type anything. I've found it very useful for my bind command.

Passing two command-line parameters results in the first being used as a script file and the second as a transcript (output) file. Every line written to the screen (except prompts and lines from misbehaving extensions) is also written to that file. The transcript file is recreated each time ActiveNav is run, but I might change that.

Friday, September 11, 2015

ActiveNav Extensions

I'll be out of communication when this goes live - this post is pre-scheduled.

ActiveNav, the command-line Active Directory browser, is extensible; third parties can write DLLs that interact with it and/or the user after being loaded with the "dll" command. This post is a reference for the extension API.

Extensions must be .NET class libraries referencing ActiveNav.exe and containing exactly one type that implements IActiveNavExtension and has a public parameterless constructor. After being constructed, the object will receive an IActiveNavExtension.Load(IActiveNav) call containing an ActiveNav controller object. IActiveNav has the following methods:

  • WriteLine(String) writes some text to the console window and to the transcript file if there is one. Use this instead of Console.WriteLine.
  • SetListener(IActiveNavExtension) causes all text that would be sent to the screen or to the transcript to be first send to the provided extension (usually the calling one) via an IActiveNavExtension.ListenerLine(String) call. Returning True from that function prevents the line from being printed. Only one extension can be the listener at a time, and the listener is cleared after each command finishes.
  • PushCommand(String) enqueues the given string as a command to be executed after the current command and any other auto-commands are finished.
  • RegisterCommand(String, Command) associates the given Command object with the given command name.
IActiveNav has the following events, which can be hooked in the IActiveNavExtension.Load method:
  • Exiting() is raised when the user issues the "exit" command. It is usually not raised when the command window containing ActiveNav is closed.
  • CommandString(String, ByRef Handled) is raised when the user enters some text as a command. If Handled is True when ActiveNav regains control, no attempt is made to interpret the text as an ActiveNav command. (It is assumed that the extension did something useful.)
  • CommandParsed(String, String(), ByRef Handled) is raised after the desired command (whose name is the first parameter) is identified but before it is invoked. The second parameter (the string array) is the array of arguments that would be passed to the command. Setting Handled to True causes ActiveNav to cancel the processing of the command.
  • CommandExecuting(String, String()) is raised after it is confirmed that the command will execute as a normal ActiveNav command but before any execution actually happens.
  • CommandFinished(String, String()) is raised after the given command is completed with the given arguments.
Adding new commands is done by inheriting Command, which has only two members:
  • Description (read-only property as String) is used to describe the command in the listing provided by the "help" command.
  • Run(String()) is invoked when the user runs the command with the given set of arguments.
Implementing IHelpSupport, while not required, allows the "help" command to give more detailed information on the command:
  • Arguments (read-only property as List(Of Tuple(Of String, String))) should be a collection of command arguments (the first entry in the tuple) and their respective description (the second entry).

Thursday, September 10, 2015

ActiveNav Find Reference

I'll be out of communication when this goes live - this post is pre-scheduled.

ActiveNav's "find" command is very powerful and very useful for finding entries in Active Directory that satisfy a certain set of predicates, but it is also far and away the most complicated command in the program. Since it's made of subcommands, the in-program help is not very useful, so I have trouble remembering how to use it. This entry will be useful to me and maybe to other people if/when I release ActiveNav in a completed state.

The "find" command is invoked as find subcommand [parameters...]. Each entry in this list is a subcommand, presented in what is hopefully a useful order.

  • load downloads all entries that are children - directly or indirectly - of the current entry, and prepares them for querying. No parameters. This will hit network utilization really hard if your Active Directory is big and you're at the root entry. Every other subcommand requires that a load has been issued.
  • list produces a list of entries currently in the result set, with result ID and entry name. No parameters.
  • go moves the current entry to the one in the result set with the numeric ID specified as the only parameter.
  • goname moves the current entry to the one in the result set with the name specified as the only parameter.
  • back moves the current entry to whatever it was before go or goname was used. No parameters.
  • filter narrows down the result set to only entries that match the predicate given as parameters. The first parameter after "filter" is the name of the object attribute being filtered on, the second is the verb/comparison (see the filter list below), and the third is the parameter to the verb. An exclamation mark before the verb inverts the filter so it leaves only entries that do not match it.
  • sort reorders the entries in the result set. The first parameter after "sort" is the name of the object attribute being compared, and the second is the comparison function (see below for sort verbs). An exclamation mark before the verb creates a descending sort.
  • flip reverses the order of the entries in the result set. No parameters.
  • cut leaves only the first N entries in the result set, with N being a number specified as the only parameter.
  • undo reverts the last change to the result set. "flip" changes do not count, and will be undone along with whatever was before them if they were the last change. There was a good reason for this, but I don't remember it. No parameters.
  • unfilter also puts the result set back to what it was before the last change, but "undo" can undo the unfiltering. No parameters.
  • clear removes everything from the result set, and clears the undo history.
Filter verbs:
  • is compares string values for equality.
  • like uses the Like (wildcard) comparison to compare string values for likeness.
  • = compares integer values for equality.
  • > checks whether the attribute is numerically greater than the parameter. Use !> for "less than or equal."
  • < checks whether the attribute is numerically lesser than the parameter. Use !< for "greater than or equal."
  • before checks whether the attribute is a date/time before the parameter.
  • after checks whether the attribute is a date/time after the parameter.
  • has checks whether the attribute is a list containing the parameter.
  • haslike checks whether the attribute is a list containing an entry that is wildcard-like the parameter.
  • cobefore is like before, but works on System.__ComObject entries that are actually dates.
  • coafter is to after as cobefore is to before.
  • bit checks whether the attribute has any of the bits that are set in the parameter.
  • and checks whether the attribute has all of the bits that are set in the parameter.
Sort verbs:
  • num compares values numerically.
  • str compares values alphabetically.
  • date compares dates.
  • codate compares System.__ComObject entries that are actually dates.
Special attribute names that work in "sort" and "filter":
  • . (a period) is the entry's name minus the LDAP cruft.
  • * (an asterisk) is the entry's non-fully-qualified name, but with the LDAP prefix.
  • ` (a backtick) is the entry's schema class name minus the LDAP prefix.
  • ~ (a tilde) is the entry's schema class name, including the LDAP prefix.

Wednesday, September 9, 2015

Unexpected Connections Between Windows

I'll be out of communication when this goes live - this post is pre-scheduled.

I really like Google Chrome; it is an excellent browser. But it has one infelicity that nettles me from time to time: all open Chrome windows are connected in some invisible way. (Well, invisible to a normal user. I'm sure they have pipe connections or TCP sessions or mutexes or something between each other.) That normally wouldn't be a problem, because the close button in the upper-right works as expected; it closes the window on which I clicked it.

However, because of the pen-and-touch that I use as a mouse (which is amazing), I frequently accidentally end up clicking on and dragging down from the hamburger/menu icon. I notice my mistake immediately, and drag the mouse cursor down and off to avoid clicking anything, but most of the time I release on an entry anyway (activating it), and that entry is usually Exit at the very bottom. That's a shame, but it's my mistake. The problem is that clicking the Exit menu item in any Chrome window closes all the Chrome windows.

So, even if I meant to click Exit to close one window (maybe I was looking through the menu options and decided that I didn't need this window anymore), any other windows - even ones not at the top of my mind but needed for some other in-progress task - get closed too. Fortunately, Chrome has a really nice way to recover an entire window, but I would still appreciate a confirmation before all browser windows get closed.

Tuesday, September 8, 2015

Robotics - Mentor

I'll be out of communication when this goes live - this post is pre-scheduled.

The FTC robotics season will be starting in a few weeks, so my school is preparing the teams. I am going to be very busy this year with a heavy schedule of classes, the required junior year volunteering project, and an online course that will be starting in a month. Since I don't know whether I'll be able to attend the robotics meetings and still keep up with classes, I've been waiting to confirm my membership on a team. Seeing that I hadn't completed the team application, the faculty adviser for the team asked me if I wanted to be a mentor this year.

Mentors are there to provide direction for FTC teams, handling logistics and keeping people on track. I can do that, I think, especially with the help of the mentor's manual FTC published this year. Mentors shouldn't do the actual robotics work for the team, so that's a disadvantage for me, but my experience should still be useful. There's no restriction that a mentor has to only mentor one team, so I'll be able to help the veteran team (of which I would be a member if I was on a team) and the team of newbies, which probably need it more.

That arrangement sounds pretty good to me. I'll be able to attend meetings when I can - it won't be a problem at all if I miss some - and I'll still be useful to both teams. I accepted the offer.

Monday, September 7, 2015

Have Different Router Maintenance and WiFi Passwords

Two facts:
  • Every router, even if it's a cheap home router, has a management interface accessible by pointing a web browser as the router's private-side IP address.
  • Home routers that provide a Wi-Fi signal to the home frequently spill signal into neighboring apartments/houses/areas.
Most people by now understand that it's a good idea to protect Wi-Fi networks with a password. It is indeed a good idea to do that, but a moderately determined attacker can still break the password and listen in on communications with a cheap antenna and some time, depending on the length of the password and the encryption mode of the network. (WPA2 is strong, but not so much if you use a password that appears in dictionaries. However, passwords of all currently used encryption modes can be attacked offline once a connection is intercepted out of the air.) 

That means Wi-Fi network passwords could conceivably be intercepted. If the same password is used for the Wi-Fi network and the router's management interface, an attacker gets control of your router too. That's really bad, because most routers (all that I've seen) can be reprogrammed by uploading a new firmware package. Once an attacker gets that done, your router and all data that passes through it is compromised, even after the attacker leaves your network/vicinity. The router could be used to launch exploits against machines on your network, or it could be instructed to send all data to the bad guy's server, just to name a couple nefarious options.

Unlike Wi-Fi passwords, management passwords cannot be cracked offline. Therefore, it is worthwhile to make your management password and Wi-Fi password different. Oh, and you did change the management password to not be the default one, right?

Sunday, September 6, 2015

PowerPoint Glitch: Zero-Area Selection Rectangles Remain

A while ago, I noticed an unusual visual artifact in PowerPoint 2013: sometimes, the selection rectangles (from dragging with the mouse to select multiple items) don't go away. A little fiddling around revealed that the glitch only occurs for zero-area rectangles, selections where the starting coordinate is the same as the ending coordinate for one axis. Selecting a region with nonzero area works as expected; the rectangle disappears after releasing the mouse.

I'm guessing there is an "optimization" to not bother erasing a zero-area rectangle; perhaps somebody forgot that at least one pixel is always rendered to display the edges of the rectangle.

Saturday, September 5, 2015

Linksys Home Router Modem Link Problems

Today I was setting up a new Linksys N600 home router, model E2500, and experiencing some strange problems. The router was not receiving any IP address via DHCP when connected to the modem, even though the laptop I was using did get an IP address and had a perfectly working Internet connection when I connected it directly to the modem.

I fiddled around with router settings for a while, and eventually called tech support. Three potentially important things happened, but I'm not sure which actually fixed the problem:

  • The router was reset to factory defaults with the old paperclip method.
  • It was given one distinct SSID for each frequency (it's a dual-band), with no spaces in either.
  • Its public MAC address was changed to be the same as the laptop's MAC address.
Whichever was the important part, the router is now working as expected, and clients can connect to the Internet via its Wi-Fi.

Friday, September 4, 2015

False Blame on Caller of Uncompilable Lambdas in Visual Studio 2015

Today while doing some work in Visual Studio 2015, I noticed some odd behavior involving multiline lambdas passed to functions. My code includes invocations of Task.Factory.StartNew with a moderately complex parameterless, void-returning delegate - an Action - passed to it like so:

Task.Factory.StartNew(Sub()
                          ' Do some stuff
                          ' And some things
                      End Sub)

I was doing some refactoring that involved removing a variable from one function since the capability that required it was being moved somewhere else. After I deleted the declaration line, I noticed that Visual Studio put a red squiggly underline on StartNew, indicating a compilation error. Mousing over the underlined text informed me that the type of the parameter could not be inferred.

That was very strange, since the type of a Sub() lambda is completely unambiguous - it's always just Action with no type parameters. I set it aside for a moment and finished my refactoring of the lambda. Once all references to the nonexistent variable were removed, the error went away.

Assigning the large uncompilable lambda to a variable and then passing the variable to the StartNew function worked as expected; uses of the variable inside the lambda received squiggles. It appears that the Visual Studio 2015 compiler incorrectly lays the blame for all errors inside a lambda-as-an-argument on the calling function as type confusion.

Thursday, September 3, 2015

TliExtend 2

Quite a while back, I made some significant changes to TliExtend, the quick-and-dirty tileinfo extension utility. Quick summary:

  • Has built-in help (try invoking it without any arguments)
  • Can remove (truncate) tiles, and will ask for confirmation before doing so
  • Supports merged maphead/tileinfo files with an optional argument
It's still not super well-tested, so if you run into any issues, please tell me. This build, like the last, requires FMod.dll, which is included with Abiathar.

Wednesday, September 2, 2015

Dell PowerEdge Server Drive Setup

After getting the PowerEdge server's memory configuration correct, I was faced with another challenge: drive setup. Even though I put a drive into the SCSI array, the XenServer installer (on a CD) did not see any hard drives; a message printed by the BIOS (or maybe some other firmware component) before transferring control to any boot program indicated that no logical disks were configured. I was very confused, because I could see that the drive was connected - its power light was on.

It turns out that in addition to the standard BIOS setup utility, the server has a RAID controller setup utility/firmware as well. I looked in there, and it reported that it did see the physical drive, but that no virtual drives were configured. After a couple minutes of poking around in the integrated help articles, I discovered that the RAID controller only presents virtual views of the disks to the OS as physical drives. I created a new virtual drive that consisted of only the one physical drive, and everything was good. I might try out the hardware RAID capabilities later.

Tuesday, September 1, 2015

Dell PowerEdge Server RAM Setup

Today I had the opportunity to set up a Dell PowerEdge server. It seems to be a powerful machine - it has 12 RAM slots, 8 SCSI drive bays, 2 CPU slots, 2 Ethernet ports, 2 power inputs, and many noisy fans. (Aside: starting it up tripped the circuit breaker because it drew so much power.) The trickiest part of getting it up and running was getting the RAM arrangement correct.

It is a used server, and one of the RAM modules was bad. Fortunately, the boot process gives all sorts of information on hardware misconfigurations, so finding the bad module was easy. The slots are numbered from 1 to 12, and arranged into four groups of three, with a white slot as the first slot in the group. Rather than moving linearly, the numbering skips from one group to the next before moving to the next slot in each group. So, slot 2 is the first slot (the white one) in the second group, while slot 5 is the second slot in the first group (because slot 4 would be the first slot of the last group).

Then there are pairs of slots. Slot 1 is in a pair with slot 2, #3 with #4, et cetera. Slots in a pair must be filled with the same size and speed of RAM module, so having a module in slot 7 but not in slot 8 will cause the boot process to fail. Having a 1GB module in slot 1 but a 512MB module in slot 2 will also cause a boot fail.

Slots must be filled sequentially or BIOS will complain about some modules being "electrically isolated." Therefore, having slots 1 and 2 empty and 3 and 4 filled will cause a boot fail.

Finally, it is recommended - but not required - that every layer of 3 be either completely full or completely empty. BIOS will warn you if you have slots 1 through 6 full but 7 and up empty because slots 7 and 8 would complete the layer started by 4 and 5. I do not know how bad the performance hit is for such a misconfiguration.