在RHEL系统上使用“subscription-manager”注册和激活“subscription”

RHEL系统中注册和使用subscription是两个过程:

NOTE: With Red Hat Subscription-Manager, registration and utilization of a subscription is actually a two-part process. First register a system, then apply a subscription.

可以使用下面命令一次完成两个过程:

# subscription-manager register --username <username> --password <password> --auto-attach

在我的RHEL 7.2系统上执行上述命令:

# subscription-manager register --username=xxxx --password=xxxx --auto-attach
Registering to: subscription.rhn.redhat.com:443/subscription
The system has been registered with ID: 333486bb-xxxxxx

Installed Product Current Status:
Product Name: Red Hat Enterprise Linux Server
Status:       Subscribed

然后检查状态:

# subscription-manager list

+-------------------------------------------+
    Installed Product Status
+-------------------------------------------+
Product Name:   Red Hat Enterprise Linux Server
Product ID:     69
Version:        7.2
Arch:           x86_64
Status:         Subscribed
Status Details:
Starts:         06/29/2015
Ends:           06/28/2016

接下来就可以使用“yum install”,“yum update”等命令安装和更新软件了,非常方便。

参考资料:
How to Register and Enable Red Hat Subscription, Repositories and Updates for RHEL 7.0 Server
How to register and subscribe a system to the Red Hat Customer Portal using Red Hat Subscription-Manager
RHEL : Register Subscription

 

Haskell笔记 (10)—— Lazy evaluation

Haskell中对表达式的计算使用的是Lazy evaluation(也称之为nonstrict evaluation):即只有表达式的值真正需要时,才会被计算。Haskell中把用来跟踪还没有计算的表达式的记录称之为trunk

参考自stackoverflow

Mostly because it can be more efficient — values don’t need to be computed if they’re not going to be used. For example, I may pass three values into a function, but depending on the sequence of conditional expressions, only a subset may actually be used. In a language like C, all three values would be computed anyway; but in Haskell, only the necessary values are computed.

It also allows for cool stuff like infinite lists. I can’t have an infinite list in a language like C, but in Haskell, that’s no problem. Infinite lists are used fairly often in certain areas of mathematics, so it can be useful to have the ability to manipulate them.

Lazy evaluation的优点:高效(延迟执行代码),支持像infinite lists这样的cool stuff

 

Mesos笔记 (9)—— Containerizer类代码解析

Containerizer类(定义在src/slave/containerizer/containerizer.hpp )是所有Containerizer的抽象父类。除了默认的构造函数和一个什么都没做的析构函数,其只实现了createresources方法。create方法代码如下(v0.26版本):

Try<Containerizer*> Containerizer::create(
    const Flags& flags,
    bool local,
    Fetcher* fetcher)
{
  if (flags.isolation == "external") {
    LOG(WARNING) << "The 'external' isolation flag is deprecated, "
                 << "please update your flags to"
                 << " '--containerizers=external'.";

    Try<ExternalContainerizer*> containerizer =
      ExternalContainerizer::create(flags);
    if (containerizer.isError()) {
      return Error("Could not create ExternalContainerizer: " +
                   containerizer.error());
    }

    return containerizer.get();
  }

  // TODO(benh): We need to store which containerizer or
  // containerizers were being used. See MESOS-1663.

  // Create containerizer(s).
  vector<Containerizer*> containerizers;

  foreach (const string& type, strings::split(flags.containerizers, ",")) {
    if (type == "mesos") {
      Try<MesosContainerizer*> containerizer =
        MesosContainerizer::create(flags, local, fetcher);
      if (containerizer.isError()) {
        return Error("Could not create MesosContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else if (type == "docker") {
      Try<DockerContainerizer*> containerizer =
        DockerContainerizer::create(flags, fetcher);
      if (containerizer.isError()) {
        return Error("Could not create DockerContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else if (type == "external") {
      Try<ExternalContainerizer*> containerizer =
        ExternalContainerizer::create(flags);
      if (containerizer.isError()) {
        return Error("Could not create ExternalContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else {
      return Error("Unknown or unsupported containerizer: " + type);
    }
  }

  if (containerizers.size() == 1) {
    return containerizers.front();
  }

  Try<ComposingContainerizer*> containerizer =
    ComposingContainerizer::create(containerizers);

  if (containerizer.isError()) {
    return Error(containerizer.error());
  }

  return containerizer.get();
}

默认情况下,containerizerstypemesos,所以会调用MesosContainerizer::create来生成containerizer。关于resources方法,参考Mesos笔记 (5)—— 资源

 

使用LXC初体验

我使用的OSCentOS 7.1,需要安装lxclxc-templates。安装后的模板在/usr/share/lxc/templates目录下:

# ls
lxc-alpine    lxc-archlinux  lxc-centos  lxc-debian    lxc-fedora  lxc-openmandriva  lxc-oracle  lxc-sshd    lxc-ubuntu-cloud
lxc-altlinux  lxc-busybox    lxc-cirros  lxc-download  lxc-gentoo  lxc-opensuse      lxc-plamo   lxc-ubuntu

接下来以CentOS为模板创建一个container

lxc-create -t centos --name cn-centos

临时的root密码存在/var/lib/lxc/cn-01/tmp_root_pass

# cat /var/lib/lxc/cn-centos/tmp_root_pass
Root-cn-centos-EXb6bB

启动container

# lxc-start -n cn-centos

停止container

# lxc-stop -n cn-centos

参考资料:
Setup Linux Containers Using LXC On Ubuntu 15.04

 

Mesos笔记 (8)—— message格式

MesosFrameworkMasterSlave之间使用http协议传递消息。参考下图:

Capture

由于Transfer-Encodingchunked格式,所以在http message body开始部分会包含data长度:0x44,也就是68个字节。另外,data的编码使用protobuf协议,也是key-value格式,具体编码请参考这里

参考资料:
《HTTP:The Definitive Guide》笔记(2)—— messages
HTTP – What does ‘Transfer-Encoding : Chunked’ mean?

LXC,cgroups和namespace简介

LXC is a userspace interface for the Linux kernel containment features. Through a powerful API and simple tools, it lets Linux users easily create and manage system or application containers.

The linux containers, lxc, aims to use these new functionalities to provide a userspace container object which provides full resource isolation and resource control for an application or a system.

Linux container技术的目标是为应用程序或系统提供完整的资源隔离和控制。LXC项目通过提供一组API接口和工具,可以让其他程序方便地使用Linux container技术。

The container technology is actively being pushed into the mainstream linux kernel. It provides the resource management through the control groups aka process containers and resource isolation through the namespaces.

Linux container技术cgroups(control groups)namespaces实现。两者的功能如下:

cgroups = limits how much you can use;
namespaces = limits what you can see (and therefore use)

Cgroups限制了你能够拥有的资源,而namespces限制了你能够看到的资源。

参考资料:
LXC
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic

 

Haskell笔记 (9)—— typeclass

Typeclass顾名思义:typeclass,类型的分类,同Java中的interface类似。参看下例:

> :t (==)
(==) :: Eq a => a -> a -> Bool

=>之前的Eq a表示:atypeEqtypeclassaEq的一个实例。

参考资料:
Typeclasses 101
Why sum x y is of type (Num a) => a -> a -> a in Haskell?
Explain Type Classes in Haskell

 

CPU,GPU和GPGPU的区别

下面摘自Why are we still using CPUs instead of GPUs?

GPUs have far more processor cores than CPUs, but because each GPU core runs significantly slower than a CPU core and do not have the features needed for modern operating systems, they are not appropriate for performing most of the processing in everyday computing. They are most suited to compute-intensive operations such as video processing and physics simulations.

GPU(Graphics Processing Unit)core数量比CPU的多,它是显卡(video card)的CPU。由于它的指令集不如CPU强大,但是core数量多,所以适合做一些相对简单的,计算密集性的运算:比如图像处理等等。GPGPU(General Purpose Graphics Processing Unit)则不仅仅只做图像处理的相关运算,也会做一些一般性的运算。

更新:计算机屏幕上的图像是如何显示出来的?这个帖子给了很好的解释:

The GPU has a series of registers that the BIOS maps. These permit the CPU to access the GPU’s memory and instruct the GPU to perform operations. The CPU plugs values into those registers to map some of the GPU’s memory so that the CPU can access it. Then it loads instructions into that memory. It then writes a value to a register that tells the GPU to execute the instructions the CPU loaded into its memory.

The information consists of the software that the GPU needs to run. This software is bundled with the driver and then the driver handles the responsibility split between the CPU and GPU (by running portions of its code on both devices).

The driver then manages a series of “windows” into GPU memory that the CPU can read from and write to. Generally, the access pattern involves the CPU writing instructions or information into mapped GPU memory and then instructing the GPU, through a register, to execute those instruction or process that information. The information includes shader logic, textures, and so on.

简单地讲,CPU会把要显示的图像和指令存到显卡(video card)的register中,然后通知GPU(显卡上的CPU)去执行画图命令。 此外,wiki百科上的这张图形象地描述了整个过程:

CUDA_processing_flow_(En)

参考资料:

 

Haskell笔记 (8)—— 类型变量(type variables)

参看下面程序:

> :t head
head :: [a] -> a

这里的a不是typeHaskell中的类型以大写字母开头),而是type variale,可以代表任一类型,有点类似于其它编程语言的generics。含有type variable的函数称之为polymorphic functions

现在可以知道为什么type名字必须以大写字母开头,这是为了与type variable名字区分开。type variable必须以小写字母开头。 

此外:

You can always tell a type variable from a normal variable by context, because the languages of types and functions are separate: type variables live in type signatures, and regular variables live in normal expressions.

type variable存在于type signature中,而regular variable则存在于正常的表达式中。

 

Mesos笔记 (7)—— 打印VLOG函数输出的log

默认情况下,Mesos不会输出VLOG函数的log信息。如果想输出的话,需要加上GLOG_v=m

$ sudo GLOG_v=3 ./bin/mesos-master.sh --ip=15.242.100.56 --work_dir=/var/lib/mesos
WARNING: Logging before InitGoogleLogging() is written to STDERR
I1229 22:42:38.818521 11830 process.cpp:2426] Spawned process __gc__@15.242.100.56:5050
I1229 22:42:38.818613 11846 process.cpp:2436] Resuming __gc__@15.242.100.56:5050 at 2015-12-30 03:42:38.818540032+00:00
I1229 22:42:38.818749 11847 process.cpp:2436] Resuming __gc__@15.242.100.56:5050 at 2015-12-30 03:42:38.818712832+00:00
I1229 22:42:38.818802 11844 process.cpp:2436] Resuming help@15.242.100.56:5050 at 2015-12-30 03:42:38.818746112+00:00
I1229 22:42:38.819092 11844 process.cpp:2393] Dropping event for process @0.0.0.0:0
I1229 22:42:38.819212 11830 process.cpp:2426] Spawned process help@15.242.100.56:5050
I1229 22:42:38.819373 11858 process.cpp:2436] Resuming __gc__@15.242.100.56:5050 at 2015-12-30 03:42:38.819341056+00:00
I1229 22:42:38.819762 11830 process.cpp:2426] Spawned process logging@15.242.100.56:5050
I1229 22:42:38.819864 11830 process.cpp:2426] Spawned process profiler@15.242.100.56:5050
I1229 22:42:38.819890 11854 process.cpp:2436] Resuming logging@15.242.100.56:5050 at 2015-12-30 03:42:38.819844096+00:00
I1229 22:42:38.819907 11849 process.cpp:2436] Resuming profiler@15.242.100.56:5050 at 2015-12-30 03:42:38.819878144+00:00
......

参考资料:
Re: How can mesos print logs from VLOG function?