Archive for the ‘ Storage ’ Category

The backup quandary

With an increasing number of backup solutions available, I’d like ask a question. Why are so many people reluctant to backup their data?

I see this problem all the time. Even in corporate environments, where backup is pretty much mandated, people are reluctant to use the solutions. Some go out of their way to avoid mandated solutions. But really, how many of us have been bitten over the years about losing data because our system crashed?

The bottom line is there is almost no excuse for not backing up ones data on a fairly regular basis. Having said that, I’d like to actually list some cool ideas and why I wouldn’t rely on them.

  1. Apple’s Time Machine: is really a pretty cool solution, for the most part. If you’ve never tried it, and own a Mac, you should. Having said that, the problem really isn’t in using it the first time. It’s the 2nd time and after that. About the best thing Time Machine is good for is when it comes to restoration of a Mac. It will capture and restore every little thing including cookies, passwords, etc. You don’t have to worry about re-installing all of your applications either.

    The reason I say it’s not so great the 2nd time is that depending on how much you actually have to backup, the time required to determine what has changed can be quite long. While the actual backup part can be quite fast, it’s this generation of a list that can be intolerable. I suppose it’s a small price to pay for the ability to restore everything so easily.

  2. Dropbox: is currently a pretty hot item in the reviews. It’s a pure software widget that allows you to upload all of your files, share them with others and it’s dead simple to install and use. The service is also pretty cheap at just $9.99 per month for 50GB.

    The problem with the Dropbox solution is time. You have to have lots and lots of time depending on the speed of your internet access and how much data you really wish to backup online. If you are with a cable provider, you may not think twice about uploads. However, if you’re in select areas where AT&T DSL is your only option, you may be in deep kimchee. This has certainly been the case for several friends of mine who only have 384kbps upload capabilities. In this scenario, backing up 50GB of data can take almost a week.

    Even if upload speeds aren’t a problem, you may find a problem when it comes to restoration of your computer from an online backup. Imagine downloading your apps, data, settings, etc. just so you can get back to functional.

  3. Then there are the hybrid solutions, which place a locally installed appliance to help mediate this whole process and to provide local restoration capabilities. The trade off with this approach is cost of the service and management of some extra hardware.

    So far, while I believe this is one of the best approaches, the key question in my mind is whether or not this is worth a premium monthly service. Just to illustrate the differences in prices, let’s compare the Dropbox service with service from someone like Barracuda Networks. If we take a look at the costs for backing up 50GB of storage, we’re looking at a tenfold difference– $0.20/GB to $2.00/GB.

    Some will argue that the additional costs are to subsidize the hardware that is deployed. And that may indeed be a fair argument for some. But I know in the case of Barracuda, they charge for their appliances. Even at a reduced rate, they’re by no means losing money. Still, despite the costs, they are clearly selling their offerings to corporate accounts.

So with these types of solutions, is backing up still just too much of a pain in the butt for you? Do any of these sound at all attractive?

I fundamentally believe that there is no real reason not to protect all of your data. But for whatever reason, backup is just not a very interesting application. Perhaps we don’t backup simply because in a disconnected world of laptops usage, there’s not enough to remind us to do such a simple task.

When storage guys think more highly of themselves than they should

A friend of mine, Sal, forwarded this to me last week. It’s actually entertaining, I suppose. But it’s a good indication of what happens when storage guys think a LOT about what they do.

It reminds me of when I did NetAttach and we actually had serious discussions about having Calista Flockhart do an ad for us. You all remember Ally McBeal, right?

Enjoy!

De-duplication as core infrastructure

It seems as though the subject of de-duplication is becoming more commonplace as it’s getting difficult to avoid conversations related to it. Just the other day, I had another customer ask me for a recommendation concerning it. While their question was interesting to me, their assumptions for considering it were more so.

It’s amazing the assumptions some people will make in my industry. I can remember a while back, I had a CEO for a company state to me they wanted to get into the storage industry but wanted to do so without the use of disk drives because “We all know you can’t make any margin on storage”. Well, that’s just not the case.

Anyway, the presumption on why de-duplication could be a good infrastructure solution is that they’d been told they could reduce storage consumption by as much as 50%. Really? 50%? I suppose if this were high school and plagiarism was pervasive, this might be so. But it’s not likely that people are replicating that many files. Having said that, de-duplication technology can be beneficial and I provided them an example of how it can help.

In my example, I took a fairly typical scenario in my company where I might generate a presentation that is roughly 25MB in size. It’s a corporate presentation so I might actually shoot a copy of it to all of the employees. We’ll round things to 20 just to make this rather easy. Assuming each employee is using an email reader that downloads attachments to a local folder, we’re looking at 500MB of the same file being stored onto laptops, desktops, etc.

In this day and age, 500MBs isn’t very much. So is the issue the actual storage consumption? After all, if we’re talking about 20 unique individuals, on laptops, and working from different remote offices, we’re looking at 25MB of consumption each. But if we throw all of these people into a central office and decide we want to provide backup for all of them, the problem starts to take shape. On the local area network, backing up this much information to a file server should take roughly 5 seconds on a gigabit network if there’s nothing else going on. That’s hardly anything to be concerned about. It’s not until we wish to back things up remotely that we actually see the problem.

Let’s suppose our company has a T1 connection to the internet and we can upload files at 1.2Mb/s (megabits, not megabytes). All of a sudden we’re looking at backing up all instances of this file to the remote site at fairly slow bandwidth. In this example, assuming we can get 100% utilization, we’re looking at a transit time of 3,333 seconds or roughly 56 minutes. Gee, nearly an hour just to backup all of the instances of one file over the internet. That’s a lot of utilization.

If we simply backed up the first instance and could replace all replicated objects with just hardlinks, the total job would only take 2.8 minutes. If only things were this easy. Actually, for the most part, they are.

There is a definitely a case for de-duplication when it comes to cutting down on WAN transit times for remote backups. But does this actually warrant a product purchase when the products typically cost much more than the storage that will be housing the data? Perhaps, if you look at it from a network bandwidth perspective. But when you consider emerging technologies such as WiMAX, you should re-check making expensive purchases.

There has been much hype about rolling out large WiMAX fabrics in key metro areas. With speeds as high as 72Mb/s, we’re talking about a backup window of possibly as low as 76 seconds. How real is this? Well, just in the last couple of weeks, we’ve read about Charter Communications rolling out support for their cable subscribers in the realm of 160Mb/s. The service is available in very select regions and at a premium. But that’s not the point. The point is that network bandwidth to the internet is increasing at a dramatic rate (no pun intended) and at very affordable prices.

When you consider these things, where does de-duplication really fall? Storage is getting cheaper. Network bandwidth is getting much faster and more affordable. And more and more companies are beginning to make de-duplication scripts or applications available free of charge. With these things coming and affecting much more than just backups, it’s hard to justify such capital expenses.

The reason I got on the subject is that I just read a news article on yet another FREE de-duplication tool called Dupe Manager. It’s only a 0.1 release, but it’s not the only one out there. And, it’s free. Did I mention that? Well, it is. This is yet another reason I love working with open source. Open source lives and breathes to solve simple, everyday problems like these, which makes a lot more sense considering the relative nature of the problem. It’s a bit problem for many today. But will it continue to be as big a problem in 6 months? 12 months?

Sometimes you have to dig in for that something extra

This past week has been rather encouraging despite all the news of record unemployment. I’ve had additional VC meetings that went very well. I’ve had analyst meetings supporting what I’ve built in a company. And I’ve had conversations with some of the largest companies wanting to use the products I’ve largely designed. What’s not to like? Well, during the course of the meetings, I’ve realized that my currently philosophy of do as much as humanly possible is a good one to have right about now.

Let’s see what I’m currently doing:

  1. Designing new version of our company’s OS
  2. Testing the new User Interface
  3. Tweaking business plan
  4. Redesigning company website
  5. Testing and working on deployment of new update tool
  6. Designed and now testing new de-duplication tool
  7. Working on file-system enhancements
  8. Looking at new backend storage options for a potential consulting client
  9. Fleshing out details for a new email company I’ve had floating around in my head
  10. Fleshing out designs for a new social networking site
  11. Family man, father and husband, etc.

Anyway, you get the idea. You can’t simply trust that different people will take care of their areas. And you can’t underestimate your ability to do more than one thing. I am convinced that we’ve really become lazy in America. We don’t want to really work. Give us a list of tasks and let us work 9 to 5 and only 5 days a week and we’re happy. Well, that attitude hasn’t worked well for me since doing my first real startup company, NetAttach. Back then I was still primarily a marketing person. My engineering expertise was mostly tied to designing hardware. I got pulled into doing software by accident. We were designing the industry’s first NAS appliance based on Linux and open-source and my sales guy wanted to see Appletalk supported in the first release. Well, my VP of engineering told us both that it wasn’t possible. This was one of those open-ended impossibles. It wasn’t just impossible for the first release, but also indefinitely. Ever get that type of news, only to feel rather dissatisfied?

Well, I went away over the weekend and came back that Monday to demonstrate the feature. This was rather difficult for me back then. I had tinkered a little with software back then. But doing kernel work was a little over my head. But I got the point across, though. And the example was sufficient for my VP of engineering to have a path to get Appletalk designed into the first release of our product.

This wasn’t my first example of having to undertake such work to prove a point. I think the first real example of doing this with software was when I was hired to run product marketing for a company called HolonTech. I can’t even recall how many weeks went by where our engineering team failed to show any progress on our management software. We wanted something that would be cross-platform capable and Java looked to be the tool of choice back then. The primary topic of debate was the inability to create drop down menus in Java. Seriously! This was back in 1994. So, that week I went and bought myself a copy of Visual Cafe’ and I came back with a rudimentary GUI for one of our products, complete with drop-down menus. It was crude, but I didn’t get pushed around again in that Monday’s meeting.

Now, there are a few different spirits with which to do things like these. Back in my earlier days, I did things a little out of spite. I have always hated to be told what couldn’t be done. These days I do it with a much different attitude. I’ve been around a little longer and have hence seen things that others haven’t. This provides me a unique perspective. I can visualize a problem and a solution. I do my work with the intention of allowing others to visualize what’s in my head and to see a path to the solution. Sometimes what I do is very sufficient. Sometimes it needs to be enhanced a bit. And that’s something that I have had to learn to deal with– giving something up so that others can own it. Otherwise, you risk alienating your engineering team. And no company can afford that.

Well, these times are a bit more challenging than some of the ones I’ve previously lived through. And I believe it’s necessary to dig into the extra reserves. I’m absolutely resolved to make my company successful. And to do this, it’s going to require diverting every little bit of capital to sales. And that means taking on additional personal work to ensure that can happen. When you consider the fact that there are 168 hours in a week, it’s amazing how most people operate on the notion of merely working 40 hours per week. When you get rid of all the unnecessary breaks, chewing the fat, going out to lunches, etc., it’s actually quite easy to find the extra time to do more than one job. But it requires an excessive amount of determination and discipline. This reminds me of an old skit from In Living Color. Remember the Hey Mon family? Take a look at this clip and enjoy!

IET 0.4.17 Patches for SLES10SP2

If you're using Suse Linux Enterprise Server (SLES) 10 SP2 and want the latest version of the iSCSI Enterprise Target (IET), aka iscsitarget, you'll want this patch set to basically back out a lot of the compatibility stuff that was placed in the patch's Makefile.

The reason this special patch is necessary is due to the backporting of numerous functions from 2.6.25 kernel into Novell's 2.6.16 kernel used in SLES10SP2. This version update is especially necessary if you wish to make use of blockio.

To apply this patch, use the following procedures:

  1. copy the iet-0.4.17 to your system: 'svn checkout svn://svn.berlios.de/iscsitarget/trunk'
  2. cd trunk/
  3. patch -p1 < ../[this patch]
  4. make sure openssl-devl is installed
  5. make&&make install

Enjoy!

C:
  1. diff -Nur trunk/Makefile iet-0.4.16_sles10sp2/Makefile
  2. --- trunk/Makefile  2008-11-03 15:31:35.504757355 -0700
  3. +++ iet-0.4.16_sles10sp2/Makefile   2008-11-02 16:00:51.000000000 -0700
  4. @@ -51,31 +51,6 @@
  5.  # base first the earlier patch sets will not need to be modified.
  6.  #
  7.  
  8. -# Compatibility patch for kernels>= 2.6.22 and <= 2.6.23
  9. -ifeq ($(call kver_le,2,6,23),1)
  10. -   PATCHES := $(PATCHES) compat-2.6.22-2.6.23.patch
  11. -endif
  12. -
  13. -# Compatibility patch for kernels>= 2.6.19 and <= 2.6.21
  14. -ifeq ($(call kver_le,2,6,21),1)
  15. -   PATCHES := $(PATCHES) compat-2.6.19-2.6.21.patch
  16. -endif
  17. -
  18. -# Compatibility patch for kernels>= 2.6.14 and <= 2.6.18
  19. -ifeq ($(call kver_le,2,6,18),1)
  20. -   PATCHES := $(PATCHES) compat-2.6.14-2.6.18.patch
  21. -endif
  22. -
  23. -# We don't support kernels <2.6.14 except for explicit distros
  24. -ifeq ($(call kver_lt,2,6,14),1)
  25. -   UNSUPPORTED := true
  26. -endif
  27. -
  28. -# Compatibility patch for RHEL4/CentOS4
  29. -ifeq ($(call kver_lk,"2\.6\.9-.*\.(EL|plus\.c4)"),1)
  30. -   PATCHES += compat-rhel4.patch
  31. -   UNSUPPORTED :=
  32. -endif
  33.  
  34.  MANPAGES:= ietadm.8 ietd.8 ietd.conf.5
  35.  
  36. Files trunk/kernel/._block-io.c and iet-0.4.16_sles10sp2/kernel/._block-io.c differ
  37. Files trunk/kernel/._iscsi.c and iet-0.4.16_sles10sp2/kernel/._iscsi.c differ
  38. diff -Nur trunk/kernel/block-io.c iet-0.4.16_sles10sp2/kernel/block-io.c
  39. --- trunk/kernel/block-io.c 2008-11-03 15:31:34.132495685 -0700
  40. +++ iet-0.4.16_sles10sp2/kernel/block-io.c  2008-11-02 15:57:55.000000000 -0700
  41. @@ -11,12 +11,12 @@
  42.  
  43.  #include <linux/types.h>
  44.  #include <linux/blkdev.h>
  45. -#include <linux/parser.h>
  46.  #include <linux/buffer_head.h>
  47.  
  48.  #include "iscsi.h"
  49.  #include "iscsi_dbg.h"
  50.  #include "iotype.h"
  51. +#include <linux/parser.h>
  52.  
  53.  struct blockio_data {
  54.     char *path;
  55. @@ -29,10 +29,15 @@
  56.     struct completion tio_complete;
  57.  };
  58.  
  59. -static void blockio_bio_endio(struct bio *bio, int error)
  60. +static int
  61. +blockio_bio_endio(struct bio *bio, unsigned int bytes_done, int error)
  62.  {
  63.     struct tio_work *tio_work = bio->bi_private;
  64.  
  65. +   /* Ignore partials */
  66. +   if (bio->bi_size)
  67. +      return 1;
  68. +
  69.     error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
  70.  
  71.     if (error)
  72. @@ -43,6 +48,8 @@
  73.        complete(&tio_work->tio_complete);
  74.  
  75.     bio_put(bio);
  76. +
  77. +   return 0;
  78.  }
  79.  
  80.  /*
  81. diff -Nur trunk/kernel/config.c iet-0.4.16_sles10sp2/kernel/config.c
  82. --- trunk/kernel/config.c   2008-11-03 15:31:34.132495685 -0700
  83. +++ iet-0.4.16_sles10sp2/kernel/config.c    2008-11-02 15:55:25.000000000 -0700
  84. @@ -40,7 +40,7 @@
  85.    int i;
  86.    struct proc_dir_entry *ent;
  87. -   if (!(proc_iet_dir = proc_mkdir("iet", init_net.proc_net)))
  88. +   if (!(proc_iet_dir = proc_mkdir("net/iet", 0)))
  89.       goto err;
  90.    proc_iet_dir->owner = THIS_MODULE;
  91. diff -Nur trunk/kernel/digest.c iet-0.4.16_sles10sp2/kernel/digest.c
  92. --- trunk/kernel/digest.c   2008-11-03 15:31:34.176504077 -0700
  93. +++ iet-0.4.16_sles10sp2/kernel/digest.c    2008-11-02 15:59:47.000000000 -0700
  94. @@ -12,8 +12,8 @@
  95. void digest_alg_available(unsigned int *val)
  96. {
  97. -   if (*val & DIGEST_CRC32C &&
  98. -       !crypto_has_alg("crc32c", 0, CRYPTO_ALG_ASYNC)) {
  99. +   //if (*val & DIGEST_CRC32C && !crypto_alg_available("crc32c", 0)) {
  100. +   if (*val & DIGEST_CRC32C && !crypto_has_alg("crc32c", 0, 0)) {
  101.       printk("CRC32C digest algorithm not available in kernel\n");
  102.       *val |= ~DIGEST_CRC32C;
  103.    }
  104. @@ -37,10 +37,13 @@
  105.    if (!(conn->ddigest_type & DIGEST_ALL))
  106.       conn->ddigest_type = DIGEST_NONE;
  107. +   //if (conn->hdigest_type & DIGEST_CRC32C || conn->ddigest_type & DIGEST_CRC32C) {
  108. +   // conn->rx_digest_tfm = crypto_alloc_tfm("crc32c", 0);
  109. +   // if (!conn->rx_digest_tfm) {
  110.    if (conn->hdigest_type & DIGEST_CRC32C ||
  111. -       conn->ddigest_type & DIGEST_CRC32C) {
  112. +      conn->ddigest_type & DIGEST_CRC32C) {
  113.       conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
  114. -                        CRYPTO_ALG_ASYNC);
  115. +                     CRYPTO_ALG_ASYNC);
  116.       conn->rx_hash.flags = 0;
  117.       if (IS_ERR(conn->rx_hash.tfm)) {
  118.          conn->rx_hash.tfm = NULL;
  119. @@ -48,8 +51,10 @@
  120.          goto out;
  121.       }
  122. +      //conn->tx_digest_tfm = crypto_alloc_tfm("crc32c", 0);
  123. +      //if (!conn->tx_digest_tfm) {
  124.       conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
  125. -                        CRYPTO_ALG_ASYNC);
  126. +                     CRYPTO_ALG_ASYNC);
  127.       conn->tx_hash.flags = 0;
  128.       if (IS_ERR(conn->tx_hash.tfm)) {
  129.          conn->tx_hash.tfm = NULL;
  130. @@ -73,6 +78,10 @@
  131.   */
  132.  void digest_cleanup(struct iscsi_conn *conn)
  133.  {
  134. +   //if (conn->tx_digest_tfm)
  135. +   // crypto_free_tfm(conn->tx_digest_tfm);
  136. +   //if (conn->rx_digest_tfm)
  137. +   // crypto_free_tfm(conn->rx_digest_tfm);
  138.     if (conn->tx_hash.tfm)
  139.        crypto_free_hash(conn->tx_hash.tfm);
  140.     if (conn->rx_hash.tfm)
  141. @@ -160,22 +169,34 @@
  142.     }
  143.  }
  144.  
  145. -static void digest_header(struct hash_desc *hash, struct iscsi_pdu *pdu,
  146. -           u8 *crc)
  147. +/* Copied from linux-iscsi initiator and slightly adjusted */
  148. +#define SETSG(sg, p, l) do {               \
  149. +   (sg).page = virt_to_page((p));    \
  150. +   (sg).offset = ((unsigned long)(p) & ~PAGE_CACHE_MASK); \
  151. +   (sg).length = (l);     \
  152. +} while (0)
  153. +
  154. +static void digest_header(struct crypto_desc *hash, struct iscsi_pdu *pdu, u8 *crc)
  155.  {
  156.     struct scatterlist sg[2];
  157. +   //int i = 0;
  158.     unsigned int nbytes = sizeof(struct iscsi_hdr);
  159.  
  160. -   sg_init_table(sg, pdu->ahssize ? 2 : 1);
  161. -
  162. -   sg_set_buf(&sg[0], &pdu->bhs, nbytes);
  163. +   //SETSG(sg[i], &pdu->bhs, sizeof(struct iscsi_hdr));
  164. +   //i++;
  165. +   SETSG(sg[0], &pdu->bhs, nbytes);
  166.     if (pdu->ahssize) {
  167. -      sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize);
  168. +      //SETSG(sg[i], pdu->ahs, pdu->ahssize);
  169. +      //i++;
  170. +      SETSG(sg[1], pdu->ahs, pdu->ahssize);
  171.        nbytes += pdu->ahssize;
  172.     }
  173.  
  174. +   //crypto_digest_init(tfm);
  175.     crypto_hash_init(hash);
  176. +   //crypto_digest_update(tfm, sg, i);
  177.     crypto_hash_update(hash, sg, nbytes);
  178. +   //crypto_digest_final(tfm, crc);
  179.     crypto_hash_final(hash, crc);
  180.  }
  181.  
  182. @@ -183,6 +204,7 @@
  183.  {
  184.     u32 crc;
  185.  
  186. +   //digest_header(cmnd->conn->rx_digest_tfm, &cmnd->pdu, (u8 *) &crc);
  187.     digest_header(&cmnd->conn->rx_hash, &cmnd->pdu, (u8 *) &crc);
  188.     if (crc != cmnd->hdigest)
  189.        return -EIO;
  190. @@ -192,9 +214,11 @@
  191.  
  192.  void digest_tx_header(struct iscsi_cmnd *cmnd)
  193.  {
  194. -   digest_header(&cmnd->conn->tx_hash, &cmnd->pdu, (u8 *) &cmnd->hdigest);
  195. +   //digest_header(cmnd->conn->tx_digest_tfm, &cmnd->pdu, (u8 *) &cmnd->hdigest);
  196. +   digest_header(&cmnd->conn->tx_hash, &cmnd->pdu, (u8 *)&cmnd->hdigest);
  197.  }
  198.  
  199. +//static void digest_data(struct crypto_tfm *tfm, struct iscsi_cmnd *cmnd,
  200.  static void digest_data(struct hash_desc *hash, struct iscsi_cmnd *cmnd,
  201.           struct tio *tio, u32 offset, u8 *crc)
  202.  {
  203. @@ -204,6 +228,7 @@
  204.     unsigned int nbytes;
  205.  
  206.     size = cmnd->pdu.datasize;
  207. +   //size = (size + 3) & ~3;
  208.     nbytes = size = (size + 3) & ~3;
  209.  
  210.     offset += tio->offset;
  211. @@ -214,7 +239,7 @@
  212.  
  213.     assert(count <= ISCSI_CONN_IOV_MAX);
  214.  
  215. -   sg_init_table(sg, ARRAY_SIZE(cmnd->conn->hash_sg));
  216. +   //crypto_digest_init(tfm);
  217.     crypto_hash_init(hash);
  218.  
  219.     for (i = 0; size; i++) {
  220. @@ -223,13 +248,15 @@
  221.        else
  222.           length = size;
  223.  
  224. -      sg_set_page(&sg[i], tio->pvec[idx + i], length, offset);
  225. +      sg[i].page = tio->pvec[idx + i];
  226. +      sg[i].offset = offset;
  227. +      sg[i].length = length;
  228.        size -= length;
  229.        offset = 0;
  230.     }
  231.  
  232. -   sg_mark_end(&sg[i - 1]);
  233. -
  234. +   //crypto_digest_update(tfm, sg, count);
  235. +   //crypto_digest_final(tfm, crc);
  236.     crypto_hash_update(hash, sg, nbytes);
  237.     crypto_hash_final(hash, crc);
  238.  }
  239. @@ -257,10 +284,12 @@
  240.        offset = 0;
  241.     }
  242.  
  243. +   //digest_data(cmnd->conn->rx_digest_tfm, cmnd, tio, offset, (u8 *) &crc);
  244.     digest_data(&cmnd->conn->rx_hash, cmnd, tio, offset, (u8 *) &crc);
  245.  
  246. +   //if (!cmnd->conn->read_overflow && (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) {
  247.     if (!cmnd->conn->read_overflow &&
  248. -       (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) {
  249. +      (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) {
  250.        if (crc != cmnd->ddigest)
  251.           return -EIO;
  252.     }
  253. @@ -274,6 +303,7 @@
  254.     struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs;
  255.  
  256.     assert(tio);
  257. +   //digest_data(cmnd->conn->tx_digest_tfm, cmnd, tio,
  258.     digest_data(&cmnd->conn->tx_hash, cmnd, tio,
  259.            be32_to_cpu(req->buffer_offset), (u8 *) &cmnd->ddigest);
  260.  }
  261. diff -Nur trunk/kernel/event.c iet-0.4.16_sles10sp2/kernel/event.c
  262. --- trunk/kernel/event.c    2008-11-03 15:31:34.184505603 -0700
  263. +++ iet-0.4.16_sles10sp2/kernel/event.c 2008-11-02 15:55:25.000000000 -0700
  264. @@ -28,7 +28,7 @@
  265.     return 0;
  266.  }
  267.  
  268. -static void event_recv_skb(struct sk_buff *skb)
  269. +static int event_recv_skb(struct sk_buff *skb)
  270.  {
  271.     int err;
  272.     struct nlmsghdr    *nlh;
  273. @@ -37,7 +37,7 @@
  274.     while (skb->len>= NLMSG_SPACE(0)) {
  275.        nlh = (struct nlmsghdr *)skb->data;
  276.        if (nlh->nlmsg_len <sizeof(*nlh) || skb->len <nlh->nlmsg_len)
  277. -         break;
  278. +         return 0;
  279.        rlen = NLMSG_ALIGN(nlh->nlmsg_len);
  280.        if (rlen> skb->len)
  281.           rlen = skb->len;
  282. @@ -47,6 +47,19 @@
  283.           netlink_ack(skb, nlh, 0);
  284.        skb_pull(skb, rlen);
  285.     }
  286. +   return 0;
  287. +}
  288. +
  289. +static void event_recv(struct sock *sk, int length)
  290. +{
  291. +   struct sk_buff *skb;
  292. +
  293. +   while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
  294. +      if (event_recv_skb(skb) && skb->len)
  295. +         skb_queue_head(&sk->sk_receive_queue, skb);
  296. +      else
  297. +         kfree_skb(skb);
  298. +   }
  299.  }
  300.  
  301.  static int notify(void *data, int len, int gfp_mask)
  302. @@ -82,8 +95,7 @@
  303.  
  304.  int event_init(void)
  305.  {
  306. -   nl = netlink_kernel_create(&init_net, NETLINK_IET, 1, event_recv_skb,
  307. -               NULL, THIS_MODULE);
  308. +   nl = netlink_kernel_create(NETLINK_IET, 1, event_recv, THIS_MODULE);
  309.     if (!nl)
  310.        return -ENOMEM;
  311.     else
  312. diff -Nur trunk/kernel/file-io.c iet-0.4.16_sles10sp2/kernel/file-io.c
  313. --- trunk/kernel/file-io.c  2008-11-03 15:31:34.188506365 -0700
  314. +++ iet-0.4.16_sles10sp2/kernel/file-io.c   2008-11-02 15:55:25.000000000 -0700
  315. @@ -53,9 +53,9 @@
  316.        set_fs(get_ds());
  317.  
  318.        if (rw == READ)
  319. -         ret = do_sync_read(filp, buf, count, &ppos);
  320. +         ret = generic_file_read(filp, buf, count, &ppos);
  321.        else
  322. -         ret = do_sync_write(filp, buf, count, &ppos);
  323. +         ret = generic_file_write(filp, buf, count, &ppos);
  324.  
  325.        set_fs(oldfs);
  326.  
  327. diff -Nur trunk/kernel/iscsi.c iet-0.4.16_sles10sp2/kernel/iscsi.c
  328. --- trunk/kernel/iscsi.c    2008-11-03 15:31:34.136496448 -0700
  329. +++ iet-0.4.16_sles10sp2/kernel/iscsi.c 2008-11-02 15:59:01.000000000 -0700
  330. @@ -15,7 +15,7 @@
  331.  
  332.  unsigned long debug_enable_flags;
  333.  
  334. -static struct kmem_cache *iscsi_cmnd_cache;
  335. +static kmem_cache_t *iscsi_cmnd_cache;
  336.  static u8 dummy_data[PAGE_SIZE];
  337.  
  338.  static int ctr_major;
  339. @@ -1762,7 +1762,8 @@
  340.     if ((err = event_init()) <0)
  341.        goto err;
  342.  
  343. -   iscsi_cmnd_cache = KMEM_CACHE(iscsi_cmnd, 0);
  344. +   iscsi_cmnd_cache = kmem_cache_create("iscsi_cmnd", sizeof(struct iscsi_cmnd),
  345. +                    0, 0, NULL, NULL);
  346.     if (!iscsi_cmnd_cache)
  347.        goto err;
  348.  
  349. diff -Nur trunk/kernel/iscsi.h iet-0.4.16_sles10sp2/kernel/iscsi.h
  350. --- trunk/kernel/iscsi.h    2008-11-03 15:31:34.176504077 -0700
  351. +++ iet-0.4.16_sles10sp2/kernel/iscsi.h 2008-11-03 15:32:49.342836992 -0700
  352. @@ -241,6 +241,8 @@
  353.     u32 write_offset;
  354.     int write_state;
  355.  
  356. +   //struct crypto_tfm *rx_digest_tfm;
  357. +   //struct crypto_tfm *tx_digest_tfm;
  358.     struct hash_desc rx_hash;
  359.     struct hash_desc tx_hash;
  360.     struct scatterlist hash_sg[ISCSI_CONN_IOV_MAX];
  361. diff -Nur trunk/kernel/tio.c iet-0.4.16_sles10sp2/kernel/tio.c
  362. --- trunk/kernel/tio.c  2008-11-03 15:31:34.568578840 -0700
  363. +++ iet-0.4.16_sles10sp2/kernel/tio.c   2008-11-02 15:55:25.000000000 -0700
  364. @@ -35,7 +35,7 @@
  365.     return 0;
  366.  }
  367.  
  368. -static struct kmem_cache *tio_cache;
  369. +static kmem_cache_t *tio_cache;
  370.  
  371.  struct tio *tio_alloc(int count)
  372.  {
  373. @@ -110,7 +110,8 @@
  374.  
  375.  int tio_init(void)
  376.  {
  377. -   tio_cache = KMEM_CACHE(tio, 0);
  378. +   tio_cache = kmem_cache_create("tio", sizeof(struct tio),
  379. +                  0, 0, NULL, NULL);
  380.     return  tio_cache ? 0 : -ENOMEM;
  381.  }