Example #1
0
        private void clearAll()
        {
            // We assume no-one else is using this FreeNAS server right now. We delete everything on it. >:D
            // We do, however, avoid deleting anything beginning with 'blade', so its sort-of safe to run this on
            // the production FreeNAS install, if no-one else is using it, and the only iscsi info you want to keep
            // begins with this string.

            FreeNASWithCaching foo = new FreeNASWithCaching(nashostname, nasusername, naspassword);

            foreach (iscsiTarget tgt in foo.getISCSITargets().Where(x => !x.targetName.StartsWith("blade")))
            {
                foo.deleteISCSITarget(tgt);
            }

            foreach (iscsiExtent ext in foo.getExtents().Where(x => !x.iscsi_target_extent_name.StartsWith("blade")))
            {
                foo.deleteISCSIExtent(ext);
            }

            foreach (iscsiTargetToExtentMapping tte in foo.getTargetToExtents())
            {
                var tgt = foo.getISCSITargets().SingleOrDefault(x => x.id == tte.iscsi_target);
                var ext = foo.getExtents().SingleOrDefault(x => x.id == tte.iscsi_extent);
                if (tgt == null || ext == null)
                {
                    foo.deleteISCSITargetToExtent(tte);
                }
            }

            foo.waitUntilISCSIConfigFlushed();
        }
Example #2
0
        public void canInvalidateThings()
        {
            // Here, we use a second FreeNAS instance to modify data on the server. We then invalidate the first, and ensure that
            // the differences are seen.
            string testPrefix = Guid.NewGuid().ToString();

            FreeNASWithCaching uut       = new FreeNASWithCaching(nashostname, nasusername, naspassword);
            FreeNAS            directNAS = new FreeNAS(nashostname, nasusername, naspassword);

            // Make a test file to export
            using (SSHExecutor exec = new SSHExecutor(nashostname, nasusername, naspassword))
            {
                exec.startExecutable("touch", nastempspace + "/testfile");
            }
            // Add a targets, extents, and target-to-extents
            iscsiTarget tgt = directNAS.addISCSITarget(new iscsiTarget()
            {
                targetName = testPrefix, targetAlias = "idk lol"
            });

            directNAS.createTargetGroup(directNAS.getPortals()[0], tgt);
            iscsiExtent ext = directNAS.addISCSIExtent(new iscsiExtent()
            {
                iscsi_target_extent_name = testPrefix,
                iscsi_target_extent_type = "File",
                iscsi_target_extent_path = nastempspace + "/testfile"
            });

            directNAS.addISCSITargetToExtent(tgt.id, ext);
            directNAS.waitUntilISCSIConfigFlushed();

            // The uut should now be out-of-date
            Assert.AreNotEqual(uut.getExtents().Count, directNAS.getExtents().Count);
            Assert.AreNotEqual(uut.getISCSITargets().Count, directNAS.getISCSITargets().Count);
            Assert.AreNotEqual(uut.getTargetToExtents().Count, directNAS.getTargetToExtents().Count);

            // Invalidate the uut and check that it is then up-to-date.
            uut.invalidateExtents();
            Assert.AreEqual(uut.getExtents().Count, directNAS.getExtents().Count);
            uut.invalidateTargets();
            Assert.AreEqual(uut.getISCSITargets().Count, directNAS.getISCSITargets().Count);
            uut.invalidateTargetToExtents();
            Assert.AreEqual(uut.getTargetToExtents().Count, directNAS.getTargetToExtents().Count);
        }
Example #3
0
        public void extentDeletionImpliesTTEDeletion()
        {
            string testPrefix = Guid.NewGuid().ToString();

            FreeNASWithCaching foo = new FreeNASWithCaching(nashostname, nasusername, naspassword);

            int origExtentCount = foo.getExtents().Count;
            int origTargetCount = foo.getISCSITargets().Count;
            int origTTECount    = foo.getTargetToExtents().Count;

            // Make a test file to export
            string filePath = nastempspace + "/" + testPrefix;

            using (SSHExecutor exec = new SSHExecutor(nashostname, nasusername, naspassword))
            {
                exec.startExecutable("touch", filePath);
            }

            iscsiTarget tgt1 = foo.addISCSITarget(new iscsiTarget()
            {
                targetName = testPrefix
            });
            iscsiExtent ext1 = foo.addISCSIExtent(new iscsiExtent()
            {
                iscsi_target_extent_name = testPrefix,
                iscsi_target_extent_type = "File",
                iscsi_target_extent_path = filePath
            });

            iscsiTargetToExtentMapping tte1 = foo.addISCSITargetToExtent(tgt1.id, ext1);

            foo.waitUntilISCSIConfigFlushed();

            foo.deleteISCSIExtent(ext1);

            Assert.AreEqual(origTTECount, foo.getTargetToExtents().Count());
            Assert.AreEqual(origTargetCount + 1, foo.getISCSITargets().Count());
            Assert.AreEqual(origExtentCount, foo.getExtents().Count());
        }
Example #4
0
        public void willAllowManyExportsAtOnce()
        {
            clearAll();
            FreeNASWithCaching foo = new FreeNASWithCaching(nashostname, nasusername, naspassword);

            //
            // Here we export many files (targets/extents/ttes) from ctld. Eventually, the kernel will hit CTL_MAX_PORTS and things
            // will fail. We ensure that this number is high enough that we are unlikely to have any problems.
            //

            // Make some test files to export
            string        testPrefix       = Guid.NewGuid().ToString();
            int           maxfiles         = 10000;
            int           maxFilesPossible = 0;
            List <string> uncheckedExports = new List <string>(10);

            using (SSHExecutor exec = new SSHExecutor(nashostname, nasusername, naspassword))
            {
                exec.startExecutable("/bin/sh", string.Format("-c " +
                                                              "'for a in `seq 0 {0}`; do touch {1}/testfile_${{a}}; done'", maxfiles, nastempspace));

                // Add some targets, extents, target-to-extents, and see how many we add before they stop working.
                // This is likely to be 256 for a 'factory' image, or 2048 for an XDL-customised image. Note, though,
                // that if you're using a small root partition on the FreeNAS box (which you should be, imo, because
                // a large amount of space encourages issues like this one to go unnoticed until they subtly degrade
                // performance later - and wear out the media, if root is on sdcard, which it is on store.xd.lan),
                // you may run out of space if collectd is not stopped. You can confirm this by observing that
                // collectd's dir in /var/db/collectd/rrd is huge.

                int preExisting = foo.getTargetToExtents().Count;
                for (int i = preExisting; i < maxfiles; i++)
                {
                    iscsiTarget tgt = foo.addISCSITarget(new iscsiTarget()
                    {
                        targetName = testPrefix + "-" + i
                    });
                    foo.createTargetGroup(foo.getPortals()[0], tgt);
                    iscsiExtent ext = foo.addISCSIExtent(new iscsiExtent()
                    {
                        iscsi_target_extent_name = testPrefix + "_" + i,
                        iscsi_target_extent_type = "File",
                        iscsi_target_extent_path = nastempspace + "/testfile_" + i
                    });

                    foo.addISCSITargetToExtent(tgt.id, ext);

                    uncheckedExports.Add(tgt.targetName);

                    if (i % 100 == 0)
                    {
                        // Every hundred, we reload and see if each has been exported correctly.
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        bool limitReached = false;
                        try
                        {
                            foo.waitUntilISCSIConfigFlushed();
                        }
                        catch (nasServerFullException)
                        {
                            // ok cool, we've reached our limit.
                            limitReached = true;
                        }
                        //Thread.Sleep(1000 + (i * 10));
                        watch.Stop();
                        Debug.WriteLine("Flush after adding " + i + " exports: took " + watch.ElapsedMilliseconds + " ms");

                        executionResult res = exec.startExecutable("ctladm", "portlist -f iscsi");
                        Assert.AreEqual(0, res.resultCode);

                        // Each of our unchecked testfiles should appear exactly once in this list.
                        // If not, we know we've reached the limit of what the kernel can support.
                        string[] lines = res.stdout.Split('\n');
                        for (int uncheckedIndex = 0; uncheckedIndex < uncheckedExports.Count; uncheckedIndex++)
                        {
                            var exportToCheck = uncheckedExports[uncheckedIndex];

                            if (lines.Count(x => x.Contains(exportToCheck + ",")) != 1)
                            {
                                // Oh, we've failed to export something!
                                maxFilesPossible  = i - uncheckedIndex;
                                maxFilesPossible -= 2;
                                i = maxfiles;
                                break;
                            }
                        }
                        if (limitReached)
                        {
                            maxFilesPossible = i;
                            break;
                        }
                        uncheckedExports.Clear();
                    }
                }
            }
            // Our XDL build has CTL_MAX_PORTS set to 2048, so this should be very high.
            Assert.IsTrue(maxFilesPossible >= 2048, "maxFilesPossible is " + maxFilesPossible + " which is less than 2048");
        }