30 Ağustos 2021 Pazartesi

find komutu printf seçeneği

Specifier Olmayan Şeyler
Örnek
Boş dizinleri saymak için şöyle yaparızz
find . -maxdepth 1 -type d -empty -printf '\n' | wc -l
%h specifier - dirname
Örnek
*.c uzantılı dosyaların bulunduğu dizini yazdırmak için şöyle yaparız
find . -type f -iname '*.c' -printf '%h\0' |
  sort -z |
  uniq -zc |
%g specifier - group name
group bilgisini verir.

%s specifier - File's size in bytes
Örnek
Boyu en büyük dosyaları bulmak için şöyle yaparız
find . -mindepth 2 -printf "%s\t%p\n" | sort -n | cut -f 2- | tail -n $n
%p specifier - file's name
Örnek
Şöyle yaparız. %y ile d veya f karakteri dizin veya dosya olduğunu belirtir. %p ile dosya/dizin ismi gösterilir.
$ sudo find . -name 'example.com*' -printf "%y %p\n"
d ./archive/example.com
f ./renewal/example.com.conf
d ./live/example.com
%P specifier - Dosyanın Bulunduğu Dizin İsmi
Açıklaması şöyle. Yani en son dizinin ismini verir.
File's name with the name of the starting-point under which it was found removed.
Örnek
Şöyle yaparız
find /Volumes/SpeedyG -type d >> file.txt

# Çıktı şöyle
/Volumes/SpeedyG/folder1  
/Volumes/SpeedyG/folder2  
/Volumes/SpeedyG/folder2

find /Volumes/SpeedyG -type d -printf '%P\n' >> file.txt

# Çıktı şöyle
folder1  
folder2  
folder3
Örnek
Şöyle yaparız
$ find /usr/local/bin/ /bin/ -printf '%P\n'
%t - File's last modification time
Örnek ver

%u specifier - File's user name
user yani dosya sahibini (owner) verir. Şöyle yaparız.
$ sudo find /var -printf '%u:%g\n' | sort -t: -u
_apt:root
clamav:adm
clamav:clamav
colord:colord
daemon:daemon
lightdm:lightdm
lp:lp
man:root
speech-dispatcher:root
statd:nogroup
steeldriver:crontab
steeldriver:lightdm
steeldriver:steeldriver
syslog:adm
systemd-timesync:systemd-timesync
testuser:crontab


23 Ağustos 2021 Pazartesi

Kubernetes ve DNS

Giriş
Açıklaması şöyle
You can set up a DNS service for your Kubernetes cluster using an add-on.

We all know how DNS works in the case of the internet. Every website has a unique address a.k.a domain (for e.g. www.amazon.com). A similar approach is applied in the case of service discovery in Kubernetes. DNS server watches the Kubernetes for new services and creates a set of DNS records for each one. If DNS has been enabled throughout your cluster then all Pods should automatically be able to resolve services by their DNS name.

For instance, in our case, the DNS service and control plane (Kubernetes control panel) acting together create a DNS record of shoppingcart-service.dev-ns . Pods in the dev-ns the namespace should be able to find the service by doing a name lookup for shoppingcart-service

Kubernetes provides the concept of namespaces to segregate different concerns. For instances, you can have different namespaces for dev, test and prodenvironments.
Headless Service
Açıklaması şöyle
Luckily, Kubernetes allows clients to discover pod IPs through DNS lookups. Usually, when you perform a DNS lookup for a service, the DNS server returns a single IP — the service’s cluster IP. But if you tell Kubernetes you don’t need a cluster IP for your service (you do this by setting the clusterIP field to None in the service specification ), the DNS server will return the pod IPs instead of the single service IP. Instead of returning a single DNS A record, the DNS server will return multiple A records for the service, each pointing to the IP of an individual pod backing the service at that moment. Clients can therefore do a simple DNS A record lookup and get the IPs of all the pods that are part of the service. The client can then use that information to connect to one, many, or all of them.

Setting the clusterIP field in a service spec to None makes the service headless, as Kubernetes won’t assign it a cluster IP through which clients could connect to the pods backing it.
Örnek
Şöyle yaparız
apiVersion: v1
kind: Service
metadata:
  name: grpc-server-service
spec:
  clusterIP: None
  selector:
    app: grpc-server
  ports:
    - port: 80
      targetPort: 8001

19 Ağustos 2021 Perşembe

Packaging And Deployment

fiGiriş
Bir tane java projesini Linux'a kurmak için izlenen yol şöyleydi

1. mypackaging.sh çalıştırılır
Bu dosya maven'ı çalıştırır. maven bir tane zip üretir.
mvn -s ... -P ... clean package -D...
1. maven package phase çalışırken "makeself" kullanılarak tüm properties + jar + makeself ile kullanılan startup_script dosyasını içeren bir foo_installer.sh üretilir

2. maven package phase çalışırken "maven-assembly-plugin" kullanılarak bir zip üretilir. Aslında bu adım isteğe bağlı, makeself zaten her şeyi zipliyor gibi de düşünülebilir.

makeself
Örnek kullanım şöyle
Here is an example, assuming the user has a package image stored in a /home/joe/mysoft, and he wants to generate a self-extracting package named mysoft.sh, which will launch the “setup” script initially stored in /home/joe/mysoft :

makeself.sh /home/joe/mysoft mysoft.sh "Joe's Nice Software Package" ./setup
setup.sh içindeki metodlar şöyle
install_component()
{
  mkdir -v $DEPLOYMENT_DIR/app/"$1"
  cp -v -r ./foo.jar $DEPLOYMENT_DIR/app/"$1"
  cp -v -r "$2" $DEPLOYMENT_DIR/app/"$1"
}

perform_installation()
{
  install_component AFolder a.properties
  install_component AFolder b.properties
  ...
}
print_usage()
{
  echo "..."
}
setup.sh çalışması şöyle
#Check if help is selected
if [ "$1" == '-h' ]
then
  print_usage
  exit 1
fi

if (($EUID)); then
  echo "Non-root user can not run"
  exit 1
fi

if [ -d $DEPLOYMENT_DIR ]
then
  echo "$DEPLOYMENT_DIR exists"
else
  echo "Creating folder " $DEPLOYMENT_DIR
  mkdir -p $DEPLOYMENT_DIR
fi

perform_installation

16 Ağustos 2021 Pazartesi

Firmware

Giriş
Firmware paketleri kernel ile dağıtılmaz. Açıklaması şöyle
Many hardware device manufacturers do not embed firmware into their devices, they require firmware to be loaded into the device by the operating system's driver.

Some other manufacturers embed an old version of the firmware but allow an updated version to be loaded by the driver - quite often the embedded version is ancient and/or buggy (and rarely, if ever, updated in the device itself because that might require changes to the manufacturing or testing process - this is generally a deliberate design decision. The rationale is that the embedded firmware version doesn't have to be good, it just has to resemble something that's minimally functional - updates can and should be loaded by the driver)

The firmware files almost always have a license which is incompatible with the GPL (or even no explicit or discernible license, just an implied "right to use" by being distributed with the device itself and the Windows driver it comes with) and thus can not be distributed with the kernel itself, and has to be distributed as a separate package.
Firmware için şu link takip ederiz
Firmware for the Linux kernel is distributed separately and has its own development tree.

Firmware kurmak için önce yine apt install ile driver kurulur
Örnek
Şöyle yaparızz
sudo apt install firmware-ralink
dmesg çıktısında şunu alırız. İlk iki satırda firmware'in yüklendiği görülebilir.
... ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
... ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.36
... wlan0: authenticate with 30:23:03:41:73:67
... wlan0: send auth to 30:23:03:41:73:67 (try 1/3)
... wlan0: authenticated
... wlan0: associate with 30:23:03:41:73:67 (try 1/3)
... wlan0: RX AssocResp from 30:23:03:41:73:67 (capab=0x411 status=0 aid=5)
... wlan0: associated
... IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready

12 Ağustos 2021 Perşembe

run-parts komutu

Giriş
Çöken veya çalışmayan cron.daily işlerini elle tetiklemek için kullanılır. Örneğin günlük yedekleme (backup) çalışmadıysa.

Örnek
Şöyle yaparız
sudo run-parts /etc/cron.daily

3 Ağustos 2021 Salı

Linux ve Overcommit

Giriş
Linux uygulamaların talep ettikleri bellek miktarını aslında kullanmayacaklarını farz ederek, fiziksel ve sanal bellek üst sınırından çok daha fazlasını ayırıyormuş gibi çalışabilir. 

Buna overcommit deniliyor. Linux'ta "Out Of Memory (OOM) Killer" bulunur. Bu algoritma sistem konfigürasyonuna göre devreye girip çalışıyor

Overcommit Ayarı
Sistem ayarı /proc/sys/vm/overcommit_memory dosyasında ve çoğu sistem 0 değeri yani overcommit etkin olarak başlıyor. Açıklaması şöyle
/proc/sys/vm/overcommit_memory
       This file contains the kernel virtual memory accounting mode.
       Values are:

              0: heuristic overcommit (this is the default)
              1: always overcommit, never check
              2: always check, never overcommit

       In mode 0, calls of mmap(2) with MAP_NORESERVE are not
       checked, and the default check is very weak, leading to the
       risk of getting a process "OOM-killed".

       In mode 2 (available since Linux 2.6), the total virtual
       address space that can be allocated (CommitLimit in /proc/mem‐
       info) is calculated as

           CommitLimit = (total_RAM - total_huge_TLB) *
                         overcommit_ratio / 100 + total_swap
Bu dosyadaki değerler bilgisayarı yeniden başlatınca kaybolur. Esas değeri "/etc/sysctl.conf" dosyasına yazmak lazım

overcommit_memory = 0 İse OOM-Killer Devrededir
Bu durumda overcommit yapılır ve işletim sistemi çok fazla bellek isteyen bazı uygulamaları öldürür.
Yani /var/log/kern.log veya /var/log dosyasında "Out of Memory: Kill Process or Sacrifice Child" şeklinde hatalar görebiliriz.

Örnek
Şöyle bir satır görebiliriz
[ 1584.087068] Out of memory: Kill process 3070 (java) score 547 or sacrifice child 
[ 1584.094170] Killed process 3070 (java) total-vm:56994588kB, anon-rss:35690996kB, file-rss:0kB, shmem-rss:0kB
Koyu renkli sayıların açıklaması şöyle. 3070 Process Id (PID) anlamına gelir. 547 ise OOM algoritmasının bulduğu değerdir. totalvm sanırım 56GB civarında bellek kullandığını gösteriyor.
Above is the kernel log message printed on this device. You can note that the Operating System is killing our BuggyApp java process (whose Process Id is 3070). Note Operating System has internal algorithms and heuristics and keeps track of score for each process. Score this BuggyApp got was 547, thus it killed this process.
Örnek
Şöyle bir satır görebiliriz
kernel: [28244264.657076] Out of memory: Kill process 28854 (java) score 977 or sacrifice child

kernel: [28244264.657146] Killed process 28854, UID 500, (java) total-vm:138204008kB, 
  anon-rss:128965112kB, file-rss:144kB rss:0kB
overcommit_memory = 1 İse
İşletim sistemi hiç bir kontrol yapmaz. Açıklaması şöyle
... setting overcommit to 1, will set the stage so that when a program calls something like malloc() to allocate a chunk of memory (man 3 malloc), it will always succeed regardless if the system knows it will not have all the memory that is being asked for.

overcommit_memory = 2 İse
Halen overcommit yapılır ancak bu sefer üst sınır konulmuştur. Eldeki toplam bellek alanı * vm.overcommit_ratio değeri kadar bellek isteği yapılabilir. Açıklaması şöyle
When you set vm.overcommit_memory to 2, the vm.overcommit_ratio value becomes relevant. By default, this value is set to 50, which means the system would only allocate up to 50% of your RAM (plus swap).
Bir açıklama şöyle
If you set vm.overcommitmemory=2 then it will overcommit up to the percentage of physical RAM configured in vm.overcommitratio (default is 50%).

Overcommit Kod Örnekleri

Örnek
Aşağıdaki örnek döngü içinde çağrılarak 50GB bellek istense bile sorun çıkartmıyor.
unsigned long long memory_to_eat = 1024 * 50000;
size_t eaten_memory = 0;
void *memory = NULL;

int eat_kilobyte()
{
  if (memory == NULL)
    memory = malloc(1024);
  else
    memory = realloc(memory, (eaten_memory * 1024) + 1024);
  if (memory == NULL)
  {
    return 1;
  }
  else
  {
    eaten_memory++;
    return 0;
  }
}
Ancak ne zamanki kod sayfalara dokunmaya başlar, o zaman OOM hatası alırız.
int eat_kilobyte()
{
  if (memory == NULL)
    memory = malloc(1024);
  else
    memory = realloc(memory, (eaten_memory * 1024) + 1024);
  if (memory == NULL)
  {
    return 1;
  }
  else
  {
    //Force the kernel to map the containing memory page.
    ((char*)memory)[1024*eaten_memory] = 42;

    eaten_memory++;
    return 0;
  }
}