Hard Disk shortage. Yeah, right!

Haven’t hard disk drives suddenly become expensive? It’s a world-wide shortage caused by flooding in Thailand, apparently. Yeah yeah, we’ve been here before: Fire in the jungle somewhere causing a loss of chip production, and so on. The problem is that when you looked for a fire in a fab, there never was one – and there aren’t that many fabs around.

Actually, it is true that floods in Thailand have affected some drive production. There are blogs all around the place predicting doom, gloom and providing figures as to what the shortfall might be. People are wringing their hands and predicting even worse supply problems and price rises after Christmas.

I say phooey.

I’m sceptical that the lost production is as high as claimed, and given the rising price of drives, all the HD makers will be ramping up at other facilities in double-quick time. This will lead to over-production pretty soon. The short-term supply shortfall shouldn’t even be seen as there are always lots of drive sitting in warehouses.

But you’re wrong, I hear the cries. If you were right, why is everything out of stock in spite of inflated prices. Panic buying might have an effect on that. If the channel thinks prices are going to rise, they will. It’s a self-fulfilling prophecy if ever there was one. But it has a use-by date. Sooner or later everyone will be sitting on their expensive stock pile and wondering why supplies haven’t run out – and when they do the over-supply will come through the system.

The suppliers aren’t going to quash the rumours, of course. Why should they when everyone further down the chain is paying double for everything in their warehouse.

How do I know all this? I’ve seen it all before.

Warning: Just because this happened in the past, doesn’t mean it will happen in the future. If you lose money based on the above prediction, it’s entirely down to you.

What is to become of Computer Science?

When people ask what I do, I normally say I work with computers. “Ah,” they say. “You’re in IT. My nephew is in the same line.” Well actually, no – I don’t do IT and I don’t do the modern version: ICT. I was around long before these terms were coined, and they really don’t apply. IT is all about setting up Windows and writing Macros in Excel (if you’re advanced).  If I say I’m a computer programmer it’s assumed I’m a “web developer”. System programmer doesn’t mean anything to most people; assembler programmer even less.

Then a few years ago I realised what I was – I’m a Computer Scientist. Well I lecture on Computer Science degree courses, ergo I must be. Actually this antiquated term is very appropriate for an antiquated computer person, and if the hat fits…

Back in the 1970’s and early 1980’s we were all Computer Scientists. If you wanted a computer you pretty much had to build it yourself with a soldering iron and a load of chips and when complete, you had to program it. If your employer purchased one of these expensive items ready built, you still had to program it yourself – unless you were an operator, in which case you merely had to understand it. You learned a lot in the process, if you were that way inclined.

These days people want a career in IT, so they do Computer Science courses at University. They’re wasting their time. They learn very little from the university about computer science, and the university is perfectly happy with that. The way computers work is difficult; difficult means expensive to teach and certain to put off students. If you put off students, you get less money. So you need to teach easy stuff.

Easy stuff in Computer Science basically comes down to playing around with luser-land software, animation packages and an SQL query or two – but not too hard. Perhaps write a bit of HTML by hand before moving on to some web page design package or CMS.

Here’s the conundrum.

Students = money, but only if they stay the course.

A low pass rate = Less students want to do the course.

Without lots of students passing the course, you don’t get enough money and everyone loses their job.

Computer programming is difficult. Most IT students can’t hack it. Therefore it has to be dumbed down to an extent you’d never believe. Those with the aptitude could program before they came on the course; those without it would never learn.

Please generate and paste your ad code here. If left empty, the ad location will be highlighted on your blog pages with a reminder to enter your code. Mid-Post

In 2009 the university I taught programming at decided that the need to pass the programming module was affecting their overall pass rate, so they made it optional. Yes folks – you can get a Computer Science degree without being able to write a single line of code. I’d name names here, but I understand this is common practice at many institutions, so what’s the point?

Now I’m not saying I’m unique or even special in understanding how computers work. There are plenty of others of my generation that know as much, if not more. What I’m wondering about is what happens when our generation retires? It’s not possible to go through the learning process we had back then – learning by tinkering and doing (because frankly, the education system was nowhere near the leading edge back then either).

I believe there was a sweet spot at the end of the 1970’s, where microprocessors had just appeared on the scene and you had to understand things from first principles if you wanted to do anything with them. If you didn’t have to construct a machine yourself, you certainly needed to program it if you wanted it to do anything – and they were simple enough back then that this was a realistic possibility.

Sitting in front of a modern Windows PC is not the same experience at all. With a PET/Apple/Tandy computer you turned it on and the first thing you saw was a prompt to start entering your program in BASIC. You lived in a programming environment. With CP/M it was only a few keystrokes away. Now we’re presented with a graphic user interface and no programming language whatsoever – just Facebook. The complexity of the Windows API is daunting; more so given that everyone thinks its cool to write stuff using the current favourite object-oriented wrapper library. In order to achieve anything looking like a modern computer program (where the graphic user interface is everything) you have to jump through numerous hoops before you can get started. If I complain, I’m pointed at the application generator – it’ll write most of the code for me, apparently. If you ask what the reams of generated preamble code it actually produces is for, people just shrug their shoulders and ask why you’re questioning it.

In 1998 I found myself writing a system-level utility for Windows inside a large company, and needed to sort an array into alphabetical order. I don’t think there’s a Windows API function, and qsort seemed to be missing from the library, so I consulted the lead Windows programmer across the room. The answer came back to put my strings (one by one) into this file selector structure (as file name), make some call or other to the file selector box and presto – my strings would come back sorted. No, he wasn’t joking. Two minutes later I’d written bubble-sort, for the umpteenth time.

This was thirteen years ago; how much has it deteriorated since then? I’m lucky to be developing software either solo, or with a developer of my generation, so I’m probably insulated against the worst excesses.

So, back to the point: where are we going to get Computer Scientists from? I started on the sweet spot, where it was possible to learn pretty much everything about the computer in front of you – every instruction, every I/O register, and every line of the operating system. As computers expanded, our knowledge expanded, but could rest  on these early foundations. We can’t do that any more. If we ran a three-year degree course in computing and started from the basics you’d end up with me someone whose knowledge was wide enough to cover a BBC Micro. They’d need another twenty-seven years after that to reach the modern era, and by the time they qualified they’d be thirty years out-of-date.

And why should anyone even bother? I can assure you, there’s more money to be made out of IT than Computer Science. The only decent return available if you understand computer fundamentals appears to come from cyber-crime, and even then that’s as  perpetrator; no one wants to pay for security.

I’m told that the government plans to bring back an element of programming into the ‘O’ level maths (or its modern equivalent). This is a start, but a small one.

In the mean time I’m watching the other members of the OS/2 drinking club fall away and wondering what is to become of us. The draw of Bletchley Park grows every stronger.

 

IP Expo 2011 – what was fun

That’s IP Expo over with for another year. I’ve never quite get what the show is about, but it’s one I seriously consider attending. It’s lack of focus is probably what makes it intersting. I’ve always suspected that some exhibition organiser kept reading about IP and decided it was a buzzword lacking its own show and started one. Anything connected to an IP network is fair game, and these days this means almost everything.

The Violin memory box is an amazing piece of kit – a massive, high-performance thumb drive connected via fibre channel. They’ve done a lot of work basically striping data across flash modules which boosts performance, avoids hitting the same flash chip repetitively and gives redundancy – I believe they can lose six modules before it bites and its hot swappable.

There were quite a lot of other storage solutions on show, some interesting, some very much the same. One company is using ZFS, which is a technology I’ve had my eye on for some time.

Prize for the fund gadget is Pelco’s thermal imaging camera – at less than £2K for the low-res version it suddenly becomes affordable, and it certainly works well enough. Still on CCTV, someone had a monitor connected to a web cam and some software to identity faces. Spooky. This put a mug-shot of everyone looking at the camera down the side of the screen, recorded how long they were standing there and guessed their sex and age. It actually took ten years of most people, which helped with the feel-good but this technology obviously works and an obvious application is snooping on people looking at shop windows to work out what attracts the right kind of demographic (why else would they have developed it). I should point out that this was showing off the screen – the web-cam and face recognition was a crowd-puller

Another interesting bit of kit is an LG stand-alone vmware terminal. This basicall allows you to virtualise your PC and use them on a thin client. The implications of this for managability are obvious – keep your PC environment in a server room, where it can be cloned and configured at will, and leave a dumb-terminal in the front line. If the terminal breaks or is stolen – no problem whatsoever. The snag? Well the terminals aren’t cheap and they could do with toughened glass.

 

PAM authentication in PHP on FreeBSD

I have several groups of lusers who want to be able to set/change their mail vacation settings but aren’t up to using ssh to edit their .forward and .vacation.msg files. I thought I’d write a quick PHP application to allow them to do it in a luser-friendly way using a web browser. If this isn’t what PHP is for, I don’t know what good it is. The snag: you need to make sure the right user is editing the right file.

The obvious answer is to authenticate them with their mail user-name and password pair using PAM. (This is the system that will check user-name/password combinations against whatever authentication you see fit – by default /etc/passwd).

PHP has a module available for doing just this – it’s called “PAM” and there’s even a FreeBSD port of it you can install from /usr/ports/security/pecl-pam. If you want to use it, just “make” and “make install” – it’ll add it to the PHP extensions automatically, but don’t forget to restart Apache if you’re planning to use it there.

You’ll also have to configure PAM itself. This involves listing the authentication methods applicable to your module in /etc/pam.d/. In this case the php module will have the default name ‘php’ unless you’ve changed it in /etc/php.ini using a line like pam.servicename = "php";

Adding the above line above obviously does nothing as it’s the default, but it’s useful as a reminder of what the default is set to. I don’t like implicit defaults, but then again I don’t like a lot of the shortcuts taken by PHP.

The only thing you need to do to get it workings is to add a PAM module definition file called /etc/pam.d/php. The easy way to create this is copy an existing one, such as /etc/pam.d/ftp. This will be about right for most people, but read /etc/pam.d/README if you want to understand exactly what’s going on.

So – to test it. A quick PHP program such as the following will do the trick:

<?php
var_dump (pam_auth('auser','theirpassword',&$error,0));
print $error;
?>

If there’s an entry in /etc/passwd that matches then it’ll return true, otherwise false, and $error will contain the reason. Actually, it checks the file /etc/master.passwd – the one that isn’t world readable and therefore can contain the MD5 password hashes. And there’s the rub…

This works fine when run as root, but not as any other users; it always returns false. This makes it next to useless. It might be a bug in the code, but even if it isn’t it leads to interesting questions about security. For example, it would allow a PHP user to hammer away trying to brute-force guess passwords. I’ve seen it suggested to Linux users can overcome the need to run as root by making their shadow password group or world readable. Yikes!

If you’re going to use this with PHP inside Apache, you’re talking about giving the “limited” Apache user access to one of the most critical system files as far as security goes. I can see the LAMP lusers clamouring for for me to let them do this, but the answer is “no!” Pecl-pam is not a safe solution to this, especially on a shared machine. You could probably persuade it to use a different password file, but what’s the point? If the www user can read it, all web hosting users can and you might just as well read it from the disk directly (or use a database). PAM only makes sense for using system-wide passwords for authenticating real users.

I do now have a work-around: if you want your Apache PHP script to modify files in a user’s home directory you can do this using FTP. I’ve written some code to achieve this (not hard) and I’ll post it here if there’s any interest, and after I’ve decided it’s not another security nightmare.

 

Kindle not on Fire

Amazon has just launched a Kindle for £89 in the UK, beating the price of its previous model by £20. It’s 30% lighter and 20% smaller too. This is no big deal: they’ve simply chopped off the alphanumeric keyboard and replaced it with a few buttons, removed the audio playback and cut the battery size in half.

I don’t think much of it. The original Kindle at £109 (£149 with 3G) looks well worth the extra.

In the US, Amazon has launched additional models: Kindle Fire and Kindle Touch. The Touch dispenses with all keys in favour of a touch screen. It comes with or without 3G and is clearly intended as the new standard model. The Kindle Fire isn’t a Kindle at all – it’s a 7” Android Tablet.

I’m not impressed. They’re using the Kindle brand to flog a fairly standard tablet. I’m sure it’s a fine Android tablet as Android tablets go, but a colour version of the Kindle e-book reader, it isn’t. It’ll rip through batteries at the same rate as every other tablet, and its colour screen will be just has hard to read in bright sunlight – the two problems overcome by the original Kindle’s e-paper display.

Comparing the Kindle Fire to the iPad2: well it’s half the price but lacks the cameras, and has only 8G of storage. It’s also Android rather than iOS (if that matters to you). And it’ll probably be about the same price using Amazon’s exchange rate; and a lot more expensive than other Android tablets already available.

One distinguishing feature is the new Amazon browser – Silk. Whatever else it does, it’s designed to work with Amazon’s cloud servers to cache content and “speed things up”. Hmm. Sounds like Phrom’s notorious Webwise system all over again. Okay if you don’t mind Amazon data mining your web traffic.

Another strange feature is the pricing. The Touch and Fire aren’t available in England yet (the US launch is set for 15th November, no date for here). The US prices for all Kindles are substantially lower.  (Note that the original Kindle has been renamed the Kindle Keyboard).

England USA
Kindle Keyboard   £109 $99
Kindle Keyboard 3G   £149 $139
Kindle (buttons)   £89 $79
Kindle Touch   (£112) $99
Kindle Touch 3G   (£168) $149
Kindle Fire   (£224) $199

The figures in brackets are my calculation, using Amazon’s astonishing exchange rate of $1=89p.  All this talk in the UK media about these new models being cheap is overlooking this point.

It might explain why Amazon isn’t launching the Fire in England any time soon.

Update October 2012

The Kindle Fire is now available in England, from Tesco in fact, with a price tag of £130 including tax. At this price it’s a whole lot more interesting. Both the Kindle Touch and standard Kindle are £70, although the former is on “special offer”. The 3G versions are a lot more. It looks like I was right about the pricing <smug>

 

PHP PDO driver missing on FreeBSD

I got an email today – a FreeBSD 8.2 Web server installation with Apache and PHP 5.3 was missing its mySQL driver. No it wasn’t, I protested. But this error was appearing:

[error] [exception.CDbException] could not find driver
[error] [exception.CDbException] exception 'CDbException' with message 'CDbConnection failed to open the DB

“It’s not the database, it’s the PDO module”, came the explanation. Actually the pdo.so module was there and loaded, and it was installed in just the same way as it had been on earlier versions. So what was going on?

It turns out that as of PHP 5.3 there has been a change. You don’t get the important module – pdo_mysql – loaded when you compile /usr/ports/lang/php5-extensions. It’s not that it’s no longer checked by default – it’s not even there! I’m told this applies to Postgress too.

Further investigation revealed that PHP5.3 has a new native-mode driver (mysqlnd), and this is now outside the standard install. If you’re using sqlite for Persistant Data Objects, no problem, but if you’re using a more restrictive hosting account and therefore need to store them in a mySQL (or Postgress) database you seem to be out of luck.

For more information, see here.

However, the required module can still be found. Go to

/usr/ports/databases/php5-pdo_mysql

(If you’re using Postgress go to php5-pdo_pgsql instead – see Geoffrey McRae’s comment below).

make and make install what you find there. Also, make sure you compiled the original php5-extensions with mysql and mysqli, and don’t forget to restart Apache afterwards!

Note that it’s quite possible that none of the above relates to Linux. It’s to do with what gets installed from where with the FreeBSD ports tree.

Large swap files on FreeBSD die with mystery “Killed” – howto add lots of swap space

Adding extra swap space to FreeBSD is easy, right? Just find a spare block storage device and run swapon with its name as an argument. I’ll put a step-by-step on how you actually do this at the end of the post in case this is news to you.

However, I’ve just found a very interesting gotcha, which could bite anyone running a 64-bit kernel and 8Gb+ of RAM.

From here we’re getting into the FreeBSD kernel – if you just want to know how to set up a lot of swap space, skip to the end…

I’ve been running a program to process a very large XML file into a large binary file – distilling 100Gb of XML into 1Gb of binary. This is the excuse for needing 16Gb of working storage (please excuse my 1970’s computer science terminology, but it’s a lot more precise than the modern “memory” and it makes a difference here).

I was using 2Gb of core and 8Gb of swap space, but this was too little so I added an extra 32Gb of swap file. Problem sorted? Well top and vmstat both reported 40Gb of swap space available so it looked good. However, on running the code it bombed out at random, with an enigmatic message “Killed” on the user console. Putting trace lines in the code narrowed it down to a random point while traversing a large array of pointers to pointers to the 15Gb heap, about an hour into the run. It looked for all the world like pointer corruption causing a Segmentation Fault or Bus Error, but if the process had a got that kind of signal it should have done a core dump, and it wasn’t happening. The output suggested a SIGKILL. But it wasn’t me sending it, and there were no other users logged in. Even a stack space error, which might have happened as qsort() was involved, was ruled out as the cause – and the kernel would have sent an ABORT, not a KILL in this case.

I finally tracked it down to a rather interesting “undocumented” feature. Within the kernel there is a structure called swblock in the John Dyson/Matthew Dillon VM handler, and a pointer called “swap” points to a chain of these these structures. Its size is limited by the value of kern.maxswzone, which you can tweak in /boot/loader.conf. The default (AMD64 8.2-Release) allows for about 14Gb of swap space, but because it’s a radix tree you’ll probably get a headache if you try to work it out directly. However, if you increase the swap space beyond this it’ll report as being there, but when when you try to use the excess, crunch!

Although this variable is tunable, it’s also hard-limited in include/param.h to 32M entries; each entry can manage 16 pages (if I’ve understood the code correctly). If you want to see exactly what’s happening, look at vm/swap_pager.c.

The hard limit to the size number of swblock entries is set as VM_SWZONE_SIZE_MAX in include/param.h. I have no idea why, and I haven’t yet tried messing with it as I have no need.

So, what was happening to my process? Well it was being killed by vm_pageout_oom() in vm/vm_pageout.c. This gets called when swap space OR the swblock space is exhausted, either in vm_pageout.c or swap_pager.c. In some circumstances it prints “swap zone exhausted, increase kern.maxswzone\n” beforehand, but not always. It’s effect is to find the largest running non-system process on the system and shoot it using killproc().

Mystery solved.

So, here’s how to set up 32Gb of USABLE swap space.

First, find your swap device. You can have as many as you want. This is either a disk slice available in /dev or, if you want to swap to a file, you need ramdisk to do the mapping. You can have as many swap devices as you like and FreeBSD will balance their use.

If you can’t easily add another drive, you’re best option is to add an extra swap file in the form of a ram disk on the existing filing system. You’ll need to be the root user for this.

To create a ram disk you’ll need a file to back it. The easy way to create one is using “dd”:

dd if=/dev/zero of=/var/swap0 bs=1G count=32

This creates a 32G file in /var filled with nulls – adjust as required.

It’s probably a good idea to make this file inaccessible to anyone other than root:

chmod 0600 /var/swap0

Next, create your temporary file-backed RAM disk:

mdconfig -a -t vnode -f /var/swap0 -u 0

This will create a device called /dev/md with a unit number specified by -u; in this case md0. The final step is to tell the system about it:

swapon /dev/md0

If you wish, you can make this permanent by adding the following to /etc/rc.conf:

swapfile="/var/swap0"

Now here’s the trick – if your total swap space is greater than 14Gb (as of FreeBSD 8.2) you’ll need to increase the value of kern.maxswzone in /boot/loader.conf. To check the current value use:

sysctl kern.maxswzone

The default output is:

kern.maxswzone: 33554432

That’s 0x2000000 32M. For 32Gb of VM I’m pretty sure you’d be okay with 0x5000000 (in round numbers), which translates to 83886080, so add this line to /boot/loader.conf (create the file if it doesn’t exist) and reboot.

kern.maxswzone="83886080"

 

Spamassassin, spamd, FreeBSD and “autolearn: unavailable”

I recently built a mail server using FreeBSD 8.2 and compiled spamassassin from the current ports collection, to run globally. spamd looked okay and it was adding headers, but after a while I noticed the Baysian filtering didn’t seem to be working in spite of it having had enough samples through.

A closer look at the added headers showed “autolearn: no”, or “autolearn: unavailable” but never “autolearn: ham/spam”.

What was going on? RTFM and you’ll see spamassassin 3.0 and onwards has added three new autolearn return codes: disabled, failed and unavailable. The first two are pretty self-explanatory: either you’d set bayes_auto_learn 0 in the config file or there was some kind of error thrown up by the script. But I was getting the last one:

unavailable: autolearning not completed for any reason not covered above. It could be the message was already learned.

I knew perfectly well that the messages hadn’t already been learned, so was left with “any reason not covered by the above”. Unfortunately “the above” seemed to cover all bases already. There wasn’t any clue in /var/maillog or anywhere else likely.

I don’t much care for perl scripts, especially those that don’t work, so after an unpleasant rummage I discovered the problem. Simply put, it couldn’t access its database due to file permissions.

The files you need to sort are at /root/.spamassassin/bayes_* – only root will be able to write to them, not spamd – so a chmod is in order.

A better solution is to move the Bayesian database out of /root – /var would probably be more appropriate. You can achieve this by adding something like this to /etc/spamd.cf (which should link to /usr/local/etc/mail/spamassassin/local.cf):

bayes_path /var/spamassassin/bayes/bayes
bayes_file_mode 0666

I suspect that the lower-security Linux implementation avoids these problems by setting group-write-access as default, but FreeBSD, being a server OS, doesn’t. It’s also a bug in the error handling for the milter – it should clearly report as a “failed” and write something to the log file to tell you why.

You should be able to restart spamd after the edit with /usr/local/sbin/spamdreload, but to be on the safe side I use the following after shutting down Sendmail first.

/usr/local/etc/rc.d/spamass-milter restart
/usr/local/etc/rc.d/sa-spamd/restart

I don’t know if Sendmail can cope well with having spamass-milter unavailable, but why take the risk?

 

OpenLDAP, Thunderbird and roving address books

IMAP is great. It lets you keep your mail synchronised between any number of machines, including webmail, and everything works just fine. The only snag is that your address book isn’t included. I’d always assumed this was what LDAP was for: a centralised directory of names, and other things, with the useful bit being the address book. Thunderbird, is my current favourite mail client on the basis that actaully works better than Outlook. It supports LDAP address books, and has offered to configure one for me many times. All I needed to do was configure slapd (the OpenLDAP server deamon) and point Thunderbird at it.

This blog entry isn’t a tutorial in configuring FreeBSD, OpenLDAP and Thunderbird to work together. I’m saving you from wasting a lot of your time trying. It does “work”, once you’ve sorted out schemas and got to grips with the arcane syntax of the configuration files and the hierarchical nature of the thing. It’s just that it’s useless even when it’s working because it’s READ-ONLY. Being able to add and amend entries in my address book is so fundamental to the nature of an address book that I didn’t bother to check that Thunderbird could do it. What’s the use of a read-only address book? Well there might be some point in a large organisation where a company-wide address book is needed, administered by a tame geek in the basement. For the rest of us it’s as fileofax with no pen.

So what are the good people at Mozilla playing at? The omission of read/write has been listed in their bug database for over ten years, and no one has tackled it. I thought about it for a while, but given the that Lightweight-DAP is a misnomer on a spectacular scale I thought again. Clearly no one who knows about LDAP actually likes it enough to want to help; either that or none actually understands it apart from the aforementioned geek in the basement, and he’s sitting tight because allowing users to edit address books might be detrimental to his pizza supply.

The time is right for a genuinely lightweight protocol for sharing address books in a sane and sensible manner; something like IMAP for addresses. I’m therefore writing one. Unfortunately I’m not so clued up on Thunderbird’s internal workings; if you are and wish to implement the front end please drop me a line and I’ll write a protocol and server that works.

Unfortunately this one issue is a killer app for Microsoft’s lightweight over-priced Mail system called Exchange. It’s a big of a dog (inflexible) but at least Microsoft seems to have got this fundamental functionality for sharing personal address books between mail clients sorted out. I believe it uses something similar LDAP underneath (along with IMAP for the mail itself); so it’s not impossible.

I’m very surprised to find myself having anything good to say about Outlook/Exchange Server. It might still be traumatised from the discovery that my assumption that the obvious LDAP solution was nothing of the sort. It’s just it’s so damn complex for no apparent reason that it gives the impression it must be great if you could only understand it.

WordPress ends up with wrong upload directory after moving servers

If you’ve moved WordPress from one server (or home directory) to another, everything looks fine until you come to upload a file. It then complains that it can’t write to the upload directory. Something like:


Unable to create directory /usr/home/username/wp-content/uploads/xxx/yy. Is its parent directory writable by the server?

A search through the PHP config files doesn’t reveal a path to the upload directory, and if it’s possible to change it from the Dashboard I’ve yet to find where.

The only remaining option was the mySQL database, and fishing around in the likely sounding wp_option table I found a option_name of “upload_path”. A quick query showed this was the home directory.

To save you fishing, here’s the SQL needed to set things right. Obviously select the appropriate database with “use” first!


update wp_options
set option_value='<path-to-your-wordpress-installation>/wp-content/uploads'
where wp_options.option_name='upload_path';

This is how you do it using straight SQL from the command line. If you’re using some sort of restricted web hostinig account “See your system administrator” and point them here.