Example #1
0
        public static LocalIdentifierLock GetIdentifierForNameAndLock(string category, string name)
        {
            NodeID nodeid = null;

            if (!Regex.IsMatch(name, "^[a-zA-Z][a-zA-Z0-9_\\.\\-]*$"))
            {
                throw new ArgumentException("\"" + name + "\" is an invalid identifier name");
            }

            category = category.ToLowerInvariant();

            var storage_path = GetUserIdentifierStoragePath();

            Directory.CreateDirectory(Path.Combine(storage_path, category));
            string p = Path.Combine(storage_path, category, name);

            bool is_windows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);


            LocalIdentifierFD fd     = null;
            LocalIdentifierFD fd_run = null;

            try
            {
                if (is_windows)
                {
                    fd = new LocalIdentifierFD();

                    int error_code;
                    if (!fd.OpenLockWrite(p, false, out error_code))
                    {
                        if (error_code == 32)
                        {
                            throw new InvalidOperationException("Identifier already in use");
                        }
                        throw new SystemResourceException("Could not initialize local identifiers");
                    }
                }
                else
                {
                    string p_lock = Path.Combine(GetUserRunPath(), "identifiers");

                    Directory.CreateDirectory(p_lock);

                    p_lock = Path.Combine(p_lock, category);
                    Directory.CreateDirectory(p_lock);

                    p_lock = Path.Combine(p_lock, name + ".pid");

                    fd_run = new LocalIdentifierFD();

                    int open_run_err;
                    if (!fd_run.OpenLockWrite(p_lock, false, out open_run_err))
                    {
                        if (open_run_err == (int)Mono.Unix.Native.Errno.ENOLCK)
                        {
                            throw new InvalidOperationException("Identifier already in use");
                        }
                        throw new SystemResourceException("Could not initialize local identifiers");
                    }

                    string pid_str = Process.GetCurrentProcess().Id.ToString();
                    if (!fd_run.Write(pid_str))
                    {
                        throw new SystemResourceException("Could not initialize local identifiers");
                    }

                    fd = new LocalIdentifierFD();

                    int open_err;
                    if (!fd.OpenLockWrite(p, false, out open_err))
                    {
                        if (open_err == (int)Mono.Unix.Native.Errno.EROFS)
                        {
                            open_err = 0;
                            if (!fd.OpenRead(p, out open_err))
                            {
                                throw new InvalidOperationException("LocalTransport NodeID not set on read only filesystem");
                            }
                        }
                        else
                        {
                            throw new SystemResourceException("Could not initialize LocalTransport server");
                        }
                    }
                }
                int len = fd.FileLen;

                if (len == 0 || len == -1 || len > 16 * 1024)
                {
                    nodeid = NodeID.NewUniqueID();
                    string dat = nodeid.ToString();
                    fd.Write(dat);
                }
                else
                {
                    string nodeid_str;
                    fd.Read(out nodeid_str);
                    try
                    {
                        nodeid_str = nodeid_str.Trim();
                        nodeid     = new NodeID(nodeid_str);
                    }
                    catch (Exception)
                    {
                        throw new IOException("Error in identifier settings file");
                    }
                }

                var ident_uuid = new UUID()
                {
                    uuid_bytes = nodeid.ToByteArray()
                };
                var ident = new Identifier()
                {
                    name = name, uuid = ident_uuid
                };


                if (is_windows)
                {
                    return(new LocalIdentifierLock(ident, fd));
                }
                else
                {
                    fd?.Dispose();
                    return(new LocalIdentifierLock(ident, fd_run));
                }
            }
            catch (Exception)
            {
                fd?.Dispose();
                fd_run?.Dispose();
                throw;
            }
        }
Example #2
0
 internal LocalIdentifierLock(Identifier id, LocalIdentifierFD fd)
 {
     this.fd         = fd;
     this.Identifier = id;
 }